Compare commits

...

3 Commits

Author SHA1 Message Date
jasonhilder 61471536ca Updated screenshot/showcase. 2026-06-18 08:29:57 +02:00
jasonhilder 6f701560df added section for file loading + memory cleanup
Make sure to clean up any memory allocated to the sim in terms of
disassembly instructions etc
2026-06-18 08:26:14 +02:00
jasonhilder 1a6346895a Small ui changes to fit the window better. 2026-06-18 08:25:14 +02:00
6 changed files with 71 additions and 59 deletions
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

After

Width:  |  Height:  |  Size: 209 KiB

+6 -2
View File
@@ -115,6 +115,9 @@ run_gui :: proc(sim: ^Simulator) {
rl.UnloadSound(beep) rl.UnloadSound(beep)
rl.CloseAudioDevice() rl.CloseAudioDevice()
rl.CloseWindow() rl.CloseWindow()
// Free any allocated memory for the simulator
delete(sim.disasm)
} }
// @TODO: If this grows lets move it into its own file // @TODO: If this grows lets move it into its own file
@@ -128,6 +131,7 @@ calc_layout :: proc(screen_width: f32, screen_height: f32) -> Layout {
sidebar_width := screen_width * SIDEBAR_PERCENT sidebar_width := screen_width * SIDEBAR_PERCENT
display_width := screen_width - (sidebar_width * 2) - sidebar_width display_width := screen_width - (sidebar_width * 2) - sidebar_width
display_height := visible_height * DISPLAY_V_RATIO display_height := visible_height * DISPLAY_V_RATIO
keypad_height := (y_pos + visible_height - visible_height / 2)
x_center := sidebar_width x_center := sidebar_width
y_center := screen_width - sidebar_width * 2 y_center := screen_width - sidebar_width * 2
@@ -144,11 +148,11 @@ calc_layout :: proc(screen_width: f32, screen_height: f32) -> Layout {
x = 0, x = 0,
y = y_pos, y = y_pos,
width = sidebar_width, width = sidebar_width,
height = visible_height / 3 height = keypad_height - y_pos
}, },
keypad = rl.Rectangle{ keypad = rl.Rectangle{
x = 0, x = 0,
y = (y_pos + visible_height - visible_height / 2), y = keypad_height,
width = sidebar_width, width = sidebar_width,
height = visible_height / 2 height = visible_height / 2
}, },
+1 -1
View File
@@ -6,7 +6,7 @@ gui_bottom_tabs :: proc(rect: rl.Rectangle, sim: ^Simulator) {
rl.DrawRectangleLinesEx(rect, 1, rl.GRAY) rl.DrawRectangleLinesEx(rect, 1, rl.GRAY)
// Setup tab bar // Setup tab bar
tabs := [?]cstring{ "Memory", "Disassembly", "Log" } tabs := [?]cstring{ "Memory", "Log" }
tab_bar_rect := rl.Rectangle{ tab_bar_rect := rl.Rectangle{
rect.x, rect.x,
+28 -30
View File
@@ -16,15 +16,17 @@ Instruction :: struct {
gui_file_loader :: proc(rect: rl.Rectangle, sim: ^Simulator) { gui_file_loader :: proc(rect: rl.Rectangle, sim: ^Simulator) {
rl.DrawRectangleLinesEx(rect, 1, rl.GRAY) rl.DrawRectangleLinesEx(rect, 1, rl.GRAY)
// FILE SECTION:
// ---------------------------------------------
top_bounds_height := (rect.height - (PADDING_Y * 2)) / 3
bounds := rl.Rectangle { bounds := rl.Rectangle {
x = rect.x + PADDING_X, x = rect.x + PADDING_X,
y = rect.y + PADDING_Y, y = rect.y + PADDING_Y,
width = rect.width - (PADDING_X * 2), width = rect.width - (PADDING_X * 2),
height = rect.height - (PADDING_Y * 2), height = top_bounds_height
} }
rl.GuiPanel(bounds, "Rom / File") rl.GuiPanel(bounds, nil)
// open rom button below drop-zone
btn_rect := rl.Rectangle { btn_rect := rl.Rectangle {
bounds.x, bounds.x,
bounds.y, bounds.y,
@@ -48,6 +50,9 @@ gui_file_loader :: proc(rect: rl.Rectangle, sim: ^Simulator) {
} }
sim.rom_loaded = true sim.rom_loaded = true
// Free old instructions on sim
delete(sim.disasm)
sim.disasm = disassemble_rom(sim.machine.memory[:], 0x200, 0x200 + u16(rom_size)) sim.disasm = disassemble_rom(sim.machine.memory[:], 0x200, 0x200 + u16(rom_size))
} }
@@ -63,7 +68,7 @@ gui_file_loader :: proc(rect: rl.Rectangle, sim: ^Simulator) {
// centered drop-zone text // centered drop-zone text
text: cstring = "Drop a CHIP-8 ROM here" text: cstring = "Drop a CHIP-8 ROM here"
text_width := rl.MeasureText(text, BIG_FONT_SIZE) text_width := rl.MeasureText(text, BIG_FONT_SIZE)
text_x := drop_zone.x + (drop_zone.width - f32(text_width)) / 2 text_x := drop_zone.x + (drop_zone.width - f32(text_width))
text_y := drop_zone.y + (drop_zone.height - f32(BIG_FONT_SIZE)) / 2 text_y := drop_zone.y + (drop_zone.height - f32(BIG_FONT_SIZE)) / 2
rl.DrawTextEx(sim.font, text, {text_x, text_y}, BIG_FONT_SIZE, 1, rl.WHITE) rl.DrawTextEx(sim.font, text, {text_x, text_y}, BIG_FONT_SIZE, 1, rl.WHITE)
@@ -76,13 +81,31 @@ gui_file_loader :: proc(rect: rl.Rectangle, sim: ^Simulator) {
if rl.CheckCollisionPointRec(mouse, drop_zone) { if rl.CheckCollisionPointRec(mouse, drop_zone) {
path_str := string(dropped_file.paths[0]) path_str := string(dropped_file.paths[0])
log.info("file dropped: ", path_str) log.info("file dropped: ", path_str)
// @TODO: Stop sim, reset mem etc, load new rom
} else { } else {
log.info("File dropped outside drop zone, ignoring") log.info("File dropped outside drop zone, ignoring")
} }
} }
rl.UnloadDroppedFiles(dropped_file) rl.UnloadDroppedFiles(dropped_file)
} }
// FOLDER SECTION:
// ---------------------------------------------
bottom_bounds := rl.Rectangle {
x = bounds.x,
y = bounds.y + top_bounds_height,
width = rect.width - (PADDING_X * 2),
height = rect.height - top_bounds_height - (PADDING_X * 2)
}
rl.GuiPanel(bottom_bounds, nil)
bottom_btn_rect := rl.Rectangle {
bottom_bounds.x,
bottom_bounds.y,
rect.width - (PADDING_X * 2),
BUTTON_HEIGHT,
}
rl.GuiButton(bottom_btn_rect, "Open ROM Folder")
} }
disassemble_rom :: proc(memory: []u8, start: u16, end_addr: u16) -> []Instruction { disassemble_rom :: proc(memory: []u8, start: u16, end_addr: u16) -> []Instruction {
@@ -167,28 +190,3 @@ disassemble_rom :: proc(memory: []u8, start: u16, end_addr: u16) -> []Instructio
return entries[:] return entries[:]
} }
+24 -12
View File
@@ -6,42 +6,54 @@ import rl "vendor:raylib"
gui_tab_disasm :: proc(rect: rl.Rectangle, sim: ^Simulator) { gui_tab_disasm :: proc(rect: rl.Rectangle, sim: ^Simulator) {
rl.DrawRectangleRec(rect, rl.DARKGRAY) rl.DrawRectangleRec(rect, rl.DARKGRAY)
rl.GuiPanel(rect, "Disassembly")
// Header background
rl.DrawRectangle(i32(rect.x), i32(rect.y), i32(rect.width), i32(PANEL_HEADER), rl.BLACK)
// Header: Address label
rl.DrawTextEx(sim.font, "Disassembled Instructions", {rect.x + 4, rect.y + 4}, 18, 1, rl.WHITE)
// Scroll panel area (below header)
panel_rect := rl.Rectangle{
rect.x,
rect.y + PANEL_HEADER,
rect.width,
rect.height - PANEL_HEADER,
}
rl.GuiPanel(panel_rect, nil)
LINE_HEIGHT :: 22 LINE_HEIGHT :: 22
// Total height of all instructions // Total height of all instructions
conten_height := f32(len(sim.disasm)) * LINE_HEIGHT
content_rect := rl.Rectangle { content_rect := rl.Rectangle {
x = rect.x, x = panel_rect.x,
y = rect.y, y = panel_rect.y - PANEL_HEADER,
width = rect.width + PANEL_HEADER, width = panel_rect.width + PANEL_HEADER,
height = conten_height, height = f32(len(sim.disasm)) * LINE_HEIGHT
} }
view: rl.Rectangle view: rl.Rectangle
rl.GuiScrollPanel(rect, nil, content_rect, &sim.disasm_scroll, &view) rl.GuiScrollPanel(panel_rect, nil, content_rect, &sim.disasm_scroll, &view)
rl.BeginScissorMode(i32(view.x), i32(view.y), i32(view.width), i32(view.height)) rl.BeginScissorMode(i32(view.x), i32(view.y), i32(view.width), i32(view.height))
defer rl.EndScissorMode() defer rl.EndScissorMode()
for entry, i in sim.disasm { for entry, i in sim.disasm {
y_pos := rect.y + PANEL_HEADER + (f32(i) * LINE_HEIGHT) + sim.disasm_scroll.y y_pos := panel_rect.y + (f32(i) * LINE_HEIGHT) + sim.disasm_scroll.y
txt := fmt.tprintf("%d : %s", i, entry.str) txt := fmt.tprintf("%d : %s", i, entry.str)
bg_color := rl.DARKGRAY if entry.address != sim.machine.pc else rl.BLACK bg_color := rl.DARKGRAY if entry.address != sim.machine.pc else rl.BLACK
txt_color := rl.WHITE txt_color := rl.WHITE
rl.DrawRectangleV( rl.DrawRectangleV(
{rect.x + sim.disasm_scroll.x, y_pos}, {panel_rect.x + sim.disasm_scroll.x, y_pos},
{rect.width, LINE_HEIGHT}, {panel_rect.width, LINE_HEIGHT},
bg_color, bg_color,
) )
rl.DrawTextEx( rl.DrawTextEx(
sim.font, sim.font,
strings.clone_to_cstring(txt, context.temp_allocator), strings.clone_to_cstring(txt, context.temp_allocator),
{rect.x + PADDING_X + sim.disasm_scroll.x, y_pos}, {panel_rect.x + PADDING_X + sim.disasm_scroll.x, y_pos},
18, 1, 18, 1,
txt_color, txt_color,
) )
+9 -11
View File
@@ -7,7 +7,6 @@ import rl "vendor:raylib"
MEM_INDICATOR_W :: 14 MEM_INDICATOR_W :: 14
MEM_ADDRESS_W :: 72 MEM_ADDRESS_W :: 72
MEM_ROW_H :: 20 MEM_ROW_H :: 20
MEM_HEADER_H :: 24
MEM_BYTES_PER_ROW :: 16 MEM_BYTES_PER_ROW :: 16
MEM_TOTAL_ROWS :: 256 MEM_TOTAL_ROWS :: 256
MEM_FONT_ROWS :: 5 MEM_FONT_ROWS :: 5
@@ -25,32 +24,32 @@ gui_tab_memory :: proc(rect: rl.Rectangle, sim: ^Simulator) {
rl.DrawRectangleRec(rect, rl.DARKGRAY) rl.DrawRectangleRec(rect, rl.DARKGRAY)
// Header background // Header background
rl.DrawRectangle(i32(rect.x), i32(rect.y), i32(rect.width), MEM_HEADER_H, rl.BLACK) rl.DrawRectangle(i32(rect.x), i32(rect.y), i32(rect.width), i32(PANEL_HEADER), rl.BLACK)
// Header: Address label // Header: Address label
rl.DrawTextEx(sim.font, "Address", {rect.x + MEM_INDICATOR_W, rect.y + 4}, 16, 1, rl.GRAY) rl.DrawTextEx(sim.font, "Address", {rect.x + MEM_INDICATOR_W, rect.y + 4}, 18, 1, rl.WHITE)
// Header: column labels 0-F // Header: column labels 0-F
col_w := byte_col_w(rect) col_w := byte_col_w(rect)
for col in 0..<16 { for col in 0..<16 {
x := rect.x + MEM_INDICATOR_W + MEM_ADDRESS_W + f32(col) * col_w x := rect.x + MEM_INDICATOR_W + MEM_ADDRESS_W + f32(col) * col_w
label := strings.clone_to_cstring(MEM_COL_LABELS[col], context.temp_allocator) label := strings.clone_to_cstring(MEM_COL_LABELS[col], context.temp_allocator)
rl.DrawTextEx(sim.font, label, {x, rect.y + 4}, 16, 1, rl.GRAY) rl.DrawTextEx(sim.font, label, {x, rect.y + 4}, 18, 1, rl.WHITE)
} }
// Header separator // Header separator
rl.DrawLine( rl.DrawLine(
i32(rect.x), i32(rect.y + MEM_HEADER_H), i32(rect.x), i32(rect.y + PANEL_HEADER),
i32(rect.x + rect.width), i32(rect.y + MEM_HEADER_H), i32(rect.x + rect.width), i32(rect.y + PANEL_HEADER),
rl.GRAY, rl.GRAY,
) )
// Scroll panel area (below header) // Scroll panel area (below header)
panel_rect := rl.Rectangle{ panel_rect := rl.Rectangle{
rect.x, rect.x,
rect.y + MEM_HEADER_H, rect.y + PANEL_HEADER,
rect.width, rect.width,
rect.height - MEM_HEADER_H, rect.height - PANEL_HEADER,
} }
content_rect := rl.Rectangle{ content_rect := rl.Rectangle{
@@ -66,7 +65,7 @@ gui_tab_memory :: proc(rect: rl.Rectangle, sim: ^Simulator) {
draw_row := 0 draw_row := 0
// --- Font rows (0x000 - 0x04F) --- // Font rows (0x000 - 0x04F)
for row in 0..<MEM_FONT_ROWS { for row in 0..<MEM_FONT_ROWS {
addr := row * MEM_BYTES_PER_ROW addr := row * MEM_BYTES_PER_ROW
row_y := panel_rect.y + f32(draw_row) * MEM_ROW_H + sim.mem_scroll.y row_y := panel_rect.y + f32(draw_row) * MEM_ROW_H + sim.mem_scroll.y
@@ -74,7 +73,6 @@ gui_tab_memory :: proc(rect: rl.Rectangle, sim: ^Simulator) {
draw_row += 1 draw_row += 1
} }
// --- Divider ---
divider_y := panel_rect.y + f32(draw_row) * MEM_ROW_H + sim.mem_scroll.y divider_y := panel_rect.y + f32(draw_row) * MEM_ROW_H + sim.mem_scroll.y
rl.DrawRectangle(i32(rect.x), i32(divider_y), i32(rect.width), MEM_ROW_H, rl.ColorAlpha(rl.BLACK, 0.4)) rl.DrawRectangle(i32(rect.x), i32(divider_y), i32(rect.width), MEM_ROW_H, rl.ColorAlpha(rl.BLACK, 0.4))
rl.DrawTextEx( rl.DrawTextEx(
@@ -85,7 +83,7 @@ gui_tab_memory :: proc(rect: rl.Rectangle, sim: ^Simulator) {
) )
draw_row += 1 draw_row += 1
// --- ROM rows (0x200 onwards) --- // ROM rows (0x200 onwards)
for i := 0; MEM_ROM_START + i * MEM_BYTES_PER_ROW < 4096; i += 1 { for i := 0; MEM_ROM_START + i * MEM_BYTES_PER_ROW < 4096; i += 1 {
addr := MEM_ROM_START + i * MEM_BYTES_PER_ROW addr := MEM_ROM_START + i * MEM_BYTES_PER_ROW
row_y := panel_rect.y + f32(draw_row) * MEM_ROW_H + sim.mem_scroll.y row_y := panel_rect.y + f32(draw_row) * MEM_ROW_H + sim.mem_scroll.y