[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 setClipboardText(Context *ctx, const ox::String &text) 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 setWindowTitle(Context *ctx, const char *title) noexcept;
|
||||
|
||||
@ -75,6 +77,7 @@ class Context {
|
||||
ox::UniquePtr<ox::FileSystem> rom;
|
||||
ox::Vector<Drawer*, 5> drawers;
|
||||
const char *appName = "Nostalgia";
|
||||
|
||||
#ifndef OX_BARE_METAL
|
||||
AssetManager assetManager;
|
||||
int uninterruptedRefreshes = 3;
|
||||
@ -85,6 +88,7 @@ class Context {
|
||||
// sets screen refresh to constant instead of only on event
|
||||
bool constantRefresh = true;
|
||||
#endif
|
||||
KeyEventHandler m_keyEventHandler = nullptr;
|
||||
void *m_customData = nullptr;
|
||||
|
||||
private:
|
||||
@ -98,13 +102,13 @@ class Context {
|
||||
Context(const Context &other) noexcept = delete;
|
||||
Context(const Context &&other) noexcept = delete;
|
||||
|
||||
protected:
|
||||
template<typename T>
|
||||
[[nodiscard]]
|
||||
constexpr T *windowerData() noexcept {
|
||||
return static_cast<T*>(m_windowerData);
|
||||
}
|
||||
|
||||
protected:
|
||||
constexpr void setWindowerData(void *windowerData) noexcept {
|
||||
m_windowerData = windowerData;
|
||||
}
|
||||
@ -131,6 +135,14 @@ constexpr T *applicationData(Context *ctx) noexcept {
|
||||
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 {
|
||||
#ifndef OX_BARE_METAL
|
||||
ctx->constantRefresh = r;
|
||||
|
@ -74,8 +74,9 @@ uint64_t ticksMs(Context *ctx) noexcept {
|
||||
return static_cast<uint64_t>(now - id->startTime);
|
||||
}
|
||||
|
||||
bool buttonDown(Context*, Key) noexcept {
|
||||
return false;
|
||||
bool buttonDown(Context *ctx, Key key) noexcept {
|
||||
const auto id = ctx->windowerData<GlfwImplData>();
|
||||
return (id->keysDown >> static_cast<int>(key)) & 1;
|
||||
}
|
||||
|
||||
ox::Error shutdown(Context *ctx) noexcept {
|
||||
|
@ -12,7 +12,9 @@ struct GlfwImplData {
|
||||
struct GLFWwindow *window = nullptr;
|
||||
int64_t startTime = 0;
|
||||
UpdateHandler eventHandler = nullptr;
|
||||
KeyEventHandler keyEventHandler = nullptr;
|
||||
uint64_t wakeupTime = 0;
|
||||
uint64_t keysDown;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -20,19 +20,53 @@ static void handleGlfwError(int err, const char *desc) noexcept {
|
||||
oxErrf("GLFW error ({}): {}\n", err, desc);
|
||||
}
|
||||
|
||||
static void handleKeyPress(Context *ctx, int key) noexcept {
|
||||
switch (key) {
|
||||
case GLFW_KEY_ESCAPE:
|
||||
case GLFW_KEY_Q:
|
||||
if constexpr(ox::defines::Debug) {
|
||||
oxIgnoreError(shutdown(ctx));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
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) {
|
||||
case GLFW_KEY_LEFT_SHIFT:
|
||||
case GLFW_KEY_RIGHT_SHIFT:
|
||||
setKeyDownStatus(id, Key::Mod_Shift, down);
|
||||
eventHandler(ctx, Key::Mod_Shift, down);
|
||||
break;
|
||||
case GLFW_KEY_LEFT_CONTROL:
|
||||
case GLFW_KEY_RIGHT_CONTROL:
|
||||
setKeyDownStatus(id, Key::Mod_Ctrl, down);
|
||||
eventHandler(ctx, Key::Mod_Ctrl, down);
|
||||
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 {
|
||||
}
|
||||
|
||||
@ -48,7 +82,9 @@ static void handleGlfwKeyEvent(GLFWwindow *window, int key, int, int action, int
|
||||
const auto ctx = static_cast<Context*>(glfwGetWindowUserPointer(window));
|
||||
ctx->uninterruptedRefreshes = 2;
|
||||
if (action == GLFW_PRESS) {
|
||||
handleKeyPress(ctx, key);
|
||||
handleKeyPress(ctx, key, true);
|
||||
} else if (action == GLFW_RELEASE) {
|
||||
handleKeyPress(ctx, key, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,16 +8,59 @@ namespace nostalgia::core {
|
||||
|
||||
enum Key {
|
||||
// GBA implementation currently relies on GamePad entry order
|
||||
GamePad_A = 1,
|
||||
GamePad_B = 2,
|
||||
GamePad_Select = 4,
|
||||
GamePad_Start = 8,
|
||||
GamePad_Right = 16,
|
||||
GamePad_Left = 32,
|
||||
GamePad_Up = 64,
|
||||
GamePad_Down = 128,
|
||||
GamePad_R = 256,
|
||||
GamePad_L = 512,
|
||||
GamePad_A = 1,
|
||||
GamePad_B,
|
||||
GamePad_Select,
|
||||
GamePad_Start,
|
||||
GamePad_Right,
|
||||
GamePad_Left,
|
||||
GamePad_Up,
|
||||
GamePad_Down,
|
||||
GamePad_R,
|
||||
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;
|
||||
@ -25,4 +68,6 @@ class Context;
|
||||
[[nodiscard]]
|
||||
bool buttonDown(Context *ctx, Key) noexcept;
|
||||
|
||||
using KeyEventHandler = void(*)(Context*, Key, bool);
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user