diff --git a/src/game.odin b/src/game.odin index 70f51d4..dfe72d4 100644 --- a/src/game.odin +++ b/src/game.odin @@ -4,22 +4,46 @@ import rl "vendor:raylib" VIEWPORT_W :: 1280 VIEWPORT_H :: 720 -WINDOW_W :: 2560 -WINDOW_H :: 1440 WINDOW_TITLE :: "Pong" +Resolution :: struct { + width: i32, + height: i32, + label: cstring, +} + +// Preset window dimensions +RESOLUTIONS := [?]Resolution{ + {1280, 720, "1280x720"}, + {1920, 1080, "1920x1080"}, + {2560, 1440, "2560x1440"}, + {3840, 2160, "3840x2160"}, +} + Game :: struct { viewport: rl.RenderTexture2D, scene_stack: [dynamic]Scene, should_close: bool, audio: Audio_Manager, + + // resolution state + window_w: i32, + window_h: i32, + res_index: int } // ------------------------------------------------------------------------------ // Game Lifecycle // ------------------------------------------------------------------------------ game_init :: proc(game: ^Game) { - rl.InitWindow(WINDOW_W, WINDOW_H, WINDOW_TITLE) + //rl.SetConfigFlags({.WINDOW_RESIZABLE, .MSAA_4X_HINT}) + rl.SetConfigFlags({.MSAA_4X_HINT}) + + game.res_index = 2 + game.window_w = RESOLUTIONS[game.res_index].width + game.window_h = RESOLUTIONS[game.res_index].height + + rl.InitWindow(game.window_w, game.window_h, WINDOW_TITLE) rl.SetTargetFPS(60) // init any global managers @@ -62,19 +86,16 @@ game_render :: proc(game: ^Game) { for i in 0 ..< len(game.scene_stack) { scene_render(&game.scene_stack[i]) } + rl.EndTextureMode() - render_game_to_window(game.viewport.texture) + render_game_to_window(game) rl.EndDrawing() } game_quit :: proc(game: ^Game) { - delete(GLOBAL_EVENTS) - rl.UnloadRenderTexture(game.viewport) - - // cleanup global managers audio_manager_quit(&game.audio) rl.UnloadRenderTexture(game.viewport) @@ -91,13 +112,32 @@ game_should_run :: proc(game: Game) -> bool { // ------------------------------------------------------------------------------ // Window Upscale Render // ------------------------------------------------------------------------------ -render_game_to_window :: proc(texture: rl.Texture) { +game_set_resolution :: proc(game: ^Game, res_index: int) { + game.res_index = clamp(res_index, 0, len(RESOLUTIONS) - 1) + + target_w := RESOLUTIONS[game.res_index].width + target_h := RESOLUTIONS[game.res_index].height + + monitor := rl.GetCurrentMonitor() + screen_w := rl.GetMonitorWidth(monitor) + screen_h := rl.GetMonitorHeight(monitor) + + // Clamp window size so it doesn't exceed physical screen limits + game.window_w = min(target_w, screen_w) + game.window_h = min(target_h, screen_h) + + rl.SetWindowSize(game.window_w, game.window_h) +} + +render_game_to_window :: proc(game: ^Game) { + texture := game.viewport.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.Rectangle{0, 0, f32(game.window_w), f32(game.window_h)}, rl.Vector2{}, 0, rl.WHITE,