diff --git a/src/gui/control_bar.odin b/src/gui/control_bar.odin new file mode 100644 index 0000000..c446d48 --- /dev/null +++ b/src/gui/control_bar.odin @@ -0,0 +1,8 @@ +package gui + +import m "../machine" +import rl "vendor:raylib" + +gui_control_bar :: proc(rect: rl.Rectangle, s: ^m.System) { + rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY) +} diff --git a/src/gui/gui.odin b/src/gui/gui.odin index efb95c4..d218641 100644 --- a/src/gui/gui.odin +++ b/src/gui/gui.odin @@ -7,6 +7,18 @@ import rl "vendor:raylib" WINDOW_WIDTH :: 1920 WINDOW_HEIGHT :: 1080 +// TODO: If this grows lets move it into its own file +SIDEBAR_PERCENT :: 0.20 +DISPLAY_PERCENT :: 0.30 +CONTROLBAR_PERCENT :: 0.05 + +Layout :: struct { + left_panel : rl.Rectangle, + right_panel : rl.Rectangle, + display : rl.Rectangle, + control_bar : rl.Rectangle, +} + // Initialize main the gui 'window' init_gui :: proc(s: ^m.System) { rl.SetConfigFlags({.WINDOW_RESIZABLE}) @@ -20,15 +32,9 @@ init_gui :: proc(s: ^m.System) { // 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, - } + layout := calc_layout(screen_width, screen_height) rl.BeginDrawing() rl.ClearBackground(rl.BLACK) @@ -42,12 +48,50 @@ init_gui :: proc(s: ^m.System) { } // -------------------------------------- - // run each gui "component" - gui_screen(display_rect, s) + gui_left_panel(layout.left_panel, s) + gui_right_panel(layout.right_panel, s) + gui_screen(layout.display, s) + gui_control_bar(layout.control_bar, s) rl.EndDrawing() } rl.CloseAudioDevice() rl.CloseWindow() -} \ No newline at end of file +} + +// TODO: If this grows lets move it into its own file +calc_layout :: proc(screen_width: f32, screen_height: f32) -> Layout { + sidebar_width := screen_width * SIDEBAR_PERCENT + display_height := screen_height * DISPLAY_PERCENT + + return Layout { + left_panel = rl.Rectangle { + x = 0, + y = 0, + width = sidebar_width, + height = screen_height + }, + + right_panel = rl.Rectangle { + x = screen_width - sidebar_width, + y = 0, + width = sidebar_width, + height = screen_height + }, + + display = rl.Rectangle { + x = sidebar_width, + y = 0, + width = screen_width - (sidebar_width * 2), + height = display_height + }, + + control_bar = rl.Rectangle { + x = sidebar_width, + y = 0, + width = screen_width - (sidebar_width * 2), + height = (screen_height * 0.05) + display_height + } + } +} diff --git a/src/gui/left_panel.odin b/src/gui/left_panel.odin new file mode 100644 index 0000000..446a31e --- /dev/null +++ b/src/gui/left_panel.odin @@ -0,0 +1,8 @@ +package gui + +import m "../machine" +import rl "vendor:raylib" + +gui_left_panel :: proc(rect: rl.Rectangle, s: ^m.System) { + rl.DrawRectangleLinesEx(rect, 1, rl.DARKGRAY) +} diff --git a/src/gui/right_panel.odin b/src/gui/right_panel.odin new file mode 100644 index 0000000..9e06099 --- /dev/null +++ b/src/gui/right_panel.odin @@ -0,0 +1,8 @@ +package gui + +import m "../machine" +import rl "vendor:raylib" + +gui_right_panel :: proc(rect: rl.Rectangle, s: ^m.System) { + rl.DrawRectangleLinesEx(rect, 1, rl.GREEN) +} diff --git a/src/gui/screen.odin b/src/gui/screen.odin index adc815c..3376dd1 100644 --- a/src/gui/screen.odin +++ b/src/gui/screen.odin @@ -3,56 +3,33 @@ package gui import m "../machine" import rl "vendor:raylib" -control_bar_height :: f32(20.0) +gui_screen :: proc(rect: rl.Rectangle, s: ^m.System) { + // Make sure screen is staying in its aspect ratio + chip8_aspect := f32(64.0 / 32.0) + available_aspect := rect.width / rect.height + screen_rect := rect -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 + if available_aspect > chip8_aspect { + // Area is too wide + screen_rect.width = rect.height * chip8_aspect + screen_rect.x = rect.x + (rect.width - screen_rect.width) / 2 + } else { + // Area is too tall + screen_rect.height = rect.width / chip8_aspect + screen_rect.y = rect.y + (rect.height - screen_rect.height) / 2 } - 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 := 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) + display_x := i32(screen_rect.x) + i32(int(screen_rect.width) - actual_width) / 2 + display_y := i32(screen_rect.y) + i32(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(rect, 1, rl.DARKGRAY) rl.DrawRectangleLinesEx(screen_rect, 2, rl.WHITE) render_display(&s.display, display_x, display_y, i32(pixel_size)) @@ -60,17 +37,12 @@ gui_screen :: proc(window_rect: rl.Rectangle, s: ^m.System) { @(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..