From 0139da47649bac63deeb72f629a0282d84315761 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 2 Dec 2025 17:10:53 +0100 Subject: [PATCH] corregit el escalat de finestra i mode fullscreen --- source/core/rendering/sdl_manager.cpp | 161 ++++++++++++++++++-------- source/core/rendering/sdl_manager.hpp | 8 ++ source/game/options.cpp | 22 ++-- source/game/options.hpp | 2 +- 4 files changed, 135 insertions(+), 58 deletions(-) diff --git a/source/core/rendering/sdl_manager.cpp b/source/core/rendering/sdl_manager.cpp index 61d8aa5..f9bde6c 100644 --- a/source/core/rendering/sdl_manager.cpp +++ b/source/core/rendering/sdl_manager.cpp @@ -22,7 +22,11 @@ SDLManager::SDLManager() current_height_(Defaults::Window::HEIGHT), is_fullscreen_(false), max_width_(1920), - max_height_(1080) { + max_height_(1080), + zoom_factor_(Defaults::Window::BASE_ZOOM), + windowed_width_(Defaults::Window::WIDTH), + windowed_height_(Defaults::Window::HEIGHT), + max_zoom_(1.0f) { // Inicialitzar SDL3 if (!SDL_Init(SDL_INIT_VIDEO)) { std::cerr << "Error inicialitzant SDL3: " << SDL_GetError() << std::endl; @@ -82,7 +86,11 @@ SDLManager::SDLManager(int width, int height, bool fullscreen) current_height_(height), is_fullscreen_(fullscreen), max_width_(1920), - max_height_(1080) { + max_height_(1080), + zoom_factor_(static_cast(width) / Defaults::Window::WIDTH), + windowed_width_(width), + windowed_height_(height), + max_zoom_(1.0f) { // Inicialitzar SDL3 if (!SDL_Init(SDL_INIT_VIDEO)) { std::cerr << "Error inicialitzant SDL3: " << SDL_GetError() << std::endl; @@ -173,6 +181,66 @@ void SDLManager::calculateMaxWindowSize() { std::cerr << "No s'ha pogut detectar el display, usant fallback: " << max_width_ << "x" << max_height_ << std::endl; } + + // Calculate max zoom immediately after determining max size + calculateMaxZoom(); +} + +void SDLManager::calculateMaxZoom() { + // Maximum zoom limited by BOTH width and height (preserves 4:3) + float max_zoom_width = static_cast(max_width_) / Defaults::Window::WIDTH; + float max_zoom_height = static_cast(max_height_) / Defaults::Window::HEIGHT; + + // Take smaller constraint + float max_zoom_unrounded = std::min(max_zoom_width, max_zoom_height); + + // Round DOWN to nearest 0.1 increment (user preference) + max_zoom_ = std::floor(max_zoom_unrounded / Defaults::Window::ZOOM_INCREMENT) + * Defaults::Window::ZOOM_INCREMENT; + + // Safety clamp + max_zoom_ = std::max(max_zoom_, Defaults::Window::MIN_ZOOM); + + std::cout << "Max zoom: " << max_zoom_ << "x (display: " + << max_width_ << "x" << max_height_ << ")" << std::endl; +} + +void SDLManager::applyZoom(float new_zoom) { + // Clamp to valid range + new_zoom = std::max(Defaults::Window::MIN_ZOOM, + std::min(new_zoom, max_zoom_)); + + // Round to nearest 0.1 increment + new_zoom = std::round(new_zoom / Defaults::Window::ZOOM_INCREMENT) + * Defaults::Window::ZOOM_INCREMENT; + + // No change? + if (std::abs(new_zoom - zoom_factor_) < 0.01f) { + return; + } + + zoom_factor_ = new_zoom; + + // Calculate physical dimensions (4:3 maintained automatically) + int new_width = static_cast(std::round( + Defaults::Window::WIDTH * zoom_factor_)); + int new_height = static_cast(std::round( + Defaults::Window::HEIGHT * zoom_factor_)); + + // Apply to window (centers via applyWindowSize) + applyWindowSize(new_width, new_height); + + // Update windowed size cache + windowed_width_ = new_width; + windowed_height_ = new_height; + + // Persist + Options::window.width = new_width; + Options::window.height = new_height; + Options::window.zoom_factor = zoom_factor_; + + std::cout << "Zoom: " << zoom_factor_ << "x (" + << new_width << "x" << new_height << ")" << std::endl; } void SDLManager::updateLogicalPresentation() { @@ -188,48 +256,22 @@ void SDLManager::updateLogicalPresentation() { void SDLManager::increaseWindowSize() { if (is_fullscreen_) - return; // No operar en fullscreen + return; - int new_width = current_width_ + Defaults::Window::SIZE_INCREMENT; - int new_height = current_height_ + Defaults::Window::SIZE_INCREMENT; + float new_zoom = zoom_factor_ + Defaults::Window::ZOOM_INCREMENT; + applyZoom(new_zoom); - // Clamp a màxim - new_width = std::min(new_width, max_width_); - new_height = std::min(new_height, max_height_); - - if (new_width != current_width_ || new_height != current_height_) { - applyWindowSize(new_width, new_height); - - // Persistir canvis a Options (es guardarà a config.yaml al tancar) - Options::window.width = current_width_; - Options::window.height = current_height_; - - std::cout << "F2: Finestra augmentada a " << new_width << "x" << new_height - << std::endl; - } + std::cout << "F2: Zoom aumentat a " << zoom_factor_ << "x" << std::endl; } void SDLManager::decreaseWindowSize() { if (is_fullscreen_) return; - int new_width = current_width_ - Defaults::Window::SIZE_INCREMENT; - int new_height = current_height_ - Defaults::Window::SIZE_INCREMENT; + float new_zoom = zoom_factor_ - Defaults::Window::ZOOM_INCREMENT; + applyZoom(new_zoom); - // Clamp a mínim - new_width = std::max(new_width, Defaults::Window::MIN_WIDTH); - new_height = std::max(new_height, Defaults::Window::MIN_HEIGHT); - - if (new_width != current_width_ || new_height != current_height_) { - applyWindowSize(new_width, new_height); - - // Persistir canvis a Options (es guardarà a config.yaml al tancar) - Options::window.width = current_width_; - Options::window.height = current_height_; - - std::cout << "F1: Finestra reduïda a " << new_width << "x" << new_height - << std::endl; - } + std::cout << "F1: Zoom reduït a " << zoom_factor_ << "x" << std::endl; } void SDLManager::applyWindowSize(int new_width, int new_height) { @@ -265,26 +307,49 @@ void SDLManager::applyWindowSize(int new_width, int new_height) { } void SDLManager::toggleFullscreen() { - is_fullscreen_ = !is_fullscreen_; - SDL_SetWindowFullscreen(finestra_, is_fullscreen_); + if (!is_fullscreen_) { + // ENTERING FULLSCREEN + windowed_width_ = current_width_; + windowed_height_ = current_height_; + + is_fullscreen_ = true; + SDL_SetWindowFullscreen(finestra_, true); + + std::cout << "F3: Fullscreen activat (guardada: " + << windowed_width_ << "x" << windowed_height_ << ")" << std::endl; + } else { + // EXITING FULLSCREEN + is_fullscreen_ = false; + SDL_SetWindowFullscreen(finestra_, false); + + // CRITICAL: Explicitly restore windowed size + applyWindowSize(windowed_width_, windowed_height_); + + std::cout << "F3: Fullscreen desactivat (restaurada: " + << windowed_width_ << "x" << windowed_height_ << ")" << std::endl; + } - // Persistir canvis a Options (es guardarà a config.yaml al tancar) Options::window.fullscreen = is_fullscreen_; - - std::cout << "F3: Fullscreen " << (is_fullscreen_ ? "activat" : "desactivat") - << std::endl; - - // En fullscreen, SDL gestiona tot automàticament - // En sortir, restaura la mida anterior } bool SDLManager::handleWindowEvent(const SDL_Event& event) { if (event.type == SDL_EVENT_WINDOW_RESIZED) { - // Usuari ha redimensionat manualment (arrossegar vora) - // Actualitzar el nostre tracking SDL_GetWindowSize(finestra_, ¤t_width_, ¤t_height_); - std::cout << "Finestra redimensionada manualment a " << current_width_ - << "x" << current_height_ << std::endl; + + // Calculate zoom from actual size (may not align to 0.1 increments) + float new_zoom = static_cast(current_width_) / Defaults::Window::WIDTH; + zoom_factor_ = std::max(Defaults::Window::MIN_ZOOM, + std::min(new_zoom, max_zoom_)); + + // Update windowed cache (if not in fullscreen) + if (!is_fullscreen_) { + windowed_width_ = current_width_; + windowed_height_ = current_height_; + } + + std::cout << "Finestra redimensionada: " << current_width_ + << "x" << current_height_ << " (zoom ≈" << zoom_factor_ << "x)" + << std::endl; return true; } return false; diff --git a/source/core/rendering/sdl_manager.hpp b/source/core/rendering/sdl_manager.hpp index 14c4128..7068af3 100644 --- a/source/core/rendering/sdl_manager.hpp +++ b/source/core/rendering/sdl_manager.hpp @@ -62,8 +62,16 @@ class SDLManager { int max_width_; // Calculat des del display int max_height_; + // [ZOOM SYSTEM] + float zoom_factor_; // Current zoom (0.5x to max_zoom_) + int windowed_width_; // Saved size before fullscreen + int windowed_height_; // Saved size before fullscreen + float max_zoom_; // Maximum zoom (calculated from display) + // [NUEVO] Funcions internes void calculateMaxWindowSize(); // Llegir resolució del display + void calculateMaxZoom(); // Calculate max zoom from display + void applyZoom(float new_zoom); // Apply zoom and resize window void applyWindowSize(int width, int height); // Canviar mida + centrar void updateLogicalPresentation(); // Actualitzar viewport diff --git a/source/game/options.cpp b/source/game/options.cpp index 5021c0f..5f4e285 100644 --- a/source/game/options.cpp +++ b/source/game/options.cpp @@ -22,7 +22,7 @@ void init() { window.width = Defaults::Window::WIDTH; window.height = Defaults::Window::HEIGHT; window.fullscreen = false; - window.size_increment = Defaults::Window::SIZE_INCREMENT; + window.zoom_factor = Defaults::Window::BASE_ZOOM; // Physics physics.rotation_speed = Defaults::Physics::ROTATION_SPEED; @@ -90,14 +90,18 @@ static void loadWindowConfigFromYaml(const fkyaml::node& yaml) { } } - if (win.contains("size_increment")) { + if (win.contains("zoom_factor")) { try { - auto val = win["size_increment"].get_value(); - window.size_increment = - (val > 0) ? val : Defaults::Window::SIZE_INCREMENT; + auto val = win["zoom_factor"].get_value(); + window.zoom_factor = (val >= Defaults::Window::MIN_ZOOM && val <= 10.0f) + ? val : Defaults::Window::BASE_ZOOM; } catch (...) { - window.size_increment = Defaults::Window::SIZE_INCREMENT; + window.zoom_factor = Defaults::Window::BASE_ZOOM; } + } else { + // Legacy config: infer zoom from width + window.zoom_factor = static_cast(window.width) / Defaults::Window::WIDTH; + window.zoom_factor = std::max(Defaults::Window::MIN_ZOOM, window.zoom_factor); } } } @@ -360,10 +364,10 @@ auto saveToFile() -> bool { file << "# FINESTRA\n"; file << "window:\n"; - file << " width: " << window.width << "\n"; - file << " height: " << window.height << "\n"; + file << " width: " << window.width << " # Calculated from zoom_factor\n"; + file << " height: " << window.height << " # Calculated from zoom_factor\n"; file << " fullscreen: " << (window.fullscreen ? "true" : "false") << "\n"; - file << " size_increment: " << window.size_increment << "\n\n"; + file << " zoom_factor: " << window.zoom_factor << " # 0.5x-max (0.1 increments)\n\n"; file << "# FÍSICA (tots els valors en px/s, rad/s, etc.)\n"; file << "physics:\n"; diff --git a/source/game/options.hpp b/source/game/options.hpp index 74d7048..2b38280 100644 --- a/source/game/options.hpp +++ b/source/game/options.hpp @@ -10,7 +10,7 @@ struct Window { int width{640}; int height{480}; bool fullscreen{false}; - int size_increment{100}; // Increment per F1/F2 + float zoom_factor{1.0f}; // Zoom level (0.5x to max_zoom) }; struct Physics {