[nostalgia/core] Add key event handler
This commit is contained in:
parent
2223fe7863
commit
ea318bb6c8
@ -68,6 +68,8 @@ class Context {
|
|||||||
friend void setBgStatus(Context *ctx, unsigned bg, bool status) noexcept;
|
friend void setBgStatus(Context *ctx, unsigned bg, bool status) noexcept;
|
||||||
friend void setClipboardText(Context *ctx, const ox::String &text) noexcept;
|
friend void setClipboardText(Context *ctx, const ox::String &text) noexcept;
|
||||||
friend void setUpdateHandler(Context *ctx, UpdateHandler h) noexcept;
|
friend void setUpdateHandler(Context *ctx, UpdateHandler h) noexcept;
|
||||||
|
friend constexpr void setKeyEventHandler(Context *ctx, KeyEventHandler h) noexcept;
|
||||||
|
friend constexpr KeyEventHandler keyEventHandler(Context *ctx) noexcept;
|
||||||
friend void setTile(Context *ctx, int layer, int column, int row, uint8_t tile) noexcept;
|
friend void setTile(Context *ctx, int layer, int column, int row, uint8_t tile) noexcept;
|
||||||
friend void setWindowTitle(Context *ctx, const char *title) noexcept;
|
friend void setWindowTitle(Context *ctx, const char *title) noexcept;
|
||||||
|
|
||||||
@ -75,6 +77,7 @@ class Context {
|
|||||||
ox::UniquePtr<ox::FileSystem> rom;
|
ox::UniquePtr<ox::FileSystem> rom;
|
||||||
ox::Vector<Drawer*, 5> drawers;
|
ox::Vector<Drawer*, 5> drawers;
|
||||||
const char *appName = "Nostalgia";
|
const char *appName = "Nostalgia";
|
||||||
|
|
||||||
#ifndef OX_BARE_METAL
|
#ifndef OX_BARE_METAL
|
||||||
AssetManager assetManager;
|
AssetManager assetManager;
|
||||||
int uninterruptedRefreshes = 3;
|
int uninterruptedRefreshes = 3;
|
||||||
@ -85,6 +88,7 @@ class Context {
|
|||||||
// sets screen refresh to constant instead of only on event
|
// sets screen refresh to constant instead of only on event
|
||||||
bool constantRefresh = true;
|
bool constantRefresh = true;
|
||||||
#endif
|
#endif
|
||||||
|
KeyEventHandler m_keyEventHandler = nullptr;
|
||||||
void *m_customData = nullptr;
|
void *m_customData = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -98,13 +102,13 @@ class Context {
|
|||||||
Context(const Context &other) noexcept = delete;
|
Context(const Context &other) noexcept = delete;
|
||||||
Context(const Context &&other) noexcept = delete;
|
Context(const Context &&other) noexcept = delete;
|
||||||
|
|
||||||
protected:
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr T *windowerData() noexcept {
|
constexpr T *windowerData() noexcept {
|
||||||
return static_cast<T*>(m_windowerData);
|
return static_cast<T*>(m_windowerData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
constexpr void setWindowerData(void *windowerData) noexcept {
|
constexpr void setWindowerData(void *windowerData) noexcept {
|
||||||
m_windowerData = windowerData;
|
m_windowerData = windowerData;
|
||||||
}
|
}
|
||||||
@ -131,6 +135,14 @@ constexpr T *applicationData(Context *ctx) noexcept {
|
|||||||
return static_cast<T*>(ctx->m_customData);
|
return static_cast<T*>(ctx->m_customData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr void setKeyEventHandler(Context *ctx, KeyEventHandler h) noexcept {
|
||||||
|
ctx->m_keyEventHandler = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr KeyEventHandler keyEventHandler(Context *ctx) noexcept {
|
||||||
|
return ctx->m_keyEventHandler;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr void setConstantRefresh([[maybe_unused]] Context *ctx, [[maybe_unused]] bool r) noexcept {
|
constexpr void setConstantRefresh([[maybe_unused]] Context *ctx, [[maybe_unused]] bool r) noexcept {
|
||||||
#ifndef OX_BARE_METAL
|
#ifndef OX_BARE_METAL
|
||||||
ctx->constantRefresh = r;
|
ctx->constantRefresh = r;
|
||||||
|
@ -74,8 +74,9 @@ uint64_t ticksMs(Context *ctx) noexcept {
|
|||||||
return static_cast<uint64_t>(now - id->startTime);
|
return static_cast<uint64_t>(now - id->startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool buttonDown(Context*, Key) noexcept {
|
bool buttonDown(Context *ctx, Key key) noexcept {
|
||||||
return false;
|
const auto id = ctx->windowerData<GlfwImplData>();
|
||||||
|
return (id->keysDown >> static_cast<int>(key)) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error shutdown(Context *ctx) noexcept {
|
ox::Error shutdown(Context *ctx) noexcept {
|
||||||
|
@ -12,7 +12,9 @@ struct GlfwImplData {
|
|||||||
struct GLFWwindow *window = nullptr;
|
struct GLFWwindow *window = nullptr;
|
||||||
int64_t startTime = 0;
|
int64_t startTime = 0;
|
||||||
UpdateHandler eventHandler = nullptr;
|
UpdateHandler eventHandler = nullptr;
|
||||||
|
KeyEventHandler keyEventHandler = nullptr;
|
||||||
uint64_t wakeupTime = 0;
|
uint64_t wakeupTime = 0;
|
||||||
|
uint64_t keysDown;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,17 +20,51 @@ static void handleGlfwError(int err, const char *desc) noexcept {
|
|||||||
oxErrf("GLFW error ({}): {}\n", err, desc);
|
oxErrf("GLFW error ({}): {}\n", err, desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleKeyPress(Context *ctx, int key) noexcept {
|
static auto setKeyDownStatus(GlfwImplData *id, Key key, bool down) noexcept {
|
||||||
|
if (down) {
|
||||||
|
id->keysDown |= 1llu << static_cast<int>(key);
|
||||||
|
} else {
|
||||||
|
id->keysDown &= ~(1llu << static_cast<int>(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handleKeyPress(Context *ctx, int key, bool down) noexcept {
|
||||||
|
const auto eventHandler = keyEventHandler(ctx);
|
||||||
|
const auto id = ctx->windowerData<GlfwImplData>();
|
||||||
|
if (eventHandler) {
|
||||||
|
if (key >= GLFW_KEY_A && key <= GLFW_KEY_Z) {
|
||||||
|
const auto k = static_cast<Key>(Key::Alpha_A + (key - GLFW_KEY_A));
|
||||||
|
setKeyDownStatus(id, k, down);
|
||||||
|
eventHandler(ctx, k, down);
|
||||||
|
} else if (key >= GLFW_KEY_0 && key <= GLFW_KEY_9) {
|
||||||
|
const auto k = static_cast<Key>(Key::Num_0 + (key - GLFW_KEY_0));
|
||||||
|
setKeyDownStatus(id, k, down);
|
||||||
|
eventHandler(ctx, k, down);
|
||||||
|
} else {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case GLFW_KEY_ESCAPE:
|
case GLFW_KEY_LEFT_SHIFT:
|
||||||
case GLFW_KEY_Q:
|
case GLFW_KEY_RIGHT_SHIFT:
|
||||||
if constexpr(ox::defines::Debug) {
|
setKeyDownStatus(id, Key::Mod_Shift, down);
|
||||||
oxIgnoreError(shutdown(ctx));
|
eventHandler(ctx, Key::Mod_Shift, down);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
case GLFW_KEY_LEFT_CONTROL:
|
||||||
|
case GLFW_KEY_RIGHT_CONTROL:
|
||||||
|
setKeyDownStatus(id, Key::Mod_Ctrl, down);
|
||||||
|
eventHandler(ctx, Key::Mod_Ctrl, down);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//if constexpr(ox::defines::Debug) {
|
||||||
|
// switch (key) {
|
||||||
|
// case GLFW_KEY_ESCAPE:
|
||||||
|
// case GLFW_KEY_Q:
|
||||||
|
// oxIgnoreError(shutdown(ctx));
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleGlfwCursorPosEvent(GLFWwindow*, double, double) noexcept {
|
static void handleGlfwCursorPosEvent(GLFWwindow*, double, double) noexcept {
|
||||||
@ -48,7 +82,9 @@ static void handleGlfwKeyEvent(GLFWwindow *window, int key, int, int action, int
|
|||||||
const auto ctx = static_cast<Context*>(glfwGetWindowUserPointer(window));
|
const auto ctx = static_cast<Context*>(glfwGetWindowUserPointer(window));
|
||||||
ctx->uninterruptedRefreshes = 2;
|
ctx->uninterruptedRefreshes = 2;
|
||||||
if (action == GLFW_PRESS) {
|
if (action == GLFW_PRESS) {
|
||||||
handleKeyPress(ctx, key);
|
handleKeyPress(ctx, key, true);
|
||||||
|
} else if (action == GLFW_RELEASE) {
|
||||||
|
handleKeyPress(ctx, key, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,15 +9,58 @@ namespace nostalgia::core {
|
|||||||
enum Key {
|
enum Key {
|
||||||
// GBA implementation currently relies on GamePad entry order
|
// GBA implementation currently relies on GamePad entry order
|
||||||
GamePad_A = 1,
|
GamePad_A = 1,
|
||||||
GamePad_B = 2,
|
GamePad_B,
|
||||||
GamePad_Select = 4,
|
GamePad_Select,
|
||||||
GamePad_Start = 8,
|
GamePad_Start,
|
||||||
GamePad_Right = 16,
|
GamePad_Right,
|
||||||
GamePad_Left = 32,
|
GamePad_Left,
|
||||||
GamePad_Up = 64,
|
GamePad_Up,
|
||||||
GamePad_Down = 128,
|
GamePad_Down,
|
||||||
GamePad_R = 256,
|
GamePad_R,
|
||||||
GamePad_L = 512,
|
GamePad_L,
|
||||||
|
|
||||||
|
Num_0,
|
||||||
|
Num_1,
|
||||||
|
Num_2,
|
||||||
|
Num_3,
|
||||||
|
Num_4,
|
||||||
|
Num_5,
|
||||||
|
Num_6,
|
||||||
|
Num_7,
|
||||||
|
Num_8,
|
||||||
|
Num_9,
|
||||||
|
|
||||||
|
Alpha_A,
|
||||||
|
Alpha_B,
|
||||||
|
Alpha_C,
|
||||||
|
Alpha_D,
|
||||||
|
Alpha_E,
|
||||||
|
Alpha_F,
|
||||||
|
Alpha_G,
|
||||||
|
Alpha_H,
|
||||||
|
Alpha_I,
|
||||||
|
Alpha_J,
|
||||||
|
Alpha_K,
|
||||||
|
Alpha_L,
|
||||||
|
Alpha_M,
|
||||||
|
Alpha_N,
|
||||||
|
Alpha_O,
|
||||||
|
Alpha_P,
|
||||||
|
Alpha_Q,
|
||||||
|
Alpha_R,
|
||||||
|
Alpha_S,
|
||||||
|
Alpha_T,
|
||||||
|
Alpha_U,
|
||||||
|
Alpha_V,
|
||||||
|
Alpha_W,
|
||||||
|
Alpha_X,
|
||||||
|
Alpha_Y,
|
||||||
|
Alpha_Z,
|
||||||
|
|
||||||
|
Mod_Ctrl,
|
||||||
|
Mod_Shift,
|
||||||
|
|
||||||
|
End
|
||||||
};
|
};
|
||||||
|
|
||||||
class Context;
|
class Context;
|
||||||
@ -25,4 +68,6 @@ class Context;
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
bool buttonDown(Context *ctx, Key) noexcept;
|
bool buttonDown(Context *ctx, Key) noexcept;
|
||||||
|
|
||||||
|
using KeyEventHandler = void(*)(Context*, Key, bool);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user