Renamed gui to simulator as a better structure.
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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..<cycles {
|
||||
handle_input(s)
|
||||
cycle(s)
|
||||
}
|
||||
|
||||
+7
-9
@@ -3,8 +3,8 @@ package main
|
||||
import "core:log"
|
||||
import "core:mem"
|
||||
|
||||
import chip "machine"
|
||||
import gui "gui"
|
||||
import emu "machine"
|
||||
import sim "simulator"
|
||||
|
||||
DEV :: #config(DEV, false)
|
||||
|
||||
@@ -20,20 +20,18 @@ main :: proc() {
|
||||
context.allocator = mem.tracking_allocator(&track)
|
||||
}
|
||||
|
||||
// Init the Chip 8 "cpu"
|
||||
system := chip.init()
|
||||
// Init the emu 8 "cpu"
|
||||
system := emu.init()
|
||||
|
||||
// TODO: move this into a gui component
|
||||
// load rom, hardcoded for now, will eventually be cli or gui
|
||||
err := chip.load_rom(&system, "./test_roms/7-beep.ch8")
|
||||
err := emu.load_rom(&system, "./test_roms/7-beep.ch8")
|
||||
if err != nil {
|
||||
panic("failed to load rom!")
|
||||
}
|
||||
|
||||
// gui will init the layout etc, it will require reference to
|
||||
// the system as it will use its display buffer etc
|
||||
// NOTE: may just need a few fields rather than whole struct check later
|
||||
gui.init_gui(&system)
|
||||
// Initilize sim, gui etc
|
||||
sim.run_simulator(&system)
|
||||
|
||||
when DEV {
|
||||
if len(track.allocation_map) > 0 {
|
||||
|
||||
@@ -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 {
|
||||
@@ -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) {
|
||||
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
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package gui
|
||||
package simulator
|
||||
|
||||
import m "../machine"
|
||||
import rl "vendor:raylib"
|
||||
@@ -1,4 +1,4 @@
|
||||
package gui
|
||||
package simulator
|
||||
|
||||
import m "../machine"
|
||||
import rl "vendor:raylib"
|
||||
@@ -1,4 +1,4 @@
|
||||
package gui
|
||||
package simulator
|
||||
|
||||
import m "../machine"
|
||||
import rl "vendor:raylib"
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user