diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-02 09:28:28 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-02 09:28:28 +0100 |
| commit | 61139c8d9d655e07964d63ec1f5a091a7e8ab7d0 (patch) | |
| tree | 4cf3694702f24e96c1c76a339f7b3e4d4fdf5e70 | |
| parent | 0b0067cb0a8db5ea5178501a12aacdef436a9845 (diff) | |
refactor(platform): Encapsulate state in PlatformState struct
- Replaced all global static variables in the platform layer with a single PlatformState struct.
- Updated all platform function signatures to accept a pointer to this struct, making the implementation stateless and more modular.
- Refactored main.cc, tests, and tools to instantiate and pass the PlatformState struct.
- This improves code organization and removes scattered global state.
| -rw-r--r-- | src/gpu/gpu.cc | 10 | ||||
| -rw-r--r-- | src/gpu/gpu.h | 4 | ||||
| -rw-r--r-- | src/main.cc | 13 | ||||
| -rw-r--r-- | src/platform.cc | 123 | ||||
| -rw-r--r-- | src/platform.h | 53 | ||||
| -rw-r--r-- | src/tests/test_3d_render.cc | 37 | ||||
| -rw-r--r-- | tools/spectool.cc | 9 |
7 files changed, 120 insertions, 129 deletions
diff --git a/src/gpu/gpu.cc b/src/gpu/gpu.cc index 17d32ee..cecf018 100644 --- a/src/gpu/gpu.cc +++ b/src/gpu/gpu.cc @@ -310,9 +310,9 @@ static void handle_request_device(WGPURequestDeviceStatus status, #endif /* defined(DEMO_CROSS_COMPILE_WIN32) */ #endif /* !defined(STRIP_ALL) */ -void gpu_init(GLFWwindow* window, int width, int height) { +void gpu_init(PlatformState* platform_state) { g_instance = wgpuCreateInstance(nullptr); - g_surface = platform_create_wgpu_surface(g_instance); + g_surface = platform_create_wgpu_surface(g_instance, platform_state); WGPURequestAdapterOptions adapter_opts = {}; adapter_opts.compatibleSurface = g_surface; @@ -364,13 +364,13 @@ void gpu_init(GLFWwindow* window, int width, int height) { g_config.device = g_device; g_config.format = swap_chain_format; g_config.usage = WGPUTextureUsage_RenderAttachment; - g_config.width = width; - g_config.height = height; + g_config.width = platform_state->width; + g_config.height = platform_state->height; g_config.presentMode = WGPUPresentMode_Fifo; g_config.alphaMode = WGPUCompositeAlphaMode_Opaque; wgpuSurfaceConfigure(g_surface, &g_config); - g_main_sequence.init(g_device, g_queue, g_config.format, width, height); + g_main_sequence.init(g_device, g_queue, g_config.format, platform_state->width, platform_state->height); LoadTimeline(g_main_sequence, g_device, g_queue, g_config.format); } diff --git a/src/gpu/gpu.h b/src/gpu/gpu.h index 9ed1913..a0ab6ba 100644 --- a/src/gpu/gpu.h +++ b/src/gpu/gpu.h @@ -71,7 +71,7 @@ static inline WGPUStringView label_view(const char* str) { #endif /* defined(DEMO_CROSS_COMPILE_WIN32) */ -struct GLFWwindow; +struct PlatformState; // Forward declaration // Basic wrapper for WebGPU buffers struct GpuBuffer { @@ -96,7 +96,7 @@ struct RenderPass { uint32_t instance_count; }; -void gpu_init(GLFWwindow* window, int width, int height); +void gpu_init(PlatformState* platform_state); void gpu_draw(float audio_peak, float aspect_ratio, float time, float beat); #if !defined(STRIP_ALL) void gpu_simulate_until(float time); diff --git a/src/main.cc b/src/main.cc index f7136ef..2ece549 100644 --- a/src/main.cc +++ b/src/main.cc @@ -129,6 +129,7 @@ float* generate_tone(float* buffer, float freq) { } int main(int argc, char** argv) { + PlatformState platform_state = {}; bool fullscreen_enabled = false; float seek_time = 0.0f; int* width_ptr = nullptr; @@ -156,8 +157,8 @@ int main(int argc, char** argv) { fullscreen_enabled = true; #endif /* STRIP_ALL */ - platform_init_window(fullscreen_enabled, width_ptr, height_ptr); - gpu_init(platform_get_window(), platform_get_width(), platform_get_height()); + platform_init(&platform_state, fullscreen_enabled, width_ptr, height_ptr); + gpu_init(&platform_state); audio_init(); // Register drum assets @@ -234,14 +235,14 @@ int main(int argc, char** argv) { // Start real audio audio_start(); - while (!platform_should_close()) { - platform_poll(); + while (!platform_should_close(&platform_state)) { + platform_poll(&platform_state); double current_time = platform_get_time() + seek_time; // Offset logic time update_game_logic(current_time); - float aspect_ratio = platform_get_aspect_ratio(); + float aspect_ratio = platform_get_aspect_ratio(&platform_state); // Adjusted multiplier for visuals (preventing constant 1.0 saturation) float raw_peak = synth_get_output_peak(); @@ -254,6 +255,6 @@ int main(int argc, char** argv) { audio_shutdown(); gpu_shutdown(); - platform_shutdown(); + platform_shutdown(&platform_state); return 0; } diff --git a/src/platform.cc b/src/platform.cc index 464003f..8df9992 100644 --- a/src/platform.cc +++ b/src/platform.cc @@ -4,120 +4,93 @@ #include "platform.h" #include "glfw3webgpu.h" - #include <GLFW/glfw3.h> -static GLFWwindow* window = nullptr; -static int windowed_x, windowed_y, windowed_w, windowed_h; -static bool g_is_fullscreen = false; - -// --- New state for framebuffer size --- -static int g_width = 1280; -static int g_height = 720; - -// Forward declaration for callback -void platform_toggle_fullscreen(); - // --- Callbacks --- -static void framebuffer_size_callback(GLFWwindow* cb_window, int width, int height) { - (void)cb_window; // Unused - g_width = width; - g_height = height; - // Note: We would trigger a swap chain resize here, but our demo handles it implicitly. +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) { + PlatformState* state = (PlatformState*)glfwGetWindowUserPointer(window); + if (state) { + state->width = width; + state->height = height; + } } -static void glfw_key_callback(GLFWwindow* cb_window, int key, int scancode, - int action, int mods) { - if (action == GLFW_PRESS) { - if (key == GLFW_KEY_ESCAPE || key == GLFW_KEY_Q) { - glfwSetWindowShouldClose(cb_window, GLFW_TRUE); - } else if (key == GLFW_KEY_F) { - platform_toggle_fullscreen(); +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); + } } - } } -void platform_init_window(bool fullscreen, int* width_ptr, int* height_ptr) { +// --- Public API Implementation --- + +void platform_init(PlatformState* state, bool fullscreen, int* width_ptr, int* height_ptr) { if (width_ptr && height_ptr) { - g_width = *width_ptr; - g_height = *height_ptr; + state->width = *width_ptr; + state->height = *height_ptr; } glfwInit(); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - window = glfwCreateWindow(g_width, g_height, "demo64k", nullptr, nullptr); + state->window = glfwCreateWindow(state->width, state->height, "demo64k", nullptr, nullptr); + + // Store our state pointer in the window for callbacks + glfwSetWindowUserPointer(state->window, state); // Immediately query the actual framebuffer size for high-DPI displays - glfwGetFramebufferSize(window, &g_width, &g_height); + glfwGetFramebufferSize(state->window, &state->width, &state->height); - glfwSetKeyCallback(window, glfw_key_callback); - glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + glfwSetKeyCallback(state->window, glfw_key_callback); + glfwSetFramebufferSizeCallback(state->window, framebuffer_size_callback); - g_is_fullscreen = fullscreen; + state->is_fullscreen = fullscreen; if (fullscreen) { - // Save current windowed mode dimensions before going fullscreen - glfwGetWindowPos(window, &windowed_x, &windowed_y); - glfwGetWindowSize(window, &windowed_w, &windowed_h); + 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(window, monitor, 0, 0, mode->width, mode->height, - mode->refreshRate); + glfwSetWindowMonitor(state->window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); } } -void platform_shutdown() { - glfwDestroyWindow(window); +void platform_shutdown(PlatformState* state) { + if (state->window) { + glfwDestroyWindow(state->window); + } glfwTerminate(); } -void platform_poll() { +void platform_poll(PlatformState* state) { glfwPollEvents(); } -bool platform_should_close() { - return glfwWindowShouldClose(window); +bool platform_should_close(PlatformState* state) { + return glfwWindowShouldClose(state->window); } -void platform_toggle_fullscreen() { - g_is_fullscreen = !g_is_fullscreen; - if (g_is_fullscreen) { - glfwGetWindowPos(window, &windowed_x, &windowed_y); - glfwGetWindowSize(window, &windowed_w, &windowed_h); +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(window, monitor, 0, 0, mode->width, mode->height, - mode->refreshRate); + glfwSetWindowMonitor(state->window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); } else { - glfwSetWindowMonitor(window, nullptr, windowed_x, windowed_y, windowed_w, - windowed_h, 0); + glfwSetWindowMonitor(state->window, nullptr, state->windowed_x, state->windowed_y, state->windowed_w, state->windowed_h, 0); } } -GLFWwindow* platform_get_window() { - return window; +WGPUSurface platform_create_wgpu_surface(WGPUInstance instance, PlatformState* state) { + return glfwCreateWindowWGPUSurface(instance, state->window); } -double platform_get_time() { - return glfwGetTime(); -} - -// --- New dimension getters --- -int platform_get_width() { - return g_width; -} - -int platform_get_height() { - return g_height; -} - -float platform_get_aspect_ratio() { - if (g_height == 0) return 1.0f; - return (float)g_width / (float)g_height; -} - -WGPUSurface platform_create_wgpu_surface(WGPUInstance instance) { - return glfwCreateWindowWGPUSurface(instance, window); -} +// Note: platform_get_* functions are now inline in the header. +// platform_get_time() remains global. diff --git a/src/platform.h b/src/platform.h index 38a0568..2d2fc9e 100644 --- a/src/platform.h +++ b/src/platform.h @@ -1,25 +1,46 @@ -// This file is part of the 64k demo project. -// It defines the platform abstraction layer for windowing and input. -// Provides a consistent interface for GLFW-based operations. +// Handles windowing, input, and native surface creation. #pragma once -#include <webgpu.h> - // Forward declare GLFWwindow to avoid including the full header here. struct GLFWwindow; -void platform_init_window(bool fullscreen, int* width_ptr, int* height_ptr); -void platform_shutdown(); -void platform_poll(); -bool platform_should_close(); +struct PlatformState { + GLFWwindow* window = nullptr; + int width = 1280; + int height = 720; + bool is_fullscreen = false; + // Store windowed geometry for fullscreen toggle + int windowed_x = 0, windowed_y = 0, windowed_w = 0, windowed_h = 0; +}; + +void platform_init(PlatformState* state, bool fullscreen, int* width_ptr, int* height_ptr); +void platform_shutdown(PlatformState* state); +void platform_poll(PlatformState* state); +bool platform_should_close(PlatformState* state); +void platform_toggle_fullscreen(PlatformState* state); + +// Inline getters for direct access +inline GLFWwindow* platform_get_window(PlatformState* state) { return state->window; } +inline int platform_get_width(PlatformState* state) { return state->width; } +inline int platform_get_height(PlatformState* state) { return state->height; } +inline float platform_get_aspect_ratio(PlatformState* state) { + if (state->height == 0) return 1.0f; + return (float)state->width / (float)state->height; +} -GLFWwindow* platform_get_window(); -double platform_get_time(); +// glfwGetTime is a simple global query, so it doesn't need the state struct. +// Include the header directly to get the proper linkage. +#include <GLFW/glfw3.h> +inline double platform_get_time() { + return glfwGetTime(); +} -// Add dimension getters -int platform_get_width(); -int platform_get_height(); -float platform_get_aspect_ratio(); -WGPUSurface platform_create_wgpu_surface(WGPUInstance instance); +// WebGPU specific surface creation +#if defined(DEMO_CROSS_COMPILE_WIN32) +#include <webgpu/webgpu.h> +#else +#include <wgpu.h> +#endif +WGPUSurface platform_create_wgpu_surface(WGPUInstance instance, PlatformState* state); diff --git a/src/tests/test_3d_render.cc b/src/tests/test_3d_render.cc index 0a809c4..e14ed93 100644 --- a/src/tests/test_3d_render.cc +++ b/src/tests/test_3d_render.cc @@ -29,18 +29,16 @@ static WGPUQueue g_queue = nullptr; static WGPUSurface g_surface = nullptr; static WGPUAdapter g_adapter = nullptr; static WGPUTextureFormat g_format = WGPUTextureFormat_Undefined; -static int g_width = 1280; -static int g_height = 720; // ... (init_wgpu implementation same as before) -void init_wgpu() { +void init_wgpu(PlatformState* platform_state) { WGPUInstance instance = wgpuCreateInstance(nullptr); if (!instance) { std::cerr << "Failed to create WGPU instance." << std::endl; exit(1); } - g_surface = platform_create_wgpu_surface(instance); + g_surface = platform_create_wgpu_surface(instance, platform_state); if (!g_surface) { std::cerr << "Failed to create WGPU surface." << std::endl; exit(1); @@ -128,8 +126,8 @@ void init_wgpu() { config.device = g_device; config.format = g_format; config.usage = WGPUTextureUsage_RenderAttachment; - config.width = g_width; - config.height = g_height; + config.width = platform_state->width; + config.height = platform_state->height; config.presentMode = WGPUPresentMode_Fifo; config.alphaMode = WGPUCompositeAlphaMode_Opaque; wgpuSurfaceConfigure(g_surface, &config); @@ -176,22 +174,21 @@ void gen_periodic_noise(uint8_t* buffer, int w, int h, const float* params, int main() { printf("Running 3D Renderer Test...\n"); - platform_init_window(false, nullptr, nullptr); - gpu_init(platform_get_window(), platform_get_width(), platform_get_height()); - - // Create Renderer and Scene - Renderer3D renderer; + PlatformState platform_state = {}; + platform_init(&platform_state, false, nullptr, nullptr); + + // The test's own WGPU init sequence + init_wgpu(&platform_state); g_renderer.init(g_device, g_queue, g_format); - g_renderer.resize(g_width, g_height); + g_renderer.resize(platform_state.width, platform_state.height); g_textures.init(g_device, g_queue); ProceduralTextureDef noise_def; noise_def.width = 256; noise_def.height = 256; noise_def.gen_func = gen_periodic_noise; - noise_def.params = {1234.0f, - 16.0f}; // Seed, Frequency (Increased for more detail) + noise_def.params = {1234.0f, 16.0f}; g_textures.create_procedural_texture("noise", noise_def); g_renderer.set_noise_texture(g_textures.get_texture_view("noise")); @@ -202,15 +199,16 @@ int main() { g_camera.target = vec3(0, 0, 0); float time = 0.0f; - while (!platform_should_close()) { - platform_poll(); - time += 0.016f; + while (!platform_should_close(&platform_state)) { + platform_poll(&platform_state); + time = (float)platform_get_time(); float cam_radius = 10.0f + std::sin(time * 0.3f) * 4.0f; float cam_height = 5.0f + std::cos(time * 0.4f) * 3.0f; g_camera.set_look_at(vec3(std::sin(time * 0.5f) * cam_radius, cam_height, std::cos(time * 0.5f) * cam_radius), vec3(0, 0, 0), vec3(0, 1, 0)); + g_camera.aspect_ratio = platform_get_aspect_ratio(&platform_state); for (size_t i = 1; i < g_scene.objects.size(); ++i) { g_scene.objects[i].rotation = @@ -225,11 +223,8 @@ int main() { WGPUTextureViewDescriptor view_desc = {}; view_desc.format = g_format; view_desc.dimension = WGPUTextureViewDimension_2D; - view_desc.baseMipLevel = 0; view_desc.mipLevelCount = 1; - view_desc.baseArrayLayer = 0; view_desc.arrayLayerCount = 1; - view_desc.aspect = WGPUTextureAspect_All; WGPUTextureView view = wgpuTextureCreateView(surface_tex.texture, &view_desc); g_renderer.render(g_scene, g_camera, time, view); @@ -241,6 +236,6 @@ int main() { g_renderer.shutdown(); g_textures.shutdown(); - platform_shutdown(); + platform_shutdown(&platform_state); return 0; } diff --git a/tools/spectool.cc b/tools/spectool.cc index dfb00de..19f3a2f 100644 --- a/tools/spectool.cc +++ b/tools/spectool.cc @@ -131,7 +131,8 @@ int play_spec(const char* in_path) { fread(spec_data.data(), sizeof(float), spec_data.size(), f_in); fclose(f_in); - platform_init_window(false, nullptr, nullptr); + PlatformState platform_state = {}; + platform_init(&platform_state, false, nullptr, nullptr); audio_init(); audio_start(); Spectrogram spec; @@ -144,12 +145,12 @@ int play_spec(const char* in_path) { synth_trigger_voice(spec_id, 0.7f, 0.0f); printf("Playing... Press Ctrl+C to exit.\n"); - while (synth_get_active_voice_count() > 0 && !platform_should_close()) { - platform_poll(); + while (synth_get_active_voice_count() > 0 && !platform_should_close(&platform_state)) { + platform_poll(&platform_state); } audio_shutdown(); - platform_shutdown(); + platform_shutdown(&platform_state); return 0; } |
