diff --git a/assets/fonts/Inter_18pt-Regular.ttf b/assets/fonts/Inter_18pt-Regular.ttf new file mode 100644 index 0000000..ce097c8 Binary files /dev/null and b/assets/fonts/Inter_18pt-Regular.ttf differ diff --git a/assets/raygui_styles/dark.rgs b/assets/raygui_styles/dark.rgs new file mode 100644 index 0000000..0034483 Binary files /dev/null and b/assets/raygui_styles/dark.rgs differ diff --git a/assets/raygui_styles/style_dark.rgs b/assets/raygui_styles/style_dark.rgs new file mode 100644 index 0000000..1e965d9 Binary files /dev/null and b/assets/raygui_styles/style_dark.rgs differ diff --git a/src/machine/machine.odin b/src/machine/machine.odin index 544d4e9..af72f61 100644 --- a/src/machine/machine.odin +++ b/src/machine/machine.odin @@ -61,9 +61,9 @@ init :: proc() -> System { return s } -run_machine :: proc(s: ^System) { +run_machine :: proc(s: ^System, cycles: int) { // CPU cycles - for _ in 0..<12 { + for _ in 0.. 0 { diff --git a/src/gui/control_bar.odin b/src/simulator/control_bar.odin similarity index 62% rename from src/gui/control_bar.odin rename to src/simulator/control_bar.odin index a1200a4..08665d0 100644 --- a/src/gui/control_bar.odin +++ b/src/simulator/control_bar.odin @@ -1,14 +1,12 @@ -package gui +package simulator import "core:log" -import m "../machine" import rl "vendor:raylib" PADDING :: 10 -gui_control_bar :: proc(rect: rl.Rectangle, s: ^m.System) { +gui_control_bar :: proc(rect: rl.Rectangle, sim: ^Simulator) { rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY) - // Small text area // Control bar buttons @@ -17,10 +15,19 @@ gui_control_bar :: proc(rect: rl.Rectangle, s: ^m.System) { gap : f32 = 6 cursor : f32 = rect.x + PADDING - if btn(&cursor, rect, btn_h, btn_w, gap, "RUN") { log.info("RUN clicked") } - if btn(&cursor, rect, btn_h, btn_w, gap, "PAUSE") { log.info("PAUSE clicked") } + if btn(&cursor, rect, btn_h, btn_w, gap, "RUN") { + log.info("RUN clicked") + sim.paused = false + sim.running = true + } + + if btn(&cursor, rect, btn_h, btn_w, gap, "PAUSE") { + log.info("PAUSE clicked") + sim.paused = true + sim.running = false + } + if btn(&cursor, rect, btn_h, btn_w, gap, "STEP") { log.info("STEP clicked") } - if btn(&cursor, rect, btn_h, btn_w, gap, "STOP") { log.info("STOP clicked") } } btn :: proc(cursor: ^f32, rect: rl.Rectangle, h, w, gap: f32, label: cstring) -> bool { diff --git a/src/gui/gui.odin b/src/simulator/gui.odin similarity index 53% rename from src/gui/gui.odin rename to src/simulator/gui.odin index 4df9ae5..0a7491f 100644 --- a/src/gui/gui.odin +++ b/src/simulator/gui.odin @@ -1,6 +1,6 @@ -package gui +package simulator -import m "../machine" +import emu "../machine" import rl "vendor:raylib" // Initial window size @@ -17,14 +17,29 @@ Layout :: struct { left_panel : rl.Rectangle, display : rl.Rectangle, right_panel : rl.Rectangle, + status_bar : rl.Rectangle, } // Initialize main the gui 'window' -init_gui :: proc(s: ^m.System) { - rl.SetConfigFlags({.WINDOW_RESIZABLE}) - rl.InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "raylib") - rl.InitAudioDevice() - rl.SetTargetFPS(60) +run_gui :: proc(sim: ^Simulator) { + rl.SetConfigFlags({.WINDOW_RESIZABLE}) + rl.InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "raylib") + rl.InitAudioDevice() + rl.SetTargetFPS(60) + beep := rl.LoadSound("./beep.wav") + + // Load fonts + font := rl.LoadFontEx("./assets/fonts/Inter_18pt-Regular.ttf", 18, nil, 0) + rl.SetTextureFilter(font.texture, .BILINEAR) + sim.font = font + + // Initialize style system first + rl.GuiLoadStyleDefault() + // Then load dark theme + rl.GuiLoadStyle("./assets/raygui_styles/style_dark.rgs") + // Then override font AFTER (style load resets it) + rl.GuiSetFont(font) + rl.GuiSetStyle(.DEFAULT, cast(i32)rl.GuiDefaultProperty.TEXT_SIZE, 18) // Draw each of the components in its own window within the main window for !rl.WindowShouldClose() { @@ -41,17 +56,39 @@ init_gui :: proc(s: ^m.System) { rl.ClearBackground(rl.BLACK) // Cycle the machine to update memory etc - m.run_machine(s) + // if (sim.is_running) else don't run machine, here we can start,pause etc + if (!sim.paused) { + emu.run_machine(sim.machine, 12) - // Now draw the update data - gui_left_panel(layout.left_panel, s) - gui_right_panel(layout.right_panel, s) - gui_screen(layout.display, s) - gui_control_bar(layout.control_bar, s) + // Handle delay timer + if sim.machine.delay_timer > 0 do sim.machine.delay_timer -= 1 + + // Current sound file is around 1s so stop + // immediately when timer is 0 + if sim.machine.sound_timer > 0 { + sim.machine.sound_timer -= 1 + if !rl.IsSoundPlaying(beep) do rl.PlaySound(beep) + } else { + rl.StopSound(beep) + } + + } + + gui_control_bar(layout.control_bar, sim) + // gui_left_panel(layout.left_panel, s.machine) + // gui_right_panel(layout.right_panel, s.machine) + + // Screen is just drawing the display buffer just needs that as arg + // Not the whole sim struct + gui_screen(layout.display, sim.machine) + gui_status_bar(layout.status_bar, sim) rl.EndDrawing() } + rl.UnloadFont(sim.font) + rl.UnloadFont(font) + rl.UnloadSound(beep) rl.CloseAudioDevice() rl.CloseWindow() } @@ -88,5 +125,11 @@ calc_layout :: proc(screen_width: f32, screen_height: f32) -> Layout { width = sidebar_width, height = sidebar_height }, + status_bar = rl.Rectangle { + x = 0, + y = screen_height - control_bar_height, + width = screen_width, + height = control_bar_height + }, } } diff --git a/src/gui/left_panel.odin b/src/simulator/left_panel.odin similarity index 89% rename from src/gui/left_panel.odin rename to src/simulator/left_panel.odin index 446a31e..9c8dedd 100644 --- a/src/gui/left_panel.odin +++ b/src/simulator/left_panel.odin @@ -1,4 +1,4 @@ -package gui +package simulator import m "../machine" import rl "vendor:raylib" diff --git a/src/gui/right_panel.odin b/src/simulator/right_panel.odin similarity index 89% rename from src/gui/right_panel.odin rename to src/simulator/right_panel.odin index e391bfb..553bc91 100644 --- a/src/gui/right_panel.odin +++ b/src/simulator/right_panel.odin @@ -1,4 +1,4 @@ -package gui +package simulator import m "../machine" import rl "vendor:raylib" diff --git a/src/gui/screen.odin b/src/simulator/screen.odin similarity index 98% rename from src/gui/screen.odin rename to src/simulator/screen.odin index 3376dd1..4ad3ce4 100644 --- a/src/gui/screen.odin +++ b/src/simulator/screen.odin @@ -1,4 +1,4 @@ -package gui +package simulator import m "../machine" import rl "vendor:raylib" diff --git a/src/simulator/simulator.odin b/src/simulator/simulator.odin new file mode 100644 index 0000000..5e850ca --- /dev/null +++ b/src/simulator/simulator.odin @@ -0,0 +1,25 @@ +package simulator + +import emu "../machine" +import rl "vendor:raylib" + +Simulator :: struct { + font: rl.Font, + + machine: ^emu.System, + running: bool, + paused: bool, + cycles_per_second: int +} + +// Requires an initilized emulatore System Struct +run_simulator :: proc(s: ^emu.System) { + sim := Simulator { + machine = s, + running = true, + paused = false, + cycles_per_second = 12 + } + + run_gui(&sim) +} diff --git a/src/simulator/status_bar.odin b/src/simulator/status_bar.odin new file mode 100644 index 0000000..f441ff5 --- /dev/null +++ b/src/simulator/status_bar.odin @@ -0,0 +1,46 @@ +package simulator + +import "core:fmt" +import rl "vendor:raylib" + +gui_status_bar :: proc(rect: rl.Rectangle, sim: ^Simulator) { + rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY) + + cursor: f32 = rect.x + PADDING + cy := rect.y + rect.height * 0.5 + + if sim.running && !sim.paused { + status_icon(&cursor, cy, rl.GREEN, .CIRCLE, "Running", sim.font) + } else { + status_icon(&cursor, cy, rl.RED, .SQUARE, "Paused", sim.font) + } + + status_divider(&cursor, cy) + status_text(&cursor, cy, fmt.ctprintf("FPS: %d", rl.GetFPS()), sim.font) +} + +StatusIconShape :: enum { CIRCLE, SQUARE } + +status_icon :: proc(cursor: ^f32, cy: f32, color: rl.Color, shape: StatusIconShape, label: cstring, font: rl.Font) { + size: f32 = 10 + ix := cursor^ + size * 0.5 + + switch shape { + case .CIRCLE: rl.DrawCircleV({ix, cy}, size * 0.5, color) + case .SQUARE: rl.DrawRectangleV({ix - size*0.5, cy - size*0.5}, {size, size}, color) + } + + cursor^ += size + 6 + rl.DrawTextEx(font, label, {cursor^, cy - f32(font.baseSize) * 0.5}, f32(font.baseSize), 1, rl.RAYWHITE) + cursor^ += rl.MeasureTextEx(font, label, f32(font.baseSize), 1).x + PADDING +} + +status_divider :: proc(cursor: ^f32, cy: f32) { + rl.DrawLineV({cursor^, cy - 8}, {cursor^, cy + 8}, rl.DARKGRAY) + cursor^ += PADDING +} + +status_text :: proc(cursor: ^f32, cy: f32, text: cstring, font: rl.Font) { + rl.DrawTextEx(font, text, {cursor^, cy - f32(font.baseSize) * 0.5}, f32(font.baseSize), 1, rl.RAYWHITE) + cursor^ += rl.MeasureTextEx(font, text, f32(font.baseSize), 1).x + PADDING +} \ No newline at end of file