From 7a98eb4dfbf71361ec6cba3a9bf746809931ec1f Mon Sep 17 00:00:00 2001 From: Aaro Saila Date: Fri, 3 Jul 2026 22:07:03 +0300 Subject: [PATCH] keymapping --- meson.build | 2 + src/log.c | 12 ++-- src/log.h | 16 +++-- src/main.c | 20 ++++-- src/pltf/pltf.h | 23 ++++++- src/pltf/win32/gl_funcs.c | 2 +- src/pltf/win32/internal.c | 52 ++++++++++++++++ src/pltf/win32/internal.h | 37 +++++++++++ src/pltf/win32/pltf.c | 121 +++++++++--------------------------- src/pltf/win32/pltf_win32.h | 8 --- src/pltf/win32/win_proc.c | 66 ++++++++++++++++++++ src/pltf/win32/win_proc.h | 8 +++ 12 files changed, 248 insertions(+), 119 deletions(-) create mode 100644 src/pltf/win32/internal.c create mode 100644 src/pltf/win32/internal.h delete mode 100644 src/pltf/win32/pltf_win32.h create mode 100644 src/pltf/win32/win_proc.c create mode 100644 src/pltf/win32/win_proc.h diff --git a/meson.build b/meson.build index 3e36e89..4fefe49 100644 --- a/meson.build +++ b/meson.build @@ -54,7 +54,9 @@ endif executable( 'scuffedcraft', 'src/pltf/win32/gl_funcs.c', + 'src/pltf/win32/internal.c', 'src/pltf/win32/pltf.c', + 'src/pltf/win32/win_proc.c', 'src/DynArray.c', 'src/DynString.c', 'src/log.c', diff --git a/src/log.c b/src/log.c index 7fe6a81..3fa90ca 100644 --- a/src/log.c +++ b/src/log.c @@ -2,16 +2,16 @@ #include #include -void log_error(char* file, size_t line, char* str) { - fprintf(stderr, "[ERROR] %s:%zu: %s\n", file, line, str); +void log_with_tag(FILE* out_file, char* file_name, size_t line, const char* tag, char* str) { + fprintf(out_file, "[%s] %s:%zu: %s\n", tag, file_name, line, str); } -void log_errorf(char* file, size_t line, char* fmt, ...) { - fprintf(stderr, "[ERROR] %s:%zu: ", file, line); +void logf_with_tag(FILE* out_file, char* file_name, size_t line, const char* tag, char* fmt, ...) { + fprintf(out_file, "[%s] %s:%zu: ", tag, file_name, line); va_list args; va_start(args, fmt); - vfprintf(stderr, fmt, args); + vfprintf(out_file, fmt, args); va_end(args); - fprintf(stderr, "\n"); + fprintf(out_file, "\n"); } diff --git a/src/log.h b/src/log.h index 6bd126f..047981a 100644 --- a/src/log.h +++ b/src/log.h @@ -3,14 +3,18 @@ #include #include +#include -#define LOG_ERROR(str) log_error(__FILE__, __LINE__, (str)) -#define LOG_ERRORF(fmt, ...) log_errorf(__FILE__, __LINE__, (fmt), __VA_ARGS__) +#define LOG_ERROR(str) log_with_tag(stderr, __FILE__, __LINE__, "ERROR", (str)) +#define LOG_ERRORF(fmt, ...) logf_with_tag(stderr, __FILE__, __LINE__, "ERROR", (fmt), __VA_ARGS__) -#define LOG_FATAL(str) LOG_ERROR(str); exit(-1); -#define LOG_FATALF(fmt, ...) LOG_ERRORF(fmt, __VA_ARGS__); exit(-1); +#define LOG_FATAL(str) LOG_ERROR(str); exit(-1) +#define LOG_FATALF(fmt, ...) LOG_ERRORF(fmt, __VA_ARGS__); exit(-1) -void log_error(char* file, size_t line, char* str); -void log_errorf(char* file, size_t line, char* fmt, ...); +#define LOG_FATAL_TODO(str) log_with_tag(stderr, __FILE__, __LINE__, "FATAL TODO", (str)); exit(-1) +#define LOG_FATAL_TODOF(fmt, ...) logf_with_tag(stderr, __FILE__, __LINE__, "FATAL TODO", (fmt), __VA_ARGS__); exit(-1) + +void log_with_tag(FILE* out_file, char* file_name, size_t line, const char* tag, char* str); +void logf_with_tag(FILE* out_file, char* file_name, size_t line, const char* tag, char* fmt, ...); #endif // LOG_H_ diff --git a/src/main.c b/src/main.c index 6e3d65c..92cf94b 100644 --- a/src/main.c +++ b/src/main.c @@ -7,6 +7,12 @@ #include "pltf/gl_funcs.h" #include "shader.h" +void counter_cb(void* user_data) { + int* counter = (int*) user_data; + printf("Counter: %d\n", *counter); + (*counter)++; +} + int main() { pltf_init(); pltf_window_create(); @@ -15,6 +21,10 @@ int main() { pltf_gl_ctx_info_print(); + pltf_key_callback_set(PLTF_KEY_ESC, pltf_window_close, NULL); + int counter = 0; + pltf_key_callback_set(PLTF_KEY_Q, counter_cb, &counter); + // clang-format off const float triangle_verts[] = { // pos @@ -60,10 +70,6 @@ int main() { glClearColor(0.0f, 0.0f, 0.8f, 1.0f); while (true) { - if (pltf_window_event_handle() == PLTF_WE_QUIT) { - goto cleanup; - } - glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shader); @@ -71,9 +77,13 @@ int main() { glDrawArrays(GL_TRIANGLES, 0, triangle_vert_count); pltf_swap_buffers(); + + const int pltf_we = pltf_window_event_handle(); + if (pltf_we == PLTF_WE_DESTROY) { + break; + } } -cleanup: pltf_gl_ctx_destroy(); pltf_window_destroy(); pltf_deinit(); diff --git a/src/pltf/pltf.h b/src/pltf/pltf.h index ff0c8bc..8f4a79b 100644 --- a/src/pltf/pltf.h +++ b/src/pltf/pltf.h @@ -5,17 +5,38 @@ typedef enum { PLTF_WE_NULL, - PLTF_WE_QUIT + PLTF_WE_DESTROY, } PltfWindowEvent; +#define PLTF_KEYS(PLTF_KEYS_X) \ + PLTF_KEYS_X(esc, ESC) \ + PLTF_KEYS_X(q, Q) + +#define PLTF_KEYS_X(lower, upper) PLTF_KEY_##upper, + +typedef enum { + PLTF_KEY_NONE, // None doesn't need a cb etc. so it's declared outside of the macro and handled specially where needed + PLTF_KEYS(PLTF_KEYS_X) +} PltfKey; + +#undef PLTF_KEYS_X + +typedef void (*PltfKeyCallback)(void* user_data); + void pltf_init(); void pltf_deinit(); void pltf_window_create(); +void pltf_window_close(); void pltf_window_destroy(); void pltf_gl_ctx_create(); void pltf_gl_ctx_destroy(); void pltf_gl_ctx_info_print(); void pltf_swap_buffers(); PltfWindowEvent pltf_window_event_handle(); +void pltf_key_callback_set( + const PltfKey key, + const PltfKeyCallback cb, + const void* user_data +); #endif // PLTF_H_ diff --git a/src/pltf/win32/gl_funcs.c b/src/pltf/win32/gl_funcs.c index 0555c5c..6d3af0e 100644 --- a/src/pltf/win32/gl_funcs.c +++ b/src/pltf/win32/gl_funcs.c @@ -1,6 +1,6 @@ #include "../gl_funcs.h" #include "log.h" -#include "pltf_win32.h" +#include "internal.h" #define X(type, name) \ type name = NULL diff --git a/src/pltf/win32/internal.c b/src/pltf/win32/internal.c new file mode 100644 index 0000000..862056a --- /dev/null +++ b/src/pltf/win32/internal.c @@ -0,0 +1,52 @@ +#include + +#include "internal.h" +#include "pltf/pltf.h" + +HMODULE opengl_module = NULL; + +#define PLTF_KEYS_X(lower, upper) \ + .key_##lower##_cb = NULL, \ + .key_##lower##_cb_user_data = NULL, + +PltfWin32State pltf_state = { + .wc_name = L"Scuffedcraft Window Class", + .exe_module = NULL, + .hwnd = NULL, + .hdc = NULL, + .wgl_extensions = { 0 }, + .window_state = (WinState) { + .gl_ctx = NULL }, + + PLTF_KEYS(PLTF_KEYS_X) +}; + +#undef PLTF_KEYS_X + +bool pltf_has_wgl_extension(const DynString* name) { + for (size_t i = 0; i < pltf_state.wgl_extensions.len; i++) { + if (DynString_equal(name, DynArray_DynString_at(&pltf_state.wgl_extensions, i))) { + return true; + } + } + + return false; +} + +bool pltf_has_wgl_extension_c_str(const char* name) { + DynString name_dstr = DynString_alloc(name, strlen(name)); + const bool res = pltf_has_wgl_extension(&name_dstr); + DynString_free(&name_dstr); + return res; +} + +unsigned int vk_to_pltf_key(WPARAM key) { + switch (key) { + case VK_ESCAPE: + return PLTF_KEY_ESC; + case 'Q': + return PLTF_KEY_Q; + default: + return PLTF_KEY_NONE; + } +} diff --git a/src/pltf/win32/internal.h b/src/pltf/win32/internal.h new file mode 100644 index 0000000..e34cbbe --- /dev/null +++ b/src/pltf/win32/internal.h @@ -0,0 +1,37 @@ +#ifndef PLTF_WIN32_INTERNAL_H_ +#define PLTF_WIN32_INTERNAL_H_ + +#include + +#include "../pltf.h" +#include "DynArray.h" + +typedef struct { + HGLRC gl_ctx; +} WinState; + +#define PLTF_KEYS_X(lower, upper) \ + PltfKeyCallback key_##lower##_cb; \ + void* key_##lower##_cb_user_data; + +typedef struct { + const wchar_t* wc_name; + HMODULE exe_module; + HWND hwnd; + HDC hdc; + DynArray_DynString wgl_extensions; + WinState window_state; + + PLTF_KEYS(PLTF_KEYS_X); +} PltfWin32State; + +#undef PLTF_KEYS_X + +extern PltfWin32State pltf_state; +extern HMODULE opengl_module; + +bool pltf_has_wgl_extension(const DynString* name); +bool pltf_has_wgl_extension_c_str(const char* name); +unsigned int vk_to_pltf_key(WPARAM key); + +#endif // PLTF_WIN32_INTERNAL_H_ diff --git a/src/pltf/win32/pltf.c b/src/pltf/win32/pltf.c index a36b3dd..0c82bd1 100644 --- a/src/pltf/win32/pltf.c +++ b/src/pltf/win32/pltf.c @@ -9,33 +9,9 @@ #include "../pltf.h" #include "DynArray.h" #include "DynString.h" +#include "internal.h" #include "log.h" - -typedef struct { - HGLRC gl_ctx; -} WinState; - -HMODULE opengl_module = NULL; - -static struct { - const wchar_t* wc_name; - HMODULE exe_module; - HWND hwnd; - HDC hdc; - DynArray_DynString wgl_extensions; - WinState window_state; -} pltf_state = { - .wc_name = L"Sample Window Class", - .exe_module = NULL, - .hwnd = NULL, - .hdc = NULL, - .wgl_extensions = { 0 }, - .window_state = (WinState) { - .gl_ctx = NULL - } -}; - -static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +#include "win_proc.h" void pltf_init() { pltf_state.exe_module = GetModuleHandle(NULL); @@ -62,36 +38,19 @@ void pltf_deinit() { UnregisterClass(pltf_state.wc_name, pltf_state.exe_module); } -static bool pltf_has_wgl_extension(const DynString* name) { - for (size_t i = 0; i < pltf_state.wgl_extensions.len; i++) { - if (DynString_equal(name, DynArray_DynString_at(&pltf_state.wgl_extensions, i))) { - return true; - } - } - - return false; -} - -static bool pltf_has_wgl_extension_c_str(const char* name) { - DynString name_dstr = DynString_alloc(name, strlen(name)); - const bool res = pltf_has_wgl_extension(&name_dstr); - DynString_free(&name_dstr); - return res; -} - void pltf_window_create() { // Create the window pltf_state.hwnd = CreateWindowEx( 0, // Optional window styles - pltf_state.wc_name, // Window class + pltf_state.wc_name, // Window class L"Learn to Program Windows", // Window text WS_OVERLAPPEDWINDOW, // Window style // Size and position CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - NULL, // Parent window - NULL, // Menu + NULL, // Parent window + NULL, // Menu pltf_state.exe_module, // Instance handle &pltf_state.window_state // Additional application data ); @@ -108,6 +67,10 @@ void pltf_window_create() { ShowWindow(pltf_state.hwnd, SW_SHOWDEFAULT); } +void pltf_window_close() { + PostMessage(pltf_state.hwnd, WM_CLOSE, 0, 0); +} + void pltf_window_destroy() { if (pltf_state.hwnd != NULL) { DestroyWindow(pltf_state.hwnd); @@ -288,63 +251,37 @@ void pltf_swap_buffers() { PltfWindowEvent pltf_window_event_handle() { MSG msg = { 0 }; - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + if (PeekMessage(&msg, pltf_state.hwnd, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); - if (msg.message == WM_QUIT) { - return PLTF_WE_QUIT; + switch (msg.message) { + case WM_DESTROY: + return PLTF_WE_DESTROY; } } return PLTF_WE_NULL; } -static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - WinState* pState = NULL; - if (uMsg == WM_CREATE) { - CREATESTRUCT* pCreate = (CREATESTRUCT*) lParam; - pState = (WinState*) pCreate->lpCreateParams; - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) pState); - } else { - LONG_PTR ptr = GetWindowLongPtr(hwnd, GWLP_USERDATA); - pState = (WinState*) ptr; +#define PLTF_KEYS_X(lower, upper) \ + case PLTF_KEY_##upper: { \ + pltf_state.key_##lower##_cb = cb; \ + pltf_state.key_##lower##_cb_user_data = (void*) user_data; \ + break; \ } - switch (uMsg) { - // case WM_LBUTTONDOWN: { - // printf("State: msg: %s, num: %d\n", pState->msg, pState->num); - // - // printf("lParam: %llx\n", lParam); - // int mouse_x = GET_X_LPARAM(lParam); - // printf("mouse_x: %x\n", mouse_x); - // int mouse_y = GET_Y_LPARAM(lParam); - // printf("mouse_y: %x\n", mouse_y); - // printf("x: %d y: %d\n", mouse_x, mouse_y); - // - // return 0; - // } +void pltf_key_callback_set( + const PltfKey key, + const PltfKeyCallback cb, + const void* user_data +) { - case WM_CREATE: { - return 0; + switch (key) { + case PLTF_KEY_NONE: + break; + + PLTF_KEYS(PLTF_KEYS_X); } - - case WM_KEYDOWN: - if (wParam == VK_ESCAPE) { - PostMessage(hwnd, WM_DESTROY, 0, 0); - } - return 0; - - case WM_DESTROY: - wglDeleteContext(pState->gl_ctx); - PostQuitMessage(0); - return 0; - - case WM_CLOSE: - if (MessageBox(hwnd, L"Really quit?", L"My Application", MB_OKCANCEL) == IDOK) { - DestroyWindow(hwnd); - } - return 0; - } - return DefWindowProc(hwnd, uMsg, wParam, lParam); } +#undef PLTF_KEYS_X diff --git a/src/pltf/win32/pltf_win32.h b/src/pltf/win32/pltf_win32.h deleted file mode 100644 index ad6b552..0000000 --- a/src/pltf/win32/pltf_win32.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef PLTF_WIN32_H_ -#define PLTF_WIN32_H_ - -#include - -extern HMODULE opengl_module; - -#endif // PLTF_WIN32_H_ diff --git a/src/pltf/win32/win_proc.c b/src/pltf/win32/win_proc.c new file mode 100644 index 0000000..c1627b1 --- /dev/null +++ b/src/pltf/win32/win_proc.c @@ -0,0 +1,66 @@ +#include + +#include "internal.h" +#include "pltf/pltf.h" + +#define PLTF_KEYS_X(lower, upper) \ + case PLTF_KEY_##upper: \ + if (pltf_state.key_##lower##_cb != NULL) { \ + pltf_state.key_##lower##_cb(pltf_state.key_##lower##_cb_user_data); \ + } \ + break; + +static void key_down_handle(WPARAM key) { + const PltfKey pltf_key = vk_to_pltf_key(key); + + switch (pltf_key) { + case PLTF_KEY_NONE: + break; + + PLTF_KEYS(PLTF_KEYS_X); + } +} + +#undef PLTF_KEYS_X + +LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + WinState* pState = NULL; + if (uMsg == WM_CREATE) { + CREATESTRUCT* pCreate = (CREATESTRUCT*) lParam; + pState = (WinState*) pCreate->lpCreateParams; + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) pState); + } else { + LONG_PTR ptr = GetWindowLongPtr(hwnd, GWLP_USERDATA); + pState = (WinState*) ptr; + } + + switch (uMsg) { + // case WM_LBUTTONDOWN: { + // printf("State: msg: %s, num: %d\n", pState->msg, pState->num); + // + // printf("lParam: %llx\n", lParam); + // int mouse_x = GET_X_LPARAM(lParam); + // printf("mouse_x: %x\n", mouse_x); + // int mouse_y = GET_Y_LPARAM(lParam); + // printf("mouse_y: %x\n", mouse_y); + // printf("x: %d y: %d\n", mouse_x, mouse_y); + // + // return 0; + // } + + // case WM_CREATE: { + // return 0; + // } + + case WM_KEYDOWN: + key_down_handle(wParam); + return 0; + + case WM_CLOSE: + if (MessageBox(hwnd, L"Really quit?", L"My Application", MB_OKCANCEL) == IDOK) { + PostMessage(hwnd, WM_DESTROY, 0, 0); + } + return 0; + } + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} diff --git a/src/pltf/win32/win_proc.h b/src/pltf/win32/win_proc.h new file mode 100644 index 0000000..e2ba409 --- /dev/null +++ b/src/pltf/win32/win_proc.h @@ -0,0 +1,8 @@ +#ifndef WIN_PROC_H_ +#define WIN_PROC_H_ + +#include + +LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +#endif // WIN_PROC_H_