From fb2edd4df5ae697a287e381578a4a7ef2db907e6 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sun, 28 Sep 2025 08:28:13 +0200 Subject: [PATCH] Arreglar zoom y texturas: filtro NEAREST y guardas robustas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Añadir SDL_SetTextureScaleMode(render_texture_, SDL_SCALEMODE_NEAREST) para pixel-perfect - Implementar sistema de fallback robusto para detección de display - Restaurar funcionalidad completa de zoom con centrado y guardas - Las texturas ahora se ven pixel-perfect sin blur - El zoom respeta límites del escritorio correctamente 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- source/engine.cpp | 80 +----------------------------- source/window_manager.cpp | 101 +++++++++++++++++++++++++++++++------- source/window_manager.h | 2 +- 3 files changed, 85 insertions(+), 98 deletions(-) diff --git a/source/engine.cpp b/source/engine.cpp index 6243952..d213bec 100644 --- a/source/engine.cpp +++ b/source/engine.cpp @@ -39,7 +39,7 @@ bool Engine::initialize() { // Crear y configurar el window manager window_manager_ = std::make_unique(); - if (!window_manager_->initialize(WINDOW_CAPTION, SCREEN_WIDTH, SCREEN_HEIGHT, 1)) { + if (!window_manager_->initialize(WINDOW_CAPTION, SCREEN_WIDTH, SCREEN_HEIGHT, WINDOW_ZOOM)) { std::cout << "¡No se pudo inicializar el WindowManager!" << std::endl; return false; } @@ -605,84 +605,6 @@ void Engine::renderGradientBackground() { // Método addSpriteToBatch antiguo eliminado - ahora se usa el del nuevo sistema -// Métodos de zoom obsoletos - migrados a WindowManager -/* -int Engine::calculateMaxWindowZoom() const { - // Obtener información del display usando el método de Coffee Crisis - int num_displays = 0; - SDL_DisplayID *displays = SDL_GetDisplays(&num_displays); - if (displays == nullptr || num_displays == 0) { - return WINDOW_ZOOM_MIN; // Fallback si no se puede obtener - } - - // Obtener el modo de display actual - const auto *dm = SDL_GetCurrentDisplayMode(displays[0]); - if (dm == nullptr) { - SDL_free(displays); - return WINDOW_ZOOM_MIN; - } - - // Calcular zoom máximo usando la fórmula de Coffee Crisis - const int MAX_ZOOM = std::min(dm->w / SCREEN_WIDTH, (dm->h - WINDOW_DECORATION_HEIGHT) / SCREEN_HEIGHT); - - SDL_free(displays); - - // Aplicar límites - return std::max(WINDOW_ZOOM_MIN, std::min(MAX_ZOOM, WINDOW_ZOOM_MAX)); -} - -void Engine::setWindowZoom(int new_zoom) { - // Validar zoom - int max_zoom = calculateMaxWindowZoom(); - new_zoom = std::max(WINDOW_ZOOM_MIN, std::min(new_zoom, max_zoom)); - - if (new_zoom == current_window_zoom_) { - return; // No hay cambio - } - - // Obtener posición actual del centro de la ventana - int current_x, current_y; - SDL_GetWindowPosition(window_, ¤t_x, ¤t_y); - int current_center_x = current_x + (SCREEN_WIDTH * current_window_zoom_) / 2; - int current_center_y = current_y + (SCREEN_HEIGHT * current_window_zoom_) / 2; - - // Calcular nuevo tamaño - int new_width = SCREEN_WIDTH * new_zoom; - int new_height = SCREEN_HEIGHT * new_zoom; - - // Calcular nueva posición (centrada en el punto actual) - int new_x = current_center_x - new_width / 2; - int new_y = current_center_y - new_height / 2; - - // Obtener límites del escritorio para no salirse - SDL_Rect display_bounds; - if (SDL_GetDisplayBounds(SDL_GetPrimaryDisplay(), &display_bounds) == 0) { - // Aplicar márgenes - int min_x = WINDOW_DESKTOP_MARGIN; - int min_y = WINDOW_DESKTOP_MARGIN; - int max_x = display_bounds.w - new_width - WINDOW_DESKTOP_MARGIN; - int max_y = display_bounds.h - new_height - WINDOW_DESKTOP_MARGIN - WINDOW_DECORATION_HEIGHT; - - // Limitar posición - new_x = std::max(min_x, std::min(new_x, max_x)); - new_y = std::max(min_y, std::min(new_y, max_y)); - } - - // Aplicar cambios - SDL_SetWindowSize(window_, new_width, new_height); - SDL_SetWindowPosition(window_, new_x, new_y); - current_window_zoom_ = new_zoom; -} - -void Engine::zoomIn() { - setWindowZoom(current_window_zoom_ + 1); -} - -void Engine::zoomOut() { - setWindowZoom(current_window_zoom_ - 1); -} -*/ - void Engine::initializeThemes() { // SUNSET: Naranjas, rojos, amarillos, rosas (8 colores) themes_[0] = { diff --git a/source/window_manager.cpp b/source/window_manager.cpp index a1b01bc..129eb59 100644 --- a/source/window_manager.cpp +++ b/source/window_manager.cpp @@ -66,6 +66,10 @@ bool WindowManager::initialize(const char* title, int width, int height, int zoo std::cout << "¡No se pudo crear la textura de renderizado! Error: " << SDL_GetError() << std::endl; return false; } + + // Configurar filtro nearest neighbor para píxel perfect + SDL_SetTextureScaleMode(render_texture_, SDL_SCALEMODE_NEAREST); + std::cout << "Textura de renderizado creada: " << width << "x" << height << std::endl; } @@ -110,7 +114,7 @@ bool WindowManager::createSDLWindow(const char* title, int width, int height) { break; } - window_ = SDL_CreateWindow(title, width, height, window_flags); + window_ = SDL_CreateWindow(title, width * current_zoom_, height * current_zoom_, window_flags); if (!window_) { std::cout << "¡No se pudo crear la ventana! Error: " << SDL_GetError() << std::endl; return false; @@ -181,40 +185,101 @@ bool WindowManager::setRealFullscreen(bool enable) { return result; } -void WindowManager::setZoom(int zoom) { - if (zoom < MIN_ZOOM || zoom > MAX_ZOOM) return; +void WindowManager::setZoom(int new_zoom) { + // Validar zoom usando el cálculo dinámico del original + int max_zoom = calculateMaxZoom(); + new_zoom = std::max(MIN_ZOOM, std::min(new_zoom, max_zoom)); - current_zoom_ = zoom; - updateWindowSize(); -} + if (new_zoom == current_zoom_) { + return; // No hay cambio + } -void WindowManager::updateWindowSize() { - if (!window_ || fullscreen_enabled_ || real_fullscreen_enabled_) return; + // Obtener posición actual del centro de la ventana (lógica del original) + int current_x, current_y; + SDL_GetWindowPosition(window_, ¤t_x, ¤t_y); + int current_center_x = current_x + (logical_width_ * current_zoom_) / 2; + int current_center_y = current_y + (logical_height_ * current_zoom_) / 2; - int new_width = logical_width_ * current_zoom_; - int new_height = logical_height_ * current_zoom_; + // Calcular nuevo tamaño + int new_width = logical_width_ * new_zoom; + int new_height = logical_height_ * new_zoom; + // Calcular nueva posición (centrada en el punto actual) + int new_x = current_center_x - new_width / 2; + int new_y = current_center_y - new_height / 2; + + // Obtener límites del escritorio para no salirse (con fallback robusto) + SDL_Rect display_bounds; + bool bounds_success = false; + + // Intentar primero el display de la ventana, luego el primario + SDL_DisplayID display_id = SDL_GetDisplayForWindow(window_); + if (display_id != 0) { + bounds_success = (SDL_GetDisplayBounds(display_id, &display_bounds) == 0); + } + + if (!bounds_success) { + // Fallback al display primario como en el original + bounds_success = (SDL_GetDisplayBounds(SDL_GetPrimaryDisplay(), &display_bounds) == 0); + } + + if (!bounds_success) { + // Último fallback: valores seguros para resolución común + display_bounds.w = 1920; + display_bounds.h = 1080; + bounds_success = true; + } + + if (bounds_success) { + // Aplicar márgenes + int min_x = DESKTOP_MARGIN; + int min_y = DESKTOP_MARGIN; + int max_x = display_bounds.w - new_width - DESKTOP_MARGIN; + int max_y = display_bounds.h - new_height - DESKTOP_MARGIN - DECORATION_HEIGHT; + + // Limitar posición + new_x = std::max(min_x, std::min(new_x, max_x)); + new_y = std::max(min_y, std::min(new_y, max_y)); + } + + // Aplicar cambios SDL_SetWindowSize(window_, new_width, new_height); + SDL_SetWindowPosition(window_, new_x, new_y); + current_zoom_ = new_zoom; + // Notificar al renderer del cambio (mantener resolución lógica) if (renderer_) { renderer_->resize(logical_width_, logical_height_); } } +void WindowManager::updateWindowSize() { + // Simplificar: usar setZoom que ya maneja todo el centrado y guardas + setZoom(current_zoom_); +} + int WindowManager::calculateMaxZoom() const { - SDL_Rect display_bounds; - if (!SDL_GetDisplayBounds(SDL_GetDisplayForWindow(window_), &display_bounds)) { + // Obtener información del display usando el método del commit original + int num_displays = 0; + SDL_DisplayID *displays = SDL_GetDisplays(&num_displays); + if (displays == nullptr || num_displays == 0) { + return MIN_ZOOM; // Fallback si no se puede obtener + } + + // Obtener el modo de display actual + const auto *dm = SDL_GetCurrentDisplayMode(displays[0]); + if (dm == nullptr) { + SDL_free(displays); return MIN_ZOOM; } - int max_width = display_bounds.w - DESKTOP_MARGIN * 2; - int max_height = display_bounds.h - DESKTOP_MARGIN * 2 - DECORATION_HEIGHT; + // Calcular zoom máximo usando la fórmula de Coffee Crisis del original + const int MAX_ZOOM_CALC = std::min(dm->w / logical_width_, (dm->h - DECORATION_HEIGHT) / logical_height_); - int max_zoom_x = max_width / logical_width_; - int max_zoom_y = max_height / logical_height_; + SDL_free(displays); - int calculated_max = std::min(max_zoom_x, max_zoom_y); - return std::min(calculated_max, MAX_ZOOM); + // Aplicar límites + return std::max(MIN_ZOOM, std::min(MAX_ZOOM_CALC, MAX_ZOOM)); } void WindowManager::zoomIn() { diff --git a/source/window_manager.h b/source/window_manager.h index b6b1c17..b06e8ad 100644 --- a/source/window_manager.h +++ b/source/window_manager.h @@ -70,7 +70,7 @@ private: // Límites de zoom static constexpr int MIN_ZOOM = 1; static constexpr int MAX_ZOOM = 10; - static constexpr int DESKTOP_MARGIN = 10; + static constexpr int DESKTOP_MARGIN = 30; static constexpr int DECORATION_HEIGHT = 30; // Métodos privados