keymapping

This commit is contained in:
2026-07-03 22:07:03 +03:00
parent c809aa98f5
commit 7a98eb4dfb
12 changed files with 248 additions and 119 deletions

View File

@@ -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',

View File

@@ -2,16 +2,16 @@
#include <stdio.h>
#include <stdarg.h>
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");
}

View File

@@ -3,14 +3,18 @@
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#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_

View File

@@ -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();

View File

@@ -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_

View File

@@ -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

52
src/pltf/win32/internal.c Normal file
View File

@@ -0,0 +1,52 @@
#include <windows.h>
#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;
}
}

37
src/pltf/win32/internal.h Normal file
View File

@@ -0,0 +1,37 @@
#ifndef PLTF_WIN32_INTERNAL_H_
#define PLTF_WIN32_INTERNAL_H_
#include <windef.h>
#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_

View File

@@ -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,23 +38,6 @@ 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(
@@ -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;
case WM_KEYDOWN:
if (wParam == VK_ESCAPE) {
PostMessage(hwnd, WM_DESTROY, 0, 0);
PLTF_KEYS(PLTF_KEYS_X);
}
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

View File

@@ -1,8 +0,0 @@
#ifndef PLTF_WIN32_H_
#define PLTF_WIN32_H_
#include <windef.h>
extern HMODULE opengl_module;
#endif // PLTF_WIN32_H_

66
src/pltf/win32/win_proc.c Normal file
View File

@@ -0,0 +1,66 @@
#include <windows.h>
#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);
}

View File

@@ -0,0 +1,8 @@
#ifndef WIN_PROC_H_
#define WIN_PROC_H_
#include <windef.h>
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
#endif // WIN_PROC_H_