Modernizar convenciones de código C++ aplicando las siguientes directivas:
## Cambios principales
**1. Renombrar headers (.h → .hpp)**
- 36 archivos renombrados a extensión .hpp (estándar C++)
- Mantenidos como .h: stb_image.h, stb_image_resize2.h (librerías C externas)
**2. Modernizar include guards (#ifndef → #pragma once)**
- resource_manager.hpp: #ifndef RESOURCE_MANAGER_H → #pragma once
- resource_pack.hpp: #ifndef RESOURCE_PACK_H → #pragma once
- spatial_grid.hpp: #ifndef SPATIAL_GRID_H → #pragma once
**3. Sistema de includes desde raíz del proyecto**
- CMakeLists.txt: añadido include_directories(${CMAKE_SOURCE_DIR}/source)
- Eliminadas rutas relativas (../) en todos los includes
- Includes ahora usan rutas absolutas desde source/
**Antes:**
```cpp
#include "../defines.h"
#include "../text/textrenderer.h"
```
**Ahora:**
```cpp
#include "defines.hpp"
#include "text/textrenderer.hpp"
```
## Archivos afectados
- 1 archivo CMakeLists.txt modificado
- 36 archivos renombrados (.h → .hpp)
- 32 archivos .cpp actualizados (includes)
- 36 archivos .hpp actualizados (includes + guards)
- 1 archivo tools/ actualizado
**Total: 70 archivos modificados**
## Verificación
✅ Proyecto compila sin errores
✅ Todas las rutas de includes correctas
✅ Include guards modernizados
✅ Librerías externas C mantienen extensión .h
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
158 lines
5.9 KiB
C++
158 lines
5.9 KiB
C++
#define STB_IMAGE_RESIZE_IMPLEMENTATION
|
|
#include "logo_scaler.hpp"
|
|
|
|
#include <SDL3/SDL_error.h> // Para SDL_GetError
|
|
#include <SDL3/SDL_log.h> // Para SDL_Log
|
|
#include <SDL3/SDL_pixels.h> // Para SDL_PixelFormat
|
|
#include <SDL3/SDL_render.h> // Para SDL_CreateTexture
|
|
#include <SDL3/SDL_surface.h> // Para SDL_CreateSurfaceFrom
|
|
#include <SDL3/SDL_video.h> // Para SDL_GetDisplays
|
|
|
|
#include <cstdlib> // Para free()
|
|
#include <iostream> // Para std::cout
|
|
|
|
#include "external/stb_image.h" // Para stbi_load, stbi_image_free
|
|
#include "external/stb_image_resize2.h" // Para stbir_resize_uint8_srgb
|
|
#include "resource_manager.hpp" // Para cargar desde pack
|
|
|
|
// ============================================================================
|
|
// Detectar resolución nativa del monitor principal
|
|
// ============================================================================
|
|
|
|
bool LogoScaler::detectNativeResolution(int& native_width, int& native_height) {
|
|
int num_displays = 0;
|
|
SDL_DisplayID* displays = SDL_GetDisplays(&num_displays);
|
|
|
|
if (displays == nullptr || num_displays == 0) {
|
|
SDL_Log("Error al obtener displays: %s", SDL_GetError());
|
|
return false;
|
|
}
|
|
|
|
// Obtener resolución del display principal (displays[0])
|
|
const auto* dm = SDL_GetCurrentDisplayMode(displays[0]);
|
|
if (dm == nullptr) {
|
|
SDL_Log("Error al obtener modo del display: %s", SDL_GetError());
|
|
SDL_free(displays);
|
|
return false;
|
|
}
|
|
|
|
native_width = dm->w;
|
|
native_height = dm->h;
|
|
|
|
SDL_free(displays);
|
|
|
|
std::cout << "Resolución nativa detectada: " << native_width << "x" << native_height << std::endl;
|
|
return true;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Cargar PNG y escalar al tamaño especificado
|
|
// ============================================================================
|
|
|
|
unsigned char* LogoScaler::loadAndScale(const std::string& path,
|
|
int target_width, int target_height,
|
|
int& out_width, int& out_height) {
|
|
// 1. Intentar cargar imagen desde ResourceManager (pack o disco)
|
|
int orig_width, orig_height, orig_channels;
|
|
unsigned char* orig_data = nullptr;
|
|
|
|
// 1a. Cargar desde ResourceManager
|
|
unsigned char* resourceData = nullptr;
|
|
size_t resourceSize = 0;
|
|
|
|
if (ResourceManager::loadResource(path, resourceData, resourceSize)) {
|
|
// Descodificar imagen desde memoria usando stb_image
|
|
orig_data = stbi_load_from_memory(resourceData, static_cast<int>(resourceSize),
|
|
&orig_width, &orig_height, &orig_channels, STBI_rgb_alpha);
|
|
delete[] resourceData; // Liberar buffer temporal
|
|
}
|
|
|
|
// 1b. Si falla todo, error
|
|
if (orig_data == nullptr) {
|
|
SDL_Log("Error al cargar imagen %s: %s", path.c_str(), stbi_failure_reason());
|
|
return nullptr;
|
|
}
|
|
|
|
std::cout << "Imagen cargada: " << path << " (" << orig_width << "x" << orig_height << ")" << std::endl;
|
|
|
|
// 2. Calcular tamaño final manteniendo aspect ratio
|
|
// El alto está fijado por target_height (APPLOGO_HEIGHT_PERCENT)
|
|
// Calcular ancho proporcional al aspect ratio original
|
|
float aspect_ratio = static_cast<float>(orig_width) / static_cast<float>(orig_height);
|
|
out_width = static_cast<int>(target_height * aspect_ratio);
|
|
out_height = target_height;
|
|
|
|
std::cout << " Escalando a: " << out_width << "x" << out_height << std::endl;
|
|
|
|
// 3. Alocar buffer para imagen escalada (RGBA = 4 bytes por píxel)
|
|
unsigned char* scaled_data = static_cast<unsigned char*>(malloc(out_width * out_height * 4));
|
|
if (scaled_data == nullptr) {
|
|
SDL_Log("Error al alocar memoria para imagen escalada");
|
|
stbi_image_free(orig_data);
|
|
return nullptr;
|
|
}
|
|
|
|
// 4. Escalar con stb_image_resize2 (algoritmo Mitchell, espacio sRGB)
|
|
// La función devuelve el puntero de salida, o nullptr si falla
|
|
unsigned char* result = stbir_resize_uint8_srgb(
|
|
orig_data, orig_width, orig_height, 0, // Input
|
|
scaled_data, out_width, out_height, 0, // Output
|
|
STBIR_RGBA // Formato píxel
|
|
);
|
|
|
|
// Liberar imagen original (ya no la necesitamos)
|
|
stbi_image_free(orig_data);
|
|
|
|
if (result == nullptr) {
|
|
SDL_Log("Error al escalar imagen");
|
|
free(scaled_data);
|
|
return nullptr;
|
|
}
|
|
|
|
std::cout << " Escalado completado correctamente" << std::endl;
|
|
return scaled_data;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Crear textura SDL desde buffer RGBA
|
|
// ============================================================================
|
|
|
|
SDL_Texture* LogoScaler::createTextureFromBuffer(SDL_Renderer* renderer,
|
|
unsigned char* data,
|
|
int width, int height) {
|
|
if (renderer == nullptr || data == nullptr || width <= 0 || height <= 0) {
|
|
SDL_Log("Parámetros inválidos para createTextureFromBuffer");
|
|
return nullptr;
|
|
}
|
|
|
|
// 1. Crear surface SDL desde buffer RGBA
|
|
int pitch = width * 4; // 4 bytes por píxel (RGBA)
|
|
SDL_PixelFormat pixel_format = SDL_PIXELFORMAT_RGBA32;
|
|
|
|
SDL_Surface* surface = SDL_CreateSurfaceFrom(
|
|
width, height,
|
|
pixel_format,
|
|
data,
|
|
pitch
|
|
);
|
|
|
|
if (surface == nullptr) {
|
|
SDL_Log("Error al crear surface: %s", SDL_GetError());
|
|
return nullptr;
|
|
}
|
|
|
|
// 2. Crear textura desde surface
|
|
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
|
|
|
|
if (texture == nullptr) {
|
|
SDL_Log("Error al crear textura: %s", SDL_GetError());
|
|
SDL_DestroySurface(surface);
|
|
return nullptr;
|
|
}
|
|
|
|
// 3. Liberar surface (la textura ya tiene los datos)
|
|
SDL_DestroySurface(surface);
|
|
|
|
return texture;
|
|
}
|