|
|
@@ -5,6 +5,7 @@ import "core:strings"
|
|
|
|
import rl "vendor:raylib"
|
|
|
|
import rl "vendor:raylib"
|
|
|
|
|
|
|
|
|
|
|
|
gui_left_panel :: proc(rect: rl.Rectangle, sim: ^Simulator) {
|
|
|
|
gui_left_panel :: proc(rect: rl.Rectangle, sim: ^Simulator) {
|
|
|
|
|
|
|
|
// ── Top panel and components ──
|
|
|
|
top_panel := rl.Rectangle {
|
|
|
|
top_panel := rl.Rectangle {
|
|
|
|
rect.x,
|
|
|
|
rect.x,
|
|
|
|
rect.y,
|
|
|
|
rect.y,
|
|
|
@@ -12,8 +13,18 @@ gui_left_panel :: proc(rect: rl.Rectangle, sim: ^Simulator) {
|
|
|
|
rect.height / 2,
|
|
|
|
rect.height / 2,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rl.DrawRectangleLinesEx(top_panel, 1, rl.DARKGRAY)
|
|
|
|
rl.DrawRectangleLinesEx(top_panel, 1, rl.DARKGRAY)
|
|
|
|
gui_file_loader(top_panel)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Dropzone/file loader
|
|
|
|
|
|
|
|
file_loader_rect := rl.Rectangle {
|
|
|
|
|
|
|
|
top_panel.x + PANEL_PADDING,
|
|
|
|
|
|
|
|
top_panel.y + PANEL_HEADER,
|
|
|
|
|
|
|
|
top_panel.width - PANEL_PADDING * 2,
|
|
|
|
|
|
|
|
(top_panel.height / 3) - PANEL_HEADER - PANEL_PADDING * 2,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
rl.GuiPanel(file_loader_rect, "Rom / File")
|
|
|
|
|
|
|
|
gui_file_loader(file_loader_rect)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ── Bottom panel and components ──
|
|
|
|
bottom_panel := rl.Rectangle {
|
|
|
|
bottom_panel := rl.Rectangle {
|
|
|
|
rect.x,
|
|
|
|
rect.x,
|
|
|
|
rect.y + top_panel.height,
|
|
|
|
rect.y + top_panel.height,
|
|
|
@@ -24,49 +35,98 @@ gui_left_panel :: proc(rect: rl.Rectangle, sim: ^Simulator) {
|
|
|
|
gui_key_pad(bottom_panel, sim.machine.keypad, sim.font)
|
|
|
|
gui_key_pad(bottom_panel, sim.machine.keypad, sim.font)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
gui_file_loader :: proc(rect: rl.Rectangle,) {
|
|
|
|
gui_file_loader :: proc(rect: rl.Rectangle) {
|
|
|
|
|
|
|
|
// drop-zone occupies the panel's content area, minus space for the button
|
|
|
|
|
|
|
|
drop_zone := rl.Rectangle {
|
|
|
|
|
|
|
|
rect.x + PANEL_PADDING,
|
|
|
|
|
|
|
|
rect.y + PANEL_HEADER + PANEL_PADDING,
|
|
|
|
|
|
|
|
rect.width - PANEL_PADDING * 2,
|
|
|
|
|
|
|
|
rect.height - PANEL_HEADER - PANEL_PADDING * 2 - BUTTON_HEIGHT - PANEL_PADDING,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
rl.DrawRectangleLinesEx(drop_zone, 1, rl.GREEN)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// centered drop-zone text
|
|
|
|
|
|
|
|
text: cstring = "Drop a CHIP-8 ROM here"
|
|
|
|
|
|
|
|
text_width := rl.MeasureText(text, DROP_FONT_SIZE)
|
|
|
|
|
|
|
|
text_x := drop_zone.x + (drop_zone.width - f32(text_width)) / 2
|
|
|
|
|
|
|
|
text_y := drop_zone.y + (drop_zone.height - f32(DROP_FONT_SIZE)) / 2
|
|
|
|
|
|
|
|
rl.DrawText(text, i32(text_x), i32(text_y), DROP_FONT_SIZE, rl.GRAY)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// open rom button below drop-zone
|
|
|
|
|
|
|
|
btn_rect := rl.Rectangle {
|
|
|
|
|
|
|
|
drop_zone.x,
|
|
|
|
|
|
|
|
drop_zone.y + drop_zone.height + PANEL_PADDING,
|
|
|
|
|
|
|
|
BUTTON_WIDTH,
|
|
|
|
|
|
|
|
BUTTON_HEIGHT,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if rl.GuiButton(btn_rect, "Open ROM") {
|
|
|
|
|
|
|
|
// @TODO: get tinyfiledialog working here
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Handle file drop
|
|
|
|
if rl.IsFileDropped() {
|
|
|
|
if rl.IsFileDropped() {
|
|
|
|
log.info("file drop found!")
|
|
|
|
|
|
|
|
dropped_file := rl.LoadDroppedFiles()
|
|
|
|
dropped_file := rl.LoadDroppedFiles()
|
|
|
|
|
|
|
|
if dropped_file.count > 0 {
|
|
|
|
|
|
|
|
mouse := rl.GetMousePosition()
|
|
|
|
|
|
|
|
|
|
|
|
if dropped_file.count > 1 {
|
|
|
|
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 {
|
|
|
|
|
|
|
|
log.info("File dropped outside drop zone, ignoring")
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
rl.UnloadDroppedFiles(dropped_file)
|
|
|
|
rl.UnloadDroppedFiles(dropped_file)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
gui_key_pad :: proc(rect: rl.Rectangle, display: [16]bool, font: rl.Font) {
|
|
|
|
gui_key_pad :: proc(rect: rl.Rectangle, display: [16]bool, font: rl.Font) {
|
|
|
|
Key :: struct { label: string, index: int}
|
|
|
|
rl.GuiPanel(rect, "Input / Keypad")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
content := rl.Rectangle {
|
|
|
|
|
|
|
|
rect.x + PANEL_PADDING,
|
|
|
|
|
|
|
|
rect.y + PANEL_HEADER + PANEL_PADDING,
|
|
|
|
|
|
|
|
rect.width - PANEL_PADDING * 2,
|
|
|
|
|
|
|
|
rect.height - PANEL_HEADER - PANEL_PADDING * 2,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Key :: struct {
|
|
|
|
|
|
|
|
label: string,
|
|
|
|
|
|
|
|
index: int,
|
|
|
|
|
|
|
|
}
|
|
|
|
keys := [16]Key {
|
|
|
|
keys := [16]Key {
|
|
|
|
{"1", 1}, {"2", 2}, {"3", 3}, {"C", 12},
|
|
|
|
{"1", 1}, {"2", 2}, {"3", 3}, {"C", 12},
|
|
|
|
{"4", 4}, {"5", 5}, {"6", 6}, {"D", 13},
|
|
|
|
{"4", 4}, {"5", 5}, {"6", 6}, {"D", 13},
|
|
|
|
{"7", 7}, {"8", 8}, {"9", 9}, {"D", 14},
|
|
|
|
{"7", 7}, {"8", 8}, {"9", 9}, {"E", 14},
|
|
|
|
{"A", 10}, {"0", 0}, {"B", 11}, {"F", 15}
|
|
|
|
{"A", 10}, {"0", 0}, {"B", 11}, {"F", 15},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
btn_width := f32(rect.width / 4)
|
|
|
|
btn_width := content.width / 4
|
|
|
|
btn_height := f32(rect.height / 4)
|
|
|
|
btn_height := content.height / 4
|
|
|
|
|
|
|
|
|
|
|
|
for val, idx in keys {
|
|
|
|
for val, idx in keys {
|
|
|
|
str := strings.clone_to_cstring(val.label)
|
|
|
|
str := strings.clone_to_cstring(val.label)
|
|
|
|
ri := int(idx / 4)
|
|
|
|
defer delete(str)
|
|
|
|
ci := idx % 4
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
irect := rl.Rectangle{
|
|
|
|
ri := idx / 4
|
|
|
|
x = btn_width * f32(ci),
|
|
|
|
ci := idx % 4
|
|
|
|
y = (btn_height * f32(ri)) + rect.y,
|
|
|
|
irect := rl.Rectangle {
|
|
|
|
width = btn_width,
|
|
|
|
x = content.x + btn_width * f32(ci),
|
|
|
|
|
|
|
|
y = content.y + btn_height * f32(ri),
|
|
|
|
|
|
|
|
width = btn_width,
|
|
|
|
height = btn_height,
|
|
|
|
height = btn_height,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(display[val.index]) { rl.DrawRectangleRec(irect, rl.DARKGRAY) }
|
|
|
|
if display[val.index] { rl.DrawRectangleRec(irect, rl.BLACK) }
|
|
|
|
rl.DrawRectangleLinesEx(irect, 1, rl.GRAY)
|
|
|
|
|
|
|
|
rl.DrawTextEx(font, str, rl.Vector2{irect.x + btn_width / 2, irect.y + btn_height / 2}, 18, 1, rl.WHITE)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Free the allocations!
|
|
|
|
rl.DrawRectangleLinesEx(irect, 1, rl.GRAY)
|
|
|
|
delete(str)
|
|
|
|
rl.DrawTextEx( font, str,
|
|
|
|
|
|
|
|
rl.Vector2{irect.x + btn_width / 2, irect.y + btn_height / 2},
|
|
|
|
|
|
|
|
KEYPAD_FONT_SIZE,
|
|
|
|
|
|
|
|
1,
|
|
|
|
|
|
|
|
rl.WHITE,
|
|
|
|
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|