clang-tidy

This commit is contained in:
2026-03-21 23:08:07 +01:00
parent d946ab7943
commit 55b58ded70
19 changed files with 112 additions and 155 deletions

View File

@@ -216,6 +216,7 @@ list(FILTER ALL_SOURCE_FILES EXCLUDE REGEX ".*/external/.*")
# Para clang-tidy, también excluir jail_audio.hpp # Para clang-tidy, también excluir jail_audio.hpp
set(CLANG_TIDY_SOURCES ${ALL_SOURCE_FILES}) set(CLANG_TIDY_SOURCES ${ALL_SOURCE_FILES})
list(FILTER CLANG_TIDY_SOURCES EXCLUDE REGEX ".*jail_audio\\.hpp$") list(FILTER CLANG_TIDY_SOURCES EXCLUDE REGEX ".*jail_audio\\.hpp$")
list(FILTER CLANG_TIDY_SOURCES EXCLUDE REGEX ".*_spv\\.h$")
# Targets de clang-tidy # Targets de clang-tidy
if(CLANG_TIDY_EXE) if(CLANG_TIDY_EXE)

View File

@@ -161,7 +161,7 @@ auto getPressedAction() -> InputAction {
} }
} }
if (Input::get()->checkAction(InputAction::TOGGLE_POSTFX, Input::DO_NOT_ALLOW_REPEAT)) { if (Input::get()->checkAction(InputAction::TOGGLE_POSTFX, Input::DO_NOT_ALLOW_REPEAT)) {
if (Options::video.postfx && (SDL_GetModState() & SDL_KMOD_SHIFT)) { if (Options::video.postfx && ((SDL_GetModState() & SDL_KMOD_SHIFT) != 0U)) {
return InputAction::NEXT_POSTFX_PRESET; return InputAction::NEXT_POSTFX_PRESET;
} }
return InputAction::TOGGLE_POSTFX; return InputAction::TOGGLE_POSTFX;
@@ -197,7 +197,7 @@ void handle() {
if (Options::kiosk.enabled) { if (Options::kiosk.enabled) {
SDL_Keymod mod = SDL_GetModState(); SDL_Keymod mod = SDL_GetModState();
const bool* ks = SDL_GetKeyboardState(nullptr); const bool* ks = SDL_GetKeyboardState(nullptr);
if ((mod & SDL_KMOD_CTRL) && (mod & SDL_KMOD_SHIFT) && (mod & SDL_KMOD_ALT) && ks[SDL_SCANCODE_Q]) { if (((mod & SDL_KMOD_CTRL) != 0U) && ((mod & SDL_KMOD_SHIFT) != 0U) && ((mod & SDL_KMOD_ALT) != 0U) && ks[SDL_SCANCODE_Q]) {
SceneManager::current = SceneManager::Scene::QUIT; SceneManager::current = SceneManager::Scene::QUIT;
return; return;
} }

View File

@@ -1,6 +1,6 @@
#include "core/rendering/pixel_reveal.hpp" #include "core/rendering/pixel_reveal.hpp"
#include <algorithm> // Para min #include <algorithm> // Para min, ranges::all_of
#include <numeric> // Para iota #include <numeric> // Para iota
#include <queue> // Para queue (BFS en modo ORDERED) #include <queue> // Para queue (BFS en modo ORDERED)
#include <random> // Para mt19937, shuffle #include <random> // Para mt19937, shuffle
@@ -30,7 +30,7 @@ PixelReveal::PixelReveal(int width, int height, float pixels_per_second, float s
std::vector<int> offsets; std::vector<int> offsets;
offsets.push_back(0); offsets.push_back(0);
std::queue<std::pair<int, int>> bq; std::queue<std::pair<int, int>> bq;
bq.push({0, num_steps_}); bq.emplace(0, num_steps_);
while (static_cast<int>(offsets.size()) < num_steps_) { while (static_cast<int>(offsets.size()) < num_steps_) {
auto [lo, hi] = bq.front(); auto [lo, hi] = bq.front();
bq.pop(); bq.pop();
@@ -39,14 +39,14 @@ PixelReveal::PixelReveal(int width, int height, float pixels_per_second, float s
} }
const int MID = (lo + hi) / 2; const int MID = (lo + hi) / 2;
offsets.push_back(MID); offsets.push_back(MID);
bq.push({lo, MID}); bq.emplace(lo, MID);
bq.push({MID, hi}); bq.emplace(MID, hi);
} }
// Genera el orden: para cada offset, todas las columnas col = offset, offset+N, offset+2N, ... // Genera el orden: para cada offset, todas las columnas col = offset, offset+N, offset+2N, ...
std::vector<int> ordered_cols; std::vector<int> ordered_cols;
ordered_cols.reserve(width_); ordered_cols.reserve(width_);
for (const int off : offsets) { for (const int OFF : offsets) {
for (int col = off; col < width_; col += num_steps_) { for (int col = OFF; col < width_; col += num_steps_) {
ordered_cols.push_back(col); ordered_cols.push_back(col);
} }
} }
@@ -105,11 +105,6 @@ void PixelReveal::render(int dst_x, int dst_y) const {
} }
// Indica si el revelado ha completado todas las filas // Indica si el revelado ha completado todas las filas
bool PixelReveal::isComplete() const { auto PixelReveal::isComplete() const -> bool {
for (const int step : row_step_) { return std::ranges::all_of(row_step_, [this](int s) { return s >= num_steps_; });
if (step < num_steps_) {
return false;
}
}
return true;
} }

View File

@@ -26,7 +26,7 @@ class PixelReveal {
void render(int dst_x, int dst_y) const; void render(int dst_x, int dst_y) const;
// Indica si el revelado ha completado todas las filas // Indica si el revelado ha completado todas las filas
[[nodiscard]] bool isComplete() const; [[nodiscard]] auto isComplete() const -> bool;
private: private:
std::shared_ptr<Surface> cover_surface_; // Máscara negra que se va haciendo transparente std::shared_ptr<Surface> cover_surface_; // Máscara negra que se va haciendo transparente

View File

@@ -392,7 +392,7 @@ auto Screen::findPalette(const std::string& name) -> size_t {
} }
// Muestra información por pantalla // Muestra información por pantalla
void Screen::renderInfo() { void Screen::renderInfo() const {
if (show_debug_info_ && (Resource::Cache::get() != nullptr)) { if (show_debug_info_ && (Resource::Cache::get() != nullptr)) {
auto text = Resource::Cache::get()->getText("smb2"); auto text = Resource::Cache::get()->getText("smb2");
auto color = static_cast<Uint8>(PaletteColor::YELLOW); auto color = static_cast<Uint8>(PaletteColor::YELLOW);
@@ -459,7 +459,7 @@ auto loadData(const std::string& filepath) -> std::vector<uint8_t> {
void Screen::applyCurrentPostFXPreset() { void Screen::applyCurrentPostFXPreset() {
if (shader_backend_ && !Options::postfx_presets.empty()) { if (shader_backend_ && !Options::postfx_presets.empty()) {
const auto& p = Options::postfx_presets[static_cast<size_t>(Options::current_postfx_preset)]; const auto& p = Options::postfx_presets[static_cast<size_t>(Options::current_postfx_preset)];
Rendering::PostFXParams params{p.vignette, p.scanlines, p.chroma, p.mask, p.gamma, p.curvature, p.bleeding}; Rendering::PostFXParams params{.vignette = p.vignette, .scanlines = p.scanlines, .chroma = p.chroma, .mask = p.mask, .gamma = p.gamma, .curvature = p.curvature, .bleeding = p.bleeding};
shader_backend_->setPostFXParams(params); shader_backend_->setPostFXParams(params);
} }
} }

View File

@@ -116,7 +116,7 @@ class Screen {
auto findPalette(const std::string& name) -> size_t; // Localiza la paleta dentro del vector de paletas auto findPalette(const std::string& name) -> size_t; // Localiza la paleta dentro del vector de paletas
void initShaders(); // Inicializa los shaders void initShaders(); // Inicializa los shaders
void applyCurrentPostFXPreset(); // Aplica los parámetros del preset actual al backend void applyCurrentPostFXPreset(); // Aplica los parámetros del preset actual al backend
void renderInfo(); // Muestra información por pantalla void renderInfo() const; // Muestra información por pantalla
void getDisplayInfo(); // Obtiene información sobre la pantalla void getDisplayInfo(); // Obtiene información sobre la pantalla
auto initSDLVideo() -> bool; // Arranca SDL VIDEO y crea la ventana auto initSDLVideo() -> bool; // Arranca SDL VIDEO y crea la ventana
void createText(); // Crea el objeto de texto void createText(); // Crea el objeto de texto

View File

@@ -412,15 +412,15 @@ void SDL3GPUShader::render() {
float vw = 0.0F; float vw = 0.0F;
float vh = 0.0F; float vh = 0.0F;
if (integer_scale_) { if (integer_scale_) {
const int scale = std::max(1, std::min(static_cast<int>(sw) / tex_width_, static_cast<int>(sh) / tex_height_)); const int SCALE = std::max(1, std::min(static_cast<int>(sw) / tex_width_, static_cast<int>(sh) / tex_height_));
vw = static_cast<float>(tex_width_ * scale); vw = static_cast<float>(tex_width_ * SCALE);
vh = static_cast<float>(tex_height_ * scale); vh = static_cast<float>(tex_height_ * SCALE);
} else { } else {
const float scale = std::min( const float SCALE = std::min(
static_cast<float>(sw) / static_cast<float>(tex_width_), static_cast<float>(sw) / static_cast<float>(tex_width_),
static_cast<float>(sh) / static_cast<float>(tex_height_)); static_cast<float>(sh) / static_cast<float>(tex_height_));
vw = static_cast<float>(tex_width_) * scale; vw = static_cast<float>(tex_width_) * SCALE;
vh = static_cast<float>(tex_height_) * scale; vh = static_cast<float>(tex_height_) * SCALE;
} }
vx = std::floor((static_cast<float>(sw) - vw) * 0.5F); vx = std::floor((static_cast<float>(sw) - vw) * 0.5F);
vy = std::floor((static_cast<float>(sh) - vh) * 0.5F); vy = std::floor((static_cast<float>(sh) - vh) * 0.5F);

View File

@@ -40,7 +40,7 @@ class SDL3GPUShader : public ShaderBackend {
void render() override; void render() override;
void setTextureSize(float width, float height) override {} void setTextureSize(float width, float height) override {}
void cleanup() override; // Libera pipeline/texturas pero mantiene el device vivo void cleanup() final; // Libera pipeline/texturas pero mantiene el device vivo
void destroy(); // Limpieza completa (device + swapchain); llamar solo al cerrar void destroy(); // Limpieza completa (device + swapchain); llamar solo al cerrar
[[nodiscard]] auto isHardwareAccelerated() const -> bool override { return is_initialized_; } [[nodiscard]] auto isHardwareAccelerated() const -> bool override { return is_initialized_; }

View File

@@ -430,19 +430,30 @@ void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 tar
// Hash 2D estable per a dithering sense flickering // Hash 2D estable per a dithering sense flickering
static auto pixelThreshold(int col, int row) -> float { static auto pixelThreshold(int col, int row) -> float {
auto h = static_cast<uint32_t>(col) * 2246822519U ^ static_cast<uint32_t>(row) * 2654435761U; auto h = (static_cast<uint32_t>(col) * 2246822519U) ^ (static_cast<uint32_t>(row) * 2654435761U);
h ^= (h >> 13); h ^= (h >> 13);
h *= 1274126177U; h *= 1274126177U;
h ^= (h >> 16); h ^= (h >> 16);
return static_cast<float>(h & 0xFFFFU) / 65536.0F; return static_cast<float>(h & 0xFFFFU) / 65536.0F;
} }
// Calcula la densidad de fade para un pixel en posición screen_y
static auto computeFadeDensity(int screen_y, int fade_h, int canvas_height) -> float {
if (screen_y < fade_h) {
return static_cast<float>(fade_h - screen_y) / static_cast<float>(fade_h);
}
if (screen_y >= canvas_height - fade_h) {
return static_cast<float>(screen_y - (canvas_height - fade_h)) / static_cast<float>(fade_h);
}
return 0.0F;
}
// Render amb dissolució als cantons superior/inferior (hash 2D, sense parpelleig) // Render amb dissolució als cantons superior/inferior (hash 2D, sense parpelleig)
void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, SDL_FRect* src_rect) { void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, SDL_FRect* src_rect) {
const int SX = src_rect ? static_cast<int>(src_rect->x) : 0; const int SX = (src_rect != nullptr) ? static_cast<int>(src_rect->x) : 0;
const int SY = src_rect ? static_cast<int>(src_rect->y) : 0; const int SY = (src_rect != nullptr) ? static_cast<int>(src_rect->y) : 0;
const int SW = src_rect ? static_cast<int>(src_rect->w) : static_cast<int>(surface_data_->width); const int SW = (src_rect != nullptr) ? static_cast<int>(src_rect->w) : static_cast<int>(surface_data_->width);
const int SH = src_rect ? static_cast<int>(src_rect->h) : static_cast<int>(surface_data_->height); const int SH = (src_rect != nullptr) ? static_cast<int>(src_rect->h) : static_cast<int>(surface_data_->height);
auto surface_data_dest = Screen::get()->getRendererSurface()->getSurfaceData(); auto surface_data_dest = Screen::get()->getRendererSurface()->getSurfaceData();
@@ -452,12 +463,7 @@ void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height
continue; continue;
} }
float density = 0.0F; const float DENSITY = computeFadeDensity(SCREEN_Y, fade_h, canvas_height);
if (SCREEN_Y < fade_h) {
density = static_cast<float>(fade_h - SCREEN_Y) / static_cast<float>(fade_h);
} else if (SCREEN_Y >= canvas_height - fade_h) {
density = static_cast<float>(SCREEN_Y - (canvas_height - fade_h)) / static_cast<float>(fade_h);
}
for (int col = 0; col < SW; col++) { for (int col = 0; col < SW; col++) {
const int SCREEN_X = x + col; const int SCREEN_X = x + col;
@@ -465,12 +471,12 @@ void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height
continue; continue;
} }
const Uint8 COLOR = surface_data_->data[(SY + row) * static_cast<int>(surface_data_->width) + (SX + col)]; const Uint8 COLOR = surface_data_->data[((SY + row) * static_cast<int>(surface_data_->width)) + (SX + col)];
if (static_cast<int>(COLOR) == transparent_color_) { if (static_cast<int>(COLOR) == transparent_color_) {
continue; continue;
} }
if (pixelThreshold(col, row) < density) { if (pixelThreshold(col, row) < DENSITY) {
continue; // Pixel tapat per la zona de fade continue; // Pixel tapat per la zona de fade
} }
@@ -481,10 +487,10 @@ void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height
// Idem però reemplaçant un color índex // Idem però reemplaçant un color índex
void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, Uint8 source_color, Uint8 target_color, SDL_FRect* src_rect) { void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, Uint8 source_color, Uint8 target_color, SDL_FRect* src_rect) {
const int SX = src_rect ? static_cast<int>(src_rect->x) : 0; const int SX = (src_rect != nullptr) ? static_cast<int>(src_rect->x) : 0;
const int SY = src_rect ? static_cast<int>(src_rect->y) : 0; const int SY = (src_rect != nullptr) ? static_cast<int>(src_rect->y) : 0;
const int SW = src_rect ? static_cast<int>(src_rect->w) : static_cast<int>(surface_data_->width); const int SW = (src_rect != nullptr) ? static_cast<int>(src_rect->w) : static_cast<int>(surface_data_->width);
const int SH = src_rect ? static_cast<int>(src_rect->h) : static_cast<int>(surface_data_->height); const int SH = (src_rect != nullptr) ? static_cast<int>(src_rect->h) : static_cast<int>(surface_data_->height);
auto surface_data_dest = Screen::get()->getRendererSurface()->getSurfaceData(); auto surface_data_dest = Screen::get()->getRendererSurface()->getSurfaceData();
@@ -494,12 +500,7 @@ void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height
continue; continue;
} }
float density = 0.0F; const float DENSITY = computeFadeDensity(SCREEN_Y, fade_h, canvas_height);
if (SCREEN_Y < fade_h) {
density = static_cast<float>(fade_h - SCREEN_Y) / static_cast<float>(fade_h);
} else if (SCREEN_Y >= canvas_height - fade_h) {
density = static_cast<float>(SCREEN_Y - (canvas_height - fade_h)) / static_cast<float>(fade_h);
}
for (int col = 0; col < SW; col++) { for (int col = 0; col < SW; col++) {
const int SCREEN_X = x + col; const int SCREEN_X = x + col;
@@ -507,12 +508,12 @@ void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height
continue; continue;
} }
const Uint8 COLOR = surface_data_->data[(SY + row) * static_cast<int>(surface_data_->width) + (SX + col)]; const Uint8 COLOR = surface_data_->data[((SY + row) * static_cast<int>(surface_data_->width)) + (SX + col)];
if (static_cast<int>(COLOR) == transparent_color_) { if (static_cast<int>(COLOR) == transparent_color_) {
continue; continue;
} }
if (pixelThreshold(col, row) < density) { if (pixelThreshold(col, row) < DENSITY) {
continue; // Pixel tapat per la zona de fade continue; // Pixel tapat per la zona de fade
} }

View File

@@ -219,7 +219,7 @@ SurfaceAnimatedSprite::SurfaceAnimatedSprite(std::shared_ptr<Surface> surface, S
: SurfaceMovingSprite(std::move(surface), pos) { : SurfaceMovingSprite(std::move(surface), pos) {
// animations_ queda buit (protegit per el guard de animate()) // animations_ queda buit (protegit per el guard de animate())
if (surface_) { if (surface_) {
clip_ = {0, 0, static_cast<float>(surface_->getWidth()), static_cast<float>(surface_->getHeight())}; clip_ = {.x = 0, .y = 0, .w = surface_->getWidth(), .h = surface_->getHeight()};
} }
} }
@@ -239,7 +239,7 @@ auto SurfaceAnimatedSprite::getIndex(const std::string& name) -> int {
// Calcula el frame correspondiente a la animación (time-based) // Calcula el frame correspondiente a la animación (time-based)
void SurfaceAnimatedSprite::animate(float delta_time) { void SurfaceAnimatedSprite::animate(float delta_time) {
if (animations_.empty()) return; if (animations_.empty()) { return; }
if (animations_[current_animation_].speed <= 0.0F) { if (animations_[current_animation_].speed <= 0.0F) {
return; return;
} }

View File

@@ -7,7 +7,7 @@
// Hash 2D estable per a dithering (rank aleatori per posició de píxel) // Hash 2D estable per a dithering (rank aleatori per posició de píxel)
static auto pixelRank(int col, int row) -> float { static auto pixelRank(int col, int row) -> float {
auto h = static_cast<uint32_t>(col) * 2246822519U ^ static_cast<uint32_t>(row) * 2654435761U; auto h = (static_cast<uint32_t>(col) * 2246822519U) ^ (static_cast<uint32_t>(row) * 2654435761U);
h ^= (h >> 13); h ^= (h >> 13);
h *= 1274126177U; h *= 1274126177U;
h ^= (h >> 16); h ^= (h >> 16);
@@ -28,7 +28,7 @@ auto SurfaceDissolveSprite::computePixelRank(int col, int row, int frame_h, Diss
y_factor = static_cast<float>(frame_h - 1 - row) / static_cast<float>(frame_h); y_factor = static_cast<float>(frame_h - 1 - row) / static_cast<float>(frame_h);
} }
return y_factor * 0.7F + RANDOM * 0.3F; return (y_factor * 0.7F) + (RANDOM * 0.3F);
} }
// Constructor per a surface directa (sense AnimationResource) // Constructor per a surface directa (sense AnimationResource)
@@ -92,14 +92,14 @@ void SurfaceDissolveSprite::rebuildDisplaySurface() {
// Copia píxels filtrats per progress_ // Copia píxels filtrats per progress_
for (int row = 0; row < SH; ++row) { for (int row = 0; row < SH; ++row) {
for (int col = 0; col < SW; ++col) { for (int col = 0; col < SW; ++col) {
const Uint8 COLOR = src_data->data[(SY + row) * SRC_W + (SX + col)]; const Uint8 COLOR = src_data->data[((SY + row) * SRC_W) + (SX + col)];
if (COLOR == TRANSPARENT) { if (COLOR == TRANSPARENT) {
continue; continue;
} }
const float RANK = computePixelRank(col, row, SH, direction_); const float RANK = computePixelRank(col, row, SH, direction_);
if (RANK >= progress_) { if (RANK >= progress_) {
const Uint8 OUT = (COLOR == source_color_) ? target_color_ : COLOR; const Uint8 OUT = (COLOR == source_color_) ? target_color_ : COLOR;
dst_data->data[(SY + row) * DST_W + (SX + col)] = OUT; dst_data->data[((SY + row) * DST_W) + (SX + col)] = OUT;
} }
} }
} }

View File

@@ -908,11 +908,7 @@ auto Player::getProjection(Direction direction, float displacement) -> SDL_FRect
// Marca al jugador como muerto // Marca al jugador como muerto
void Player::markAsDead() { void Player::markAsDead() {
if (Options::cheats.invincible == Options::Cheat::State::ENABLED) { is_alive_ = (Options::cheats.invincible == Options::Cheat::State::ENABLED);
is_alive_ = true; // No puede morir
} else {
is_alive_ = false; // Muere
}
} }
#ifdef _DEBUG #ifdef _DEBUG

View File

@@ -29,9 +29,9 @@ void CollisionMap::initializeSurfaces() {
// Devuelve el tipo de tile que hay en ese pixel // Devuelve el tipo de tile que hay en ese pixel
auto CollisionMap::getTile(SDL_FPoint point) const -> Tile { auto CollisionMap::getTile(SDL_FPoint point) const -> Tile {
const int row = static_cast<int>(point.y / TILE_SIZE); const int ROW = static_cast<int>(point.y / TILE_SIZE);
const int col = static_cast<int>(point.x / TILE_SIZE); const int COL = static_cast<int>(point.x / TILE_SIZE);
const int POS = row * MAP_WIDTH + col; const int POS = (ROW * MAP_WIDTH) + COL;
return getTile(POS); return getTile(POS);
} }

View File

@@ -654,6 +654,13 @@ void setPostFXFile(const std::string& path) {
postfx_file_path = path; postfx_file_path = path;
} }
// Helper: extrae un campo float de un nodo YAML si existe, ignorando errores de conversión
static void parseFloatField(const fkyaml::node& node, const std::string& key, float& target) {
if (node.contains(key)) {
try { target = node[key].get_value<float>(); } catch (...) {}
}
}
// Carga los presets de PostFX desde el fichero // Carga los presets de PostFX desde el fichero
auto loadPostFXFromFile() -> bool { auto loadPostFXFromFile() -> bool {
postfx_presets.clear(); postfx_presets.clear();
@@ -675,47 +682,18 @@ auto loadPostFXFromFile() -> bool {
if (yaml.contains("presets")) { if (yaml.contains("presets")) {
const auto& presets = yaml["presets"]; const auto& presets = yaml["presets"];
for (size_t i = 0; i < presets.size(); ++i) { for (const auto& p : presets) {
const auto& p = presets[i];
PostFXPreset preset; PostFXPreset preset;
if (p.contains("name")) { if (p.contains("name")) {
preset.name = p["name"].get_value<std::string>(); preset.name = p["name"].get_value<std::string>();
} }
if (p.contains("vignette")) { parseFloatField(p, "vignette", preset.vignette);
try { parseFloatField(p, "scanlines", preset.scanlines);
preset.vignette = p["vignette"].get_value<float>(); parseFloatField(p, "chroma", preset.chroma);
} catch (...) {} parseFloatField(p, "mask", preset.mask);
} parseFloatField(p, "gamma", preset.gamma);
if (p.contains("scanlines")) { parseFloatField(p, "curvature", preset.curvature);
try { parseFloatField(p, "bleeding", preset.bleeding);
preset.scanlines = p["scanlines"].get_value<float>();
} catch (...) {}
}
if (p.contains("chroma")) {
try {
preset.chroma = p["chroma"].get_value<float>();
} catch (...) {}
}
if (p.contains("mask")) {
try {
preset.mask = p["mask"].get_value<float>();
} catch (...) {}
}
if (p.contains("gamma")) {
try {
preset.gamma = p["gamma"].get_value<float>();
} catch (...) {}
}
if (p.contains("curvature")) {
try {
preset.curvature = p["curvature"].get_value<float>();
} catch (...) {}
}
if (p.contains("bleeding")) {
try {
preset.bleeding = p["bleeding"].get_value<float>();
} catch (...) {}
}
postfx_presets.push_back(preset); postfx_presets.push_back(preset);
} }
} }

View File

@@ -111,6 +111,17 @@ void Ending::transitionToState(State new_state) {
} }
} }
// Lógica de fade común a los estados SCENE_N
void Ending::handleSceneFadeout(float scene_duration, float delta_time) {
if (state_time_ >= scene_duration - FADEOUT_START_OFFSET) {
fadeout_time_ += delta_time;
if (!scene_cover_) {
scene_cover_ = std::make_unique<PixelReveal>(Options::game.width, Options::game.height, COVER_PIXELS_PER_SECOND, STEP_DURATION, COVER_STEPS, true);
}
scene_cover_->update(fadeout_time_);
}
}
// Actualiza la máquina de estados // Actualiza la máquina de estados
void Ending::updateState(float delta_time) { void Ending::updateState(float delta_time) {
state_time_ += delta_time; state_time_ += delta_time;
@@ -125,57 +136,27 @@ void Ending::updateState(float delta_time) {
case State::SCENE_0: case State::SCENE_0:
checkChangeScene(); checkChangeScene();
if (state_time_ >= SCENE_0_DURATION - FADEOUT_START_OFFSET) { handleSceneFadeout(SCENE_0_DURATION, delta_time);
fadeout_time_ += delta_time;
if (!scene_cover_) {
scene_cover_ = std::make_unique<PixelReveal>(Options::game.width, Options::game.height, COVER_PIXELS_PER_SECOND, STEP_DURATION, COVER_STEPS, true);
}
scene_cover_->update(fadeout_time_);
}
break; break;
case State::SCENE_1: case State::SCENE_1:
checkChangeScene(); checkChangeScene();
if (state_time_ >= SCENE_1_DURATION - FADEOUT_START_OFFSET) { handleSceneFadeout(SCENE_1_DURATION, delta_time);
fadeout_time_ += delta_time;
if (!scene_cover_) {
scene_cover_ = std::make_unique<PixelReveal>(Options::game.width, Options::game.height, COVER_PIXELS_PER_SECOND, STEP_DURATION, COVER_STEPS, true);
}
scene_cover_->update(fadeout_time_);
}
break; break;
case State::SCENE_2: case State::SCENE_2:
checkChangeScene(); checkChangeScene();
if (state_time_ >= SCENE_2_DURATION - FADEOUT_START_OFFSET) { handleSceneFadeout(SCENE_2_DURATION, delta_time);
fadeout_time_ += delta_time;
if (!scene_cover_) {
scene_cover_ = std::make_unique<PixelReveal>(Options::game.width, Options::game.height, COVER_PIXELS_PER_SECOND, STEP_DURATION, COVER_STEPS, true);
}
scene_cover_->update(fadeout_time_);
}
break; break;
case State::SCENE_3: case State::SCENE_3:
checkChangeScene(); checkChangeScene();
if (state_time_ >= SCENE_3_DURATION - FADEOUT_START_OFFSET) { handleSceneFadeout(SCENE_3_DURATION, delta_time);
fadeout_time_ += delta_time;
if (!scene_cover_) {
scene_cover_ = std::make_unique<PixelReveal>(Options::game.width, Options::game.height, COVER_PIXELS_PER_SECOND, STEP_DURATION, COVER_STEPS, true);
}
scene_cover_->update(fadeout_time_);
}
break; break;
case State::SCENE_4: case State::SCENE_4:
checkChangeScene(); checkChangeScene();
if (state_time_ >= SCENE_4_DURATION - FADEOUT_START_OFFSET) { handleSceneFadeout(SCENE_4_DURATION, delta_time);
fadeout_time_ += delta_time;
if (!scene_cover_) {
scene_cover_ = std::make_unique<PixelReveal>(Options::game.width, Options::game.height, COVER_PIXELS_PER_SECOND, STEP_DURATION, COVER_STEPS, true);
}
scene_cover_->update(fadeout_time_);
}
break; break;
case State::ENDING: case State::ENDING:

View File

@@ -82,8 +82,9 @@ class Ending {
void iniTexts(); // Inicializa los textos void iniTexts(); // Inicializa los textos
void iniPics(); // Inicializa las imágenes void iniPics(); // Inicializa las imágenes
void iniScenes(); // Inicializa las escenas void iniScenes(); // Inicializa las escenas
void updateState(float delta_time); // Actualiza la máquina de estados void updateState(float delta_time); // Actualiza la máquina de estados
void transitionToState(State new_state); // Transición entre estados void handleSceneFadeout(float scene_duration, float delta_time); // Lógica de fade común a los estados SCENE_N
void transitionToState(State new_state); // Transición entre estados
void updateSpriteCovers(); // Actualiza las cortinillas de los elementos void updateSpriteCovers(); // Actualiza las cortinillas de los elementos
void checkChangeScene(); // Comprueba si se ha de cambiar de escena void checkChangeScene(); // Comprueba si se ha de cambiar de escena
void updateMusicVolume() const; // Actualiza el volumen de la música void updateMusicVolume() const; // Actualiza el volumen de la música

View File

@@ -285,7 +285,7 @@ void Ending2::updateSprites(float delta) {
const float Y = sprite->getPosY(); const float Y = sprite->getPosY();
const float H = sprite->getHeight(); const float H = sprite->getHeight();
const float CANVAS_H = static_cast<float>(Options::game.height); const auto CANVAS_H = Options::game.height;
// Checkpoint inferior: sprite entra per baix → generar de dalt a baix // Checkpoint inferior: sprite entra per baix → generar de dalt a baix
if (Y > static_cast<float>(ENTRY_EXIT_PADDING) && Y <= CANVAS_H - H - ENTRY_EXIT_PADDING && sprite->getProgress() >= 1.0F && sprite->isTransitionDone()) { if (Y > static_cast<float>(ENTRY_EXIT_PADDING) && Y <= CANVAS_H - H - ENTRY_EXIT_PADDING && sprite->getProgress() >= 1.0F && sprite->isTransitionDone()) {
@@ -306,7 +306,7 @@ void Ending2::updateTextSprites(float delta) {
const float Y = sprite->getPosY(); const float Y = sprite->getPosY();
const float H = sprite->getHeight(); const float H = sprite->getHeight();
const float CANVAS_H = static_cast<float>(Options::game.height); const auto CANVAS_H = Options::game.height;
if (Y > static_cast<float>(ENTRY_EXIT_PADDING) && Y <= CANVAS_H - H - ENTRY_EXIT_PADDING && sprite->getProgress() >= 1.0F && sprite->isTransitionDone()) { if (Y > static_cast<float>(ENTRY_EXIT_PADDING) && Y <= CANVAS_H - H - ENTRY_EXIT_PADDING && sprite->getProgress() >= 1.0F && sprite->isTransitionDone()) {
sprite->startGenerate(TRANSITION_DURATION_MS, DissolveDirection::UP); sprite->startGenerate(TRANSITION_DURATION_MS, DissolveDirection::UP);
@@ -325,7 +325,7 @@ void Ending2::updateTexts(float delta) {
const float Y = sprite->getPosY(); const float Y = sprite->getPosY();
const float H = sprite->getHeight(); const float H = sprite->getHeight();
const float CANVAS_H = static_cast<float>(Options::game.height); const auto CANVAS_H = Options::game.height;
// Checkpoint inferior: text entra per baix → generar de dalt a baix // Checkpoint inferior: text entra per baix → generar de dalt a baix
if (Y > static_cast<float>(ENTRY_EXIT_PADDING) && Y <= CANVAS_H - H - ENTRY_EXIT_PADDING && sprite->getProgress() >= 1.0F && sprite->isTransitionDone()) { if (Y > static_cast<float>(ENTRY_EXIT_PADDING) && Y <= CANVAS_H - H - ENTRY_EXIT_PADDING && sprite->getProgress() >= 1.0F && sprite->isTransitionDone()) {

View File

@@ -366,6 +366,13 @@ void Game::renderPostFadeEnding() {
} }
#ifdef _DEBUG #ifdef _DEBUG
// Helper: alterna un cheat y muestra notificación con su estado
static void toggleCheat(Options::Cheat::State& cheat, const std::string& label) {
cheat = (cheat == Options::Cheat::State::ENABLED) ? Options::Cheat::State::DISABLED : Options::Cheat::State::ENABLED;
const bool ENABLED = (cheat == Options::Cheat::State::ENABLED);
Notifier::get()->show({label + (ENABLED ? " ENABLED" : " DISABLED")}, Notifier::Style::DEFAULT, -1, true);
}
// Pasa la información de debug // Pasa la información de debug
void Game::updateDebugInfo() { void Game::updateDebugInfo() {
// Debug::get()->add("X = " + std::to_string(static_cast<int>(player_->x_)) + ", Y = " + std::to_string(static_cast<int>(player_->y_))); // Debug::get()->add("X = " + std::to_string(static_cast<int>(player_->x_)) + ", Y = " + std::to_string(static_cast<int>(player_->y_)));
@@ -437,20 +444,17 @@ void Game::handleDebugEvents(const SDL_Event& event) {
break; break;
case SDLK_1: case SDLK_1:
Options::cheats.infinite_lives = Options::cheats.infinite_lives == Options::Cheat::State::ENABLED ? Options::Cheat::State::DISABLED : Options::Cheat::State::ENABLED; toggleCheat(Options::cheats.infinite_lives, "INFINITE LIVES");
Notifier::get()->show({std::string("INFINITE LIVES ") + (Options::cheats.infinite_lives == Options::Cheat::State::ENABLED ? "ENABLED" : "DISABLED")}, Notifier::Style::DEFAULT, -1, true);
player_->setColor(); player_->setColor();
break; break;
case SDLK_2: case SDLK_2:
Options::cheats.invincible = Options::cheats.invincible == Options::Cheat::State::ENABLED ? Options::Cheat::State::DISABLED : Options::Cheat::State::ENABLED; toggleCheat(Options::cheats.invincible, "INVINCIBLE");
Notifier::get()->show({std::string("INVINCIBLE ") + (Options::cheats.invincible == Options::Cheat::State::ENABLED ? "ENABLED" : "DISABLED")}, Notifier::Style::DEFAULT, -1, true);
player_->setColor(); player_->setColor();
break; break;
case SDLK_3: case SDLK_3:
Options::cheats.jail_is_open = Options::cheats.jail_is_open == Options::Cheat::State::ENABLED ? Options::Cheat::State::DISABLED : Options::Cheat::State::ENABLED; toggleCheat(Options::cheats.jail_is_open, "JAIL IS OPEN");
Notifier::get()->show({std::string("JAIL IS OPEN ") + (Options::cheats.jail_is_open == Options::Cheat::State::ENABLED ? "ENABLED" : "DISABLED")}, Notifier::Style::DEFAULT, -1, true);
break; break;
case SDLK_7: case SDLK_7:
@@ -506,7 +510,7 @@ void Game::handleDebugMouseDrag(float delta_time) {
// Calcular distancia al objetivo // Calcular distancia al objetivo
float dx = game_x - player_x; float dx = game_x - player_x;
float dy = game_y - player_y; float dy = game_y - player_y;
float distance = std::sqrt(dx * dx + dy * dy); float distance = std::sqrt((dx * dx) + (dy * dy));
// Constantes de velocidad con ease-in (aceleración progresiva) // Constantes de velocidad con ease-in (aceleración progresiva)
constexpr float DRAG_SPEED_MIN = 30.0F; // Velocidad inicial (pixels/segundo) constexpr float DRAG_SPEED_MIN = 30.0F; // Velocidad inicial (pixels/segundo)
@@ -517,13 +521,13 @@ void Game::handleDebugMouseDrag(float delta_time) {
if (!debug_dragging_player_) { if (!debug_dragging_player_) {
debug_drag_speed_ = DRAG_SPEED_MIN; // Iniciar con velocidad mínima debug_drag_speed_ = DRAG_SPEED_MIN; // Iniciar con velocidad mínima
} }
debug_drag_speed_ = std::min(DRAG_SPEED_MAX, debug_drag_speed_ + DRAG_ACCELERATION * delta_time); debug_drag_speed_ = std::min(DRAG_SPEED_MAX, debug_drag_speed_ + (DRAG_ACCELERATION * delta_time));
if (distance > 1.0F) { if (distance > 1.0F) {
// Calcular el movimiento con la velocidad actual // Calcular el movimiento con la velocidad actual
float move_factor = std::min(1.0F, debug_drag_speed_ * delta_time / distance); float move_factor = std::min(1.0F, debug_drag_speed_ * delta_time / distance);
float new_x = player_x + dx * move_factor; float new_x = player_x + (dx * move_factor);
float new_y = player_y + dy * move_factor; float new_y = player_y + (dy * move_factor);
// Mover el jugador hacia la posición del cursor // Mover el jugador hacia la posición del cursor
player_->setDebugPosition(new_x, new_y); player_->setDebugPosition(new_x, new_y);

View File

@@ -66,10 +66,10 @@ class Game {
void updateFadeToEnding(float delta_time); // Actualiza el juego en estado FADE_TO_ENDING void updateFadeToEnding(float delta_time); // Actualiza el juego en estado FADE_TO_ENDING
void updatePostFadeEnding(float delta_time); // Actualiza el juego en estado POST_FADE_ENDING void updatePostFadeEnding(float delta_time); // Actualiza el juego en estado POST_FADE_ENDING
void renderPlaying(); // Renderiza el juego en estado PLAYING (directo a pantalla) void renderPlaying(); // Renderiza el juego en estado PLAYING (directo a pantalla)
void renderBlackScreen(); // Renderiza el juego en estado BLACK_SCREEN (pantalla negra) static void renderBlackScreen(); // Renderiza el juego en estado BLACK_SCREEN (pantalla negra)
void renderGameOver(); // Renderiza el juego en estado GAME_OVER (pantalla negra) static void renderGameOver(); // Renderiza el juego en estado GAME_OVER (pantalla negra)
void renderFadeToEnding(); // Renderiza el juego en estado FADE_TO_ENDING (via backbuffer) void renderFadeToEnding(); // Renderiza el juego en estado FADE_TO_ENDING (via backbuffer)
void renderPostFadeEnding(); // Renderiza el juego en estado POST_FADE_ENDING (pantalla negra) static void renderPostFadeEnding(); // Renderiza el juego en estado POST_FADE_ENDING (pantalla negra)
auto changeRoom(const std::string& room_path) -> bool; // Cambia de habitación auto changeRoom(const std::string& room_path) -> bool; // Cambia de habitación
void handleInput(); // Comprueba el teclado void handleInput(); // Comprueba el teclado
void checkPlayerIsOnBorder(); // Comprueba si el jugador esta en el borde de la pantalla y actua void checkPlayerIsOnBorder(); // Comprueba si el jugador esta en el borde de la pantalla y actua