clang-tidy

This commit is contained in:
2026-04-03 09:31:41 +02:00
parent 8dcc1d282a
commit 46dc81124f
25 changed files with 320 additions and 314 deletions

View File

@@ -21,7 +21,7 @@ Checks:
WarningsAsErrors: '*' WarningsAsErrors: '*'
# Solo incluir archivos de tu código fuente (external tiene su propio .clang-tidy) # Solo incluir archivos de tu código fuente (external tiene su propio .clang-tidy)
# Excluye jail_audio.hpp del análisis # Excluye jail_audio.hpp del análisis
HeaderFilterRegex: '^source/(?!core/audio/jail_audio\.hpp).*' HeaderFilterRegex: 'source/(?!core/audio/jail_audio\.hpp|core/rendering/sdl3gpu/.*_spv\.h).*'
FormatStyle: file FormatStyle: file
CheckOptions: CheckOptions:

View File

@@ -144,7 +144,7 @@ namespace GlobalInputs {
} }
// Detecta qué acción global ha sido presionada (si alguna) // Detecta qué acción global ha sido presionada (si alguna)
auto getPressedAction() -> InputAction { auto getPressedAction() -> InputAction { // NOLINT(readability-function-cognitive-complexity)
if (Input::get()->checkAction(InputAction::EXIT, Input::DO_NOT_ALLOW_REPEAT)) { if (Input::get()->checkAction(InputAction::EXIT, Input::DO_NOT_ALLOW_REPEAT)) {
return InputAction::EXIT; return InputAction::EXIT;
} }

View File

@@ -15,9 +15,9 @@
// ── Conversión string ↔ PaletteSortMode ────────────────────────────────────── // ── Conversión string ↔ PaletteSortMode ──────────────────────────────────────
auto sortModeFromString(const std::string& str) -> PaletteSortMode { auto sortModeFromString(const std::string& str) -> PaletteSortMode {
const std::string lower = toLower(str); const std::string LOWER = toLower(str);
if (lower == "luminance") { return PaletteSortMode::LUMINANCE; } if (LOWER == "luminance") { return PaletteSortMode::LUMINANCE; }
if (lower == "spectrum") { return PaletteSortMode::SPECTRUM; } if (LOWER == "spectrum") { return PaletteSortMode::SPECTRUM; }
return PaletteSortMode::ORIGINAL; return PaletteSortMode::ORIGINAL;
} }
@@ -66,15 +66,15 @@ namespace {
// Luminancia percibida (ITU-R BT.709) // Luminancia percibida (ITU-R BT.709)
auto luminance(Uint32 color) -> double { auto luminance(Uint32 color) -> double {
return 0.2126 * redOf(color) + 0.7152 * greenOf(color) + 0.0722 * blueOf(color); return (0.2126 * redOf(color)) + (0.7152 * greenOf(color)) + (0.0722 * blueOf(color));
} }
// Distancia euclídea al cuadrado en espacio RGB (no necesita sqrt para comparar) // Distancia euclídea al cuadrado en espacio RGB (no necesita sqrt para comparar)
auto rgbDistanceSq(Uint32 a, Uint32 b) -> int { auto rgbDistanceSq(Uint32 a, Uint32 b) -> int {
const int dr = redOf(a) - redOf(b); const int DR = redOf(a) - redOf(b);
const int dg = greenOf(a) - greenOf(b); const int DG = greenOf(a) - greenOf(b);
const int db = blueOf(a) - blueOf(b); const int DB = blueOf(a) - blueOf(b);
return dr * dr + dg * dg + db * db; return (DR * DR) + (DG * DG) + (DB * DB);
} }
// Cuenta los colores activos en la paleta (los que tienen alpha != 0) // Cuenta los colores activos en la paleta (los que tienen alpha != 0)
@@ -89,31 +89,31 @@ namespace {
// Ordenar por luminancia // Ordenar por luminancia
auto sortByLuminance(const Palette& palette) -> Palette { auto sortByLuminance(const Palette& palette) -> Palette {
const size_t n = countActiveColors(palette); const size_t N = countActiveColors(palette);
std::vector<Uint32> colors(palette.begin(), palette.begin() + static_cast<ptrdiff_t>(n)); std::vector<Uint32> colors(palette.begin(), palette.begin() + static_cast<ptrdiff_t>(N));
std::sort(colors.begin(), colors.end(), [](Uint32 a, Uint32 b) { std::ranges::sort(colors, [](Uint32 a, Uint32 b) {
return luminance(a) < luminance(b); return luminance(a) < luminance(b);
}); });
Palette result{}; Palette result{};
result.fill(0); result.fill(0);
std::copy(colors.begin(), colors.end(), result.begin()); std::ranges::copy(colors, result.begin());
return result; return result;
} }
// Ordenar por similitud con la paleta ZX Spectrum (greedy matching) // Ordenar por similitud con la paleta ZX Spectrum (greedy matching)
auto sortBySpectrum(const Palette& palette) -> Palette { auto sortBySpectrum(const Palette& palette) -> Palette {
const size_t n = countActiveColors(palette); const size_t N = countActiveColors(palette);
std::vector<Uint32> available(palette.begin(), palette.begin() + static_cast<ptrdiff_t>(n)); std::vector<Uint32> available(palette.begin(), palette.begin() + static_cast<ptrdiff_t>(N));
std::vector<Uint32> result; std::vector<Uint32> result;
result.reserve(n); result.reserve(N);
// Para cada color de referencia del Spectrum, buscar el más cercano disponible // Para cada color de referencia del Spectrum, buscar el más cercano disponible
const size_t refs = std::min(n, SPECTRUM_REFERENCE.size()); const size_t REFS = std::min(N, SPECTRUM_REFERENCE.size());
for (size_t i = 0; i < refs && !available.empty(); ++i) { for (size_t i = 0; i < REFS && !available.empty(); ++i) {
const Uint32 ref = SPECTRUM_REFERENCE[i]; const Uint32 REF = SPECTRUM_REFERENCE[i];
auto best = std::min_element(available.begin(), available.end(), [ref](Uint32 a, Uint32 b) { auto best = std::ranges::min_element(available, [REF](Uint32 a, Uint32 b) {
return rgbDistanceSq(a, ref) < rgbDistanceSq(b, ref); return rgbDistanceSq(a, REF) < rgbDistanceSq(b, REF);
}); });
result.push_back(*best); result.push_back(*best);
available.erase(best); available.erase(best);
@@ -126,7 +126,7 @@ namespace {
Palette out{}; Palette out{};
out.fill(0); out.fill(0);
std::copy(result.begin(), result.end(), out.begin()); std::ranges::copy(result, out.begin());
return out; return out;
} }
} // namespace } // namespace
@@ -149,9 +149,9 @@ PaletteManager::PaletteManager(
// Leer y aplicar paleta inicial directamente desde el archivo // Leer y aplicar paleta inicial directamente desde el archivo
// (Resource::Cache aún no está disponible en este punto del ciclo de vida) // (Resource::Cache aún no está disponible en este punto del ciclo de vida)
const auto initial_palette = sortPalette(readPalFile(palettes_.at(current_)), sort_mode_); const auto INITIAL_PALETTE = sortPalette(readPalFile(palettes_.at(current_)), sort_mode_);
game_surface_->setPalette(initial_palette); game_surface_->setPalette(INITIAL_PALETTE);
border_surface_->setPalette(initial_palette); border_surface_->setPalette(INITIAL_PALETTE);
// Procesar la lista: conservar solo los nombres de archivo (sin ruta) // Procesar la lista: conservar solo los nombres de archivo (sin ruta)
processPathList(); processPathList();
@@ -170,9 +170,9 @@ void PaletteManager::previous() {
} }
auto PaletteManager::setByName(const std::string& name) -> bool { auto PaletteManager::setByName(const std::string& name) -> bool {
const std::string lower_name = toLower(name + ".pal"); const std::string LOWER_NAME = toLower(name + ".pal");
for (size_t i = 0; i < palettes_.size(); ++i) { for (size_t i = 0; i < palettes_.size(); ++i) {
if (toLower(palettes_[i]) == lower_name) { if (toLower(palettes_[i]) == LOWER_NAME) {
current_ = i; current_ = i;
apply(); apply();
return true; return true;
@@ -186,8 +186,8 @@ auto PaletteManager::getNames() const -> std::vector<std::string> {
names.reserve(palettes_.size()); names.reserve(palettes_.size());
for (const auto& p : palettes_) { for (const auto& p : palettes_) {
std::string name = p; std::string name = p;
const size_t pos = name.find(".pal"); const size_t POS = name.find(".pal");
if (pos != std::string::npos) { name.erase(pos, 4); } if (POS != std::string::npos) { name.erase(POS, 4); }
std::ranges::transform(name, name.begin(), ::tolower); std::ranges::transform(name, name.begin(), ::tolower);
names.push_back(std::move(name)); names.push_back(std::move(name));
} }
@@ -196,8 +196,8 @@ auto PaletteManager::getNames() const -> std::vector<std::string> {
auto PaletteManager::getCurrentName() const -> std::string { auto PaletteManager::getCurrentName() const -> std::string {
std::string name = palettes_.at(current_); std::string name = palettes_.at(current_);
const size_t pos = name.find(".pal"); const size_t POS = name.find(".pal");
if (pos != std::string::npos) { name.erase(pos, 4); } if (POS != std::string::npos) { name.erase(POS, 4); }
std::ranges::transform(name, name.begin(), ::tolower); std::ranges::transform(name, name.begin(), ::tolower);
return name; return name;
} }
@@ -242,16 +242,16 @@ void PaletteManager::apply() {
} }
auto PaletteManager::findIndex(const std::string& name) const -> size_t { auto PaletteManager::findIndex(const std::string& name) const -> size_t {
const std::string lower_name = toLower(name + ".pal"); const std::string LOWER_NAME = toLower(name + ".pal");
for (size_t i = 0; i < palettes_.size(); ++i) { for (size_t i = 0; i < palettes_.size(); ++i) {
if (toLower(getFileName(palettes_[i])) == lower_name) { if (toLower(getFileName(palettes_[i])) == LOWER_NAME) {
return i; return i;
} }
} }
// Fallback: buscar la paleta por defecto // Fallback: buscar la paleta por defecto
const std::string default_name = toLower(std::string(Defaults::Video::PALETTE_NAME) + ".pal"); const std::string DEFAULT_NAME = toLower(std::string(Defaults::Video::PALETTE_NAME) + ".pal");
for (size_t i = 0; i < palettes_.size(); ++i) { for (size_t i = 0; i < palettes_.size(); ++i) {
if (toLower(getFileName(palettes_[i])) == default_name) { if (toLower(getFileName(palettes_[i])) == DEFAULT_NAME) {
return i; return i;
} }
} }

View File

@@ -85,7 +85,7 @@ void RenderInfo::render() const {
oss << std::fixed << std::setprecision(2) << ROUNDED; oss << std::fixed << std::setprecision(2) << ROUNDED;
zoom_str = oss.str(); zoom_str = oss.str();
if (zoom_str.back() == '0') { zoom_str.pop_back(); } if (zoom_str.back() == '0') { zoom_str.pop_back(); }
std::replace(zoom_str.begin(), zoom_str.end(), '.', ','); std::ranges::replace(zoom_str, '.', ',');
} }
line += " | " + zoom_str + "x"; line += " | " + zoom_str + "x";
@@ -108,13 +108,13 @@ void RenderInfo::render() const {
} }
// Todo en lowercase // Todo en lowercase
std::transform(line.begin(), line.end(), line.begin(), [](unsigned char c) { return std::tolower(c); }); std::ranges::transform(line, line.begin(), [](unsigned char c) { return std::tolower(c); });
// Constantes visuales (igual que Console) // Constantes visuales (igual que Console)
static constexpr Uint8 BG_COLOR = 0; // PaletteColor::BLACK static constexpr Uint8 BG_COLOR = 0; // PaletteColor::BLACK
static constexpr Uint8 MSG_COLOR = 9; // PaletteColor::BRIGHT_GREEN static constexpr Uint8 MSG_COLOR = 9; // PaletteColor::BRIGHT_GREEN
static constexpr int TEXT_SIZE = 6; static constexpr int TEXT_SIZE = 6;
static constexpr int PADDING_V = TEXT_SIZE / 2 - 1; static constexpr int PADDING_V = (TEXT_SIZE / 2) - 1;
// Fuente: preferir la de la consola si está disponible // Fuente: preferir la de la consola si está disponible
auto text_obj = (Console::get() != nullptr) ? Console::get()->getText() : Screen::get()->getText(); auto text_obj = (Console::get() != nullptr) ? Console::get()->getText() : Screen::get()->getText();

View File

@@ -209,7 +209,7 @@ auto Screen::setWindowZoom(int zoom) -> bool {
} }
// Devuelve el zoom máximo permitido según la pantalla actual // Devuelve el zoom máximo permitido según la pantalla actual
auto Screen::getMaxZoom() const -> int { auto Screen::getMaxZoom() -> int {
return Options::window.max_zoom; return Options::window.max_zoom;
} }
@@ -305,17 +305,19 @@ void Screen::adjustWindowSize() {
// Lógica de centrado y redimensionado de ventana SDL // Lógica de centrado y redimensionado de ventana SDL
if (static_cast<int>(Options::video.fullscreen) == 0) { if (static_cast<int>(Options::video.fullscreen) == 0) {
int old_w, old_h; int old_w;
int old_h;
SDL_GetWindowSize(window_, &old_w, &old_h); SDL_GetWindowSize(window_, &old_w, &old_h);
int old_x, old_y; int old_x;
int old_y;
SDL_GetWindowPosition(window_, &old_x, &old_y); SDL_GetWindowPosition(window_, &old_x, &old_y);
const int new_w = window_width_ * Options::window.zoom; const int NEW_W = window_width_ * Options::window.zoom;
const int new_h = window_height_ * Options::window.zoom; const int NEW_H = window_height_ * Options::window.zoom;
const int NEW_X = old_x + ((old_w - new_w) / 2); const int NEW_X = old_x + ((old_w - NEW_W) / 2);
const int NEW_Y = old_y + ((old_h - new_h) / 2); const int NEW_Y = old_y + ((old_h - NEW_H) / 2);
SDL_SetWindowSize(window_, new_w, new_h); SDL_SetWindowSize(window_, NEW_W, NEW_H);
// En Wayland, SDL_SetWindowPosition es ignorado por el compositor (limitación de // En Wayland, SDL_SetWindowPosition es ignorado por el compositor (limitación de
// protocolo: el compositor controla la posición de ventanas toplevel). Solo se // protocolo: el compositor controla la posición de ventanas toplevel). Solo se
@@ -324,8 +326,8 @@ void Screen::adjustWindowSize() {
// (evita el race condition en X11). // (evita el race condition en X11).
SDL_SyncWindow(window_); SDL_SyncWindow(window_);
const char* driver = SDL_GetCurrentVideoDriver(); const char* driver = SDL_GetCurrentVideoDriver();
const bool is_wayland = (driver != nullptr && SDL_strcmp(driver, "wayland") == 0); const bool IS_WAYLAND = (driver != nullptr && SDL_strcmp(driver, "wayland") == 0);
if (!is_wayland) { if (!IS_WAYLAND) {
SDL_SetWindowPosition(window_, std::max(NEW_X, WINDOWS_DECORATIONS), std::max(NEW_Y, 0)); SDL_SetWindowPosition(window_, std::max(NEW_X, WINDOWS_DECORATIONS), std::max(NEW_Y, 0));
} }
} }
@@ -348,7 +350,8 @@ void Screen::updateZoomFactor() {
zoom_factor_ = 1.0F; zoom_factor_ = 1.0F;
return; return;
} }
int pw{0}, ph{0}; int pw{0};
int ph{0};
SDL_GetRenderOutputSize(renderer_, &pw, &ph); SDL_GetRenderOutputSize(renderer_, &pw, &ph);
const float SCALE = std::min(static_cast<float>(pw) / static_cast<float>(window_width_), const float SCALE = std::min(static_cast<float>(pw) / static_cast<float>(window_width_),
static_cast<float>(ph) / static_cast<float>(window_height_)); static_cast<float>(ph) / static_cast<float>(window_height_));
@@ -401,7 +404,7 @@ void Screen::textureToRenderer() {
// Columnas laterales en las filas del área de juego // Columnas laterales en las filas del área de juego
for (int y = OFF_Y; y < OFF_Y + GAME_H; ++y) { for (int y = OFF_Y; y < OFF_Y + GAME_H; ++y) {
std::fill_n(&border_pixel_buffer_[y * BORDER_W], OFF_X, border_argb_color_); std::fill_n(&border_pixel_buffer_[y * BORDER_W], OFF_X, border_argb_color_);
std::fill_n(&border_pixel_buffer_[y * BORDER_W + OFF_X + GAME_W], std::fill_n(&border_pixel_buffer_[(y * BORDER_W) + OFF_X + GAME_W],
BORDER_W - OFF_X - GAME_W, BORDER_W - OFF_X - GAME_W,
border_argb_color_); border_argb_color_);
} }
@@ -415,7 +418,7 @@ void Screen::textureToRenderer() {
game_surface_->toARGBBuffer(game_pixel_buffer_.data()); game_surface_->toARGBBuffer(game_pixel_buffer_.data());
for (int y = 0; y < GAME_H; ++y) { for (int y = 0; y < GAME_H; ++y) {
const Uint32* src = &game_pixel_buffer_[y * GAME_W]; const Uint32* src = &game_pixel_buffer_[y * GAME_W];
Uint32* dst = &border_pixel_buffer_[(OFF_Y + y) * BORDER_W + OFF_X]; Uint32* dst = &border_pixel_buffer_[((OFF_Y + y) * BORDER_W) + OFF_X];
std::memcpy(dst, src, GAME_W * sizeof(Uint32)); std::memcpy(dst, src, GAME_W * sizeof(Uint32));
} }
@@ -606,8 +609,8 @@ void Screen::initShaders() {
if (!shader_backend_) { if (!shader_backend_) {
shader_backend_ = std::make_unique<Rendering::SDL3GPUShader>(); shader_backend_ = std::make_unique<Rendering::SDL3GPUShader>();
const std::string fallback_driver = "none"; const std::string FALLBACK_DRIVER = "none";
shader_backend_->setPreferredDriver(Options::video.gpu.acceleration ? Options::video.gpu.preferred_driver : fallback_driver); shader_backend_->setPreferredDriver(Options::video.gpu.acceleration ? Options::video.gpu.preferred_driver : FALLBACK_DRIVER);
} }
shader_backend_->init(window_, tex, "", ""); shader_backend_->init(window_, tex, "", "");
gpu_driver_ = shader_backend_->getDriverName(); gpu_driver_ = shader_backend_->getDriverName();

View File

@@ -87,7 +87,7 @@ class Screen {
[[nodiscard]] auto isHardwareAccelerated() const -> bool { return shader_backend_ && shader_backend_->isHardwareAccelerated(); } [[nodiscard]] auto isHardwareAccelerated() const -> bool { return shader_backend_ && shader_backend_->isHardwareAccelerated(); }
[[nodiscard]] auto getLastFPS() const -> int { return fps_.last_value; } [[nodiscard]] auto getLastFPS() const -> int { return fps_.last_value; }
[[nodiscard]] auto getZoomFactor() const -> float { return zoom_factor_; } [[nodiscard]] auto getZoomFactor() const -> float { return zoom_factor_; }
[[nodiscard]] auto getMaxZoom() const -> int; [[nodiscard]] static auto getMaxZoom() -> int;
[[nodiscard]] auto getSsTextureSize() const -> std::pair<int, int>; [[nodiscard]] auto getSsTextureSize() const -> std::pair<int, int>;
private: private:
@@ -166,7 +166,7 @@ class Screen {
// Configuración de ventana y pantalla // Configuración de ventana y pantalla
int window_width_{0}; // Ancho de la pantalla o ventana int window_width_{0}; // Ancho de la pantalla o ventana
int window_height_{0}; // Alto de la pantalla o ventana int window_height_{0}; // Alto de la pantalla o ventana
float zoom_factor_{1.0f}; // Factor de zoom calculado (alto físico / alto lógico) float zoom_factor_{1.0F}; // Factor de zoom calculado (alto físico / alto lógico)
SDL_FRect game_surface_dstrect_; // Coordenadas donde se dibuja la textura del juego SDL_FRect game_surface_dstrect_; // Coordenadas donde se dibuja la textura del juego
// Paletas y colores // Paletas y colores

View File

@@ -527,7 +527,7 @@ namespace Rendering {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// createPipeline // createPipeline
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
auto SDL3GPUShader::createPipeline() -> bool { auto SDL3GPUShader::createPipeline() -> bool { // NOLINT(readability-function-cognitive-complexity)
const SDL_GPUTextureFormat SWAPCHAIN_FMT = SDL_GetGPUSwapchainTextureFormat(device_, window_); const SDL_GPUTextureFormat SWAPCHAIN_FMT = SDL_GetGPUSwapchainTextureFormat(device_, window_);
// ---- PostFX pipeline (scene/scaled → swapchain) ---- // ---- PostFX pipeline (scene/scaled → swapchain) ----
@@ -770,7 +770,7 @@ namespace Rendering {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// render — upload scene texture + PostFX pass → swapchain // render — upload scene texture + PostFX pass → swapchain
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
void SDL3GPUShader::render() { void SDL3GPUShader::render() { // NOLINT(readability-function-cognitive-complexity)
if (!is_initialized_) { return; } if (!is_initialized_) { return; }
// Paso 0: si SS activo, calcular el factor necesario según el zoom actual y recrear si cambió. // Paso 0: si SS activo, calcular el factor necesario según el zoom actual y recrear si cambió.
@@ -868,9 +868,11 @@ namespace Rendering {
// pixel_scale: subpíxeles por pixel lógico. // pixel_scale: subpíxeles por pixel lógico.
// Sin SS: vh/game_height (zoom de ventana). // Sin SS: vh/game_height (zoom de ventana).
// Con SS: ss_factor_ exacto (3, 6, 9...). // Con SS: ss_factor_ exacto (3, 6, 9...).
uniforms_.pixel_scale = (oversample_ > 1 && ss_factor_ > 0) if (oversample_ > 1 && ss_factor_ > 0) {
? static_cast<float>(ss_factor_) uniforms_.pixel_scale = static_cast<float>(ss_factor_);
: ((game_height_ > 0) ? (vh / static_cast<float>(game_height_)) : 1.0F); } else {
uniforms_.pixel_scale = (game_height_ > 0) ? (vh / static_cast<float>(game_height_)) : 1.0F;
}
uniforms_.time = static_cast<float>(SDL_GetTicks()) / 1000.0F; uniforms_.time = static_cast<float>(SDL_GetTicks()) / 1000.0F;
uniforms_.oversample = (oversample_ > 1 && ss_factor_ > 0) uniforms_.oversample = (oversample_ > 1 && ss_factor_ > 0)
? static_cast<float>(ss_factor_) ? static_cast<float>(ss_factor_)
@@ -1266,8 +1268,8 @@ namespace Rendering {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
auto SDL3GPUShader::calcSsFactor(float zoom) -> int { auto SDL3GPUShader::calcSsFactor(float zoom) -> int {
const int MULTIPLE = 3; const int MULTIPLE = 3;
const int n = static_cast<int>(std::ceil(zoom / static_cast<float>(MULTIPLE))); const int N = static_cast<int>(std::ceil(zoom / static_cast<float>(MULTIPLE)));
return std::max(1, n) * MULTIPLE; return std::max(1, N) * MULTIPLE;
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@@ -177,10 +177,10 @@ void Surface::fillRect(const SDL_FRect* rect, Uint8 color) { // NOLINT(readabil
// Rellenar fila a fila con memset (memoria contigua por fila) // Rellenar fila a fila con memset (memoria contigua por fila)
Uint8* data_ptr = surface_data_->data.get(); Uint8* data_ptr = surface_data_->data.get();
const int surf_width = static_cast<int>(surface_data_->width); const int SURF_WIDTH = static_cast<int>(surface_data_->width);
const int row_width = static_cast<int>(x_end) - static_cast<int>(x_start); const int ROW_WIDTH = static_cast<int>(x_end) - static_cast<int>(x_start);
for (int y = static_cast<int>(y_start); y < static_cast<int>(y_end); ++y) { for (int y = static_cast<int>(y_start); y < static_cast<int>(y_end); ++y) {
std::memset(data_ptr + (y * surf_width) + static_cast<int>(x_start), color, row_width); std::memset(data_ptr + (y * SURF_WIDTH) + static_cast<int>(x_start), color, ROW_WIDTH);
} }
} }
@@ -194,10 +194,10 @@ void Surface::drawRectBorder(const SDL_FRect* rect, Uint8 color) { // NOLINT(re
// Dibujar bordes horizontales con memset (líneas contiguas en memoria) // Dibujar bordes horizontales con memset (líneas contiguas en memoria)
Uint8* data_ptr = surface_data_->data.get(); Uint8* data_ptr = surface_data_->data.get();
const int surf_width = static_cast<int>(surface_data_->width); const int SURF_WIDTH = static_cast<int>(surface_data_->width);
const int row_width = static_cast<int>(x_end) - static_cast<int>(x_start); const int ROW_WIDTH = static_cast<int>(x_end) - static_cast<int>(x_start);
std::memset(data_ptr + (static_cast<int>(y_start) * surf_width) + static_cast<int>(x_start), color, row_width); std::memset(data_ptr + (static_cast<int>(y_start) * SURF_WIDTH) + static_cast<int>(x_start), color, ROW_WIDTH);
std::memset(data_ptr + ((static_cast<int>(y_end) - 1) * surf_width) + static_cast<int>(x_start), color, row_width); std::memset(data_ptr + ((static_cast<int>(y_end) - 1) * SURF_WIDTH) + static_cast<int>(x_start), color, ROW_WIDTH);
// Dibujar bordes verticales // Dibujar bordes verticales
for (int y = y_start; y < y_end; ++y) { for (int y = y_start; y < y_end; ++y) {
@@ -525,7 +525,7 @@ void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height
// Vuelca los píxeles como ARGB8888 a un buffer externo (sin SDL_Texture ni SDL_Renderer) // Vuelca los píxeles como ARGB8888 a un buffer externo (sin SDL_Texture ni SDL_Renderer)
void Surface::toARGBBuffer(Uint32* buffer) const { void Surface::toARGBBuffer(Uint32* buffer) const {
if (!surface_data_ || !surface_data_->data || !buffer) { return; } if (!surface_data_ || !surface_data_->data || (buffer == nullptr)) { return; }
const int WIDTH = static_cast<int>(surface_data_->width); const int WIDTH = static_cast<int>(surface_data_->width);
const int HEIGHT = static_cast<int>(surface_data_->height); const int HEIGHT = static_cast<int>(surface_data_->height);
@@ -570,12 +570,12 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture) { //
// Cachear punteros fuera del bucle para permitir autovectorización SIMD // Cachear punteros fuera del bucle para permitir autovectorización SIMD
const Uint8* src = surface_data_->data.get(); const Uint8* src = surface_data_->data.get();
const Uint32* pal = palette_.data(); const Uint32* pal = palette_.data();
const int width = surface_data_->width; const int WIDTH = surface_data_->width;
const int height = surface_data_->height; const int HEIGHT = surface_data_->height;
for (int y = 0; y < height; ++y) { for (int y = 0; y < HEIGHT; ++y) {
const Uint8* src_row = src + (y * width); const Uint8* src_row = src + (y * WIDTH);
Uint32* dst_row = pixels + (y * row_stride); Uint32* dst_row = pixels + (y * row_stride);
for (int x = 0; x < width; ++x) { for (int x = 0; x < WIDTH; ++x) {
dst_row[x] = pal[src_row[x]]; dst_row[x] = pal[src_row[x]];
} }
} }
@@ -619,12 +619,12 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_FR
// Cachear punteros fuera del bucle para permitir autovectorización SIMD // Cachear punteros fuera del bucle para permitir autovectorización SIMD
const Uint8* src = surface_data_->data.get(); const Uint8* src = surface_data_->data.get();
const Uint32* pal = palette_.data(); const Uint32* pal = palette_.data();
const int width = surface_data_->width; const int WIDTH = surface_data_->width;
const int height = surface_data_->height; const int HEIGHT = surface_data_->height;
for (int y = 0; y < height; ++y) { for (int y = 0; y < HEIGHT; ++y) {
const Uint8* src_row = src + (y * width); const Uint8* src_row = src + (y * WIDTH);
Uint32* dst_row = pixels + (y * row_stride); Uint32* dst_row = pixels + (y * row_stride);
for (int x = 0; x < width; ++x) { for (int x = 0; x < WIDTH; ++x) {
dst_row[x] = pal[src_row[x]]; dst_row[x] = pal[src_row[x]];
} }
} }

View File

@@ -160,7 +160,7 @@ namespace Resource {
} }
// Carga recursos desde un string de configuración (para release con pack) // Carga recursos desde un string de configuración (para release con pack)
void List::loadFromString(const std::string& config_content, const std::string& prefix, const std::string& system_folder) { // NOLINT(readability-convert-member-functions-to-static) void List::loadFromString(const std::string& config_content, const std::string& prefix, const std::string& system_folder) { // NOLINT(readability-convert-member-functions-to-static,readability-function-cognitive-complexity)
try { try {
// Parsear YAML // Parsear YAML
auto yaml = fkyaml::node::deserialize(config_content); auto yaml = fkyaml::node::deserialize(config_content);

View File

@@ -50,7 +50,9 @@ Director::Director() {
// Obtiene la ruta del ejecutable // Obtiene la ruta del ejecutable
std::string base = SDL_GetBasePath(); std::string base = SDL_GetBasePath();
if (!base.empty() && base.back() == '/') base.pop_back(); if (!base.empty() && base.back() == '/') {
base.pop_back();
}
executable_path_ = base; executable_path_ = base;
// Crea la carpeta del sistema donde guardar datos // Crea la carpeta del sistema donde guardar datos

View File

@@ -3,6 +3,7 @@
#include "game/editor/editor_statusbar.hpp" #include "game/editor/editor_statusbar.hpp"
#include <string> // Para to_string #include <string> // Para to_string
#include <utility>
#include "core/rendering/screen.hpp" // Para Screen #include "core/rendering/screen.hpp" // Para Screen
#include "core/rendering/surface.hpp" // Para Surface #include "core/rendering/surface.hpp" // Para Surface
@@ -13,9 +14,9 @@
#include "utils/utils.hpp" // Para stringToColor, toLower #include "utils/utils.hpp" // Para stringToColor, toLower
// Constructor // Constructor
EditorStatusBar::EditorStatusBar(const std::string& room_number, const std::string& room_name) EditorStatusBar::EditorStatusBar(std::string room_number, std::string room_name)
: room_number_(room_number), : room_number_(std::move(room_number)),
room_name_(room_name) { room_name_(std::move(room_name)) {
const float SURFACE_WIDTH = Options::game.width; const float SURFACE_WIDTH = Options::game.width;
constexpr float SURFACE_HEIGHT = 6.0F * Tile::SIZE; // 48 pixels, igual que el scoreboard constexpr float SURFACE_HEIGHT = 6.0F * Tile::SIZE; // 48 pixels, igual que el scoreboard

View File

@@ -11,7 +11,7 @@ class Surface;
class EditorStatusBar { class EditorStatusBar {
public: public:
EditorStatusBar(const std::string& room_number, const std::string& room_name); EditorStatusBar(std::string room_number, std::string room_name);
~EditorStatusBar() = default; ~EditorStatusBar() = default;
void render(); void render();

View File

@@ -4,6 +4,7 @@
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <algorithm>
#include <cmath> // Para std::round #include <cmath> // Para std::round
#include <cstdio> // Para std::remove (borrar fichero) #include <cstdio> // Para std::remove (borrar fichero)
#include <fstream> // Para ifstream, ofstream #include <fstream> // Para ifstream, ofstream
@@ -88,7 +89,7 @@ void MapEditor::loadSettings() {
} }
// Guarda las opciones del editor a editor.yaml // Guarda las opciones del editor a editor.yaml
void MapEditor::saveSettings() { void MapEditor::saveSettings() const {
std::string path = Resource::List::get()->get("editor.yaml"); std::string path = Resource::List::get()->get("editor.yaml");
if (path.empty()) { return; } if (path.empty()) { return; }
@@ -332,7 +333,7 @@ void MapEditor::update(float delta_time) {
// Si estamos pintando tiles, pintar en la posición actual del ratón // Si estamos pintando tiles, pintar en la posición actual del ratón
if (painting_ && brush_tile_ != NO_BRUSH) { if (painting_ && brush_tile_ != NO_BRUSH) {
int tile_index = mouse_tile_y_ * 32 + mouse_tile_x_; int tile_index = (mouse_tile_y_ * 32) + mouse_tile_x_;
if (tile_index >= 0 && tile_index < static_cast<int>(room_data_.tile_map.size())) { if (tile_index >= 0 && tile_index < static_cast<int>(room_data_.tile_map.size())) {
if (room_data_.tile_map[tile_index] != brush_tile_) { if (room_data_.tile_map[tile_index] != brush_tile_) {
room_data_.tile_map[tile_index] = brush_tile_; room_data_.tile_map[tile_index] = brush_tile_;
@@ -382,7 +383,7 @@ void MapEditor::render() {
} }
// Maneja eventos del editor // Maneja eventos del editor
void MapEditor::handleEvent(const SDL_Event& event) { void MapEditor::handleEvent(const SDL_Event& event) { // NOLINT(readability-function-cognitive-complexity)
// Si el tile picker está abierto, los eventos van a él // Si el tile picker está abierto, los eventos van a él
if (tile_picker_.isOpen()) { if (tile_picker_.isOpen()) {
tile_picker_.handleEvent(event); tile_picker_.handleEvent(event);
@@ -426,7 +427,7 @@ void MapEditor::handleEvent(const SDL_Event& event) {
selected_item_ = -1; selected_item_ = -1;
// Tile bajo el cursor como tile actual del picker // Tile bajo el cursor como tile actual del picker
int tile_index = mouse_tile_y_ * 32 + mouse_tile_x_; int tile_index = (mouse_tile_y_ * 32) + mouse_tile_x_;
int current = (tile_index >= 0 && tile_index < static_cast<int>(room_data_.tile_map.size())) int current = (tile_index >= 0 && tile_index < static_cast<int>(room_data_.tile_map.size()))
? room_data_.tile_map[tile_index] ? room_data_.tile_map[tile_index]
: -1; : -1;
@@ -463,7 +464,7 @@ void MapEditor::handleEvent(const SDL_Event& event) {
if (!hit_entity) { if (!hit_entity) {
// Pintar tile y entrar en modo painting // Pintar tile y entrar en modo painting
painting_ = true; painting_ = true;
int tile_index = mouse_tile_y_ * 32 + mouse_tile_x_; int tile_index = (mouse_tile_y_ * 32) + mouse_tile_x_;
if (tile_index >= 0 && tile_index < static_cast<int>(room_data_.tile_map.size())) { if (tile_index >= 0 && tile_index < static_cast<int>(room_data_.tile_map.size())) {
room_data_.tile_map[tile_index] = brush_tile_; room_data_.tile_map[tile_index] = brush_tile_;
room_->setTile(tile_index, brush_tile_); room_->setTile(tile_index, brush_tile_);
@@ -487,7 +488,7 @@ void MapEditor::handleMouseDown(float game_x, float game_y) {
// Prioridad de hit test: jugador → enemigos (initial) → enemigos (boundaries) → items // Prioridad de hit test: jugador → enemigos (initial) → enemigos (boundaries) → items
// Helper para iniciar drag // Helper para iniciar drag
auto startDrag = [&](DragTarget target, int index, float entity_x, float entity_y) { auto start_drag = [&](DragTarget target, int index, float entity_x, float entity_y) {
drag_.target = target; drag_.target = target;
drag_.index = index; drag_.index = index;
drag_.offset_x = game_x - entity_x; drag_.offset_x = game_x - entity_x;
@@ -500,7 +501,7 @@ void MapEditor::handleMouseDown(float game_x, float game_y) {
// 1. Hit test sobre el jugador (8x16) // 1. Hit test sobre el jugador (8x16)
SDL_FRect player_rect = player_->getRect(); SDL_FRect player_rect = player_->getRect();
if (pointInRect(game_x, game_y, player_rect)) { if (pointInRect(game_x, game_y, player_rect)) {
startDrag(DragTarget::PLAYER, -1, player_rect.x, player_rect.y); start_drag(DragTarget::PLAYER, -1, player_rect.x, player_rect.y);
return; return;
} }
@@ -509,7 +510,7 @@ void MapEditor::handleMouseDown(float game_x, float game_y) {
for (int i = 0; i < enemy_mgr->getCount(); ++i) { for (int i = 0; i < enemy_mgr->getCount(); ++i) {
SDL_FRect enemy_rect = enemy_mgr->getEnemy(i)->getRect(); SDL_FRect enemy_rect = enemy_mgr->getEnemy(i)->getRect();
if (pointInRect(game_x, game_y, enemy_rect)) { if (pointInRect(game_x, game_y, enemy_rect)) {
startDrag(DragTarget::ENEMY_INITIAL, i, enemy_rect.x, enemy_rect.y); start_drag(DragTarget::ENEMY_INITIAL, i, enemy_rect.x, enemy_rect.y);
return; return;
} }
} }
@@ -517,17 +518,17 @@ void MapEditor::handleMouseDown(float game_x, float game_y) {
// 3. Hit test sobre boundaries de enemigos (rectángulos 8x8 en las posiciones de room_data_) // 3. Hit test sobre boundaries de enemigos (rectángulos 8x8 en las posiciones de room_data_)
for (int i = 0; i < static_cast<int>(room_data_.enemies.size()); ++i) { for (int i = 0; i < static_cast<int>(room_data_.enemies.size()); ++i) {
const auto& ed = room_data_.enemies[i]; const auto& ed = room_data_.enemies[i];
constexpr float SZ = static_cast<float>(Tile::SIZE); constexpr auto SZ = static_cast<float>(Tile::SIZE);
SDL_FRect b1_rect = {.x = static_cast<float>(ed.x1), .y = static_cast<float>(ed.y1), .w = SZ, .h = SZ}; SDL_FRect b1_rect = {.x = static_cast<float>(ed.x1), .y = static_cast<float>(ed.y1), .w = SZ, .h = SZ};
if (pointInRect(game_x, game_y, b1_rect)) { if (pointInRect(game_x, game_y, b1_rect)) {
startDrag(DragTarget::ENEMY_BOUND1, i, b1_rect.x, b1_rect.y); start_drag(DragTarget::ENEMY_BOUND1, i, b1_rect.x, b1_rect.y);
return; return;
} }
SDL_FRect b2_rect = {.x = static_cast<float>(ed.x2), .y = static_cast<float>(ed.y2), .w = SZ, .h = SZ}; SDL_FRect b2_rect = {.x = static_cast<float>(ed.x2), .y = static_cast<float>(ed.y2), .w = SZ, .h = SZ};
if (pointInRect(game_x, game_y, b2_rect)) { if (pointInRect(game_x, game_y, b2_rect)) {
startDrag(DragTarget::ENEMY_BOUND2, i, b2_rect.x, b2_rect.y); start_drag(DragTarget::ENEMY_BOUND2, i, b2_rect.x, b2_rect.y);
return; return;
} }
} }
@@ -537,7 +538,7 @@ void MapEditor::handleMouseDown(float game_x, float game_y) {
for (int i = 0; i < item_mgr->getCount(); ++i) { for (int i = 0; i < item_mgr->getCount(); ++i) {
SDL_FRect item_rect = item_mgr->getItem(i)->getCollider(); SDL_FRect item_rect = item_mgr->getItem(i)->getCollider();
if (pointInRect(game_x, game_y, item_rect)) { if (pointInRect(game_x, game_y, item_rect)) {
startDrag(DragTarget::ITEM, i, item_rect.x, item_rect.y); start_drag(DragTarget::ITEM, i, item_rect.x, item_rect.y);
return; return;
} }
} }
@@ -548,7 +549,7 @@ void MapEditor::handleMouseDown(float game_x, float game_y) {
} }
// Procesa soltar el ratón: commit del drag // Procesa soltar el ratón: commit del drag
void MapEditor::handleMouseUp() { void MapEditor::handleMouseUp() { // NOLINT(readability-function-cognitive-complexity)
if (drag_.target == DragTarget::NONE) { return; } if (drag_.target == DragTarget::NONE) { return; }
const int IDX = drag_.index; const int IDX = drag_.index;
@@ -681,7 +682,7 @@ void MapEditor::renderSelectionHighlight() {
auto game_surface = Screen::get()->getRendererSurface(); auto game_surface = Screen::get()->getRendererSurface();
if (!game_surface) { return; } if (!game_surface) { return; }
constexpr float SZ = static_cast<float>(Tile::SIZE); constexpr auto SZ = static_cast<float>(Tile::SIZE);
// Highlight del enemigo seleccionado (persistente, color bright_green) // Highlight del enemigo seleccionado (persistente, color bright_green)
if (selected_enemy_ >= 0 && selected_enemy_ < room_->getEnemyManager()->getCount()) { if (selected_enemy_ >= 0 && selected_enemy_ < room_->getEnemyManager()->getCount()) {
@@ -767,10 +768,10 @@ void MapEditor::renderEnemyBoundaries() {
// Posiciones base (pueden estar siendo arrastradas) // Posiciones base (pueden estar siendo arrastradas)
float init_x = enemy.x; float init_x = enemy.x;
float init_y = enemy.y; float init_y = enemy.y;
float b1_x = static_cast<float>(enemy.x1); auto b1_x = static_cast<float>(enemy.x1);
float b1_y = static_cast<float>(enemy.y1); auto b1_y = static_cast<float>(enemy.y1);
float b2_x = static_cast<float>(enemy.x2); auto b2_x = static_cast<float>(enemy.x2);
float b2_y = static_cast<float>(enemy.y2); auto b2_y = static_cast<float>(enemy.y2);
// Si estamos arrastrando una boundary de este enemigo, usar la posición snapped // Si estamos arrastrando una boundary de este enemigo, usar la posición snapped
if (drag_.index == i) { if (drag_.index == i) {
@@ -824,14 +825,14 @@ void MapEditor::updateMousePosition() {
mouse_tile_y_ = static_cast<int>(mouse_game_y_) / Tile::SIZE; mouse_tile_y_ = static_cast<int>(mouse_game_y_) / Tile::SIZE;
// Clampear a los límites del mapa // Clampear a los límites del mapa
if (mouse_tile_x_ < 0) { mouse_tile_x_ = 0; } mouse_tile_x_ = std::max(mouse_tile_x_, 0);
if (mouse_tile_x_ >= PlayArea::WIDTH / Tile::SIZE) { mouse_tile_x_ = PlayArea::WIDTH / Tile::SIZE - 1; } if (mouse_tile_x_ >= PlayArea::WIDTH / Tile::SIZE) { mouse_tile_x_ = PlayArea::WIDTH / Tile::SIZE - 1; }
if (mouse_tile_y_ < 0) { mouse_tile_y_ = 0; } mouse_tile_y_ = std::max(mouse_tile_y_, 0);
if (mouse_tile_y_ >= PlayArea::HEIGHT / Tile::SIZE) { mouse_tile_y_ = PlayArea::HEIGHT / Tile::SIZE - 1; } if (mouse_tile_y_ >= PlayArea::HEIGHT / Tile::SIZE) { mouse_tile_y_ = PlayArea::HEIGHT / Tile::SIZE - 1; }
} }
// Actualiza la información de la barra de estado // Actualiza la información de la barra de estado
void MapEditor::updateStatusBarInfo() { void MapEditor::updateStatusBarInfo() { // NOLINT(readability-function-cognitive-complexity)
if (!statusbar_) { return; } if (!statusbar_) { return; }
statusbar_->setMouseTile(mouse_tile_x_, mouse_tile_y_); statusbar_->setMouseTile(mouse_tile_x_, mouse_tile_y_);
@@ -944,7 +945,7 @@ auto MapEditor::getSetCompletions() const -> std::vector<std::string> {
} }
// Modifica una propiedad del enemigo seleccionado // Modifica una propiedad del enemigo seleccionado
auto MapEditor::setEnemyProperty(const std::string& property, const std::string& value) -> std::string { auto MapEditor::setEnemyProperty(const std::string& property, const std::string& value) -> std::string { // NOLINT(readability-function-cognitive-complexity)
if (!active_) { return "Editor not active"; } if (!active_) { return "Editor not active"; }
if (!hasSelectedEnemy()) { return "No enemy selected"; } if (!hasSelectedEnemy()) { return "No enemy selected"; }
@@ -1124,7 +1125,7 @@ auto MapEditor::duplicateEnemy() -> std::string {
} }
// Modifica una propiedad de la habitación // Modifica una propiedad de la habitación
auto MapEditor::setRoomProperty(const std::string& property, const std::string& value) -> std::string { auto MapEditor::setRoomProperty(const std::string& property, const std::string& value) -> std::string { // NOLINT(readability-function-cognitive-complexity)
if (!active_) { return "Editor not active"; } if (!active_) { return "Editor not active"; }
std::string val = toLower(value); std::string val = toLower(value);
@@ -1267,7 +1268,7 @@ auto MapEditor::setRoomProperty(const std::string& property, const std::string&
} }
// Crea una nueva habitación // Crea una nueva habitación
auto MapEditor::createNewRoom(const std::string& direction) -> std::string { auto MapEditor::createNewRoom(const std::string& direction) -> std::string { // NOLINT(readability-function-cognitive-complexity)
if (!active_) { return "Editor not active"; } if (!active_) { return "Editor not active"; }
// Validar dirección si se proporcionó // Validar dirección si se proporcionó
@@ -1340,7 +1341,7 @@ auto MapEditor::createNewRoom(const std::string& direction) -> std::string {
} }
// Conexiones del YAML // Conexiones del YAML
auto connStr = [](const std::string& c) -> std::string { return (c == "0") ? "null" : c; }; auto conn_str = [](const std::string& c) -> std::string { return (c == "0") ? "null" : c; };
// Crear el YAML // Crear el YAML
std::ofstream file(new_path); std::ofstream file(new_path);
@@ -1355,10 +1356,10 @@ auto MapEditor::createNewRoom(const std::string& direction) -> std::string {
file << " tileSetFile: standard.gif\n"; file << " tileSetFile: standard.gif\n";
file << "\n"; file << "\n";
file << " connections:\n"; file << " connections:\n";
file << " up: " << connStr(new_room.upper_room) << "\n"; file << " up: " << conn_str(new_room.upper_room) << "\n";
file << " down: " << connStr(new_room.lower_room) << "\n"; file << " down: " << conn_str(new_room.lower_room) << "\n";
file << " left: " << connStr(new_room.left_room) << "\n"; file << " left: " << conn_str(new_room.left_room) << "\n";
file << " right: " << connStr(new_room.right_room) << "\n"; file << " right: " << conn_str(new_room.right_room) << "\n";
file << "\n"; file << "\n";
file << " itemColor1: bright_cyan\n"; file << " itemColor1: bright_cyan\n";
file << " itemColor2: yellow\n"; file << " itemColor2: yellow\n";
@@ -1405,7 +1406,7 @@ auto MapEditor::createNewRoom(const std::string& direction) -> std::string {
} }
// Elimina la habitación actual // Elimina la habitación actual
auto MapEditor::deleteRoom() -> std::string { auto MapEditor::deleteRoom() -> std::string { // NOLINT(readability-function-cognitive-complexity)
if (!active_) { return "Editor not active"; } if (!active_) { return "Editor not active"; }
std::string deleted_name = room_path_; std::string deleted_name = room_path_;
@@ -1434,7 +1435,7 @@ auto MapEditor::deleteRoom() -> std::string {
if (target == "0") { return "Cannot delete: no other room to navigate to"; } if (target == "0") { return "Cannot delete: no other room to navigate to"; }
// Desenlazar todas las conexiones recíprocas // Desenlazar todas las conexiones recíprocas
auto unlinkReciprocal = [&](const std::string& neighbor, const std::string& field_name) { auto unlink_reciprocal = [&](const std::string& neighbor, const std::string& field_name) {
if (neighbor == "0" || neighbor.empty()) { return; } if (neighbor == "0" || neighbor.empty()) { return; }
auto other = Resource::Cache::get()->getRoom(neighbor); auto other = Resource::Cache::get()->getRoom(neighbor);
if (!other) { return; } if (!other) { return; }
@@ -1455,10 +1456,10 @@ auto MapEditor::deleteRoom() -> std::string {
} }
}; };
unlinkReciprocal(room_data_.upper_room, "lower_room"); // Si nosotros somos su lower unlink_reciprocal(room_data_.upper_room, "lower_room"); // Si nosotros somos su lower
unlinkReciprocal(room_data_.lower_room, "upper_room"); // Si nosotros somos su upper unlink_reciprocal(room_data_.lower_room, "upper_room"); // Si nosotros somos su upper
unlinkReciprocal(room_data_.left_room, "right_room"); // Si nosotros somos su right unlink_reciprocal(room_data_.left_room, "right_room"); // Si nosotros somos su right
unlinkReciprocal(room_data_.right_room, "left_room"); // Si nosotros somos su left unlink_reciprocal(room_data_.right_room, "left_room"); // Si nosotros somos su left
// Navegar a la room destino antes de borrar // Navegar a la room destino antes de borrar
reenter_ = true; reenter_ = true;
@@ -1473,9 +1474,7 @@ auto MapEditor::deleteRoom() -> std::string {
// Quitar del cache // Quitar del cache
auto& cache_rooms = Resource::Cache::get()->getRooms(); auto& cache_rooms = Resource::Cache::get()->getRooms();
cache_rooms.erase( std::erase_if(cache_rooms, [&](const RoomResource& r) { return r.name == deleted_name; });
std::remove_if(cache_rooms.begin(), cache_rooms.end(), [&](const RoomResource& r) { return r.name == deleted_name; }),
cache_rooms.end());
// Quitar de Resource::List (mapa + assets.yaml) // Quitar de Resource::List (mapa + assets.yaml)
Resource::List::get()->removeAsset(deleted_name); Resource::List::get()->removeAsset(deleted_name);
@@ -1598,7 +1597,7 @@ auto MapEditor::duplicateItem() -> std::string {
// Elige un color de grid que contraste con el fondo // Elige un color de grid que contraste con el fondo
// Empieza con bright_black (1), si coincide con el bg en la paleta activa, sube índices // Empieza con bright_black (1), si coincide con el bg en la paleta activa, sube índices
static auto pickGridColor(Uint8 bg, const std::shared_ptr<Surface>& surface) -> Uint8 { static auto pickGridColor(Uint8 bg, const std::shared_ptr<Surface>& surface) -> Uint8 {
Uint8 grid = static_cast<Uint8>(PaletteColor::BRIGHT_BLACK); auto grid = static_cast<Uint8>(PaletteColor::BRIGHT_BLACK);
Uint32 bg_argb = surface->getPaletteColor(bg); Uint32 bg_argb = surface->getPaletteColor(bg);
// Si bright_black es igual al bg, buscar el siguiente color distinto // Si bright_black es igual al bg, buscar el siguiente color distinto
@@ -1610,7 +1609,7 @@ static auto pickGridColor(Uint8 bg, const std::shared_ptr<Surface>& surface) ->
} }
// Dibuja la cuadrícula de tiles (líneas de puntos, 1 pixel sí / 1 no) // Dibuja la cuadrícula de tiles (líneas de puntos, 1 pixel sí / 1 no)
void MapEditor::renderGrid() { void MapEditor::renderGrid() const {
auto game_surface = Screen::get()->getRendererSurface(); auto game_surface = Screen::get()->getRendererSurface();
if (!game_surface) { return; } if (!game_surface) { return; }

View File

@@ -65,7 +65,7 @@ class MapEditor {
void openTilePicker(const std::string& tileset_name, int current_tile); void openTilePicker(const std::string& tileset_name, int current_tile);
private: private:
static MapEditor* instance_; // [SINGLETON] Objeto privado static MapEditor* instance_; // NOLINT(readability-identifier-naming) [SINGLETON] Objeto privado
MapEditor(); // Constructor MapEditor(); // Constructor
~MapEditor(); // Destructor ~MapEditor(); // Destructor
@@ -79,7 +79,7 @@ class MapEditor {
}; };
Settings settings_; Settings settings_;
void loadSettings(); void loadSettings();
void saveSettings(); void saveSettings() const;
// Tipos para drag & drop y selección // Tipos para drag & drop y selección
enum class DragTarget { NONE, enum class DragTarget { NONE,
@@ -102,9 +102,9 @@ class MapEditor {
// Métodos internos // Métodos internos
void updateMousePosition(); void updateMousePosition();
void renderEnemyBoundaries(); void renderEnemyBoundaries();
void renderBoundaryMarker(float x, float y, Uint8 color); static void renderBoundaryMarker(float x, float y, Uint8 color);
void renderSelectionHighlight(); void renderSelectionHighlight();
void renderGrid(); void renderGrid() const;
void handleMouseDown(float game_x, float game_y); void handleMouseDown(float game_x, float game_y);
void handleMouseUp(); void handleMouseUp();
void updateDrag(); void updateDrag();

View File

@@ -94,7 +94,7 @@ void MiniMap::layoutRooms() {
// Empezar por la primera room // Empezar por la primera room
const std::string& start = rooms[0].name; const std::string& start = rooms[0].name;
bfs.push({start, {0, 0}}); bfs.push({start, {.x = 0, .y = 0}});
visited.insert(start); visited.insert(start);
// Grid ocupado: posición → nombre de room // Grid ocupado: posición → nombre de room
@@ -120,21 +120,21 @@ void MiniMap::layoutRooms() {
int dx, dy; int dx, dy;
}; };
std::array<Neighbor, 4> neighbors = {{ std::array<Neighbor, 4> neighbors = {{
{data->upper_room, 0, -1}, {.room = data->upper_room, .dx = 0, .dy = -1},
{data->lower_room, 0, 1}, {.room = data->lower_room, .dx = 0, .dy = 1},
{data->left_room, -1, 0}, {.room = data->left_room, .dx = -1, .dy = 0},
{data->right_room, 1, 0}, {.room = data->right_room, .dx = 1, .dy = 0},
}}; }};
for (const auto& [neighbor_name, dx, dy] : neighbors) { for (const auto& [neighbor_name, dx, dy] : neighbors) {
if (neighbor_name == "0" || neighbor_name.empty()) { continue; } if (neighbor_name == "0" || neighbor_name.empty()) { continue; }
if (visited.contains(neighbor_name)) { continue; } if (visited.contains(neighbor_name)) { continue; }
GridPos neighbor_pos = {pos.x + dx, pos.y + dy}; GridPos neighbor_pos = {.x = pos.x + dx, .y = pos.y + dy};
auto nkey = std::make_pair(neighbor_pos.x, neighbor_pos.y); auto nkey = std::make_pair(neighbor_pos.x, neighbor_pos.y);
if (!grid_occupied.contains(nkey)) { if (!grid_occupied.contains(nkey)) {
visited.insert(neighbor_name); visited.insert(neighbor_name);
bfs.push({neighbor_name, neighbor_pos}); bfs.emplace(neighbor_name, neighbor_pos);
} }
} }
} }
@@ -181,7 +181,7 @@ auto MiniMap::getRoomMiniSurface(const std::string& room_name) -> std::shared_pt
const auto& tile_map = room_data->tile_map; const auto& tile_map = room_data->tile_map;
for (int y = 0; y < ROOM_H; ++y) { for (int y = 0; y < ROOM_H; ++y) {
for (int x = 0; x < ROOM_W; ++x) { for (int x = 0; x < ROOM_W; ++x) {
int index = y * ROOM_W + x; int index = (y * ROOM_W) + x;
if (index >= static_cast<int>(tile_map.size())) { continue; } if (index >= static_cast<int>(tile_map.size())) { continue; }
int tile = tile_map[index]; int tile = tile_map[index];
@@ -253,14 +253,14 @@ void MiniMap::drawConnections() {
// Conexión derecha // Conexión derecha
if (room_data->right_room != "0" && !room_data->right_room.empty() && room_positions_.contains(room_data->right_room)) { if (room_data->right_room != "0" && !room_data->right_room.empty() && room_positions_.contains(room_data->right_room)) {
int x1 = px + CELL_W; int x1 = px + CELL_W;
int y_mid = py + CELL_H / 2 - 1; int y_mid = py + (CELL_H / 2) - 1;
SDL_FRect line = {.x = static_cast<float>(x1), .y = static_cast<float>(y_mid), .w = static_cast<float>(GAP), .h = 3.0F}; SDL_FRect line = {.x = static_cast<float>(x1), .y = static_cast<float>(y_mid), .w = static_cast<float>(GAP), .h = 3.0F};
map_surface_->fillRect(&line, conn_color_); map_surface_->fillRect(&line, conn_color_);
} }
// Conexión abajo // Conexión abajo
if (room_data->lower_room != "0" && !room_data->lower_room.empty() && room_positions_.contains(room_data->lower_room)) { if (room_data->lower_room != "0" && !room_data->lower_room.empty() && room_positions_.contains(room_data->lower_room)) {
int x_mid = px + CELL_W / 2 - 1; int x_mid = px + (CELL_W / 2) - 1;
int y1 = py + CELL_H; int y1 = py + CELL_H;
SDL_FRect line = {.x = static_cast<float>(x_mid), .y = static_cast<float>(y1), .w = 3.0F, .h = static_cast<float>(GAP)}; SDL_FRect line = {.x = static_cast<float>(x_mid), .y = static_cast<float>(y1), .w = 3.0F, .h = static_cast<float>(GAP)};
map_surface_->fillRect(&line, conn_color_); map_surface_->fillRect(&line, conn_color_);
@@ -274,8 +274,8 @@ void MiniMap::centerOnRoom(const std::string& room_name) {
if (it == room_positions_.end()) { return; } if (it == room_positions_.end()) { return; }
const auto& pos = it->second.pos; const auto& pos = it->second.pos;
float room_cx = static_cast<float>(cellPixelX(pos.x) + CELL_W / 2); auto room_cx = static_cast<float>(cellPixelX(pos.x) + (CELL_W / 2));
float room_cy = static_cast<float>(cellPixelY(pos.y) + CELL_H / 2); auto room_cy = static_cast<float>(cellPixelY(pos.y) + (CELL_H / 2));
view_x_ = static_cast<float>(PlayArea::WIDTH) / 2.0F - room_cx; view_x_ = static_cast<float>(PlayArea::WIDTH) / 2.0F - room_cx;
view_y_ = static_cast<float>(PlayArea::HEIGHT) / 2.0F - room_cy; view_y_ = static_cast<float>(PlayArea::HEIGHT) / 2.0F - room_cy;
} }
@@ -287,8 +287,8 @@ auto MiniMap::roomAtScreen(float screen_x, float screen_y) -> std::string {
float map_y = screen_y - view_y_; float map_y = screen_y - view_y_;
for (const auto& [name, mini] : room_positions_) { for (const auto& [name, mini] : room_positions_) {
float rx = static_cast<float>(cellPixelX(mini.pos.x)); auto rx = static_cast<float>(cellPixelX(mini.pos.x));
float ry = static_cast<float>(cellPixelY(mini.pos.y)); auto ry = static_cast<float>(cellPixelY(mini.pos.y));
if (map_x >= rx && map_x < rx + CELL_W && map_y >= ry && map_y < ry + CELL_H) { if (map_x >= rx && map_x < rx + CELL_W && map_y >= ry && map_y < ry + CELL_H) {
return name; return name;
} }
@@ -314,8 +314,8 @@ void MiniMap::render(const std::string& current_room) {
if (it != room_positions_.end()) { if (it != room_positions_.end()) {
float cur_x = vx + static_cast<float>(cellPixelX(it->second.pos.x)) - 1; float cur_x = vx + static_cast<float>(cellPixelX(it->second.pos.x)) - 1;
float cur_y = vy + static_cast<float>(cellPixelY(it->second.pos.y)) - 1; float cur_y = vy + static_cast<float>(cellPixelY(it->second.pos.y)) - 1;
float cur_w = static_cast<float>(CELL_W + 2); auto cur_w = static_cast<float>(CELL_W + 2);
float cur_h = static_cast<float>(CELL_H + 2); auto cur_h = static_cast<float>(CELL_H + 2);
if (cur_x >= 0 && cur_y >= 0 && cur_x + cur_w <= PlayArea::WIDTH && cur_y + cur_h <= PlayArea::HEIGHT) { if (cur_x >= 0 && cur_y >= 0 && cur_x + cur_w <= PlayArea::WIDTH && cur_y + cur_h <= PlayArea::HEIGHT) {
SDL_FRect highlight = {.x = cur_x, .y = cur_y, .w = cur_w, .h = cur_h}; SDL_FRect highlight = {.x = cur_x, .y = cur_y, .w = cur_w, .h = cur_h};
game_surface->drawRectBorder(&highlight, stringToColor("bright_white")); game_surface->drawRectBorder(&highlight, stringToColor("bright_white"));

View File

@@ -54,8 +54,8 @@ class MiniMap {
auto getRoomMiniSurface(const std::string& room_name) -> std::shared_ptr<Surface>; auto getRoomMiniSurface(const std::string& room_name) -> std::shared_ptr<Surface>;
void drawConnections(); void drawConnections();
auto roomAtScreen(float screen_x, float screen_y) -> std::string; auto roomAtScreen(float screen_x, float screen_y) -> std::string;
auto cellPixelX(int grid_x) const -> int { return PADDING + (grid_x - min_grid_x_) * (CELL_W + GAP); } auto cellPixelX(int grid_x) const -> int { return PADDING + ((grid_x - min_grid_x_) * (CELL_W + GAP)); }
auto cellPixelY(int grid_y) const -> int { return PADDING + (grid_y - min_grid_y_) * (CELL_H + GAP); } auto cellPixelY(int grid_y) const -> int { return PADDING + ((grid_y - min_grid_y_) * (CELL_H + GAP)); }
// Tabla de color predominante por tile index // Tabla de color predominante por tile index
std::vector<Uint8> tile_colors_; // tile_index → palette color index std::vector<Uint8> tile_colors_; // tile_index → palette color index
@@ -84,11 +84,11 @@ class MiniMap {
float view_start_y_{0.0F}; float view_start_y_{0.0F};
// Constantes // Constantes
static constexpr int ROOM_W = 32; // Ancho de una room en pixels del minimapa static constexpr int ROOM_W = 32; // Ancho de una room en pixels del minimapa
static constexpr int ROOM_H = 16; // Alto de una room en pixels del minimapa static constexpr int ROOM_H = 16; // Alto de una room en pixels del minimapa
static constexpr int BORDER = 1; // Borde alrededor de cada room static constexpr int BORDER = 1; // Borde alrededor de cada room
static constexpr int CELL_W = ROOM_W + BORDER * 2; // Room + borde static constexpr int CELL_W = ROOM_W + (BORDER * 2); // Room + borde
static constexpr int CELL_H = ROOM_H + BORDER * 2; static constexpr int CELL_H = ROOM_H + (BORDER * 2);
static constexpr int GAP = 4; // Separación entre celdas static constexpr int GAP = 4; // Separación entre celdas
static constexpr int SHADOW_OFFSET = 1; // Desplazamiento de la sombra static constexpr int SHADOW_OFFSET = 1; // Desplazamiento de la sombra
static constexpr int PADDING = 4; // Padding alrededor del minimapa static constexpr int PADDING = 4; // Padding alrededor del minimapa

View File

@@ -36,7 +36,7 @@ auto RoomSaver::conveyorBeltToString(int direction) -> std::string {
} }
// Genera el YAML completo como texto con formato compacto // Genera el YAML completo como texto con formato compacto
auto RoomSaver::buildYAML(const fkyaml::node& original_yaml, const Room::Data& room_data) -> std::string { auto RoomSaver::buildYAML(const fkyaml::node& original_yaml, const Room::Data& room_data) -> std::string { // NOLINT(readability-function-cognitive-complexity)
std::ostringstream out; std::ostringstream out;
// --- Cabecera: nombre como comentario --- // --- Cabecera: nombre como comentario ---
@@ -49,9 +49,9 @@ auto RoomSaver::buildYAML(const fkyaml::node& original_yaml, const Room::Data& r
if (original_yaml.contains("room")) { if (original_yaml.contains("room")) {
const auto& room_node = original_yaml["room"]; const auto& room_node = original_yaml["room"];
for (auto it = room_node.begin(); it != room_node.end(); ++it) { for (auto it = room_node.begin(); it != room_node.end(); ++it) {
const std::string key = it.key().get_value<std::string>(); const auto KEY = it.key().get_value<std::string>();
if (key.substr(0, 5) == "name_") { if (KEY.substr(0, 5) == "name_") {
out << " " << key << ": \"" << it.value().get_value<std::string>() << "\"\n"; out << " " << KEY << ": \"" << it.value().get_value<std::string>() << "\"\n";
} }
} }
} }
@@ -90,7 +90,7 @@ auto RoomSaver::buildYAML(const fkyaml::node& original_yaml, const Room::Data& r
for (int row = 0; row < MAP_HEIGHT; ++row) { for (int row = 0; row < MAP_HEIGHT; ++row) {
out << " - ["; out << " - [";
for (int col = 0; col < MAP_WIDTH; ++col) { for (int col = 0; col < MAP_WIDTH; ++col) {
int index = row * MAP_WIDTH + col; int index = (row * MAP_WIDTH) + col;
if (index < static_cast<int>(room_data.tile_map.size())) { if (index < static_cast<int>(room_data.tile_map.size())) {
out << room_data.tile_map[index]; out << room_data.tile_map[index];
} else { } else {

View File

@@ -38,12 +38,12 @@ void TilePicker::open(const std::string& tileset_name, int current_tile, int bg_
// Dimensiones de salida (con spacing visual entre tiles) // Dimensiones de salida (con spacing visual entre tiles)
int out_cell = Tile::SIZE + spacing_out_; int out_cell = Tile::SIZE + spacing_out_;
int display_w = tileset_width_ * out_cell - spacing_out_; // Sin trailing int display_w = (tileset_width_ * out_cell) - spacing_out_; // Sin trailing
int display_h = tileset_height_ * out_cell - spacing_out_; int display_h = (tileset_height_ * out_cell) - spacing_out_;
// Frame: display + borde // Frame: display + borde
int frame_w = display_w + BORDER_PAD * 2; int frame_w = display_w + (BORDER_PAD * 2);
int frame_h = display_h + BORDER_PAD * 2; int frame_h = display_h + (BORDER_PAD * 2);
frame_surface_ = std::make_shared<Surface>(frame_w, frame_h); frame_surface_ = std::make_shared<Surface>(frame_w, frame_h);
// Componer: fondo + borde + tiles uno a uno // Componer: fondo + borde + tiles uno a uno
@@ -61,7 +61,7 @@ void TilePicker::open(const std::string& tileset_name, int current_tile, int bg_
frame_surface_->drawRectBorder(&inner, stringToColor("white")); frame_surface_->drawRectBorder(&inner, stringToColor("white"));
// Renderizar cada tile individualmente // Renderizar cada tile individualmente
constexpr float TS = static_cast<float>(Tile::SIZE); constexpr auto TS = static_cast<float>(Tile::SIZE);
for (int row = 0; row < tileset_height_; ++row) { for (int row = 0; row < tileset_height_; ++row) {
for (int col = 0; col < tileset_width_; ++col) { for (int col = 0; col < tileset_width_; ++col) {
// Fuente: posición en el tileset original // Fuente: posición en el tileset original
@@ -72,8 +72,8 @@ void TilePicker::open(const std::string& tileset_name, int current_tile, int bg_
.h = TS}; .h = TS};
// Destino: posición en el frame con spacing de salida // Destino: posición en el frame con spacing de salida
int dst_x = BORDER_PAD + col * out_cell; int dst_x = BORDER_PAD + (col * out_cell);
int dst_y = BORDER_PAD + row * out_cell; int dst_y = BORDER_PAD + (row * out_cell);
if (source_color >= 0 && target_color >= 0) { if (source_color >= 0 && target_color >= 0) {
tileset_->renderWithColorReplace(dst_x, dst_y, static_cast<Uint8>(source_color), static_cast<Uint8>(target_color), &src); tileset_->renderWithColorReplace(dst_x, dst_y, static_cast<Uint8>(source_color), static_cast<Uint8>(target_color), &src);
@@ -90,7 +90,7 @@ void TilePicker::open(const std::string& tileset_name, int current_tile, int bg_
// Centrar en el play area // Centrar en el play area
offset_x_ = (PlayArea::WIDTH - frame_w) / 2; offset_x_ = (PlayArea::WIDTH - frame_w) / 2;
int offset_y = (PlayArea::HEIGHT - frame_h) / 2; int offset_y = (PlayArea::HEIGHT - frame_h) / 2;
if (offset_y < 0) { offset_y = 0; } offset_y = std::max(offset_y, 0);
visible_height_ = PlayArea::HEIGHT; visible_height_ = PlayArea::HEIGHT;
@@ -143,7 +143,7 @@ void TilePicker::render() {
int out_cell = Tile::SIZE + spacing_out_; int out_cell = Tile::SIZE + spacing_out_;
float tileset_screen_x = frame_dst_.x + BORDER_PAD; float tileset_screen_x = frame_dst_.x + BORDER_PAD;
float tileset_screen_y = frame_dst_.y + BORDER_PAD - static_cast<float>(scroll_y_); float tileset_screen_y = frame_dst_.y + BORDER_PAD - static_cast<float>(scroll_y_);
constexpr float TS = static_cast<float>(Tile::SIZE); constexpr auto TS = static_cast<float>(Tile::SIZE);
// Highlight del tile bajo el cursor (blanco) // Highlight del tile bajo el cursor (blanco)
if (hover_tile_ >= 0) { if (hover_tile_ >= 0) {
@@ -190,7 +190,7 @@ void TilePicker::handleEvent(const SDL_Event& event) {
if (event.type == SDL_EVENT_MOUSE_WHEEL) { if (event.type == SDL_EVENT_MOUSE_WHEEL) {
scroll_y_ -= static_cast<int>(event.wheel.y) * Tile::SIZE * 2; scroll_y_ -= static_cast<int>(event.wheel.y) * Tile::SIZE * 2;
int max_scroll = static_cast<int>(frame_dst_.h) - visible_height_; int max_scroll = static_cast<int>(frame_dst_.h) - visible_height_;
if (max_scroll < 0) { max_scroll = 0; } max_scroll = std::max(max_scroll, 0);
scroll_y_ = std::clamp(scroll_y_, 0, max_scroll); scroll_y_ = std::clamp(scroll_y_, 0, max_scroll);
updateMousePosition(); updateMousePosition();
} }

View File

@@ -26,7 +26,7 @@ Enemy::Enemy(const Data& enemy)
const int FLIP = (should_flip_ && enemy.vx < 0.0F) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE; const int FLIP = (should_flip_ && enemy.vx < 0.0F) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
const int MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE; const int MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
sprite_->setFlip(static_cast<SDL_FlipMode>(FLIP | MIRROR)); sprite_->setFlip(static_cast<SDL_FlipMode>(FLIP | MIRROR)); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange) SDL flags are designed for bitwise OR
collider_ = getRect(); collider_ = getRect();
@@ -63,7 +63,7 @@ void Enemy::resetToInitialPosition(const Data& data) {
const int FLIP = (should_flip_ && data.vx < 0.0F) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE; const int FLIP = (should_flip_ && data.vx < 0.0F) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
const int MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE; const int MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
sprite_->setFlip(static_cast<SDL_FlipMode>(FLIP | MIRROR)); sprite_->setFlip(static_cast<SDL_FlipMode>(FLIP | MIRROR)); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange)
collider_ = getRect(); collider_ = getRect();
} }

View File

@@ -156,7 +156,7 @@ void Room::setItemColors(const std::string& color1, const std::string& color2) {
Uint8 c1 = stringToColor(color1); Uint8 c1 = stringToColor(color1);
Uint8 c2 = stringToColor(color2); Uint8 c2 = stringToColor(color2);
auto* item_mgr = item_manager_.get(); auto* item_mgr = item_manager_.get();
for (int i = 0; i < static_cast<int>(item_mgr->getCount()); ++i) { for (int i = 0; i < item_mgr->getCount(); ++i) {
item_mgr->getItem(i)->setColors(c1, c2); item_mgr->getItem(i)->setColors(c1, c2);
} }
} }

View File

@@ -23,8 +23,8 @@ Scoreboard::Scoreboard(std::shared_ptr<Data> data)
constexpr float SURFACE_HEIGHT = 6.0F * Tile::SIZE; constexpr float SURFACE_HEIGHT = 6.0F * Tile::SIZE;
// Reserva memoria para los objetos // Reserva memoria para los objetos
const std::string player_anim_path = Player::skinToAnimationPath(Options::game.player_skin); const std::string PLAYER_ANIM_PATH = Player::skinToAnimationPath(Options::game.player_skin);
const auto& player_animation_data = Resource::Cache::get()->getAnimationData(player_anim_path); const auto& player_animation_data = Resource::Cache::get()->getAnimationData(PLAYER_ANIM_PATH);
player_sprite_ = std::make_shared<AnimatedSprite>(player_animation_data); player_sprite_ = std::make_shared<AnimatedSprite>(player_animation_data);
player_sprite_->setCurrentAnimation("default"); player_sprite_->setCurrentAnimation("default");
@@ -78,8 +78,8 @@ auto Scoreboard::getTime() -> Scoreboard::ClockData { // NOLINT(readability-con
// Actualiza el sprite del jugador con la skin actual // Actualiza el sprite del jugador con la skin actual
void Scoreboard::refreshPlayerSkin() { void Scoreboard::refreshPlayerSkin() {
const std::string player_anim_path = Player::skinToAnimationPath(Options::game.player_skin); const std::string PLAYER_ANIM_PATH = Player::skinToAnimationPath(Options::game.player_skin);
const auto& player_animation_data = Resource::Cache::get()->getAnimationData(player_anim_path); const auto& player_animation_data = Resource::Cache::get()->getAnimationData(PLAYER_ANIM_PATH);
player_sprite_ = std::make_shared<AnimatedSprite>(player_animation_data); player_sprite_ = std::make_shared<AnimatedSprite>(player_animation_data);
player_sprite_->setCurrentAnimation("default"); player_sprite_->setCurrentAnimation("default");
} }

View File

@@ -359,8 +359,8 @@ namespace Options {
} }
if (sh_node.contains("current_shader")) { if (sh_node.contains("current_shader")) {
try { try {
const std::string s = sh_node["current_shader"].get_value<std::string>(); const auto S = sh_node["current_shader"].get_value<std::string>();
video.shader.current_shader = (s == "crtpi") ? Rendering::ShaderType::CRTPI : Rendering::ShaderType::POSTFX; video.shader.current_shader = (S == "crtpi") ? Rendering::ShaderType::CRTPI : Rendering::ShaderType::POSTFX;
} catch (...) { } catch (...) {
video.shader.current_shader = Rendering::ShaderType::POSTFX; video.shader.current_shader = Rendering::ShaderType::POSTFX;
} }
@@ -566,7 +566,7 @@ namespace Options {
} }
// Carga configuración de audio desde YAML // Carga configuración de audio desde YAML
void loadAudioConfigFromYaml(const fkyaml::node& yaml) { void loadAudioConfigFromYaml(const fkyaml::node& yaml) { // NOLINT(readability-function-cognitive-complexity)
if (!yaml.contains("audio")) { return; } if (!yaml.contains("audio")) { return; }
const auto& a = yaml["audio"]; const auto& a = yaml["audio"];
@@ -688,9 +688,9 @@ namespace Options {
// Helper: retorna el nombre del preset PostFX actual (para guardar en config) // Helper: retorna el nombre del preset PostFX actual (para guardar en config)
auto currentPostFXPresetName() -> std::string { auto currentPostFXPresetName() -> std::string {
const auto idx = static_cast<size_t>(video.shader.current_postfx_preset); const auto IDX = static_cast<size_t>(video.shader.current_postfx_preset);
if (idx < postfx_presets.size()) { if (IDX < postfx_presets.size()) {
return postfx_presets[idx].name; return postfx_presets[IDX].name;
} }
// Presets no cargados aún: devolver el nombre almacenado del config // Presets no cargados aún: devolver el nombre almacenado del config
return video.shader.current_postfx_preset_name; return video.shader.current_postfx_preset_name;
@@ -698,9 +698,9 @@ namespace Options {
// Helper: retorna el nombre del preset CrtPi actual (para guardar en config) // Helper: retorna el nombre del preset CrtPi actual (para guardar en config)
auto currentCrtPiPresetName() -> std::string { auto currentCrtPiPresetName() -> std::string {
const auto idx = static_cast<size_t>(video.shader.current_crtpi_preset); const auto IDX = static_cast<size_t>(video.shader.current_crtpi_preset);
if (idx < crtpi_presets.size()) { if (IDX < crtpi_presets.size()) {
return crtpi_presets[idx].name; return crtpi_presets[IDX].name;
} }
return video.shader.current_crtpi_preset_name; return video.shader.current_crtpi_preset_name;
} }
@@ -1021,17 +1021,17 @@ namespace Options {
} }
// Carga los presets del shader CrtPi desde el fichero. Crea defaults si no existe. // Carga los presets del shader CrtPi desde el fichero. Crea defaults si no existe.
auto loadCrtPiFromFile() -> bool { auto loadCrtPiFromFile() -> bool { // NOLINT(readability-function-cognitive-complexity)
crtpi_presets.clear(); crtpi_presets.clear();
std::ifstream file(crtpi_file_path); std::ifstream file(crtpi_file_path);
if (!file.good()) { if (!file.good()) {
std::cout << "CrtPi file not found, creating default: " << crtpi_file_path << '\n'; std::cout << "CrtPi file not found, creating default: " << crtpi_file_path << '\n';
// Crear directorio padre si no existe // Crear directorio padre si no existe
const std::filesystem::path p(crtpi_file_path); const std::filesystem::path P(crtpi_file_path);
if (p.has_parent_path()) { if (P.has_parent_path()) {
std::error_code ec; std::error_code ec;
std::filesystem::create_directories(p.parent_path(), ec); std::filesystem::create_directories(P.parent_path(), ec);
} }
// Escribir defaults // Escribir defaults
std::ofstream out(crtpi_file_path); std::ofstream out(crtpi_file_path);

View File

@@ -164,7 +164,7 @@ void Console::redrawText() {
} }
// Actualiza la animación de la consola // Actualiza la animación de la consola
void Console::update(float delta_time) { void Console::update(float delta_time) { // NOLINT(readability-function-cognitive-complexity)
if (status_ == Status::HIDDEN) { if (status_ == Status::HIDDEN) {
return; return;
} }
@@ -196,9 +196,9 @@ void Console::update(float delta_time) {
if (status_ == Status::ACTIVE && height_ != target_height_) { if (status_ == Status::ACTIVE && height_ != target_height_) {
const float PREV_HEIGHT = height_; const float PREV_HEIGHT = height_;
if (height_ < target_height_) { if (height_ < target_height_) {
height_ = std::min(height_ + SLIDE_SPEED * delta_time, target_height_); height_ = std::min(height_ + (SLIDE_SPEED * delta_time), target_height_);
} else { } else {
height_ = std::max(height_ - SLIDE_SPEED * delta_time, target_height_); height_ = std::max(height_ - (SLIDE_SPEED * delta_time), target_height_);
} }
// Actualizar el Notifier incrementalmente con el delta de altura // Actualizar el Notifier incrementalmente con el delta de altura
if (Notifier::get() != nullptr) { if (Notifier::get() != nullptr) {
@@ -300,7 +300,7 @@ void Console::toggle() {
} }
// Procesa el evento SDL: entrada de texto, Backspace, Enter // Procesa el evento SDL: entrada de texto, Backspace, Enter
void Console::handleEvent(const SDL_Event& event) { void Console::handleEvent(const SDL_Event& event) { // NOLINT(readability-function-cognitive-complexity)
if (status_ != Status::ACTIVE) { return; } if (status_ != Status::ACTIVE) { return; }
if (event.type == SDL_EVENT_TEXT_INPUT) { if (event.type == SDL_EVENT_TEXT_INPUT) {
@@ -348,8 +348,8 @@ void Console::handleEvent(const SDL_Event& event) {
std::string upper; std::string upper;
for (unsigned char c : input_line_) { upper += static_cast<char>(std::toupper(c)); } for (unsigned char c : input_line_) { upper += static_cast<char>(std::toupper(c)); }
const size_t space_pos = upper.rfind(' '); const size_t SPACE_POS = upper.rfind(' ');
if (space_pos == std::string::npos) { if (SPACE_POS == std::string::npos) {
// Modo comando: ciclar keywords visibles que empiecen por el prefijo // Modo comando: ciclar keywords visibles que empiecen por el prefijo
for (const auto& kw : registry_.getVisibleKeywords()) { for (const auto& kw : registry_.getVisibleKeywords()) {
if (upper.empty() || kw.starts_with(upper)) { if (upper.empty() || kw.starts_with(upper)) {
@@ -357,12 +357,12 @@ void Console::handleEvent(const SDL_Event& event) {
} }
} }
} else { } else {
const std::string base_cmd = upper.substr(0, space_pos); const std::string BASE_CMD = upper.substr(0, SPACE_POS);
const std::string sub_prefix = upper.substr(space_pos + 1); const std::string SUB_PREFIX = upper.substr(SPACE_POS + 1);
const auto opts = registry_.getCompletions(base_cmd); const auto OPTS = registry_.getCompletions(BASE_CMD);
for (const auto& arg : opts) { for (const auto& arg : OPTS) {
if (sub_prefix.empty() || std::string_view{arg}.starts_with(sub_prefix)) { if (SUB_PREFIX.empty() || std::string_view{arg}.starts_with(SUB_PREFIX)) {
tab_matches_.emplace_back(base_cmd + " " + arg); tab_matches_.emplace_back(BASE_CMD + " " + arg);
} }
} }
} }

View File

@@ -55,7 +55,7 @@ static auto boolToggle(
// ── Command handlers ───────────────────────────────────────────────────────── // ── Command handlers ─────────────────────────────────────────────────────────
// SS [ON|OFF|SIZE|UPSCALE [NEAREST|LINEAR]|DOWNSCALE [BILINEAR|LANCZOS2|LANCZOS3]] // SS [ON|OFF|SIZE|UPSCALE [NEAREST|LINEAR]|DOWNSCALE [BILINEAR|LANCZOS2|LANCZOS3]]
static auto cmd_ss(const std::vector<std::string>& args) -> std::string { static auto cmdSs(const std::vector<std::string>& args) -> std::string { // NOLINT(readability-function-cognitive-complexity)
if (!Screen::get()->isHardwareAccelerated()) { return "No GPU acceleration"; } if (!Screen::get()->isHardwareAccelerated()) { return "No GPU acceleration"; }
static const std::array<std::string_view, 3> DOWNSCALE_NAMES = {"Bilinear", "Lanczos2", "Lanczos3"}; static const std::array<std::string_view, 3> DOWNSCALE_NAMES = {"Bilinear", "Lanczos2", "Lanczos3"};
if (!args.empty() && args[0] == "SIZE") { if (!args.empty() && args[0] == "SIZE") {
@@ -118,34 +118,34 @@ static auto applyPreset(const std::vector<std::string>& args) -> std::string {
const bool IS_CRTPI = Options::video.shader.current_shader == Rendering::ShaderType::CRTPI; const bool IS_CRTPI = Options::video.shader.current_shader == Rendering::ShaderType::CRTPI;
const auto& presets_postfx = Options::postfx_presets; const auto& presets_postfx = Options::postfx_presets;
const auto& presets_crtpi = Options::crtpi_presets; const auto& presets_crtpi = Options::crtpi_presets;
const std::string shader_label = IS_CRTPI ? "CrtPi" : "PostFX"; const std::string SHADER_LABEL = IS_CRTPI ? "CrtPi" : "PostFX";
auto& current_idx = IS_CRTPI ? Options::video.shader.current_crtpi_preset auto& current_idx = IS_CRTPI ? Options::video.shader.current_crtpi_preset
: Options::video.shader.current_postfx_preset; : Options::video.shader.current_postfx_preset;
const int count = static_cast<int>(IS_CRTPI ? presets_crtpi.size() : presets_postfx.size()); const int COUNT = static_cast<int>(IS_CRTPI ? presets_crtpi.size() : presets_postfx.size());
if (count == 0) { return "No " + shader_label + " presets available"; } if (COUNT == 0) { return "No " + SHADER_LABEL + " presets available"; }
const auto presetName = [&]() -> std::string { const auto PRESET_NAME = [&]() -> std::string {
const auto& name = IS_CRTPI ? presets_crtpi[static_cast<size_t>(current_idx)].name const auto& name = IS_CRTPI ? presets_crtpi[static_cast<size_t>(current_idx)].name // NOLINT(clang-analyzer-core.CallAndMessage)
: presets_postfx[static_cast<size_t>(current_idx)].name; : presets_postfx[static_cast<size_t>(current_idx)].name; // NOLINT(clang-analyzer-core.CallAndMessage)
return prettyName(name); return prettyName(name);
}; };
if (args.empty()) { if (args.empty()) {
return shader_label + " preset: " + presetName(); return SHADER_LABEL + " preset: " + PRESET_NAME();
} }
if (args[0] == "NEXT") { if (args[0] == "NEXT") {
current_idx = (current_idx + 1) % count; current_idx = (current_idx + 1) % COUNT;
} else if (args[0] == "PREV") { } else if (args[0] == "PREV") {
current_idx = (current_idx - 1 + count) % count; current_idx = (current_idx - 1 + COUNT) % COUNT;
} else { } else {
// Buscar por nombre (case-insensitive, con guiones) // Buscar por nombre (case-insensitive, con guiones)
std::string search = args[0]; std::string search = args[0];
std::ranges::transform(search, search.begin(), ::toupper); std::ranges::transform(search, search.begin(), ::toupper);
bool found = false; bool found = false;
for (int i = 0; i < count; ++i) { for (int i = 0; i < COUNT; ++i) {
const auto& name = IS_CRTPI ? presets_crtpi[static_cast<size_t>(i)].name const auto& name = IS_CRTPI ? presets_crtpi[static_cast<size_t>(i)].name
: presets_postfx[static_cast<size_t>(i)].name; : presets_postfx[static_cast<size_t>(i)].name;
if (toUpper(name) == search) { if (toUpper(name) == search) {
@@ -166,11 +166,11 @@ static auto applyPreset(const std::vector<std::string>& args) -> std::string {
} else { } else {
Screen::get()->reloadPostFX(); Screen::get()->reloadPostFX();
} }
return shader_label + " preset: " + presetName(); return SHADER_LABEL + " preset: " + PRESET_NAME();
} }
// SHADER [ON|OFF|NEXT|POSTFX|CRTPI|PRESET [NEXT|PREV|<name>]] // SHADER [ON|OFF|NEXT|POSTFX|CRTPI|PRESET [NEXT|PREV|<name>]]
static auto cmd_shader(const std::vector<std::string>& args) -> std::string { static auto cmdShader(const std::vector<std::string>& args) -> std::string {
if (!Screen::get()->isHardwareAccelerated()) { return "No GPU acceleration"; } if (!Screen::get()->isHardwareAccelerated()) { return "No GPU acceleration"; }
if (args.empty()) { if (args.empty()) {
Screen::get()->toggleShaders(); Screen::get()->toggleShaders();
@@ -200,19 +200,19 @@ static auto cmd_shader(const std::vector<std::string>& args) -> std::string {
(Options::video.shader.current_shader == Rendering::ShaderType::CRTPI ? "CrtPi" : "PostFX"); (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI ? "CrtPi" : "PostFX");
} }
if (args[0] == "PRESET") { if (args[0] == "PRESET") {
const std::vector<std::string> rest(args.begin() + 1, args.end()); const std::vector<std::string> REST(args.begin() + 1, args.end());
return applyPreset(rest); return applyPreset(REST);
} }
return "usage: shader [on|off|next|postfx|crtpi|preset [next|prev|<name>]]"; return "usage: shader [on|off|next|postfx|crtpi|preset [next|prev|<name>]]";
} }
// BORDER [ON|OFF] // BORDER [ON|OFF]
static auto cmd_border(const std::vector<std::string>& args) -> std::string { static auto cmdBorder(const std::vector<std::string>& args) -> std::string {
return boolToggle("Border", Options::video.border.enabled, [] { Screen::get()->toggleBorder(); }, args); return boolToggle("Border", Options::video.border.enabled, [] { Screen::get()->toggleBorder(); }, args);
} }
// FULLSCREEN [ON|OFF [PLEASE]] // FULLSCREEN [ON|OFF [PLEASE]]
static auto cmd_fullscreen(const std::vector<std::string>& args) -> std::string { static auto cmdFullscreen(const std::vector<std::string>& args) -> std::string {
const bool EXPLICIT_ON = !args.empty() && args[0] == "ON"; const bool EXPLICIT_ON = !args.empty() && args[0] == "ON";
const bool EXPLICIT_OFF = !args.empty() && args[0] == "OFF"; const bool EXPLICIT_OFF = !args.empty() && args[0] == "OFF";
const bool WITH_PLEASE = !args.empty() && args.back() == "PLEASE"; const bool WITH_PLEASE = !args.empty() && args.back() == "PLEASE";
@@ -240,8 +240,8 @@ static auto cmd_fullscreen(const std::vector<std::string>& args) -> std::string
} }
// ZOOM UP/DOWN/<num> // ZOOM UP/DOWN/<num>
static auto cmd_zoom(const std::vector<std::string>& args) -> std::string { static auto cmdZoom(const std::vector<std::string>& args) -> std::string {
if (args.empty()) { return "usage: zoom [up|down|<1-" + std::to_string(Screen::get()->getMaxZoom()) + ">]"; } if (args.empty()) { return "usage: zoom [up|down|<1-" + std::to_string(Screen::getMaxZoom()) + ">]"; }
if (args[0] == "UP") { if (args[0] == "UP") {
if (!Screen::get()->incWindowZoom()) { return "Max zoom reached"; } if (!Screen::get()->incWindowZoom()) { return "Max zoom reached"; }
return "Zoom " + std::to_string(Options::window.zoom); return "Zoom " + std::to_string(Options::window.zoom);
@@ -252,7 +252,7 @@ static auto cmd_zoom(const std::vector<std::string>& args) -> std::string {
} }
try { try {
const int N = std::stoi(args[0]); const int N = std::stoi(args[0]);
const int MAX = Screen::get()->getMaxZoom(); const int MAX = Screen::getMaxZoom();
if (N < 1 || N > MAX) { if (N < 1 || N > MAX) {
return "Zoom must be between 1 and " + std::to_string(MAX); return "Zoom must be between 1 and " + std::to_string(MAX);
} }
@@ -260,11 +260,11 @@ static auto cmd_zoom(const std::vector<std::string>& args) -> std::string {
Screen::get()->setWindowZoom(N); Screen::get()->setWindowZoom(N);
return "Zoom " + std::to_string(Options::window.zoom); return "Zoom " + std::to_string(Options::window.zoom);
} catch (...) {} } catch (...) {}
return "usage: zoom [up|down|<1-" + std::to_string(Screen::get()->getMaxZoom()) + ">]"; return "usage: zoom [up|down|<1-" + std::to_string(Screen::getMaxZoom()) + ">]";
} }
// INTSCALE [ON|OFF] // INTSCALE [ON|OFF]
static auto cmd_intscale(const std::vector<std::string>& args) -> std::string { static auto cmdIntscale(const std::vector<std::string>& args) -> std::string {
const bool ON = args.empty() ? !Options::video.integer_scale const bool ON = args.empty() ? !Options::video.integer_scale
: (args[0] == "ON"); : (args[0] == "ON");
if (!args.empty() && args[0] != "ON" && args[0] != "OFF") { if (!args.empty() && args[0] != "ON" && args[0] != "OFF") {
@@ -279,12 +279,12 @@ static auto cmd_intscale(const std::vector<std::string>& args) -> std::string {
} }
// VSYNC [ON|OFF] // VSYNC [ON|OFF]
static auto cmd_vsync(const std::vector<std::string>& args) -> std::string { static auto cmdVsync(const std::vector<std::string>& args) -> std::string {
return boolToggle("VSync", Options::video.vertical_sync, [] { Screen::get()->toggleVSync(); }, args); return boolToggle("VSync", Options::video.vertical_sync, [] { Screen::get()->toggleVSync(); }, args);
} }
// DRIVER [LIST|AUTO|NONE|<name>] // DRIVER [LIST|AUTO|NONE|<name>]
static auto cmd_driver(const std::vector<std::string>& args) -> std::string { static auto cmdDriver(const std::vector<std::string>& args) -> std::string {
if (args.empty()) { if (args.empty()) {
const auto& driver = Screen::get()->getGPUDriver(); const auto& driver = Screen::get()->getGPUDriver();
return "GPU: " + (driver.empty() ? std::string("sdl") : driver); return "GPU: " + (driver.empty() ? std::string("sdl") : driver);
@@ -336,22 +336,22 @@ static auto cmd_driver(const std::vector<std::string>& args) -> std::string {
} }
// PALETTE NEXT/PREV/SORT/DEFAULT/<name> // PALETTE NEXT/PREV/SORT/DEFAULT/<name>
static auto cmd_palette(const std::vector<std::string>& args) -> std::string { static auto cmdPalette(const std::vector<std::string>& args) -> std::string {
const auto palName = []() -> std::string { const auto PAL_NAME = []() -> std::string {
return Screen::get()->getPalettePrettyName(); return Screen::get()->getPalettePrettyName();
}; };
if (args.empty()) { return "usage: palette [next|prev|sort [original|luminance|spectrum]|default|<name>]"; } if (args.empty()) { return "usage: palette [next|prev|sort [original|luminance|spectrum]|default|<name>]"; }
if (args[0] == "NEXT") { if (args[0] == "NEXT") {
Screen::get()->nextPalette(); Screen::get()->nextPalette();
return "Palette: " + palName(); return "Palette: " + PAL_NAME();
} }
if (args[0] == "PREV") { if (args[0] == "PREV") {
Screen::get()->previousPalette(); Screen::get()->previousPalette();
return "Palette: " + palName(); return "Palette: " + PAL_NAME();
} }
if (args[0] == "DEFAULT") { if (args[0] == "DEFAULT") {
Screen::get()->setPaletteByName(Defaults::Video::PALETTE_NAME); Screen::get()->setPaletteByName(Defaults::Video::PALETTE_NAME);
return "Palette: " + palName(); return "Palette: " + PAL_NAME();
} }
if (args[0] == "SORT") { if (args[0] == "SORT") {
if (args.size() == 1) { if (args.size() == 1) {
@@ -374,11 +374,11 @@ static auto cmd_palette(const std::vector<std::string>& args) -> std::string {
std::ranges::transform(arg_lower, arg_lower.begin(), ::tolower); std::ranges::transform(arg_lower, arg_lower.begin(), ::tolower);
return "Unknown palette: " + arg_lower; return "Unknown palette: " + arg_lower;
} }
return "Palette: " + palName(); return "Palette: " + PAL_NAME();
} }
// AUDIO [ON|OFF|VOL <0-100>] // AUDIO [ON|OFF|VOL <0-100>]
static auto cmd_audio(const std::vector<std::string>& args) -> std::string { static auto cmdAudio(const std::vector<std::string>& args) -> std::string {
if (args.empty()) { if (args.empty()) {
const int VOL = static_cast<int>(Options::audio.volume * 100.0F); const int VOL = static_cast<int>(Options::audio.volume * 100.0F);
return std::string("Audio ") + (Options::audio.enabled ? "ON" : "OFF") + return std::string("Audio ") + (Options::audio.enabled ? "ON" : "OFF") +
@@ -409,7 +409,7 @@ static auto cmd_audio(const std::vector<std::string>& args) -> std::string {
} }
// MUSIC [ON|OFF|VOL <0-100>] // MUSIC [ON|OFF|VOL <0-100>]
static auto cmd_music(const std::vector<std::string>& args) -> std::string { static auto cmdMusic(const std::vector<std::string>& args) -> std::string {
if (args.empty()) { if (args.empty()) {
const int VOL = static_cast<int>(Options::audio.music.volume * 100.0F); const int VOL = static_cast<int>(Options::audio.music.volume * 100.0F);
return std::string("Music ") + (Options::audio.music.enabled ? "ON" : "OFF") + return std::string("Music ") + (Options::audio.music.enabled ? "ON" : "OFF") +
@@ -444,7 +444,7 @@ static auto cmd_music(const std::vector<std::string>& args) -> std::string {
} }
// SOUND [ON|OFF|VOL <0-100>] // SOUND [ON|OFF|VOL <0-100>]
static auto cmd_sound(const std::vector<std::string>& args) -> std::string { static auto cmdSound(const std::vector<std::string>& args) -> std::string {
if (args.empty()) { if (args.empty()) {
const int VOL = static_cast<int>(Options::audio.sound.volume * 100.0F); const int VOL = static_cast<int>(Options::audio.sound.volume * 100.0F);
return std::string("Sound ") + (Options::audio.sound.enabled ? "ON" : "OFF") + return std::string("Sound ") + (Options::audio.sound.enabled ? "ON" : "OFF") +
@@ -480,7 +480,7 @@ static auto cmd_sound(const std::vector<std::string>& args) -> std::string {
#ifdef _DEBUG #ifdef _DEBUG
// DEBUG [MODE [ON|OFF]|START [HERE|ROOM|POS|SCENE <name>]] // DEBUG [MODE [ON|OFF]|START [HERE|ROOM|POS|SCENE <name>]]
static auto cmd_debug(const std::vector<std::string>& args) -> std::string { static auto cmdDebug(const std::vector<std::string>& args) -> std::string { // NOLINT(readability-function-cognitive-complexity)
// --- START subcommands (START SCENE works from any scene) --- // --- START subcommands (START SCENE works from any scene) ---
if (!args.empty() && args[0] == "START") { if (!args.empty() && args[0] == "START") {
// START SCENE [<name>] — works from any scene // START SCENE [<name>] — works from any scene
@@ -566,7 +566,7 @@ static auto cmd_debug(const std::vector<std::string>& args) -> std::string {
static auto changeRoomWithEditor(const std::string& room_file) -> std::string { static auto changeRoomWithEditor(const std::string& room_file) -> std::string {
if (!GameControl::change_room) { return "Game not initialized"; } if (!GameControl::change_room) { return "Game not initialized"; }
const bool EDITOR_WAS_ACTIVE = MapEditor::get() && MapEditor::get()->isActive(); const bool EDITOR_WAS_ACTIVE = (MapEditor::get() != nullptr) && MapEditor::get()->isActive();
// Si el editor está activo, salir primero (guarda y recarga la room actual) // Si el editor está activo, salir primero (guarda y recarga la room actual)
if (EDITOR_WAS_ACTIVE && GameControl::exit_editor) { if (EDITOR_WAS_ACTIVE && GameControl::exit_editor) {
@@ -591,19 +591,19 @@ static auto changeRoomWithEditor(const std::string& room_file) -> std::string {
return std::string("Room: ") + room_file; return std::string("Room: ") + room_file;
} }
static auto cmd_room(const std::vector<std::string>& args) -> std::string { static auto cmdRoom(const std::vector<std::string>& args) -> std::string { // NOLINT(readability-function-cognitive-complexity)
if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; } if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; }
if (args.empty()) { return "usage: room <1-60>|next|prev|left|right|up|down"; } if (args.empty()) { return "usage: room <1-60>|next|prev|left|right|up|down"; }
// DELETE: borrar la habitación actual // DELETE: borrar la habitación actual
if (args[0] == "DELETE") { if (args[0] == "DELETE") {
if (!MapEditor::get() || !MapEditor::get()->isActive()) { return "Editor not active"; } if ((MapEditor::get() == nullptr) || !MapEditor::get()->isActive()) { return "Editor not active"; }
return MapEditor::get()->deleteRoom(); return MapEditor::get()->deleteRoom();
} }
// NEW [LEFT|RIGHT|UP|DOWN]: crear habitación nueva (opcionalmente conectada) // NEW [LEFT|RIGHT|UP|DOWN]: crear habitación nueva (opcionalmente conectada)
if (args[0] == "NEW") { if (args[0] == "NEW") {
if (!MapEditor::get() || !MapEditor::get()->isActive()) { return "Editor not active"; } if ((MapEditor::get() == nullptr) || !MapEditor::get()->isActive()) { return "Editor not active"; }
std::string direction = (args.size() >= 2) ? args[1] : ""; std::string direction = (args.size() >= 2) ? args[1] : "";
return MapEditor::get()->createNewRoom(direction); return MapEditor::get()->createNewRoom(direction);
} }
@@ -621,9 +621,9 @@ static auto cmd_room(const std::vector<std::string>& args) -> std::string {
int num = 0; int num = 0;
if (args[0] == "NEXT" || args[0] == "PREV") { if (args[0] == "NEXT" || args[0] == "PREV") {
if (!GameControl::get_current_room) { return "Game not initialized"; } if (!GameControl::get_current_room) { return "Game not initialized"; }
const std::string current = GameControl::get_current_room(); const std::string CURRENT = GameControl::get_current_room();
try { try {
num = std::stoi(current.substr(0, current.find('.'))); num = std::stoi(CURRENT.substr(0, CURRENT.find('.')));
} catch (...) { return "Cannot determine current room"; } } catch (...) { return "Cannot determine current room"; }
num += (args[0] == "NEXT") ? 1 : -1; num += (args[0] == "NEXT") ? 1 : -1;
} else { } else {
@@ -638,7 +638,7 @@ static auto cmd_room(const std::vector<std::string>& args) -> std::string {
} }
// ITEMS <0-200> // ITEMS <0-200>
static auto cmd_items(const std::vector<std::string>& args) -> std::string { static auto cmdItems(const std::vector<std::string>& args) -> std::string {
if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; } if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; }
if (args.empty()) { return "usage: items <0-200>"; } if (args.empty()) { return "usage: items <0-200>"; }
int count = 0; int count = 0;
@@ -652,7 +652,7 @@ static auto cmd_items(const std::vector<std::string>& args) -> std::string {
} }
// SCENE [LOGO|LOADING|TITLE|CREDITS|GAME|ENDING|ENDING2|RESTART] // SCENE [LOGO|LOADING|TITLE|CREDITS|GAME|ENDING|ENDING2|RESTART]
static auto cmd_scene(const std::vector<std::string>& args) -> std::string { static auto cmdScene(const std::vector<std::string>& args) -> std::string {
if (Options::kiosk.enabled) { return "Not allowed in kiosk mode"; } if (Options::kiosk.enabled) { return "Not allowed in kiosk mode"; }
if (args.empty()) { return "usage: scene [logo|loading|title|credits|game|ending|ending2|restart]"; } if (args.empty()) { return "usage: scene [logo|loading|title|credits|game|ending|ending2|restart]"; }
@@ -683,10 +683,10 @@ static auto cmd_scene(const std::vector<std::string>& args) -> std::string {
} }
// EDIT [ON|OFF|REVERT] // EDIT [ON|OFF|REVERT]
static auto cmd_edit(const std::vector<std::string>& args) -> std::string { static auto cmdEdit(const std::vector<std::string>& args) -> std::string { // NOLINT(readability-function-cognitive-complexity)
if (args.empty()) { if (args.empty()) {
// Toggle: si está activo → off, si no → on // Toggle: si está activo → off, si no → on
if (MapEditor::get() && MapEditor::get()->isActive()) { if ((MapEditor::get() != nullptr) && MapEditor::get()->isActive()) {
if (GameControl::exit_editor) { GameControl::exit_editor(); } if (GameControl::exit_editor) { GameControl::exit_editor(); }
return "Editor OFF"; return "Editor OFF";
} }
@@ -718,26 +718,26 @@ static auto cmd_edit(const std::vector<std::string>& args) -> std::string {
} }
// EDIT SHOW/HIDE INFO/GRID // EDIT SHOW/HIDE INFO/GRID
if ((args[0] == "SHOW" || args[0] == "HIDE") && args.size() >= 2) { if ((args[0] == "SHOW" || args[0] == "HIDE") && args.size() >= 2) {
if (!MapEditor::get() || !MapEditor::get()->isActive()) { return "Editor not active"; } if ((MapEditor::get() == nullptr) || !MapEditor::get()->isActive()) { return "Editor not active"; }
bool show = (args[0] == "SHOW"); bool show = (args[0] == "SHOW");
if (args[1] == "INFO") { return MapEditor::get()->showInfo(show); } if (args[1] == "INFO") { return MapEditor::get()->showInfo(show); }
if (args[1] == "GRID") { return MapEditor::get()->showGrid(show); } if (args[1] == "GRID") { return MapEditor::get()->showGrid(show); }
} }
// EDIT MAPBG/MAPCONN <color> // EDIT MAPBG/MAPCONN <color>
if (args[0] == "MAPBG" && args.size() >= 2) { if (args[0] == "MAPBG" && args.size() >= 2) {
if (!MapEditor::get() || !MapEditor::get()->isActive()) { return "Editor not active"; } if ((MapEditor::get() == nullptr) || !MapEditor::get()->isActive()) { return "Editor not active"; }
return MapEditor::get()->setMiniMapBg(args[1]); return MapEditor::get()->setMiniMapBg(args[1]);
} }
if (args[0] == "MAPCONN" && args.size() >= 2) { if (args[0] == "MAPCONN" && args.size() >= 2) {
if (!MapEditor::get() || !MapEditor::get()->isActive()) { return "Editor not active"; } if ((MapEditor::get() == nullptr) || !MapEditor::get()->isActive()) { return "Editor not active"; }
return MapEditor::get()->setMiniMapConn(args[1]); return MapEditor::get()->setMiniMapConn(args[1]);
} }
return "usage: edit [on|off|revert|show|hide|mapbg|mapconn] [...]"; return "usage: edit [on|off|revert|show|hide|mapbg|mapconn] [...]";
} }
// SET <property> <value> — modifica propiedad del enemigo seleccionado o de la habitación // SET <property> <value> — modifica propiedad del enemigo seleccionado o de la habitación
static auto cmd_set(const std::vector<std::string>& args) -> std::string { static auto cmdSet(const std::vector<std::string>& args) -> std::string {
if (!MapEditor::get() || !MapEditor::get()->isActive()) { return "Editor not active"; } if ((MapEditor::get() == nullptr) || !MapEditor::get()->isActive()) { return "Editor not active"; }
if (args.empty()) { return "usage: set <property> <value>"; } if (args.empty()) { return "usage: set <property> <value>"; }
// SET TILE no necesita argumento (abre el tile picker visual) // SET TILE no necesita argumento (abre el tile picker visual)
@@ -762,8 +762,8 @@ static auto cmd_set(const std::vector<std::string>& args) -> std::string {
} }
// ENEMY [ADD|DELETE|DUPLICATE] // ENEMY [ADD|DELETE|DUPLICATE]
static auto cmd_enemy(const std::vector<std::string>& args) -> std::string { static auto cmdEnemy(const std::vector<std::string>& args) -> std::string {
if (!MapEditor::get() || !MapEditor::get()->isActive()) { return "Editor not active"; } if ((MapEditor::get() == nullptr) || !MapEditor::get()->isActive()) { return "Editor not active"; }
if (args.empty()) { return "usage: enemy <add|delete|duplicate>"; } if (args.empty()) { return "usage: enemy <add|delete|duplicate>"; }
if (args[0] == "ADD") { return MapEditor::get()->addEnemy(); } if (args[0] == "ADD") { return MapEditor::get()->addEnemy(); }
if (args[0] == "DELETE") { if (args[0] == "DELETE") {
@@ -778,8 +778,8 @@ static auto cmd_enemy(const std::vector<std::string>& args) -> std::string {
} }
// ITEM [ADD|DELETE|DUPLICATE] // ITEM [ADD|DELETE|DUPLICATE]
static auto cmd_item(const std::vector<std::string>& args) -> std::string { static auto cmdItem(const std::vector<std::string>& args) -> std::string {
if (!MapEditor::get() || !MapEditor::get()->isActive()) { return "Editor not active"; } if ((MapEditor::get() == nullptr) || !MapEditor::get()->isActive()) { return "Editor not active"; }
if (args.empty()) { return "usage: item <add|delete|duplicate>"; } if (args.empty()) { return "usage: item <add|delete|duplicate>"; }
if (args[0] == "ADD") { return MapEditor::get()->addItem(); } if (args[0] == "ADD") { return MapEditor::get()->addItem(); }
if (args[0] == "DELETE") { if (args[0] == "DELETE") {
@@ -795,7 +795,7 @@ static auto cmd_item(const std::vector<std::string>& args) -> std::string {
#endif #endif
// SHOW [INFO|NOTIFICATION|CHEEVO] // SHOW [INFO|NOTIFICATION|CHEEVO]
static auto cmd_show(const std::vector<std::string>& args) -> std::string { static auto cmdShow(const std::vector<std::string>& args) -> std::string {
#ifdef _DEBUG #ifdef _DEBUG
if (!args.empty() && args[0] == "NOTIFICATION") { if (!args.empty() && args[0] == "NOTIFICATION") {
Notifier::get()->show({"NOTIFICATION"}); Notifier::get()->show({"NOTIFICATION"});
@@ -815,7 +815,7 @@ static auto cmd_show(const std::vector<std::string>& args) -> std::string {
} }
// HIDE [INFO] // HIDE [INFO]
static auto cmd_hide(const std::vector<std::string>& args) -> std::string { static auto cmdHide(const std::vector<std::string>& args) -> std::string {
if (args.empty() || args[0] != "INFO") { return "usage: hide [info]"; } if (args.empty() || args[0] != "INFO") { return "usage: hide [info]"; }
if (!RenderInfo::get()->isActive()) { return "Info overlay already OFF"; } if (!RenderInfo::get()->isActive()) { return "Info overlay already OFF"; }
RenderInfo::get()->toggle(); RenderInfo::get()->toggle();
@@ -823,7 +823,7 @@ static auto cmd_hide(const std::vector<std::string>& args) -> std::string {
} }
// CHEAT [subcomando] // CHEAT [subcomando]
static auto cmd_cheat(const std::vector<std::string>& args) -> std::string { static auto cmdCheat(const std::vector<std::string>& args) -> std::string { // NOLINT(readability-function-cognitive-complexity)
if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; } if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; }
if (args.empty()) { return "usage: cheat [infinite lives|invincibility|open the jail|close the jail]"; } if (args.empty()) { return "usage: cheat [infinite lives|invincibility|open the jail|close the jail]"; }
@@ -885,7 +885,7 @@ static auto cmd_cheat(const std::vector<std::string>& args) -> std::string {
} }
// PLAYER SKIN / PLAYER COLOR // PLAYER SKIN / PLAYER COLOR
static auto cmd_player(const std::vector<std::string>& args) -> std::string { static auto cmdPlayer(const std::vector<std::string>& args) -> std::string {
if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; } if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; }
// PLAYER SKIN <name> // PLAYER SKIN <name>
@@ -920,14 +920,14 @@ static auto cmd_player(const std::vector<std::string>& args) -> std::string {
} }
// RESTART // RESTART
static auto cmd_restart(const std::vector<std::string>&) -> std::string { static auto cmdRestart(const std::vector<std::string>& /*unused*/) -> std::string {
SceneManager::current = SceneManager::Scene::LOGO; SceneManager::current = SceneManager::Scene::LOGO;
Audio::get()->stopMusic(); Audio::get()->stopMusic();
return "Restarting..."; return "Restarting...";
} }
// KIOSK [ON|OFF PLEASE|PLEASE] // KIOSK [ON|OFF PLEASE|PLEASE]
static auto cmd_kiosk(const std::vector<std::string>& args) -> std::string { static auto cmdKiosk(const std::vector<std::string>& args) -> std::string {
const bool DISABLE = (!args.empty() && args[0] == "PLEASE") || const bool DISABLE = (!args.empty() && args[0] == "PLEASE") ||
(args.size() >= 2 && args[0] == "OFF" && args[1] == "PLEASE"); (args.size() >= 2 && args[0] == "OFF" && args[1] == "PLEASE");
if (DISABLE) { if (DISABLE) {
@@ -947,7 +947,7 @@ static auto cmd_kiosk(const std::vector<std::string>& args) -> std::string {
} }
// EXIT / QUIT // EXIT / QUIT
static auto cmd_exit(const std::vector<std::string>& args) -> std::string { static auto cmdExit(const std::vector<std::string>& args) -> std::string {
if (Options::kiosk.enabled && (args.empty() || args[0] != "PLEASE")) { if (Options::kiosk.enabled && (args.empty() || args[0] != "PLEASE")) {
return "Not allowed in kiosk mode"; return "Not allowed in kiosk mode";
} }
@@ -956,7 +956,7 @@ static auto cmd_exit(const std::vector<std::string>& args) -> std::string {
} }
// SIZE // SIZE
static auto cmd_size(const std::vector<std::string>&) -> std::string { static auto cmdSize(const std::vector<std::string>& /*unused*/) -> std::string {
int w = 0; int w = 0;
int h = 0; int h = 0;
SDL_GetWindowSize(SDL_GetRenderWindow(Screen::get()->getRenderer()), &w, &h); SDL_GetWindowSize(SDL_GetRenderWindow(Screen::get()->getRenderer()), &w, &h);
@@ -965,37 +965,37 @@ static auto cmd_size(const std::vector<std::string>&) -> std::string {
// ── CommandRegistry ────────────────────────────────────────────────────────── // ── CommandRegistry ──────────────────────────────────────────────────────────
void CommandRegistry::registerHandlers() { void CommandRegistry::registerHandlers() { // NOLINT(readability-function-cognitive-complexity)
handlers_["cmd_ss"] = cmd_ss; handlers_["cmd_ss"] = cmdSs;
handlers_["cmd_shader"] = cmd_shader; handlers_["cmd_shader"] = cmdShader;
handlers_["cmd_border"] = cmd_border; handlers_["cmd_border"] = cmdBorder;
handlers_["cmd_fullscreen"] = cmd_fullscreen; handlers_["cmd_fullscreen"] = cmdFullscreen;
handlers_["cmd_zoom"] = cmd_zoom; handlers_["cmd_zoom"] = cmdZoom;
handlers_["cmd_intscale"] = cmd_intscale; handlers_["cmd_intscale"] = cmdIntscale;
handlers_["cmd_vsync"] = cmd_vsync; handlers_["cmd_vsync"] = cmdVsync;
handlers_["cmd_driver"] = cmd_driver; handlers_["cmd_driver"] = cmdDriver;
handlers_["cmd_palette"] = cmd_palette; handlers_["cmd_palette"] = cmdPalette;
handlers_["cmd_audio"] = cmd_audio; handlers_["cmd_audio"] = cmdAudio;
handlers_["cmd_music"] = cmd_music; handlers_["cmd_music"] = cmdMusic;
handlers_["cmd_sound"] = cmd_sound; handlers_["cmd_sound"] = cmdSound;
handlers_["cmd_show"] = cmd_show; handlers_["cmd_show"] = cmdShow;
handlers_["cmd_hide"] = cmd_hide; handlers_["cmd_hide"] = cmdHide;
handlers_["cmd_cheat"] = cmd_cheat; handlers_["cmd_cheat"] = cmdCheat;
handlers_["cmd_player"] = cmd_player; handlers_["cmd_player"] = cmdPlayer;
handlers_["cmd_restart"] = cmd_restart; handlers_["cmd_restart"] = cmdRestart;
handlers_["cmd_kiosk"] = cmd_kiosk; handlers_["cmd_kiosk"] = cmdKiosk;
handlers_["cmd_exit"] = cmd_exit; handlers_["cmd_exit"] = cmdExit;
handlers_["cmd_quit"] = cmd_exit; // QUIT usa el mismo handler que EXIT handlers_["cmd_quit"] = cmdExit; // QUIT usa el mismo handler que EXIT
handlers_["cmd_size"] = cmd_size; handlers_["cmd_size"] = cmdSize;
#ifdef _DEBUG #ifdef _DEBUG
handlers_["cmd_debug"] = cmd_debug; handlers_["cmd_debug"] = cmdDebug;
handlers_["cmd_items"] = cmd_items; handlers_["cmd_items"] = cmdItems;
handlers_["cmd_room"] = cmd_room; handlers_["cmd_room"] = cmdRoom;
handlers_["cmd_scene"] = cmd_scene; handlers_["cmd_scene"] = cmdScene;
handlers_["cmd_edit"] = cmd_edit; handlers_["cmd_edit"] = cmdEdit;
handlers_["cmd_set"] = cmd_set; handlers_["cmd_set"] = cmdSet;
handlers_["cmd_enemy"] = cmd_enemy; handlers_["cmd_enemy"] = cmdEnemy;
handlers_["cmd_item"] = cmd_item; handlers_["cmd_item"] = cmdItem;
#endif #endif
// HELP se registra en load() como lambda que captura this // HELP se registra en load() como lambda que captura this
@@ -1081,7 +1081,7 @@ void CommandRegistry::registerHandlers() {
#endif #endif
} }
void CommandRegistry::load(const std::string& yaml_path) { void CommandRegistry::load(const std::string& yaml_path) { // NOLINT(readability-function-cognitive-complexity)
registerHandlers(); registerHandlers();
// Cargar y parsear el YAML // Cargar y parsear el YAML
@@ -1103,8 +1103,8 @@ void CommandRegistry::load(const std::string& yaml_path) {
if (!yaml.contains("categories")) { return; } if (!yaml.contains("categories")) { return; }
for (const auto& cat_node : yaml["categories"]) { for (const auto& cat_node : yaml["categories"]) {
const std::string category = cat_node["name"].get_value<std::string>(); const auto CATEGORY = cat_node["name"].get_value<std::string>();
const bool cat_debug_only = cat_node.contains("debug_only") && cat_node["debug_only"].get_value<bool>(); const bool CAT_DEBUG_ONLY = cat_node.contains("debug_only") && cat_node["debug_only"].get_value<bool>();
// Scopes por defecto de la categoría // Scopes por defecto de la categoría
std::vector<std::string> cat_scopes; std::vector<std::string> cat_scopes;
@@ -1123,12 +1123,12 @@ void CommandRegistry::load(const std::string& yaml_path) {
CommandDef def; CommandDef def;
def.keyword = cmd_node["keyword"].get_value<std::string>(); def.keyword = cmd_node["keyword"].get_value<std::string>();
def.handler_id = cmd_node["handler"].get_value<std::string>(); def.handler_id = cmd_node["handler"].get_value<std::string>();
def.category = category; def.category = CATEGORY;
def.description = cmd_node.contains("description") ? cmd_node["description"].get_value<std::string>() : ""; def.description = cmd_node.contains("description") ? cmd_node["description"].get_value<std::string>() : "";
def.usage = cmd_node.contains("usage") ? cmd_node["usage"].get_value<std::string>() : def.keyword; def.usage = cmd_node.contains("usage") ? cmd_node["usage"].get_value<std::string>() : def.keyword;
def.instant = cmd_node.contains("instant") && cmd_node["instant"].get_value<bool>(); def.instant = cmd_node.contains("instant") && cmd_node["instant"].get_value<bool>();
def.hidden = cmd_node.contains("hidden") && cmd_node["hidden"].get_value<bool>(); def.hidden = cmd_node.contains("hidden") && cmd_node["hidden"].get_value<bool>();
def.debug_only = cat_debug_only || (cmd_node.contains("debug_only") && cmd_node["debug_only"].get_value<bool>()); def.debug_only = CAT_DEBUG_ONLY || (cmd_node.contains("debug_only") && cmd_node["debug_only"].get_value<bool>());
def.help_hidden = cmd_node.contains("help_hidden") && cmd_node["help_hidden"].get_value<bool>(); def.help_hidden = cmd_node.contains("help_hidden") && cmd_node["help_hidden"].get_value<bool>();
def.dynamic_completions = cmd_node.contains("dynamic_completions") && cmd_node["dynamic_completions"].get_value<bool>(); def.dynamic_completions = cmd_node.contains("dynamic_completions") && cmd_node["dynamic_completions"].get_value<bool>();
@@ -1143,14 +1143,14 @@ void CommandRegistry::load(const std::string& yaml_path) {
} else if (!cat_scopes.empty()) { } else if (!cat_scopes.empty()) {
def.scopes = cat_scopes; def.scopes = cat_scopes;
} else { } else {
def.scopes.push_back("global"); def.scopes.emplace_back("global");
} }
// Completions estáticas // Completions estáticas
if (cmd_node.contains("completions")) { if (cmd_node.contains("completions")) {
auto completions_node = cmd_node["completions"]; auto completions_node = cmd_node["completions"];
for (auto it = completions_node.begin(); it != completions_node.end(); ++it) { for (auto it = completions_node.begin(); it != completions_node.end(); ++it) {
std::string path = it.key().get_value<std::string>(); auto path = it.key().get_value<std::string>();
std::vector<std::string> opts; std::vector<std::string> opts;
for (const auto& opt : *it) { for (const auto& opt : *it) {
opts.push_back(opt.get_value<std::string>()); opts.push_back(opt.get_value<std::string>());
@@ -1171,7 +1171,7 @@ void CommandRegistry::load(const std::string& yaml_path) {
def.completions.clear(); def.completions.clear();
auto extras_completions = extras["completions"]; auto extras_completions = extras["completions"];
for (auto it = extras_completions.begin(); it != extras_completions.end(); ++it) { for (auto it = extras_completions.begin(); it != extras_completions.end(); ++it) {
std::string path = it.key().get_value<std::string>(); auto path = it.key().get_value<std::string>();
std::vector<std::string> opts; std::vector<std::string> opts;
for (const auto& opt : *it) { for (const auto& opt : *it) {
opts.push_back(opt.get_value<std::string>()); opts.push_back(opt.get_value<std::string>());
@@ -1237,9 +1237,9 @@ auto CommandRegistry::findCommand(const std::string& keyword) const -> const Com
auto CommandRegistry::execute(const std::string& keyword, const std::vector<std::string>& args) const -> std::string { auto CommandRegistry::execute(const std::string& keyword, const std::vector<std::string>& args) const -> std::string {
const auto* def = findCommand(keyword); const auto* def = findCommand(keyword);
if (def == nullptr) { return ""; } if (def == nullptr) { return ""; }
const auto it = handlers_.find(def->handler_id); const auto IT = handlers_.find(def->handler_id);
if (it == handlers_.end()) { return "Handler not found: " + def->handler_id; } if (IT == handlers_.end()) { return "Handler not found: " + def->handler_id; }
return it->second(args); return IT->second(args);
} }
auto CommandRegistry::generateTerminalHelp() const -> std::string { auto CommandRegistry::generateTerminalHelp() const -> std::string {
@@ -1270,7 +1270,7 @@ auto CommandRegistry::generateTerminalHelp() const -> std::string {
return out.str(); return out.str();
} }
auto CommandRegistry::generateConsoleHelp() const -> std::string { auto CommandRegistry::generateConsoleHelp() const -> std::string { // NOLINT(readability-function-cognitive-complexity)
// Agrupar comandos visibles por scope // Agrupar comandos visibles por scope
std::string global_cmds; std::string global_cmds;
std::string debug_cmds; std::string debug_cmds;
@@ -1328,13 +1328,13 @@ auto CommandRegistry::getCompletions(const std::string& path) const -> std::vect
} }
// Primero: buscar proveedor dinámico (tiene prioridad si existe) // Primero: buscar proveedor dinámico (tiene prioridad si existe)
const auto dyn_it = dynamic_providers_.find(path); const auto DYN_IT = dynamic_providers_.find(path);
if (dyn_it != dynamic_providers_.end()) { if (DYN_IT != dynamic_providers_.end()) {
return dyn_it->second(); return DYN_IT->second();
} }
// Fallback: completions estáticas del YAML // Fallback: completions estáticas del YAML
const auto it = completions_map_.find(path); const auto IT = completions_map_.find(path);
if (it != completions_map_.end()) { return it->second; } if (IT != completions_map_.end()) { return IT->second; }
return {}; return {};
} }
@@ -1345,12 +1345,11 @@ auto CommandRegistry::getCompletions(const std::string& path) const -> std::vect
auto CommandRegistry::isCommandVisible(const CommandDef& cmd) const -> bool { auto CommandRegistry::isCommandVisible(const CommandDef& cmd) const -> bool {
if (cmd.hidden) { return false; } if (cmd.hidden) { return false; }
for (const auto& s : cmd.scopes) { return std::ranges::any_of(cmd.scopes, [this](const auto& s) {
if (s == "global" || s == "game") { return true; } if (s == "global" || s == "game") { return true; }
if (s == "debug" && (active_scope_ == "debug" || active_scope_ == "editor")) { return true; } if (s == "debug" && (active_scope_ == "debug" || active_scope_ == "editor")) { return true; }
if (s == "editor" && active_scope_ == "editor") { return true; } return s == "editor" && active_scope_ == "editor";
} });
return false;
} }
auto CommandRegistry::getVisibleKeywords() const -> std::vector<std::string> { auto CommandRegistry::getVisibleKeywords() const -> std::vector<std::string> {

View File

@@ -139,7 +139,7 @@ if [[ ${#FILES[@]} -gt 0 ]]; then
else else
# Comportamiento original: procesar todos los archivos # Comportamiento original: procesar todos los archivos
echo "=== Escaneando recursivamente source/ (excluyendo external/ y jail_audio.hpp) ===" echo "=== Escaneando recursivamente source/ (excluyendo external/ y jail_audio.hpp) ==="
find "$SOURCE_DIR" \( -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) -not -path "*/external/*" -not -path "*/core/audio/jail_audio.hpp" -print0 | \ find "$SOURCE_DIR" \( -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) -not -path "*/external/*" -not -path "*/core/audio/jail_audio.hpp" -not -name '*_spv.h' -print0 | \
xargs -0 -P4 -I{} bash -c 'echo "Procesando: {}"; clang-tidy {} -p '"$BUILD_DIR"' '"$FIX_FLAG" xargs -0 -P4 -I{} bash -c 'echo "Procesando: {}"; clang-tidy {} -p '"$BUILD_DIR"' '"$FIX_FLAG"
echo echo