Support of IsKeyPressed that only trigger for the frame it is pressed on.
This commit is contained in:
+18
-1
@@ -5,13 +5,16 @@
|
||||
|
||||
#include <game.h>
|
||||
|
||||
#include <Core/Common/EnumUtils.h>
|
||||
#include <Core/HAL/Filesystem/Filesystem.h>
|
||||
#include <Core/HAL/Keyboard/Keyboard.h>
|
||||
#include <Core/JulietInit.h>
|
||||
#include <Core/Logging/LogManager.h>
|
||||
#include <Core/Memory/MemoryArena.h>
|
||||
#include <Entity/Entity.h>
|
||||
#include <Entity/EntityManager.h>
|
||||
#include <Graphics/Camera.h>
|
||||
#include <imgui.h>
|
||||
|
||||
GameState* gGameState = nullptr;
|
||||
GameState* GetGameState()
|
||||
@@ -92,5 +95,19 @@ extern "C" JULIET_API void __cdecl GameUpdate(Juliet::GameData* params, [[maybe_
|
||||
printf("Rock has %d health points\n", rock->Health);
|
||||
}
|
||||
|
||||
// printf("Updating game...\n");
|
||||
if (IsKeyPressed(ScanCode::F1))
|
||||
{
|
||||
gGameState->Mode = static_cast<GameMode>((ToUnderlying(gGameState->Mode) + 1) % 2);
|
||||
}
|
||||
|
||||
if (gGameState->Mode == GameMode::Play)
|
||||
{
|
||||
// update game
|
||||
}
|
||||
|
||||
if (gGameState->Mode == GameMode::Debug)
|
||||
{
|
||||
ImGui::Begin("Debug");
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,12 +10,20 @@ struct World
|
||||
EntityManager* EntityManager;
|
||||
};
|
||||
|
||||
enum class GameMode
|
||||
{
|
||||
Play,
|
||||
Debug
|
||||
};
|
||||
|
||||
struct GameState
|
||||
{
|
||||
Juliet::Arena* TotalArena;
|
||||
|
||||
World* World;
|
||||
|
||||
GameMode Mode = GameMode::Play;
|
||||
|
||||
float TotalTime;
|
||||
int Score;
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Juliet
|
||||
virtual ~IApplication() = default;
|
||||
virtual void Init(NonNullPtr<Arena> arena) = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
virtual void Update() = 0;
|
||||
virtual void Update(float deltaTime) = 0;
|
||||
virtual bool IsRunning() = 0;
|
||||
|
||||
// Accessors for Engine Systems
|
||||
|
||||
@@ -118,4 +118,6 @@ namespace Juliet
|
||||
// Add an event onto the event queue.
|
||||
// TODO : support array of events
|
||||
extern JULIET_API bool AddEvent(SystemEvent& event);
|
||||
|
||||
extern void Events_NewFrame(float deltaTime);
|
||||
} // namespace Juliet
|
||||
|
||||
@@ -8,12 +8,18 @@ namespace Juliet
|
||||
{
|
||||
using KeyboardID = uint8;
|
||||
|
||||
enum class KeyState : bool
|
||||
enum class KeyPosition : bool
|
||||
{
|
||||
Up = false,
|
||||
Down = true
|
||||
};
|
||||
|
||||
struct KeyState
|
||||
{
|
||||
KeyPosition Position;
|
||||
float Time;
|
||||
};
|
||||
|
||||
struct Key
|
||||
{
|
||||
ScanCode ScanCode;
|
||||
@@ -22,6 +28,7 @@ namespace Juliet
|
||||
};
|
||||
|
||||
extern JULIET_API bool IsKeyDown(ScanCode scanCode);
|
||||
extern JULIET_API bool IsKeyPressed(ScanCode scanCode);
|
||||
|
||||
extern JULIET_API KeyMod GetKeyModState();
|
||||
extern JULIET_API KeyCode GetKeyCodeFromScanCode(ScanCode scanCode, KeyMod keyModState);
|
||||
|
||||
@@ -31,6 +31,11 @@ namespace Juliet
|
||||
|
||||
} // namespace Memory
|
||||
|
||||
namespace Time
|
||||
{
|
||||
uint64 Timestamp();
|
||||
} // namespace Time
|
||||
|
||||
namespace Debug
|
||||
{
|
||||
JULIET_API bool IsDebuggerPresent();
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <Core/Memory/Utils.h>
|
||||
|
||||
// For GET_X_LPARAM, GET_Y_LPARAM.
|
||||
#include <Core/HAL/OS/OS.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
#ifdef JULIET_ENABLE_IMGUI
|
||||
@@ -157,7 +158,7 @@ namespace Juliet::Win32
|
||||
LRESULT returnCode = -1;
|
||||
|
||||
// Wait until the window state is created before doing anything
|
||||
auto* windowState = GetWindowStateFromHandle(handle);
|
||||
Window32State* windowState = GetWindowStateFromHandle(handle);
|
||||
if (!windowState)
|
||||
{
|
||||
return CallWindowProcA(DefWindowProcA, handle, message, wParam, lParam);
|
||||
@@ -188,7 +189,7 @@ namespace Juliet::Win32
|
||||
SendWindowEvent(windowState->Window, EventType::Window_Close_Request);
|
||||
}
|
||||
|
||||
SendKeyboardKey(1, kGlobalKeyboardID, key, KeyState::Down);
|
||||
SendKeyboardKey(Time::Timestamp(), kGlobalKeyboardID, key, KeyPosition::Down);
|
||||
|
||||
returnCode = 0;
|
||||
break;
|
||||
@@ -197,7 +198,7 @@ namespace Juliet::Win32
|
||||
case WM_KEYUP:
|
||||
{
|
||||
Key key = GetScanScodeFromWinScanCode(wParam, lParam);
|
||||
SendKeyboardKey(1, kGlobalKeyboardID, key, KeyState::Up);
|
||||
SendKeyboardKey(Time::Timestamp(), kGlobalKeyboardID, key, KeyPosition::Up);
|
||||
|
||||
returnCode = 0;
|
||||
break;
|
||||
|
||||
@@ -15,14 +15,14 @@ namespace Juliet
|
||||
KeyMod KeyModState;
|
||||
} KeyboardState;
|
||||
|
||||
bool SendKeyboardKey_Internal(uint64 timestamp, KeyboardID /*ID*/, Key key, KeyState keyState)
|
||||
bool SendKeyboardKey_Internal(uint64 timestamp, KeyboardID /*ID*/, Key key, KeyPosition keyPosition)
|
||||
{
|
||||
Assert(key.KeyCode == KeyCode::Unknown); // At this point Keycode is not yet extracted
|
||||
|
||||
auto& keyboardState = KeyboardState; // Needed because MSVC debugger ignores variable in anonymouse namespace
|
||||
|
||||
auto type = EventType::None;
|
||||
const bool isKeyDown = keyState == KeyState::Down;
|
||||
const bool isKeyDown = keyPosition == KeyPosition::Down;
|
||||
if (isKeyDown)
|
||||
{
|
||||
type = EventType::Key_Down;
|
||||
@@ -40,20 +40,20 @@ namespace Juliet
|
||||
// If state didn't change, this is a key repeat
|
||||
if (isKeyDown)
|
||||
{
|
||||
if (currentKeyState == KeyState::Down)
|
||||
if (currentKeyState.Position == KeyPosition::Down)
|
||||
{
|
||||
isKeyRepeat = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentKeyState == KeyState::Up)
|
||||
if (currentKeyState.Position == KeyPosition::Up)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
keyboardState.KeyState[ToUnderlying(key.ScanCode)] = keyState;
|
||||
currentKeyState.Position = keyPosition;
|
||||
key.KeyCode = GetKeyCodeFromScanCode(key.ScanCode, keyboardState.KeyModState);
|
||||
}
|
||||
else if (key.Raw == 0)
|
||||
@@ -99,7 +99,7 @@ namespace Juliet
|
||||
evt.Type = type;
|
||||
evt.Data.Keyboard.AssociatedKeyboardID = kGlobalKeyboardID;
|
||||
evt.Data.Keyboard.Key = key;
|
||||
evt.Data.Keyboard.KeyState = keyState;
|
||||
evt.Data.Keyboard.KeyState = { keyPosition };
|
||||
evt.Data.Keyboard.KeyModeState = keyboardState.KeyModState;
|
||||
|
||||
bool evtPosted = AddEvent(evt);
|
||||
@@ -108,14 +108,42 @@ namespace Juliet
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool SendKeyboardKey(uint64 timestamp, KeyboardID ID, Key key, KeyState keyState)
|
||||
bool SendKeyboardKey(uint64 timestamp, KeyboardID ID, Key key, KeyPosition keyPosition)
|
||||
{
|
||||
return SendKeyboardKey_Internal(timestamp, ID, key, keyState);
|
||||
return SendKeyboardKey_Internal(timestamp, ID, key, keyPosition);
|
||||
}
|
||||
|
||||
void UpdateKeyboardstate(float deltaTime)
|
||||
{
|
||||
for (KeyState& state : KeyboardState.KeyState)
|
||||
{
|
||||
if (state.Position == KeyPosition::Down)
|
||||
{
|
||||
if (state.Time < 0.0f)
|
||||
{
|
||||
state.Time = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.Time += deltaTime;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
state.Time = -1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsKeyDown(ScanCode scanCode)
|
||||
{
|
||||
return KeyboardState.KeyState[ToUnderlying(scanCode)] == KeyState::Down;
|
||||
return KeyboardState.KeyState[ToUnderlying(scanCode)].Position == KeyPosition::Down;
|
||||
}
|
||||
|
||||
bool IsKeyPressed(ScanCode scanCode)
|
||||
{
|
||||
auto& keyState = KeyboardState.KeyState[ToUnderlying(scanCode)];
|
||||
return keyState.Position == KeyPosition::Down && keyState.Time == 0.0f;
|
||||
}
|
||||
|
||||
KeyMod GetKeyModState()
|
||||
@@ -129,9 +157,9 @@ namespace Juliet
|
||||
return GetKeyCodeFromDefaultMapping(scanCode, keyModState);
|
||||
}
|
||||
|
||||
static_assert(sizeof(KeyState) == sizeof(bool));
|
||||
static_assert(ToUnderlying(KeyState::Down) == true);
|
||||
static_assert(ToUnderlying(KeyState::Up) == false);
|
||||
static_assert(sizeof(KeyPosition) == sizeof(bool));
|
||||
static_assert(ToUnderlying(KeyPosition::Down) == true);
|
||||
static_assert(ToUnderlying(KeyPosition::Up) == false);
|
||||
static_assert(sizeof(ScanCode) == sizeof(uint16));
|
||||
static_assert(ToUnderlying(ScanCode::Count) == 512);
|
||||
} // namespace Juliet
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
extern bool SendKeyboardKey(uint64 timestamp, KeyboardID ID, Key key, KeyState keyState);
|
||||
extern bool SendKeyboardKey(uint64 timestamp, KeyboardID ID, Key key, KeyPosition keyPosition);
|
||||
extern void UpdateKeyboardstate(float deltaTime);
|
||||
|
||||
extern const KeyboardID kGlobalKeyboardID;
|
||||
} // namespace Juliet
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <Core/HAL/Display/DisplayDevice.h>
|
||||
#include <Core/HAL/Event/SystemEvent.h>
|
||||
|
||||
#include <Core/HAL/Event/Keyboard_Private.h>
|
||||
|
||||
#pragma push_macro("global")
|
||||
#undef global
|
||||
|
||||
@@ -87,4 +89,10 @@ namespace Juliet
|
||||
|
||||
return AddEvent_Internal(event);
|
||||
}
|
||||
|
||||
void Events_NewFrame(float deltaTime)
|
||||
{
|
||||
UpdateKeyboardstate(deltaTime);
|
||||
}
|
||||
|
||||
} // namespace Juliet
|
||||
|
||||
@@ -21,6 +21,14 @@ namespace Juliet
|
||||
}
|
||||
} // namespace Memory
|
||||
|
||||
namespace Time
|
||||
{
|
||||
uint64 Timestamp()
|
||||
{
|
||||
return Internal::OS_Timestamp();
|
||||
}
|
||||
} // namespace Time
|
||||
|
||||
namespace Debug
|
||||
{
|
||||
bool IsDebuggerPresent()
|
||||
|
||||
@@ -13,6 +13,12 @@ namespace Juliet
|
||||
{
|
||||
bool IsDebuggerPresent();
|
||||
} // namespace Debug::Internal
|
||||
|
||||
namespace Time::Internal
|
||||
{
|
||||
uint64 OS_Timestamp();
|
||||
}
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
int OS_Main(EntryPointFunc entryPointFunc, int argc, wchar_t** argv);
|
||||
|
||||
@@ -45,6 +45,17 @@ namespace Juliet
|
||||
}
|
||||
} // namespace Memory::Internal
|
||||
|
||||
namespace Time::Internal
|
||||
{
|
||||
uint64 OS_Timestamp()
|
||||
{
|
||||
FILETIME ft;
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
|
||||
return (static_cast<uint64>(ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
|
||||
}
|
||||
} // namespace Time::Internal
|
||||
|
||||
namespace Debug::Internal
|
||||
{
|
||||
bool IsDebuggerPresent()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <Engine/Engine.h>
|
||||
|
||||
#include <Core/Common/CoreUtils.h>
|
||||
#include <Core/HAL/Event/SystemEvent.h>
|
||||
#include <Core/HAL/Filesystem/Filesystem_Private.h>
|
||||
#include <Core/JulietInit.h>
|
||||
#include <Core/Logging/LogManager.h>
|
||||
@@ -18,6 +19,14 @@
|
||||
#include <imgui.h>
|
||||
#endif
|
||||
|
||||
// TODO Move to os hal for query perf
|
||||
#ifdef _WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
#if JULIET_DEBUG
|
||||
@@ -210,8 +219,25 @@ namespace Juliet
|
||||
ImGuiRenderer_NewFrame();
|
||||
#endif
|
||||
|
||||
// TODO : Move to os side as it is win32 only
|
||||
static LARGE_INTEGER frequency = {};
|
||||
static LARGE_INTEGER lastTime = {};
|
||||
if (frequency.QuadPart == 0)
|
||||
{
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
QueryPerformanceCounter(&lastTime);
|
||||
}
|
||||
|
||||
LARGE_INTEGER currentTime;
|
||||
QueryPerformanceCounter(¤tTime);
|
||||
float deltaTime =
|
||||
static_cast<float>(currentTime.QuadPart - lastTime.QuadPart) / static_cast<float>(frequency.QuadPart);
|
||||
lastTime = currentTime;
|
||||
|
||||
Events_NewFrame(deltaTime);
|
||||
|
||||
// Logic tick
|
||||
EngineInstance.Application->Update();
|
||||
EngineInstance.Application->Update(deltaTime);
|
||||
|
||||
// Render tick
|
||||
RenderFrame();
|
||||
|
||||
+1
-12
@@ -225,20 +225,9 @@ void JulietApplication::Shutdown()
|
||||
Log(LogLevel::Message, LogCategory::Tool, "Juliet App shutdown Completed");
|
||||
}
|
||||
|
||||
void JulietApplication::Update()
|
||||
void JulietApplication::Update(float deltaTime)
|
||||
{
|
||||
static LARGE_INTEGER frequency = {};
|
||||
static LARGE_INTEGER lastTime = {};
|
||||
if (frequency.QuadPart == 0)
|
||||
{
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
QueryPerformanceCounter(&lastTime);
|
||||
}
|
||||
|
||||
LARGE_INTEGER currentTime;
|
||||
QueryPerformanceCounter(¤tTime);
|
||||
float deltaTime = static_cast<float>(currentTime.QuadPart - lastTime.QuadPart) / static_cast<float>(frequency.QuadPart);
|
||||
lastTime = currentTime;
|
||||
|
||||
CameraTime += deltaTime;
|
||||
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ class JulietApplication : public Juliet::IApplication
|
||||
protected:
|
||||
void Init(Juliet::NonNullPtr<Juliet::Arena> arena) override;
|
||||
void Shutdown() override;
|
||||
void Update() override;
|
||||
void Update(float deltaTime) override;
|
||||
bool IsRunning() override;
|
||||
|
||||
Juliet::Window* GetPlatformWindow() override { return MainWindow; }
|
||||
|
||||
Reference in New Issue
Block a user