Compare commits

...

3 Commits

Author SHA1 Message Date
jasonhilder 6ca732f178 Updated showcase. 2026-06-23 08:40:51 +02:00
jasonhilder baa1e1a5cf added game roms to src for embedding. 2026-06-23 08:40:34 +02:00
jasonhilder c909d28587 Added embed roms and cleaned up selecting roms.
Added 2 new helper functions one to load a rom selected on system and
anothe to load a rom into memory from the embedded roms.
2026-06-23 08:06:08 +02:00
28 changed files with 82 additions and 22 deletions
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 KiB

After

Width:  |  Height:  |  Size: 286 KiB

+1
View File
@@ -25,6 +25,7 @@ BUTTON_WIDTH :: 120
// Fonts // Fonts
BIG_FONT_SIZE :: 20 BIG_FONT_SIZE :: 20
KEYPAD_FONT_SIZE :: 18 KEYPAD_FONT_SIZE :: 18
LINE_HEIGHT :: 22
Layout :: struct { Layout :: struct {
control_bar : rl.Rectangle, control_bar : rl.Rectangle,
+76 -20
View File
@@ -1,5 +1,6 @@
package simulator package simulator
import "core:strings"
import "core:fmt" import "core:fmt"
import "core:log" import "core:log"
import rl "vendor:raylib" import rl "vendor:raylib"
@@ -32,18 +33,7 @@ gui_file_loader :: proc(rect: rl.Rectangle, sim: ^Simulator) {
ret := tfd.openFileDialog("Open File Dialog", nil, 0, nil, nil, 0,) ret := tfd.openFileDialog("Open File Dialog", nil, 0, nil, nil, 0,)
rom_path := string(ret) rom_path := string(ret)
if rom_path == "" do return if rom_path == "" do return
load_selected_rom(sim, rom_path)
// Reset machine state
emu.reset_machine(sim.machine)
// load new rom
rom_size, err := emu.load_rom(sim.machine, rom_path)
if err != nil {
// @TODO: update status bar here
panic("failed to load rom!")
}
sim.rom_loaded = true
sim.disasm_count = disassemble_rom_n(sim.machine.memory[:], 0x200, 0x200 + u16(rom_size), sim.disasm[:])
} }
// drop-zone occupies the panel's content area, minus space for the button // drop-zone occupies the panel's content area, minus space for the button
@@ -78,7 +68,7 @@ gui_file_loader :: proc(rect: rl.Rectangle, sim: ^Simulator) {
rl.UnloadDroppedFiles(dropped_file) rl.UnloadDroppedFiles(dropped_file)
} }
// FOLDER SECTION: // Embedded Rom Section:
// --------------------------------------------- // ---------------------------------------------
bottom_bounds := rl.Rectangle { bottom_bounds := rl.Rectangle {
x = bounds.x, x = bounds.x,
@@ -86,16 +76,82 @@ gui_file_loader :: proc(rect: rl.Rectangle, sim: ^Simulator) {
width = rect.width - (PADDING_X * 2), width = rect.width - (PADDING_X * 2),
height = rect.height - top_bounds_height - (PADDING_X * 2) height = rect.height - top_bounds_height - (PADDING_X * 2)
} }
rl.GuiPanel(bottom_bounds, nil) rl.GuiPanel(bottom_bounds, "ROM List")
bottom_btn_rect := rl.Rectangle { panel_rect := rl.Rectangle {
bottom_bounds.x, x = bottom_bounds.x,
bottom_bounds.y, y = bottom_bounds.y + PANEL_HEADER,
rect.width - (PADDING_X * 2), width = rect.width - (PADDING_X * 2),
BUTTON_HEIGHT, height = rect.height - top_bounds_height - (PADDING_X * 2) - PANEL_HEADER
} }
rl.GuiButton(bottom_btn_rect, "Open ROM Folder") content_rect := rl.Rectangle {
x = panel_rect.x,
y = panel_rect.y - PANEL_HEADER,
width = panel_rect.width + PANEL_HEADER,
height = f32(len(roms)) * LINE_HEIGHT
}
view: rl.Rectangle
rl.GuiScrollPanel(panel_rect, nil, content_rect, &sim.rompick_scroll, &view)
rl.BeginScissorMode(i32(view.x), i32(view.y), i32(view.width), i32(view.height))
defer rl.EndScissorMode()
for path, index in roms {
y_pos := panel_rect.y + f32(index * LINE_HEIGHT) + sim.rompick_scroll.y
row_rect := rl.Rectangle {
x = view.x,
y = y_pos,
width = view.width,
height = LINE_HEIGHT,
}
// make selected visible
if path.name == sim.selected_rom {
rl.DrawRectangleRec(row_rect, rl.ColorAlpha(rl.SKYBLUE, 0.25))
}
// hover rows
mouse := rl.GetMousePosition()
if rl.CheckCollisionPointRec(mouse, row_rect) {
rl.DrawRectangleRec(row_rect, rl.ColorAlpha(rl.WHITE, 0.08))
if rl.IsMouseButtonPressed(.LEFT) {
sim.selected_rom = path.name
load_embedded_rom(sim, path.name, roms[index].data)
}
}
txt := fmt.tprintf("%v: %v", (index + 1), path.name)
rl.DrawTextEx(
sim.font,
strings.clone_to_cstring(txt, context.temp_allocator),
{panel_rect.x + PADDING_X + sim.rompick_scroll.x, y_pos + (LINE_HEIGHT - 18) * 0.5},
18, 1,
rl.WHITE
)
}
}
load_selected_rom :: proc(sim: ^Simulator, rom_path: string) {
emu.reset_machine(sim.machine)
rom_size, err := emu.load_rom(sim.machine, rom_path)
if err != nil {
// @TODO: update status bar here
panic("failed to load rom!")
}
sim.rom_loaded = true
sim.paused = true
sim.disasm_count = disassemble_rom_n(sim.machine.memory[:], 0x200, 0x200 + u16(rom_size), sim.disasm[:])
}
load_embedded_rom :: proc(sim: ^Simulator, path: string, data: []byte) {
emu.reset_machine(sim.machine)
copy(sim.machine.memory[0x200:], data)
sim.rom_loaded = true
sim.paused = true
sim.disasm_count = disassemble_rom_n(sim.machine.memory[:], 0x200, 0x200 + u16(len(data)), sim.disasm[:])
} }
disassemble_rom_n :: proc(memory: []u8, start_addr: u16, end_addr: u16, out: []Instruction) -> int { disassemble_rom_n :: proc(memory: []u8, start_addr: u16, end_addr: u16, out: []Instruction) -> int {
-2
View File
@@ -27,8 +27,6 @@ gui_tab_disasm :: proc(rect: rl.Rectangle, sim: ^Simulator) {
} }
rl.GuiPanel(panel_rect, nil) rl.GuiPanel(panel_rect, nil)
LINE_HEIGHT :: 22
// Total height of all instructions // Total height of all instructions
content_rect := rl.Rectangle { content_rect := rl.Rectangle {
x = panel_rect.x, x = panel_rect.x,
+5
View File
@@ -3,6 +3,9 @@ package simulator
import emu "../machine" import emu "../machine"
import rl "vendor:raylib" import rl "vendor:raylib"
// Embed roms
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
@@ -25,6 +28,8 @@ Simulator :: struct {
font: rl.Font, font: rl.Font,
active_tab: i32, active_tab: i32,
mem_scroll: rl.Vector2, mem_scroll: rl.Vector2,
rompick_scroll: rl.Vector2,
selected_rom: string,
// disassembly props // disassembly props
disasm: [MAX_INSTRUCTIONS]Instruction, disasm: [MAX_INSTRUCTIONS]Instruction,
disasm_follow: bool, disasm_follow: bool,