From 6a430580331365544a73e7c9d5241d5c997b4eb5 Mon Sep 17 00:00:00 2001 From: Jason Hilder Date: Wed, 24 Jun 2026 10:21:52 +0200 Subject: [PATCH] Added adjustable speed for simulator. Added struct fields, calcs for the correct cycles per frame by hz value. Updated control bar to wire it all up and make sure it updates in real time. --- src/simulator/gui.odin | 3 ++- src/simulator/gui_control_bar.odin | 36 ++++++++++++++++++++++++++---- src/simulator/simulator.odin | 14 ++++++++---- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/simulator/gui.odin b/src/simulator/gui.odin index 8daa459..bd58104 100644 --- a/src/simulator/gui.odin +++ b/src/simulator/gui.odin @@ -70,9 +70,10 @@ run_gui :: proc(sim: ^Simulator) { rl.BeginDrawing() rl.ClearBackground(rl.Color{0x18, 0x18, 0x18, 0xFF}) + cycles := int(sim.cpu_hz / SIM_FPS) if (!sim.paused) { // Cycle the machine to update memory etc - emu.run_machine(sim.machine, 12) + emu.run_machine(sim.machine, cycles) tick_timers(sim, beep) } diff --git a/src/simulator/gui_control_bar.odin b/src/simulator/gui_control_bar.odin index 3ab68f0..fb6385a 100644 --- a/src/simulator/gui_control_bar.odin +++ b/src/simulator/gui_control_bar.odin @@ -1,5 +1,6 @@ package simulator +import "core:fmt" import "core:log" import emu "../machine" @@ -36,14 +37,41 @@ gui_control_bar :: proc(rect: rl.Rectangle, sim: ^Simulator) { emu.reset_machine(sim.machine) } - // @TODO: Get this working slider_rect := rl.Rectangle{ - x = rect.width - 100 - 50, - y = rect.y + 15, + x = rect.width - 210, + y = rect.y + PADDING_X + 5, width = 100, height = 15 } - rl.GuiSlider(slider_rect, "Speed ", nil, &sim.speed_value, 0, 100) + hz_label := fmt.ctprintf("%dHz", int(sim.cpu_hz)) + rl.GuiSlider(slider_rect, "Speed ", hz_label, &sim.cpu_hz, 200, MAX_HZ) + + mouse := rl.GetMousePosition() + if rl.CheckCollisionPointRec(mouse, slider_rect) { + rl.SetMouseCursor(.POINTING_HAND) + } else { + rl.SetMouseCursor(.DEFAULT) + } + + reset_rect := rl.Rectangle{ + x = slider_rect.x - slider_rect.width - 20, + y = slider_rect.y, + width = 55, + height = 15, + } + if rl.GuiButton(reset_rect, "reset") { + sim.cpu_hz = DEFAULT_CPU_HZ + } + + info_rect := rl.Rectangle{ + x = rect.width - 35, + y = rect.y + PADDING_X, + width = 25, + height = BUTTON_HEIGHT, + } + if rl.GuiButton(info_rect, " ? ") { + sim.info_box = true + } } btn :: proc(cursor: ^f32, rect: rl.Rectangle, h, w, gap: f32, label: cstring) -> bool { diff --git a/src/simulator/simulator.odin b/src/simulator/simulator.odin index c0fb5f4..7b2a483 100644 --- a/src/simulator/simulator.odin +++ b/src/simulator/simulator.odin @@ -9,6 +9,10 @@ roms := #load_directory("../roms") // CHIP-8 ROM can be at most 3584 bytes (4096 - 0x200 reserved) // Each instruction is 2 bytes, 3584 / 2 = 1792 instructions. MAX_INSTRUCTIONS :: 1792 +SIM_FPS :: 60 +DEFAULT_CPU_HZ :: 700 +MIN_HZ :: 100 +MAX_HZ :: 1500 Instruction :: struct { address: u16, @@ -22,14 +26,16 @@ Simulator :: struct { rom_loaded: bool, paused: bool, step: bool, - cycles_per_second: int, - speed_value: f32, + cpu_hz: f32, + info_box: bool, // GUI font: rl.Font, active_tab: i32, mem_scroll: rl.Vector2, rompick_scroll: rl.Vector2, selected_rom: string, + // stack props + stack_scroll: rl.Vector2, // disassembly props disasm: [MAX_INSTRUCTIONS]Instruction, disasm_follow: bool, @@ -44,8 +50,8 @@ run_simulator :: proc(s: ^emu.System) { rom_loaded = false, paused = true, step = false, - cycles_per_second = 12, - disasm_follow = true + cpu_hz = 700, + disasm_follow = true, } run_gui(&sim)