105 lines
3.1 KiB
Odin
105 lines
3.1 KiB
Odin
package simulator
|
||
|
||
import rl "vendor:raylib"
|
||
|
||
CPU_SECTION_H :: 100 // enough for 3 rows of labels
|
||
REG_CELL_H :: 40 // fixed, won't grow with the panel
|
||
|
||
gui_cpu :: proc(rect: rl.Rectangle, sim: ^Simulator) {
|
||
rl.DrawRectangleLinesEx(rect, 1, rl.GRAY)
|
||
|
||
bounds := rl.Rectangle {
|
||
x = rect.x + PADDING_X,
|
||
y = rect.y + PADDING_Y,
|
||
width = rect.width - (PADDING_X * 2),
|
||
height = rect.height - (PADDING_Y * 2),
|
||
}
|
||
rl.GuiPanel(bounds, "CPU / Registers")
|
||
|
||
cpu_rect := rl.Rectangle {
|
||
x = bounds.x + PADDING_X,
|
||
y = bounds.y + PADDING_Y + PANEL_HEADER,
|
||
width = bounds.width - (PADDING_X * 2),
|
||
height = CPU_SECTION_H - (PADDING_Y * 2),
|
||
}
|
||
|
||
// Grid constants
|
||
COLS :: 2
|
||
ROWS :: 3
|
||
LRATIO :: f32(0.6)
|
||
|
||
cell_w := cpu_rect.width / COLS
|
||
cell_h := cpu_rect.height / ROWS
|
||
|
||
labels := [5]string{ "Progam Counter", "Increment pointer", "Stack Pointer", "Delay Timer", "Sound Timer" }
|
||
values := [5]u16{
|
||
sim.machine.pc,
|
||
sim.machine.i,
|
||
u16(sim.machine.sp),
|
||
u16(sim.machine.delay_timer),
|
||
u16(sim.machine.sound_timer),
|
||
}
|
||
|
||
for index in 0..<5 {
|
||
col := index % COLS
|
||
row := index / COLS
|
||
|
||
cell_x := cpu_rect.x + f32(col) * cell_w
|
||
cell_y := cpu_rect.y + f32(row) * cell_h
|
||
|
||
label_rect := rl.Rectangle{cell_x + 20, cell_y, cell_w,cell_h}
|
||
box_rect := rl.Rectangle{cell_x + cell_w * LRATIO, cell_y, cell_w * (1 - LRATIO), cell_h}
|
||
|
||
rl.GuiLabel(label_rect, rl.TextFormat("%s", labels[index]))
|
||
rl.DrawRectangleLinesEx(box_rect, 1, rl.DARKGRAY)
|
||
|
||
// Right-aligned value
|
||
value_text := rl.TextFormat("0x%04X", values[index])
|
||
text_w := rl.MeasureText(value_text, 18)
|
||
value_x := box_rect.x + box_rect.width - f32(text_w) - 4
|
||
rl.GuiLabel({value_x, box_rect.y, box_rect.width, box_rect.height}, value_text)
|
||
}
|
||
|
||
|
||
register_bounds := rl.Rectangle {
|
||
x = bounds.x,
|
||
y = bounds.y + PANEL_HEADER + PADDING_Y + CPU_SECTION_H,
|
||
width = bounds.width,
|
||
height = bounds.height - PANEL_HEADER - PADDING_Y - CPU_SECTION_H,
|
||
}
|
||
rl.GuiPanel(register_bounds, "Registers")
|
||
|
||
register_rect := rl.Rectangle {
|
||
x = register_bounds.x + PADDING_X,
|
||
y = register_bounds.y + PADDING_Y + PANEL_HEADER,
|
||
width = register_bounds.width - (PADDING_X * 2),
|
||
height = register_bounds.height - (PADDING_Y * 2) - PANEL_HEADER,
|
||
}
|
||
|
||
// V registers grid (V0–VF, 16 registers)
|
||
REG_COLS :: 4
|
||
REG_ROWS :: 4
|
||
|
||
reg_cell_w := register_rect.width / REG_COLS
|
||
|
||
for index in 0..<16 {
|
||
col := index % REG_COLS
|
||
row := index / REG_COLS
|
||
|
||
cell_x := register_rect.x + f32(col) * reg_cell_w
|
||
cell_y := register_rect.y + f32(row) * REG_CELL_H
|
||
|
||
label_rect := rl.Rectangle{cell_x + 20, cell_y, reg_cell_w, REG_CELL_H}
|
||
box_rect := rl.Rectangle{cell_x + reg_cell_w * LRATIO, cell_y, reg_cell_w * (1 - LRATIO), REG_CELL_H}
|
||
|
||
rl.GuiLabel(label_rect, rl.TextFormat("V%X", index))
|
||
rl.DrawRectangleLinesEx(box_rect, 1, rl.DARKGRAY)
|
||
|
||
// Right-aligned value
|
||
value_text := rl.TextFormat("0x%02X", sim.machine.v[index])
|
||
text_w := rl.MeasureText(value_text, 18)
|
||
value_x := box_rect.x + box_rect.width - f32(text_w) - 4
|
||
rl.GuiLabel({value_x, box_rect.y, box_rect.width, box_rect.height}, value_text)
|
||
}
|
||
}
|