Arreglar zoom y texturas: filtro NEAREST y guardas robustas

- 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 <noreply@anthropic.com>
This commit is contained in:
2025-09-28 08:28:13 +02:00
parent dab71d41b6
commit fb2edd4df5
3 changed files with 85 additions and 98 deletions

View File

@@ -39,7 +39,7 @@ bool Engine::initialize() {
// Crear y configurar el window manager
window_manager_ = std::make_unique<vibe4::WindowManager>();
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_, &current_x, &current_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] = {

View File

@@ -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_, &current_x, &current_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() {

View File

@@ -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