From cf572179eaf8fd9cb4b9f2b9589a1f1898d0f05c Mon Sep 17 00:00:00 2001 From: Jason Hilder Date: Tue, 2 Jun 2026 08:23:26 +0200 Subject: [PATCH] Initial gui commit. Very much WIP trying to find a good way to keep components self contained and composable. --- src/gui/gui.odin | 53 +++++++++++++++++++++++++++++++ src/gui/screen.odin | 77 +++++++++++++++++++++++++++++++++++++++++++++ src/main.odin | 13 ++++---- 3 files changed, 137 insertions(+), 6 deletions(-) create mode 100644 src/gui/gui.odin create mode 100644 src/gui/screen.odin diff --git a/src/gui/gui.odin b/src/gui/gui.odin new file mode 100644 index 0000000..efb95c4 --- /dev/null +++ b/src/gui/gui.odin @@ -0,0 +1,53 @@ +package gui + +import m "../machine" +import rl "vendor:raylib" + +// Initial window size +WINDOW_WIDTH :: 1920 +WINDOW_HEIGHT :: 1080 + +// Initialize main the gui 'window' +init_gui :: proc(s: ^m.System) { + rl.SetConfigFlags({.WINDOW_RESIZABLE}) + rl.InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "raylib") + rl.InitAudioDevice() + rl.SetTargetFPS(60) + + // Draw each of the components in its own window within the main window + for !rl.WindowShouldClose() { + // Recalculate layout each frame based on current window size + // Pass these down to gui functions so they can setup their sizes? + screen_width := f32(rl.GetScreenWidth()) + screen_height := f32(rl.GetScreenHeight()) + + sidebar_width := screen_width * 0.20 + + display_rect := rl.Rectangle{ + x = sidebar_width, + y = 0, + width = screen_width - (sidebar_width * 2), + height = screen_height * 0.30, + } + + rl.BeginDrawing() + rl.ClearBackground(rl.BLACK) + + // TODO: move this out / make better + // -------------------------------------- + // CPU cycles + for _ in 0..<12 { + m.handle_input(s) + m.cycle(s) + } + // -------------------------------------- + + // run each gui "component" + gui_screen(display_rect, s) + + rl.EndDrawing() + } + + rl.CloseAudioDevice() + rl.CloseWindow() +} \ No newline at end of file diff --git a/src/gui/screen.odin b/src/gui/screen.odin new file mode 100644 index 0000000..adc815c --- /dev/null +++ b/src/gui/screen.odin @@ -0,0 +1,77 @@ +package gui + +import m "../machine" +import rl "vendor:raylib" + +control_bar_height :: f32(20.0) + +gui_screen :: proc(window_rect: rl.Rectangle, s: ^m.System) { + control_bar_rect := rl.Rectangle{ + x = window_rect.x, + y = window_rect.y, + width = window_rect.width, + height = control_bar_height + } + + content_rect := rl.Rectangle{ + x = window_rect.x, + y = window_rect.y + control_bar_height, + width = window_rect.width, + height = window_rect.height - control_bar_height + } + + chip8_aspect := f32(64.0 / 32.0) + available_aspect := content_rect.width / content_rect.height + + screen_rect := content_rect + + if available_aspect > chip8_aspect { + // Content area is too wide + screen_rect.height = content_rect.height + screen_rect.width = content_rect.height * chip8_aspect + + screen_rect.x = content_rect.x + (content_rect.width - screen_rect.width) / 2 + screen_rect.y = content_rect.y + } else { + // Content area is too tall + screen_rect.width = content_rect.width + screen_rect.height = content_rect.width / chip8_aspect + + screen_rect.x = content_rect.x + screen_rect.y = content_rect.y + (content_rect.height - screen_rect.height) / 2 + } + + pixel_size := min(int(screen_rect.width / 64), int(screen_rect.height / 32)) + pixel_size = max(pixel_size, 1) + + actual_width := pixel_size * 64 + actual_height := pixel_size * 32 + + display_x := i32(int(screen_rect.x) + (int(screen_rect.width) - actual_width) / 2) + display_y := i32(int(screen_rect.y) + (int(screen_rect.height) - actual_height) / 2) + + // Debug borders + rl.DrawRectangleLinesEx(window_rect, 1, rl.DARKGRAY) + rl.DrawRectangleLinesEx(control_bar_rect, 1, rl.GREEN) + rl.DrawRectangleLinesEx(screen_rect, 2, rl.WHITE) + + render_display(&s.display, display_x, display_y, i32(pixel_size)) +} + +@(private = "file") +render_display :: proc(display_buffer: ^[32][64]u8, offset_x, offset_y, scale: i32) { + // Fill display area with black background + rl.DrawRectangle(offset_x, offset_y, 64 * scale, 32 * scale, rl.BLACK) + for y in 0.. 0 {