package game import rl "vendor:raylib" VIEWPORT_W :: 1280 VIEWPORT_H :: 720 WINDOW_W :: 2560 WINDOW_H :: 1440 WINDOW_TITLE :: "Pong" Game :: struct { viewport: rl.RenderTexture2D, scene: Scene, overlay_scene: Maybe(Scene), should_close: bool, } // ------------------------------------------------------------------------------ // Game Lifecycle // ------------------------------------------------------------------------------ game_init :: proc(game: ^Game) { rl.InitWindow(WINDOW_W, WINDOW_H, WINDOW_TITLE) rl.SetTargetFPS(60) // allocate some event capacity to stop early dynamic reallocations GLOBAL_EVENTS = make([dynamic]Event, 0, 16) game.viewport = rl.LoadRenderTexture(VIEWPORT_W, VIEWPORT_H) game.scene = make_main_menu() game.overlay_scene = nil game.should_close = false } game_update :: proc(game: ^Game) { dt := rl.GetFrameTime() input := poll_input() // Pass direct pointers (^Scene) so modifications persist if overlay, ok := &game.overlay_scene.?; ok { scene_update(overlay, game, input, dt) } else { scene_update(&game.scene, game, input, dt) } // flush any events triggered in this loop flush_events() } game_render :: proc(game: ^Game) { rl.BeginDrawing() rl.ClearBackground(rl.BLACK) rl.BeginTextureMode(game.viewport) rl.ClearBackground(rl.BLACK) // Render base scene scene_render(&game.scene) // Render active overlay on top if present if overlay, ok := &game.overlay_scene.?; ok { scene_render(overlay) } rl.EndTextureMode() render_game_to_window(game.viewport.texture) rl.EndDrawing() } game_quit :: proc(game: ^Game) { delete(GLOBAL_EVENTS) rl.UnloadRenderTexture(game.viewport) rl.CloseWindow() } game_should_run :: proc(game: Game) -> bool { return !game.should_close && !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, ) }