Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cf572179ea | |||
| 37da094469 |
@@ -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()
|
||||
}
|
||||
@@ -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..<len(display_buffer) {
|
||||
for x in 0..<len(display_buffer[0]) {
|
||||
if display_buffer[y][x] == 0x01 {
|
||||
rl.DrawRectangle(
|
||||
i32(x) * scale + offset_x,
|
||||
i32(y) * scale + offset_y,
|
||||
scale, scale,
|
||||
rl.WHITE,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import rl "vendor:raylib"
|
||||
|
||||
// Handle the "display" and all of its required functions
|
||||
// raylib window, rendering, scale constants
|
||||
|
||||
SCALE :: 20
|
||||
SCREEN_WITDH :: 64 * SCALE
|
||||
SCREEN_HEIGHT :: 32 * SCALE
|
||||
@@ -12,10 +11,13 @@ CYCLES_PER_FRAME :: 12
|
||||
|
||||
// Display will handle all the screen drawing with raylib etc
|
||||
run_system :: proc(s: ^System) {
|
||||
rl.InitWindow(SCREEN_WITDH, SCREEN_HEIGHT, "chip8")
|
||||
rl.InitWindow(SCREEN_WITDH, SCREEN_HEIGHT, "raylib")
|
||||
rl.InitAudioDevice()
|
||||
|
||||
rl.SetTargetFPS(60)
|
||||
|
||||
beep := rl.LoadSound("./beep.wav")
|
||||
|
||||
for !rl.WindowShouldClose() {
|
||||
rl.BeginDrawing()
|
||||
rl.ClearBackground(rl.BLACK)
|
||||
@@ -26,14 +28,26 @@ run_system :: proc(s: ^System) {
|
||||
handle_input(s)
|
||||
cycle(s)
|
||||
}
|
||||
if s.delay_timer > 0 { s.delay_timer -= 1 }
|
||||
if s.sound_timer > 0 { s.sound_timer -= 1 }
|
||||
|
||||
// Handle delay timer
|
||||
if s.delay_timer > 0 do s.delay_timer -= 1
|
||||
|
||||
// Current sound file is around 1s so stop
|
||||
// immediately when timer is 0
|
||||
if s.sound_timer > 0 {
|
||||
s.sound_timer -= 1
|
||||
if !rl.IsSoundPlaying(beep) do rl.PlaySound(beep)
|
||||
} else {
|
||||
rl.StopSound(beep)
|
||||
}
|
||||
|
||||
render_display_buffer(&s.display)
|
||||
|
||||
rl.EndDrawing()
|
||||
}
|
||||
|
||||
rl.UnloadSound(beep)
|
||||
rl.CloseAudioDevice()
|
||||
rl.CloseWindow()
|
||||
}
|
||||
|
||||
|
||||
+7
-6
@@ -4,6 +4,7 @@ import "core:log"
|
||||
import "core:mem"
|
||||
|
||||
import chip "machine"
|
||||
import gui "gui"
|
||||
|
||||
DEV :: #config(DEV, false)
|
||||
|
||||
@@ -22,17 +23,17 @@ main :: proc() {
|
||||
// Init the Chip 8 "cpu"
|
||||
system := chip.init()
|
||||
|
||||
// TODO: move this into a gui component
|
||||
// load rom, hardcoded for now, will eventually be cli or gui
|
||||
// err := chip.load_rom(&system, "./test_roms/2-ibm-logo.ch8")
|
||||
// err := chip.load_rom(&system, "./test_roms/1-chip8-logo.ch8")
|
||||
// err := chip.load_rom(&system, "./test_roms/4-flags.ch8")
|
||||
err := chip.load_rom(&system, "./test_roms/6-keypad.ch8")
|
||||
err := chip.load_rom(&system, "./test_roms/7-beep.ch8")
|
||||
if err != nil {
|
||||
panic("failed to load rom!")
|
||||
}
|
||||
|
||||
// start the cycle
|
||||
chip.run_system(&system)
|
||||
// gui will init the layout etc, it will require reference to
|
||||
// the system as it will use its display buffer etc
|
||||
// NOTE: may just need a few fields rather than whole struct check later
|
||||
gui.init_gui(&system)
|
||||
|
||||
when DEV {
|
||||
if len(track.allocation_map) > 0 {
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user