Removed unneeded components, renamed reused.
Updated the components to start with a gui_ prefix, changed the layout idea that each component is responsible for their own bounding box and inner content.
This commit is contained in:
@@ -3,15 +3,16 @@ package simulator
|
||||
import "core:log"
|
||||
import rl "vendor:raylib"
|
||||
|
||||
PADDING :: 10
|
||||
|
||||
gui_control_bar :: proc(rect: rl.Rectangle, sim: ^Simulator) {
|
||||
rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY)
|
||||
|
||||
// Cursor moves for every btn call places them left to right with padding
|
||||
cursor : f32 = rect.x + PANEL_PADDING
|
||||
rl.DrawTextEx(sim.font, "Octal Cookie Chip 8 Sim ", {rect.x + PADDING_X, rect.y + 12}, 25, 1, rl.WHITE)
|
||||
text_size := rl.MeasureTextEx(sim.font, "Octal Cookie Chip 8 Sim ", 25, 1)
|
||||
|
||||
if btn(&cursor, rect, BUTTON_HEIGHT, BUTTON_WIDTH, PANEL_PADDING, "RUN") {
|
||||
// Cursor moves for every btn call places them left to right with padding
|
||||
cursor : f32 = text_size.x + 5 + rect.x + PADDING_X
|
||||
|
||||
if btn(&cursor, rect, BUTTON_HEIGHT, BUTTON_WIDTH, PADDING_X, "RUN") {
|
||||
if sim.rom_loaded {
|
||||
sim.paused = false
|
||||
sim.running = true
|
||||
@@ -20,14 +21,18 @@ gui_control_bar :: proc(rect: rl.Rectangle, sim: ^Simulator) {
|
||||
}
|
||||
}
|
||||
|
||||
if btn(&cursor, rect, BUTTON_HEIGHT, BUTTON_WIDTH, PANEL_PADDING, "PAUSE") {
|
||||
if btn(&cursor, rect, BUTTON_HEIGHT, BUTTON_WIDTH, PADDING_X, "PAUSE") {
|
||||
sim.paused = true
|
||||
sim.running = false
|
||||
}
|
||||
|
||||
if btn(&cursor, rect, BUTTON_HEIGHT, BUTTON_WIDTH, PADDING_X, "RESET") {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
btn :: proc(cursor: ^f32, rect: rl.Rectangle, h, w, gap: f32, label: cstring) -> bool {
|
||||
r := rl.Rectangle{cursor^, rect.y + PADDING, w, h}
|
||||
r := rl.Rectangle{cursor^, rect.y + PADDING_X, w, h}
|
||||
cursor^ += w + gap
|
||||
return rl.GuiButton(r, label)
|
||||
}
|
||||
@@ -3,6 +3,14 @@ package simulator
|
||||
import rl "vendor:raylib"
|
||||
|
||||
gui_screen :: proc(rect: rl.Rectangle, sim: ^Simulator) {
|
||||
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, nil)
|
||||
|
||||
s := sim.machine
|
||||
|
||||
// 2 : 1
|
||||
@@ -12,14 +20,14 @@ gui_screen :: proc(rect: rl.Rectangle, sim: ^Simulator) {
|
||||
|
||||
// create viewport for the ratio
|
||||
view := rect
|
||||
avail_space := rect.width / rect.height
|
||||
avail_space := bounds.width / bounds.height
|
||||
|
||||
if avail_space > aspect_ratio {
|
||||
view.width = rect.height * aspect_ratio
|
||||
view.x = rect.x + (rect.width - view.width) * 0.5
|
||||
view.width = bounds.height * aspect_ratio
|
||||
view.x = bounds.x + (bounds.width - view.width) * 0.5
|
||||
} else {
|
||||
view.height = rect.width / aspect_ratio
|
||||
view.y = rect.y + (rect.height - view.height) * 0.5
|
||||
view.height = bounds.width / aspect_ratio
|
||||
view.y = bounds.y + (bounds.height - view.height) * 0.5
|
||||
}
|
||||
|
||||
// get scale
|
||||
@@ -32,9 +40,7 @@ gui_screen :: proc(rect: rl.Rectangle, sim: ^Simulator) {
|
||||
// center frame
|
||||
x := i32(view.x + (view.width - f32(draw_w)) * 0.5)
|
||||
y := i32(view.y + (view.height - f32(draw_h)) * 0.5)
|
||||
|
||||
rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY)
|
||||
rl.DrawRectangleLinesEx(view, 2, rl.WHITE)
|
||||
|
||||
if !sim.rom_loaded {
|
||||
// centered drop-zone text
|
||||
@@ -3,12 +3,14 @@ package simulator
|
||||
import "core:fmt"
|
||||
import rl "vendor:raylib"
|
||||
|
||||
StatusIconShape :: enum { CIRCLE, SQUARE }
|
||||
|
||||
// @TODO: render status bar text
|
||||
gui_status_bar :: proc(rect: rl.Rectangle, sim: ^Simulator) {
|
||||
// Left to right text draws
|
||||
rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY)
|
||||
|
||||
cursor: f32 = rect.x + PADDING
|
||||
cursor: f32 = rect.x + PADDING_X
|
||||
cy := rect.y + rect.height * 0.5
|
||||
|
||||
if sim.running && !sim.paused {
|
||||
@@ -23,7 +25,7 @@ gui_status_bar :: proc(rect: rl.Rectangle, sim: ^Simulator) {
|
||||
// FPS set far right
|
||||
fps_text := fmt.ctprintf("FPS: %d", rl.GetFPS())
|
||||
fps_width := rl.MeasureTextEx(sim.font, fps_text, f32(sim.font.baseSize), 1).x
|
||||
fps_x := rect.x + rect.width - PADDING - fps_width
|
||||
fps_x := rect.x + rect.width - PADDING_X - fps_width
|
||||
|
||||
rl.DrawTextEx(
|
||||
sim.font,
|
||||
@@ -35,8 +37,6 @@ gui_status_bar :: proc(rect: rl.Rectangle, sim: ^Simulator) {
|
||||
)
|
||||
}
|
||||
|
||||
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
|
||||
@@ -48,15 +48,15 @@ status_icon :: proc(cursor: ^f32, cy: f32, color: rl.Color, shape: StatusIconSha
|
||||
|
||||
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
|
||||
cursor^ += rl.MeasureTextEx(font, label, f32(font.baseSize), 1).x + PADDING_X
|
||||
}
|
||||
|
||||
status_divider :: proc(cursor: ^f32, cy: f32) {
|
||||
rl.DrawLineV({cursor^, cy - 8}, {cursor^, cy + 8}, rl.DARKGRAY)
|
||||
cursor^ += PADDING
|
||||
cursor^ += PADDING_X
|
||||
}
|
||||
|
||||
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
|
||||
cursor^ += rl.MeasureTextEx(font, text, f32(font.baseSize), 1).x + PADDING_X
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
package simulator
|
||||
|
||||
import "core:log"
|
||||
import "core:strings"
|
||||
import rl "vendor:raylib"
|
||||
|
||||
import emu "../machine"
|
||||
import tfd "../../external/tinyfiledialogs"
|
||||
|
||||
gui_left_panel :: proc(rect: rl.Rectangle, sim: ^Simulator) {
|
||||
// ── Top panel and components ──
|
||||
top_panel := rl.Rectangle {
|
||||
rect.x,
|
||||
rect.y,
|
||||
rect.width,
|
||||
rect.height / 2,
|
||||
}
|
||||
rl.DrawRectangleLinesEx(top_panel, 1, rl.DARKGRAY)
|
||||
|
||||
// Dropzone/file loader
|
||||
file_loader_rect := rl.Rectangle {
|
||||
top_panel.x,
|
||||
top_panel.y,
|
||||
top_panel.width,
|
||||
(top_panel.height / 3) - PANEL_HEADER - PANEL_PADDING * 2,
|
||||
}
|
||||
gui_file_loader(file_loader_rect, sim)
|
||||
|
||||
// ── Bottom panel and components ──
|
||||
bottom_panel := rl.Rectangle {
|
||||
rect.x,
|
||||
rect.y + top_panel.height,
|
||||
rect.width,
|
||||
rect.height / 2,
|
||||
}
|
||||
rl.DrawRectangleLinesEx(bottom_panel, 1, rl.GREEN)
|
||||
gui_key_pad(bottom_panel, sim.machine.keypad, sim.font)
|
||||
}
|
||||
|
||||
gui_file_loader :: proc(rect: rl.Rectangle, sim: ^Simulator) {
|
||||
rl.GuiPanel(rect, "Rom / File")
|
||||
|
||||
// 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, BIG_FONT_SIZE)
|
||||
text_x := drop_zone.x + (drop_zone.width - f32(text_width)) / 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)
|
||||
|
||||
// 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") {
|
||||
ret := tfd.openFileDialog("Open File Dialog", nil, 0, nil, nil, 0,)
|
||||
rom_path := string(ret)
|
||||
if rom_path == "" do return
|
||||
|
||||
// reset machine state
|
||||
emu.reset_machine(sim.machine)
|
||||
|
||||
// load new rom
|
||||
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.running = true
|
||||
sim.paused = false
|
||||
}
|
||||
|
||||
// Handle file drop
|
||||
if rl.IsFileDropped() {
|
||||
dropped_file := rl.LoadDroppedFiles()
|
||||
if dropped_file.count > 0 {
|
||||
mouse := rl.GetMousePosition()
|
||||
|
||||
if rl.CheckCollisionPointRec(mouse, drop_zone) {
|
||||
path_str := string(dropped_file.paths[0])
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
gui_key_pad :: proc(rect: rl.Rectangle, display: [16]bool, font: rl.Font) {
|
||||
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 {
|
||||
{"1", 1}, {"2", 2}, {"3", 3}, {"C", 12},
|
||||
{"4", 4}, {"5", 5}, {"6", 6}, {"D", 13},
|
||||
{"7", 7}, {"8", 8}, {"9", 9}, {"E", 14},
|
||||
{"A", 10}, {"0", 0}, {"B", 11}, {"F", 15},
|
||||
}
|
||||
|
||||
btn_width := content.width / 4
|
||||
btn_height := content.height / 4
|
||||
|
||||
for val, idx in keys {
|
||||
str := strings.clone_to_cstring(val.label)
|
||||
defer delete(str)
|
||||
|
||||
ri := idx / 4
|
||||
ci := idx % 4
|
||||
irect := rl.Rectangle {
|
||||
x = content.x + btn_width * f32(ci),
|
||||
y = content.y + btn_height * f32(ri),
|
||||
width = btn_width,
|
||||
height = btn_height,
|
||||
}
|
||||
|
||||
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},
|
||||
KEYPAD_FONT_SIZE,
|
||||
1,
|
||||
rl.WHITE,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package simulator
|
||||
|
||||
import m "../machine"
|
||||
import rl "vendor:raylib"
|
||||
|
||||
gui_right_panel :: proc(rect: rl.Rectangle, s: ^m.System) {
|
||||
rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY)
|
||||
}
|
||||
Reference in New Issue
Block a user