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.
This commit is contained in:
2026-06-24 10:21:52 +02:00
parent 7403efa6cf
commit 6a43058033
3 changed files with 44 additions and 9 deletions
+2 -1
View File
@@ -70,9 +70,10 @@ run_gui :: proc(sim: ^Simulator) {
rl.BeginDrawing() rl.BeginDrawing()
rl.ClearBackground(rl.Color{0x18, 0x18, 0x18, 0xFF}) rl.ClearBackground(rl.Color{0x18, 0x18, 0x18, 0xFF})
cycles := int(sim.cpu_hz / SIM_FPS)
if (!sim.paused) { if (!sim.paused) {
// Cycle the machine to update memory etc // Cycle the machine to update memory etc
emu.run_machine(sim.machine, 12) emu.run_machine(sim.machine, cycles)
tick_timers(sim, beep) tick_timers(sim, beep)
} }
+32 -4
View File
@@ -1,5 +1,6 @@
package simulator package simulator
import "core:fmt"
import "core:log" import "core:log"
import emu "../machine" import emu "../machine"
@@ -36,14 +37,41 @@ gui_control_bar :: proc(rect: rl.Rectangle, sim: ^Simulator) {
emu.reset_machine(sim.machine) emu.reset_machine(sim.machine)
} }
// @TODO: Get this working
slider_rect := rl.Rectangle{ slider_rect := rl.Rectangle{
x = rect.width - 100 - 50, x = rect.width - 210,
y = rect.y + 15, y = rect.y + PADDING_X + 5,
width = 100, width = 100,
height = 15 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 { btn :: proc(cursor: ^f32, rect: rl.Rectangle, h, w, gap: f32, label: cstring) -> bool {
+10 -4
View File
@@ -9,6 +9,10 @@ roms := #load_directory("../roms")
// CHIP-8 ROM can be at most 3584 bytes (4096 - 0x200 reserved) // CHIP-8 ROM can be at most 3584 bytes (4096 - 0x200 reserved)
// Each instruction is 2 bytes, 3584 / 2 = 1792 instructions. // Each instruction is 2 bytes, 3584 / 2 = 1792 instructions.
MAX_INSTRUCTIONS :: 1792 MAX_INSTRUCTIONS :: 1792
SIM_FPS :: 60
DEFAULT_CPU_HZ :: 700
MIN_HZ :: 100
MAX_HZ :: 1500
Instruction :: struct { Instruction :: struct {
address: u16, address: u16,
@@ -22,14 +26,16 @@ Simulator :: struct {
rom_loaded: bool, rom_loaded: bool,
paused: bool, paused: bool,
step: bool, step: bool,
cycles_per_second: int, cpu_hz: f32,
speed_value: f32, info_box: bool,
// GUI // GUI
font: rl.Font, font: rl.Font,
active_tab: i32, active_tab: i32,
mem_scroll: rl.Vector2, mem_scroll: rl.Vector2,
rompick_scroll: rl.Vector2, rompick_scroll: rl.Vector2,
selected_rom: string, selected_rom: string,
// stack props
stack_scroll: rl.Vector2,
// disassembly props // disassembly props
disasm: [MAX_INSTRUCTIONS]Instruction, disasm: [MAX_INSTRUCTIONS]Instruction,
disasm_follow: bool, disasm_follow: bool,
@@ -44,8 +50,8 @@ run_simulator :: proc(s: ^emu.System) {
rom_loaded = false, rom_loaded = false,
paused = true, paused = true,
step = false, step = false,
cycles_per_second = 12, cpu_hz = 700,
disasm_follow = true disasm_follow = true,
} }
run_gui(&sim) run_gui(&sim)