Small refactor as well as an overlay scene

This commit is contained in:
2026-09-11 07:50:30 +02:00
parent 07ac240e1c
commit 9b1c07fc53
+38 -31
View File
@@ -2,7 +2,6 @@ package game
import rl "vendor:raylib"
// 16:9 internal res, window scales up to 1080/4k etc
VIEWPORT_W :: 1280
VIEWPORT_H :: 720
WINDOW_W :: 2560
@@ -10,66 +9,74 @@ WINDOW_H :: 1440
WINDOW_TITLE :: "Pong"
Game :: struct {
viewport: rl.RenderTexture2D,
scene: Scene,
paused: bool,
viewport: rl.RenderTexture2D,
// base scene (gameplay, mainmenu)
scene: Scene,
// active overlay (pause, settings, or nil)
overlay_scene: Maybe(Overlay_Scene),
}
// ------------------------------------------------------------------------------
// Game initializes and sets up any needed state
// - Then we load in the initial scene
// Game Lifecycle
// ------------------------------------------------------------------------------
game_init :: proc(game: ^Game) {
// Window configs
rl.InitWindow(WINDOW_W, WINDOW_H, WINDOW_TITLE)
rl.SetTargetFPS(60)
// initial state
game.viewport = rl.LoadRenderTexture(VIEWPORT_W, VIEWPORT_H)
game.paused = false
// initial scene (should be menu when setup)
game.scene = init_gameplay_scene()
}
// ------------------------------------------------------------------------------
// Game loop update phase
// - TODO: get inputs pressed and store them
// - apply any updates to the current scene
// ------------------------------------------------------------------------------
game_update :: proc(game: ^Game) {
dt := rl.GetFrameTime()
input := poll_input()
// Update the current scene
scene_update(game, input, dt)
// update the overlay if active, otherwise update base scene
if game.overlay_scene != nil {
overlay_update(game, input, dt)
} else {
scene_update(game, input, dt)
}
}
// ------------------------------------------------------------------------------
// Game loop integration phase
// - after the states and scene has been updated render whats active
// ------------------------------------------------------------------------------
game_render :: proc(game: ^Game) {
rl.BeginDrawing()
rl.ClearBackground(rl.BLACK)
// render the current scene
scene_render(game)
// offscreen pass render everything into virtual 1280x720 target
rl.BeginTextureMode(game.viewport)
rl.ClearBackground(rl.BLACK)
scene_render(game) // Renders base scene (Level field or Main Menu)
overlay_render(game) // Renders active overlay on top if present
rl.EndTextureMode()
// upscale pass stretch virtual buffer onto physical window display
render_game_to_window(game.viewport.texture)
rl.EndDrawing()
}
// ------------------------------------------------------------------------------
// Game shutdown
// - before closing windows etc we cleanup free anything that was allocated
// ------------------------------------------------------------------------------
game_quit :: proc(game: ^Game) {
// TODO: any cleanup goes here before
// shutting down the window
rl.UnloadRenderTexture(game.viewport)
rl.CloseWindow()
}
game_should_run :: proc() -> bool {
return !rl.WindowShouldClose()
}
// ------------------------------------------------------------------------------
// Window Upscale Render
// ------------------------------------------------------------------------------
render_game_to_window :: proc(texture: rl.Texture) {
rl.DrawTexturePro(
texture,
// src: inverted y coordinate flips opengl texture buffer correctly
rl.Rectangle{0, 0, f32(texture.width), -f32(texture.height)},
// dst: scales viewport canvas to fill window resolution
rl.Rectangle{0, 0, f32(WINDOW_W), f32(WINDOW_H)},
rl.Vector2{},
0,
rl.WHITE,
)
}