Aaro Saila 4 hónapja
szülő
commit
7a98eb4dfb

+ 2 - 0
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',

+ 6 - 6
src/log.c

@@ -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");
 }
 

+ 10 - 6
src/log.h

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

+ 15 - 5
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();

+ 22 - 1
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_

+ 1 - 1
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

+ 52 - 0
src/pltf/win32/internal.c

@@ -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 - 0
src/pltf/win32/internal.h

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

+ 28 - 91
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;
-    }
-
-    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;
+#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;                                             \
     }
 
-    case WM_KEYDOWN:
-        if (wParam == VK_ESCAPE) {
-            PostMessage(hwnd, WM_DESTROY, 0, 0);
-        }
-        return 0;
+void pltf_key_callback_set(
+    const PltfKey key,
+    const PltfKeyCallback cb,
+    const void* user_data
+) {
 
-    case WM_DESTROY:
-        wglDeleteContext(pState->gl_ctx);
-        PostQuitMessage(0);
-        return 0;
+    switch (key) {
+    case PLTF_KEY_NONE:
+        break;
 
-    case WM_CLOSE:
-        if (MessageBox(hwnd, L"Really quit?", L"My Application", MB_OKCANCEL) == IDOK) {
-            DestroyWindow(hwnd);
-        }
-        return 0;
+        PLTF_KEYS(PLTF_KEYS_X);
     }
-    return DefWindowProc(hwnd, uMsg, wParam, lParam);
 }
 
+#undef PLTF_KEYS_X

+ 0 - 8
src/pltf/win32/pltf_win32.h

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

+ 66 - 0
src/pltf/win32/win_proc.c

@@ -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);
+}

+ 8 - 0
src/pltf/win32/win_proc.h

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