From 0b5491e0a2f1a9a4023e2c4eb171287bede41388 Mon Sep 17 00:00:00 2001 From: Marc Sunet Date: Fri, 21 Nov 2025 09:41:06 -0800 Subject: Switch to plain C --- app/CMakeLists.txt | 11 +++++++ app/include/dxwindow.h | 28 +++++++++++++++++ app/src/dxwindow.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 app/CMakeLists.txt create mode 100644 app/include/dxwindow.h create mode 100644 app/src/dxwindow.c (limited to 'app') 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 @@ +cmake_minimum_required(VERSION 3.20) + +add_library(app + include/dxwindow.h + src/dxwindow.c) + +target_include_directories(app PUBLIC + include) + +target_link_libraries(app PUBLIC + 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 @@ +#pragma once + +#include // HWND + +#include + +typedef struct Window Window; + +/// Initialise the window subsystem. +/// +/// This function must be called at the start of your application before any +/// Windows are created. +bool window_global_init(); + +/// Terminate the window subsystem. +/// +/// This function should be called at the end of your application. Any existing +/// Windows are destroyed and are invalid beyond this call. +void window_global_quit(); + +/// Return the last Window error. +const char* window_get_error(); + +Window* window_init(int width, int height, const char* title); +void window_destroy(Window**); +HWND window_handle(Window*); +void window_update(Window*); +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 @@ +#include + +// Include Windows.h before GLFW to avoid macro redefinition warnings. +#define WIN32_LEAN_AND_MEAN +#include + +#define GLFW_INCLUDE_NONE // Do not include OpenGL headers. +#include + +#define GLFW_EXPOSE_NATIVE_WIN32 +#include + +#include +#include +#include + +typedef struct Window { + GLFWwindow* glfw_window; +} Window; + +static char glfw_error[1024] = {}; + +static void glfw_error_callback(int error, const char* description) { + sprintf_s(glfw_error, sizeof(glfw_error), + "GLFW error %d: %s", error, description); +} + +bool window_global_init() { + glfwSetErrorCallback(glfw_error_callback); + return glfwInit() == GLFW_TRUE; +} + +void window_global_quit() { + glfwTerminate(); +} + +const char* window_get_error(Window* wnd) { + assert(wnd); + return glfw_error; +} + +Window* window_init(int width, int height, const char* title) { + Window* wnd = calloc(1, sizeof(Window)); + if (!wnd) { + return 0; + } + // GLFW by default creates an OpenGL context with the window. + // Use GLFW_NO_API to tell it not to do so. + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + if ((wnd->glfw_window = glfwCreateWindow( + width, height, title, /*monitor=*/NULL, /*share=*/NULL)) == 0) { + free(wnd); + return 0; + } + return wnd; +} + +void window_destroy(Window** ppWindow) { + assert(ppWindow); + Window* wnd = *ppWindow; + if (wnd) { + glfwDestroyWindow(wnd->glfw_window); + free(wnd); + *ppWindow = 0; + } +} + +HWND window_handle(Window* wnd) { + assert(wnd); + return glfwGetWin32Window(wnd->glfw_window); +} + +void window_update(Window* wnd) { + assert(wnd); + glfwPollEvents(); +} + +bool window_should_close(const Window* wnd) { + assert(wnd); + return glfwWindowShouldClose(wnd->glfw_window) == GLFW_TRUE; +} -- cgit v1.2.3