diff options
| author | Marc Sunet <marc.sunet@amd.com> | 2025-11-21 09:41:06 -0800 |
|---|---|---|
| committer | Marc Sunet <marc.sunet@amd.com> | 2025-11-21 09:41:06 -0800 |
| commit | 0b5491e0a2f1a9a4023e2c4eb171287bede41388 (patch) | |
| tree | e82e93313f1fcfcc5622bae706aea9335dbc43ef /app | |
| parent | b5697421bbc73ed17ef3a8bc003571d1b6351b5c (diff) | |
Switch to plain C
Diffstat (limited to 'app')
| -rw-r--r-- | app/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | app/include/dxwindow.h | 28 | ||||
| -rw-r--r-- | app/src/dxwindow.c | 81 |
3 files changed, 120 insertions, 0 deletions
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..7b2bdaf --- /dev/null +++ b/app/CMakeLists.txt | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | cmake_minimum_required(VERSION 3.20) | ||
| 2 | |||
| 3 | add_library(app | ||
| 4 | include/dxwindow.h | ||
| 5 | src/dxwindow.c) | ||
| 6 | |||
| 7 | target_include_directories(app PUBLIC | ||
| 8 | include) | ||
| 9 | |||
| 10 | target_link_libraries(app PUBLIC | ||
| 11 | glfw) | ||
diff --git a/app/include/dxwindow.h b/app/include/dxwindow.h new file mode 100644 index 0000000..7e5a373 --- /dev/null +++ b/app/include/dxwindow.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <WinDef.h> // HWND | ||
| 4 | |||
| 5 | #include <stdbool.h> | ||
| 6 | |||
| 7 | typedef struct Window Window; | ||
| 8 | |||
| 9 | /// Initialise the window subsystem. | ||
| 10 | /// | ||
| 11 | /// This function must be called at the start of your application before any | ||
| 12 | /// Windows are created. | ||
| 13 | bool window_global_init(); | ||
| 14 | |||
| 15 | /// Terminate the window subsystem. | ||
| 16 | /// | ||
| 17 | /// This function should be called at the end of your application. Any existing | ||
| 18 | /// Windows are destroyed and are invalid beyond this call. | ||
| 19 | void window_global_quit(); | ||
| 20 | |||
| 21 | /// Return the last Window error. | ||
| 22 | const char* window_get_error(); | ||
| 23 | |||
| 24 | Window* window_init(int width, int height, const char* title); | ||
| 25 | void window_destroy(Window**); | ||
| 26 | HWND window_handle(Window*); | ||
| 27 | void window_update(Window*); | ||
| 28 | bool window_should_close(const Window*); | ||
diff --git a/app/src/dxwindow.c b/app/src/dxwindow.c new file mode 100644 index 0000000..3f775e7 --- /dev/null +++ b/app/src/dxwindow.c | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | #include <dxwindow.h> | ||
| 2 | |||
| 3 | // Include Windows.h before GLFW to avoid macro redefinition warnings. | ||
| 4 | #define WIN32_LEAN_AND_MEAN | ||
| 5 | #include <Windows.h> | ||
| 6 | |||
| 7 | #define GLFW_INCLUDE_NONE // Do not include OpenGL headers. | ||
| 8 | #include <GLFW/glfw3.h> | ||
| 9 | |||
| 10 | #define GLFW_EXPOSE_NATIVE_WIN32 | ||
| 11 | #include <GLFW/glfw3native.h> | ||
| 12 | |||
| 13 | #include <assert.h> | ||
| 14 | #include <stdio.h> | ||
| 15 | #include <stdlib.h> | ||
| 16 | |||
| 17 | typedef struct Window { | ||
| 18 | GLFWwindow* glfw_window; | ||
| 19 | } Window; | ||
| 20 | |||
| 21 | static char glfw_error[1024] = {}; | ||
| 22 | |||
| 23 | static void glfw_error_callback(int error, const char* description) { | ||
| 24 | sprintf_s(glfw_error, sizeof(glfw_error), | ||
| 25 | "GLFW error %d: %s", error, description); | ||
| 26 | } | ||
| 27 | |||
| 28 | bool window_global_init() { | ||
| 29 | glfwSetErrorCallback(glfw_error_callback); | ||
| 30 | return glfwInit() == GLFW_TRUE; | ||
| 31 | } | ||
| 32 | |||
| 33 | void window_global_quit() { | ||
| 34 | glfwTerminate(); | ||
| 35 | } | ||
| 36 | |||
| 37 | const char* window_get_error(Window* wnd) { | ||
| 38 | assert(wnd); | ||
| 39 | return glfw_error; | ||
| 40 | } | ||
| 41 | |||
| 42 | Window* window_init(int width, int height, const char* title) { | ||
| 43 | Window* wnd = calloc(1, sizeof(Window)); | ||
| 44 | if (!wnd) { | ||
| 45 | return 0; | ||
| 46 | } | ||
| 47 | // GLFW by default creates an OpenGL context with the window. | ||
| 48 | // Use GLFW_NO_API to tell it not to do so. | ||
| 49 | glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); | ||
| 50 | if ((wnd->glfw_window = glfwCreateWindow( | ||
| 51 | width, height, title, /*monitor=*/NULL, /*share=*/NULL)) == 0) { | ||
| 52 | free(wnd); | ||
| 53 | return 0; | ||
| 54 | } | ||
| 55 | return wnd; | ||
| 56 | } | ||
| 57 | |||
| 58 | void window_destroy(Window** ppWindow) { | ||
| 59 | assert(ppWindow); | ||
| 60 | Window* wnd = *ppWindow; | ||
| 61 | if (wnd) { | ||
| 62 | glfwDestroyWindow(wnd->glfw_window); | ||
| 63 | free(wnd); | ||
| 64 | *ppWindow = 0; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | HWND window_handle(Window* wnd) { | ||
| 69 | assert(wnd); | ||
| 70 | return glfwGetWin32Window(wnd->glfw_window); | ||
| 71 | } | ||
| 72 | |||
| 73 | void window_update(Window* wnd) { | ||
| 74 | assert(wnd); | ||
| 75 | glfwPollEvents(); | ||
| 76 | } | ||
| 77 | |||
| 78 | bool window_should_close(const Window* wnd) { | ||
| 79 | assert(wnd); | ||
| 80 | return glfwWindowShouldClose(wnd->glfw_window) == GLFW_TRUE; | ||
| 81 | } | ||
