From 17b8ffac48643040cddfb0a51025bab62245326f Mon Sep 17 00:00:00 2001 From: skal Date: Sat, 7 Feb 2026 09:20:19 +0100 Subject: refactor: Move platform files to src/platform/ subdirectory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reorganized platform windowing code into dedicated subdirectory for better organization and consistency with other subsystems (audio/, gpu/, 3d/). Changes: - Created src/platform/ directory - Moved src/platform.{h,cc} → src/platform/platform.{h,cc} - Updated 11 include paths: "platform.h" → "platform/platform.h" - src/main.cc, src/test_demo.cc - src/gpu/gpu.{h,cc} - src/platform/platform.cc (self-include) - 6 test files - Updated CMakeLists.txt PLATFORM_SOURCES variable Verification: ✓ All targets build successfully (demo64k, test_demo, test_platform) ✓ test_platform passes (70% coverage maintained) ✓ demo64k smoke test passed This completes the platform code reorganization side quest. No functional changes, purely organizational. --- CMakeLists.txt | 2 +- src/gpu/gpu.cc | 2 +- src/gpu/gpu.h | 2 +- src/main.cc | 2 +- src/platform.cc | 131 ----------------------------------- src/platform.h | 100 -------------------------- src/platform/platform.cc | 131 +++++++++++++++++++++++++++++++++++ src/platform/platform.h | 100 ++++++++++++++++++++++++++ src/test_demo.cc | 2 +- src/tests/test_3d_physics.cc | 2 +- src/tests/test_3d_render.cc | 2 +- src/tests/test_mesh.cc | 2 +- src/tests/test_platform.cc | 2 +- src/tests/test_shader_compilation.cc | 2 +- src/tests/test_texture_manager.cc | 2 +- 15 files changed, 242 insertions(+), 242 deletions(-) delete mode 100644 src/platform.cc delete mode 100644 src/platform.h create mode 100644 src/platform/platform.cc create mode 100644 src/platform/platform.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5828db7..3f0db8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,7 +116,7 @@ set(3D_SOURCES src/3d/bvh.cc src/3d/physics.cc ) -set(PLATFORM_SOURCES src/platform.cc third_party/glfw3webgpu/glfw3webgpu.c) +set(PLATFORM_SOURCES src/platform/platform.cc third_party/glfw3webgpu/glfw3webgpu.c) set(UTIL_SOURCES src/util/asset_manager.cc) #-- - Subsystem Libraries -- - diff --git a/src/gpu/gpu.cc b/src/gpu/gpu.cc index 1d661c7..45f0f34 100644 --- a/src/gpu/gpu.cc +++ b/src/gpu/gpu.cc @@ -6,7 +6,7 @@ #include "demo_effects.h" #include "effect.h" #include "gpu/effects/shaders.h" -#include "platform.h" +#include "platform/platform.h" #include #include diff --git a/src/gpu/gpu.h b/src/gpu/gpu.h index 40274b9..d7f5a8d 100644 --- a/src/gpu/gpu.h +++ b/src/gpu/gpu.h @@ -4,7 +4,7 @@ #pragma once -#include "platform.h" +#include "platform/platform.h" struct PlatformState; // Forward declaration diff --git a/src/main.cc b/src/main.cc index 978a34e..0fb0fb6 100644 --- a/src/main.cc +++ b/src/main.cc @@ -14,7 +14,7 @@ #include "generated/assets.h" // Include generated asset header #include "gpu/demo_effects.h" // For GetDemoDuration() #include "gpu/gpu.h" -#include "platform.h" +#include "platform/platform.h" #include "util/math.h" #include #include diff --git a/src/platform.cc b/src/platform.cc deleted file mode 100644 index fbd1d51..0000000 --- a/src/platform.cc +++ /dev/null @@ -1,131 +0,0 @@ -// This file is part of the 64k demo project. -// It implements platform-specific windowing and input using GLFW. -// Handles fullscreen toggling and native surface creation for WebGPU. - -#include "platform.h" -#include "glfw3webgpu.h" -#include - -// --- Callbacks --- - -static void framebuffer_size_callback(GLFWwindow* window, int width, - int height) { - PlatformState* state = (PlatformState*)glfwGetWindowUserPointer(window); - if (state) { - state->width = width; - state->height = height; - if (height > 0) { - state->aspect_ratio = (float)width / (float)height; - } - } -} - -static void glfw_key_callback(GLFWwindow* window, int key, int scancode, - int action, int mods) { - PlatformState* state = (PlatformState*)glfwGetWindowUserPointer(window); - if (action == GLFW_PRESS) { - if (key == GLFW_KEY_ESCAPE || key == GLFW_KEY_Q) { - glfwSetWindowShouldClose(window, GLFW_TRUE); - } else if (key == GLFW_KEY_F) { - if (state) - platform_toggle_fullscreen(state); - } - } -} - -// --- Public API Implementation --- - -PlatformState platform_init(bool fullscreen, int width, int height) { - PlatformState state = {}; - state.width = width; - state.height = height; - state.is_fullscreen = fullscreen; - - glfwInit(); - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - state.window = - glfwCreateWindow(state.width, state.height, "demo64k", nullptr, nullptr); - - // Immediately query the actual framebuffer size for high-DPI displays - glfwGetFramebufferSize(state.window, &state.width, &state.height); - if (state.height > 0) { - state.aspect_ratio = (float)state.width / (float)state.height; - } - - // Store our state in a static pointer or use the window pointer? - // We'll use a pointer to a persistent state. - // For this demo, we can assume the PlatformState persists in main(). - // But we return by value. This is a bit tricky with callbacks. - // We'll fix the callbacks in platform_poll if needed, or just let main pass - // the pointer back. - - glfwSetWindowUserPointer(state.window, - nullptr); // Will be set in main's state - - glfwSetKeyCallback(state.window, glfw_key_callback); - glfwSetFramebufferSizeCallback(state.window, framebuffer_size_callback); - - if (fullscreen) { - glfwGetWindowPos(state.window, &state.windowed_x, &state.windowed_y); - glfwGetWindowSize(state.window, &state.windowed_w, &state.windowed_h); - - GLFWmonitor* monitor = glfwGetPrimaryMonitor(); - const GLFWvidmode* mode = glfwGetVideoMode(monitor); - glfwSetWindowMonitor(state.window, monitor, 0, 0, mode->width, mode->height, - mode->refreshRate); - } - - state.time = glfwGetTime(); - - return state; -} - -void platform_shutdown(PlatformState* state) { - if (state->window) { - glfwDestroyWindow(state->window); - } - glfwTerminate(); -} - -void platform_poll(PlatformState* state) { - // Ensure the window has the current state pointer for callbacks - if (glfwGetWindowUserPointer(state->window) != state) { - glfwSetWindowUserPointer(state->window, state); - } - - glfwPollEvents(); - state->time = glfwGetTime(); - if (state->height > 0) { - state->aspect_ratio = (float)state->width / (float)state->height; - } -} - -bool platform_should_close(PlatformState* state) { - return glfwWindowShouldClose(state->window); -} - -void platform_toggle_fullscreen(PlatformState* state) { - state->is_fullscreen = !state->is_fullscreen; - if (state->is_fullscreen) { - glfwGetWindowPos(state->window, &state->windowed_x, &state->windowed_y); - glfwGetWindowSize(state->window, &state->windowed_w, &state->windowed_h); - - GLFWmonitor* monitor = glfwGetPrimaryMonitor(); - const GLFWvidmode* mode = glfwGetVideoMode(monitor); - glfwSetWindowMonitor(state->window, monitor, 0, 0, mode->width, - mode->height, mode->refreshRate); - } else { - glfwSetWindowMonitor(state->window, nullptr, state->windowed_x, - state->windowed_y, state->windowed_w, - state->windowed_h, 0); - } -} - -WGPUSurface platform_create_wgpu_surface(WGPUInstance instance, - PlatformState* state) { - return glfwCreateWindowWGPUSurface(instance, state->window); -} - -double platform_get_time() { - return glfwGetTime(); -} \ No newline at end of file diff --git a/src/platform.h b/src/platform.h deleted file mode 100644 index 0a98850..0000000 --- a/src/platform.h +++ /dev/null @@ -1,100 +0,0 @@ -// Handles windowing, input, and native surface creation. -// Consolidates platform-specific shims for WebGPU. - -#pragma once - -#include -#include - -// WebGPU specific headers and shims -#if defined(DEMO_CROSS_COMPILE_WIN32) -#include -#include - -#define WGPUOptionalBool_True true -#define WGPUOptionalBool_False false -#define WGPUSType_ShaderSourceWGSL WGPUSType_ShaderModuleWGSLDescriptor -#define WGPU_DEPTH_SLICE_UNDEFINED 0xffffffff -#define WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal \ - WGPUSurfaceGetCurrentTextureStatus_Success -#define WGPUSurfaceGetCurrentTextureStatus_SuccessSuboptimal \ - WGPUSurfaceGetCurrentTextureStatus_Success -#define WGPUCallbackMode_WaitAnyOnly 0 - -typedef WGPUShaderModuleWGSLDescriptor WGPUShaderSourceWGSL; - -static inline const char* str_view(const char* str) { - return str; -} -static inline const char* label_view(const char* str) { - return str; -} - -static inline void platform_wgpu_wait_any(WGPUInstance instance) { - wgpuInstanceProcessEvents(instance); -} -static inline void -platform_wgpu_set_error_callback(WGPUDevice device, - WGPUErrorCallback callback) { - wgpuDeviceSetUncapturedErrorCallback(device, callback, nullptr); -} - -#else -#include -#include - -static inline WGPUStringView str_view(const char* str) { - if (!str) - return {nullptr, 0}; - return {str, strlen(str)}; -} - -static inline WGPUStringView label_view(const char* str) { -#if !defined(STRIP_ALL) - if (!str) - return {nullptr, 0}; - return {str, strlen(str)}; -#else - (void)str; - return {nullptr, 0}; -#endif -} - -static inline void platform_wgpu_wait_any(WGPUInstance instance) { - wgpuInstanceWaitAny(instance, 0, nullptr, 0); -} -static inline void -platform_wgpu_set_error_callback(WGPUDevice device, - WGPUUncapturedErrorCallback callback) { - // Handled in descriptor for new API, but provided for compatibility if needed - // elsewhere -} -#endif - -// Forward declare GLFWwindow to avoid including the full header here. -struct GLFWwindow; - -struct PlatformState { - GLFWwindow* window = nullptr; - int width = 1280; - int height = 720; - float aspect_ratio = 1.0f; - double time = 0.0; - bool is_fullscreen = false; - // Store windowed geometry for fullscreen toggle - int windowed_x = 0, windowed_y = 0, windowed_w = 0, windowed_h = 0; -}; - -// Refactored platform API -PlatformState platform_init(bool fullscreen, int width, int height); -void platform_shutdown(PlatformState* state); -void platform_poll(PlatformState* state); -bool platform_should_close(PlatformState* state); -void platform_toggle_fullscreen(PlatformState* state); - -// WebGPU specific surface creation -WGPUSurface platform_create_wgpu_surface(WGPUInstance instance, - PlatformState* state); - -// Global time query (if needed without state) -double platform_get_time(); \ No newline at end of file diff --git a/src/platform/platform.cc b/src/platform/platform.cc new file mode 100644 index 0000000..29b3af3 --- /dev/null +++ b/src/platform/platform.cc @@ -0,0 +1,131 @@ +// This file is part of the 64k demo project. +// It implements platform-specific windowing and input using GLFW. +// Handles fullscreen toggling and native surface creation for WebGPU. + +#include "platform/platform.h" +#include "glfw3webgpu.h" +#include + +// --- Callbacks --- + +static void framebuffer_size_callback(GLFWwindow* window, int width, + int height) { + PlatformState* state = (PlatformState*)glfwGetWindowUserPointer(window); + if (state) { + state->width = width; + state->height = height; + if (height > 0) { + state->aspect_ratio = (float)width / (float)height; + } + } +} + +static void glfw_key_callback(GLFWwindow* window, int key, int scancode, + int action, int mods) { + PlatformState* state = (PlatformState*)glfwGetWindowUserPointer(window); + if (action == GLFW_PRESS) { + if (key == GLFW_KEY_ESCAPE || key == GLFW_KEY_Q) { + glfwSetWindowShouldClose(window, GLFW_TRUE); + } else if (key == GLFW_KEY_F) { + if (state) + platform_toggle_fullscreen(state); + } + } +} + +// --- Public API Implementation --- + +PlatformState platform_init(bool fullscreen, int width, int height) { + PlatformState state = {}; + state.width = width; + state.height = height; + state.is_fullscreen = fullscreen; + + glfwInit(); + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + state.window = + glfwCreateWindow(state.width, state.height, "demo64k", nullptr, nullptr); + + // Immediately query the actual framebuffer size for high-DPI displays + glfwGetFramebufferSize(state.window, &state.width, &state.height); + if (state.height > 0) { + state.aspect_ratio = (float)state.width / (float)state.height; + } + + // Store our state in a static pointer or use the window pointer? + // We'll use a pointer to a persistent state. + // For this demo, we can assume the PlatformState persists in main(). + // But we return by value. This is a bit tricky with callbacks. + // We'll fix the callbacks in platform_poll if needed, or just let main pass + // the pointer back. + + glfwSetWindowUserPointer(state.window, + nullptr); // Will be set in main's state + + glfwSetKeyCallback(state.window, glfw_key_callback); + glfwSetFramebufferSizeCallback(state.window, framebuffer_size_callback); + + if (fullscreen) { + glfwGetWindowPos(state.window, &state.windowed_x, &state.windowed_y); + glfwGetWindowSize(state.window, &state.windowed_w, &state.windowed_h); + + GLFWmonitor* monitor = glfwGetPrimaryMonitor(); + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + glfwSetWindowMonitor(state.window, monitor, 0, 0, mode->width, mode->height, + mode->refreshRate); + } + + state.time = glfwGetTime(); + + return state; +} + +void platform_shutdown(PlatformState* state) { + if (state->window) { + glfwDestroyWindow(state->window); + } + glfwTerminate(); +} + +void platform_poll(PlatformState* state) { + // Ensure the window has the current state pointer for callbacks + if (glfwGetWindowUserPointer(state->window) != state) { + glfwSetWindowUserPointer(state->window, state); + } + + glfwPollEvents(); + state->time = glfwGetTime(); + if (state->height > 0) { + state->aspect_ratio = (float)state->width / (float)state->height; + } +} + +bool platform_should_close(PlatformState* state) { + return glfwWindowShouldClose(state->window); +} + +void platform_toggle_fullscreen(PlatformState* state) { + state->is_fullscreen = !state->is_fullscreen; + if (state->is_fullscreen) { + glfwGetWindowPos(state->window, &state->windowed_x, &state->windowed_y); + glfwGetWindowSize(state->window, &state->windowed_w, &state->windowed_h); + + GLFWmonitor* monitor = glfwGetPrimaryMonitor(); + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + glfwSetWindowMonitor(state->window, monitor, 0, 0, mode->width, + mode->height, mode->refreshRate); + } else { + glfwSetWindowMonitor(state->window, nullptr, state->windowed_x, + state->windowed_y, state->windowed_w, + state->windowed_h, 0); + } +} + +WGPUSurface platform_create_wgpu_surface(WGPUInstance instance, + PlatformState* state) { + return glfwCreateWindowWGPUSurface(instance, state->window); +} + +double platform_get_time() { + return glfwGetTime(); +} \ No newline at end of file diff --git a/src/platform/platform.h b/src/platform/platform.h new file mode 100644 index 0000000..0a98850 --- /dev/null +++ b/src/platform/platform.h @@ -0,0 +1,100 @@ +// Handles windowing, input, and native surface creation. +// Consolidates platform-specific shims for WebGPU. + +#pragma once + +#include +#include + +// WebGPU specific headers and shims +#if defined(DEMO_CROSS_COMPILE_WIN32) +#include +#include + +#define WGPUOptionalBool_True true +#define WGPUOptionalBool_False false +#define WGPUSType_ShaderSourceWGSL WGPUSType_ShaderModuleWGSLDescriptor +#define WGPU_DEPTH_SLICE_UNDEFINED 0xffffffff +#define WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal \ + WGPUSurfaceGetCurrentTextureStatus_Success +#define WGPUSurfaceGetCurrentTextureStatus_SuccessSuboptimal \ + WGPUSurfaceGetCurrentTextureStatus_Success +#define WGPUCallbackMode_WaitAnyOnly 0 + +typedef WGPUShaderModuleWGSLDescriptor WGPUShaderSourceWGSL; + +static inline const char* str_view(const char* str) { + return str; +} +static inline const char* label_view(const char* str) { + return str; +} + +static inline void platform_wgpu_wait_any(WGPUInstance instance) { + wgpuInstanceProcessEvents(instance); +} +static inline void +platform_wgpu_set_error_callback(WGPUDevice device, + WGPUErrorCallback callback) { + wgpuDeviceSetUncapturedErrorCallback(device, callback, nullptr); +} + +#else +#include +#include + +static inline WGPUStringView str_view(const char* str) { + if (!str) + return {nullptr, 0}; + return {str, strlen(str)}; +} + +static inline WGPUStringView label_view(const char* str) { +#if !defined(STRIP_ALL) + if (!str) + return {nullptr, 0}; + return {str, strlen(str)}; +#else + (void)str; + return {nullptr, 0}; +#endif +} + +static inline void platform_wgpu_wait_any(WGPUInstance instance) { + wgpuInstanceWaitAny(instance, 0, nullptr, 0); +} +static inline void +platform_wgpu_set_error_callback(WGPUDevice device, + WGPUUncapturedErrorCallback callback) { + // Handled in descriptor for new API, but provided for compatibility if needed + // elsewhere +} +#endif + +// Forward declare GLFWwindow to avoid including the full header here. +struct GLFWwindow; + +struct PlatformState { + GLFWwindow* window = nullptr; + int width = 1280; + int height = 720; + float aspect_ratio = 1.0f; + double time = 0.0; + bool is_fullscreen = false; + // Store windowed geometry for fullscreen toggle + int windowed_x = 0, windowed_y = 0, windowed_w = 0, windowed_h = 0; +}; + +// Refactored platform API +PlatformState platform_init(bool fullscreen, int width, int height); +void platform_shutdown(PlatformState* state); +void platform_poll(PlatformState* state); +bool platform_should_close(PlatformState* state); +void platform_toggle_fullscreen(PlatformState* state); + +// WebGPU specific surface creation +WGPUSurface platform_create_wgpu_surface(WGPUInstance instance, + PlatformState* state); + +// Global time query (if needed without state) +double platform_get_time(); \ No newline at end of file diff --git a/src/test_demo.cc b/src/test_demo.cc index a93b0b1..0d6be0a 100644 --- a/src/test_demo.cc +++ b/src/test_demo.cc @@ -7,7 +7,7 @@ #include "generated/assets.h" // Note: uses main demo asset bundle #include "gpu/demo_effects.h" #include "gpu/gpu.h" -#include "platform.h" +#include "platform/platform.h" #include #include #include diff --git a/src/tests/test_3d_physics.cc b/src/tests/test_3d_physics.cc index 0dfe1ce..eb1f5ef 100644 --- a/src/tests/test_3d_physics.cc +++ b/src/tests/test_3d_physics.cc @@ -9,7 +9,7 @@ #include "3d/scene.h" #include "gpu/effects/shaders.h" #include "gpu/texture_manager.h" -#include "platform.h" +#include "platform/platform.h" #include "procedural/generator.h" #include #include diff --git a/src/tests/test_3d_render.cc b/src/tests/test_3d_render.cc index 00de60e..d9fb118 100644 --- a/src/tests/test_3d_render.cc +++ b/src/tests/test_3d_render.cc @@ -8,7 +8,7 @@ #include "generated/assets.h" #include "gpu/effects/shaders.h" #include "gpu/texture_manager.h" -#include "platform.h" +#include "platform/platform.h" #include "procedural/generator.h" #include #include diff --git a/src/tests/test_mesh.cc b/src/tests/test_mesh.cc index 55de3a9..7f898c4 100644 --- a/src/tests/test_mesh.cc +++ b/src/tests/test_mesh.cc @@ -7,7 +7,7 @@ #include "3d/scene.h" #include "gpu/effects/shaders.h" #include "gpu/texture_manager.h" -#include "platform.h" +#include "platform/platform.h" #include "util/asset_manager_utils.h" #include #include "procedural/generator.h" diff --git a/src/tests/test_platform.cc b/src/tests/test_platform.cc index 80016ec..feac14b 100644 --- a/src/tests/test_platform.cc +++ b/src/tests/test_platform.cc @@ -1,7 +1,7 @@ // Tests for platform windowing and input abstraction. // Covers basic lifecycle, time queries, and string view helpers. -#include "platform.h" +#include "platform/platform.h" #include #include #include diff --git a/src/tests/test_shader_compilation.cc b/src/tests/test_shader_compilation.cc index 8b3b5f5..fdd71b8 100644 --- a/src/tests/test_shader_compilation.cc +++ b/src/tests/test_shader_compilation.cc @@ -8,7 +8,7 @@ #include "generated/assets.h" #include "gpu/effects/shader_composer.h" #include "gpu/effects/shaders.h" -#include "platform.h" +#include "platform/platform.h" #include #include #include diff --git a/src/tests/test_texture_manager.cc b/src/tests/test_texture_manager.cc index 75d897d..47c3f9f 100644 --- a/src/tests/test_texture_manager.cc +++ b/src/tests/test_texture_manager.cc @@ -3,7 +3,7 @@ // with valid device). #include "gpu/texture_manager.h" -#include "platform.h" +#include "platform/platform.h" #include "procedural/generator.h" #include -- cgit v1.2.3