feat(engine): PostFX cycle + fixes de reinicialització i overflow

- Afegir handlePostFXCycle() amb 5 presets (vinyeta/scanlines/cromàtica/complet/off)
  i tecla X per ciclar-los (input_handler + engine.hpp)
- Augmentar MAX_SPRITES de 65536 a 200000 i afegir guard d'overflow a pushQuad()
- Netejar textures/objectes UI abans de reinicialitzar (AppLogo::initialize,
  UIManager::initialize) per evitar leaks en toggleRealFullscreen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-19 22:53:13 +01:00
parent 310c6d244e
commit badf92420b
6 changed files with 21 additions and 1 deletions

View File

@@ -75,6 +75,9 @@ class Engine {
void toggleRealFullscreen(); void toggleRealFullscreen();
void toggleIntegerScaling(); void toggleIntegerScaling();
// PostFX presets
void handlePostFXCycle();
// Modo kiosko // Modo kiosko
void setKioskMode(bool enabled) { kiosk_mode_ = enabled; } void setKioskMode(bool enabled) { kiosk_mode_ = enabled; }
bool isKioskMode() const { return kiosk_mode_; } bool isKioskMode() const { return kiosk_mode_; }
@@ -165,6 +168,7 @@ class Engine {
// PostFX uniforms (passed to GPU each frame) // PostFX uniforms (passed to GPU each frame)
PostFXUniforms postfx_uniforms_ = {1.5f, 0.0f, 0.0f, 0.0f}; PostFXUniforms postfx_uniforms_ = {1.5f, 0.0f, 0.0f, 0.0f};
int postfx_effect_mode_ = 0;
// Sistema de zoom dinámico // Sistema de zoom dinámico
int current_window_zoom_ = DEFAULT_WINDOW_ZOOM; int current_window_zoom_ = DEFAULT_WINDOW_ZOOM;

View File

@@ -179,6 +179,7 @@ void GpuSpriteBatch::toNDC(float px, float py,
void GpuSpriteBatch::pushQuad(float ndx0, float ndy0, float ndx1, float ndy1, void GpuSpriteBatch::pushQuad(float ndx0, float ndy0, float ndx1, float ndy1,
float u0, float v0, float u1, float v1, float u0, float v0, float u1, float v1,
float r, float g, float b, float a) { float r, float g, float b, float a) {
if (vertices_.size() + 4 > static_cast<size_t>(MAX_SPRITES) * 4) return;
uint32_t vi = static_cast<uint32_t>(vertices_.size()); uint32_t vi = static_cast<uint32_t>(vertices_.size());
// TL, TR, BR, BL // TL, TR, BR, BL

View File

@@ -27,7 +27,7 @@ struct GpuVertex {
class GpuSpriteBatch { class GpuSpriteBatch {
public: public:
// Maximum sprites (background + UI overlay each count as one sprite) // Maximum sprites (background + UI overlay each count as one sprite)
static constexpr int MAX_SPRITES = 65536; static constexpr int MAX_SPRITES = 200000;
bool init(SDL_GPUDevice* device); bool init(SDL_GPUDevice* device);
void destroy(SDL_GPUDevice* device); void destroy(SDL_GPUDevice* device);

View File

@@ -280,6 +280,11 @@ bool InputHandler::processEvents(Engine& engine) {
engine.toggleLogoMode(); engine.toggleLogoMode();
break; break;
// Ciclar presets PostFX (vinyeta/scanlines/cromàtica/complet/desactivat)
case SDLK_X:
engine.handlePostFXCycle();
break;
// Toggle Debug Display (movido de H a F12) // Toggle Debug Display (movido de H a F12)
case SDLK_F12: case SDLK_F12:
engine.toggleDebug(); engine.toggleDebug();

View File

@@ -36,6 +36,11 @@ AppLogo::~AppLogo() {
// ============================================================================ // ============================================================================
bool AppLogo::initialize(SDL_Renderer* renderer, int screen_width, int screen_height) { bool AppLogo::initialize(SDL_Renderer* renderer, int screen_width, int screen_height) {
if (logo1_base_texture_) { SDL_DestroyTexture(logo1_base_texture_); logo1_base_texture_ = nullptr; }
if (logo1_native_texture_) { SDL_DestroyTexture(logo1_native_texture_); logo1_native_texture_ = nullptr; }
if (logo2_base_texture_) { SDL_DestroyTexture(logo2_base_texture_); logo2_base_texture_ = nullptr; }
if (logo2_native_texture_) { SDL_DestroyTexture(logo2_native_texture_); logo2_native_texture_ = nullptr; }
renderer_ = renderer; renderer_ = renderer;
base_screen_width_ = screen_width; base_screen_width_ = screen_width;
base_screen_height_ = screen_height; base_screen_height_ = screen_height;

View File

@@ -70,6 +70,11 @@ UIManager::~UIManager() {
void UIManager::initialize(SDL_Renderer* renderer, ThemeManager* theme_manager, void UIManager::initialize(SDL_Renderer* renderer, ThemeManager* theme_manager,
int physical_width, int physical_height, int physical_width, int physical_height,
int logical_width, int logical_height) { int logical_width, int logical_height) {
delete text_renderer_debug_; text_renderer_debug_ = nullptr;
delete text_renderer_notifier_; text_renderer_notifier_ = nullptr;
delete notifier_; notifier_ = nullptr;
delete help_overlay_; help_overlay_ = nullptr;
renderer_ = renderer; renderer_ = renderer;
theme_manager_ = theme_manager; theme_manager_ = theme_manager;
physical_window_width_ = physical_width; physical_window_width_ = physical_width;