From 0bb7fa35cc340a65c944e546231632379bcfa30c Mon Sep 17 00:00:00 2001 From: skal Date: Sat, 31 Jan 2026 15:44:30 +0100 Subject: feat: Add --seek command line option for fast-forward debugging This feature allows developers to jump to a specific time in the demo sequence (e.g., './demo64k --seek 10.5'). It simulates the game logic, audio state (rendering silent buffers), and visual physics (compute shaders) from t=0 up to the target time before starting real-time playback. Audio initialization is refactored to separate device init and start. --- src/gpu/effect.cc | 38 ++++++++++++++++++++++++++++++++++++++ src/gpu/effect.h | 4 ++++ src/gpu/gpu.cc | 4 ++++ src/gpu/gpu.h | 1 + 4 files changed, 47 insertions(+) (limited to 'src/gpu') diff --git a/src/gpu/effect.cc b/src/gpu/effect.cc index cfef7f9..040b523 100644 --- a/src/gpu/effect.cc +++ b/src/gpu/effect.cc @@ -195,6 +195,44 @@ void MainSequence::render_frame(float global_time, float beat, float peak, wgpuTextureRelease(surface_texture.texture); } +void MainSequence::simulate_until(float target_time, float step_rate) { +#ifndef STRIP_ALL + // Assuming 128 BPM as per main.cc. + // Ideally this should be passed in or shared. + const float bpm = 128.0f; + const float aspect_ratio = 16.0f / 9.0f; // Dummy aspect + + for (float t = 0.0f; t < target_time; t += step_rate) { + WGPUCommandEncoderDescriptor encoder_desc = {}; + WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(device, &encoder_desc); + + float beat = fmodf(t * bpm / 60.0f, 1.0f); + + // Update active lists + for (auto &entry : sequences_) { + if (t >= entry.start_time) { + entry.seq->update_active_list(t - entry.start_time); + } + } + + // Dispatch compute + for (auto &entry : sequences_) { + if (t >= entry.start_time) { + // peak = 0.0f during simulation (no audio analysis) + entry.seq->dispatch_compute(encoder, t - entry.start_time, beat, 0.0f, aspect_ratio); + } + } + + WGPUCommandBufferDescriptor cmd_desc = {}; + WGPUCommandBuffer commands = wgpuCommandEncoderFinish(encoder, &cmd_desc); + wgpuQueueSubmit(queue, 1, &commands); + } +#else + (void)target_time; + (void)step_rate; +#endif +} + void MainSequence::shutdown() { for (auto &entry : sequences_) { entry.seq->reset(); diff --git a/src/gpu/effect.h b/src/gpu/effect.h index 50b2d72..f92e3ef 100644 --- a/src/gpu/effect.h +++ b/src/gpu/effect.h @@ -105,6 +105,10 @@ public: void render_frame(float global_time, float beat, float peak, float aspect_ratio, WGPUSurface surface); + // Fast-forwards the simulation (updates & compute) without rendering. + // Used for seeking/debugging. + void simulate_until(float target_time, float step_rate); + void shutdown(); private: diff --git a/src/gpu/gpu.cc b/src/gpu/gpu.cc index 0655bb3..e68b84d 100644 --- a/src/gpu/gpu.cc +++ b/src/gpu/gpu.cc @@ -425,6 +425,10 @@ void gpu_draw(float audio_peak, float aspect_ratio, float time, float beat) { g_main_sequence.render_frame(time, beat, audio_peak, aspect_ratio, g_surface); } +void gpu_simulate_until(float time) { + g_main_sequence.simulate_until(time, 1.0f / 60.0f); +} + void gpu_shutdown() { g_main_sequence.shutdown(); } \ No newline at end of file diff --git a/src/gpu/gpu.h b/src/gpu/gpu.h index f9c322c..1d79781 100644 --- a/src/gpu/gpu.h +++ b/src/gpu/gpu.h @@ -33,6 +33,7 @@ struct RenderPass { void gpu_init(GLFWwindow *window); void gpu_draw(float audio_peak, float aspect_ratio, float time, float beat); +void gpu_simulate_until(float time); void gpu_shutdown(); // Helper functions (exposed for internal/future use) -- cgit v1.2.3