diff --git a/.clang-tidy b/.clang-tidy index 91663f0..78d31f3 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -6,15 +6,15 @@ Checks: # ✅ Check 4: readability-const-return-type (código ya cumple) # ✅ Check 5: readability-else-after-return (código ya cumple) # ✅ Check 6: readability-simplify-boolean-expr (código ya cumple) - - readability-uppercase-literal-suffix - - readability-math-missing-parentheses - #- readability-identifier-naming # TEMP DISABLED - - readability-const-return-type - - readability-else-after-return - - readability-simplify-boolean-expr - - # TODO: Habilitar gradualmente -# - readability-* + # ✅ Check 7: readability-* (225 fixes aplicados) + - readability-* + - -readability-identifier-naming # Excluido (cascada de cambios) + - -readability-identifier-length # Excluido (nombres cortos son OK) + - -readability-magic-numbers # Excluido (muchos falsos positivos) + - -readability-convert-member-functions-to-static # Excluido (rompe encapsulación) + - -readability-use-anyofallof # Excluido (C++20 ranges - no todos los compiladores) + - -readability-function-cognitive-complexity # Excluido (complejidad ciclomática aceptable) + - -clang-analyzer-security.insecureAPI.rand # Excluido (rand() es suficiente para juegos) # - modernize-* # - performance-* # - bugprone-unchecked-optional-access diff --git a/source/core/defaults.hpp b/source/core/defaults.hpp index 590e51d..f0c1896 100644 --- a/source/core/defaults.hpp +++ b/source/core/defaults.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace Defaults { @@ -441,13 +442,13 @@ constexpr float CENTER_Y = Game::HEIGHT / 2.0F; // 240.0f // Nota: std::cos/sin no són constexpr en C++20, però funcionen en runtime // Les funcions inline són optimitzades pel compilador (zero overhead) inline float P1_TARGET_X() { - return CENTER_X + CLOCK_RADIUS * std::cos(CLOCK_8_ANGLE); + return CENTER_X + (CLOCK_RADIUS * std::cos(CLOCK_8_ANGLE)); } inline float P1_TARGET_Y() { return CENTER_Y + ((Game::HEIGHT / 2.0F) * TARGET_Y_RATIO); } inline float P2_TARGET_X() { - return CENTER_X + CLOCK_RADIUS * std::cos(CLOCK_4_ANGLE); + return CENTER_X + (CLOCK_RADIUS * std::cos(CLOCK_4_ANGLE)); } inline float P2_TARGET_Y() { return CENTER_Y + ((Game::HEIGHT / 2.0F) * TARGET_Y_RATIO); diff --git a/source/core/graphics/shape.cpp b/source/core/graphics/shape.cpp index d066112..2d25f2a 100644 --- a/source/core/graphics/shape.cpp +++ b/source/core/graphics/shape.cpp @@ -44,8 +44,9 @@ bool Shape::parsejar_fitxer(const std::string& contingut) { line = trim(line); // Skip comments and blanks - if (line.empty() || line[0] == '#') + if (line.empty() || line[0] == '#') { continue; + } // Parse command if (starts_with(line, "name:")) { @@ -91,8 +92,9 @@ bool Shape::parsejar_fitxer(const std::string& contingut) { std::string Shape::trim(const std::string& str) const { const char* whitespace = " \t\n\r"; size_t start = str.find_first_not_of(whitespace); - if (start == std::string::npos) + if (start == std::string::npos) { return ""; + } size_t end = str.find_last_not_of(whitespace); return str.substr(start, end - start + 1); @@ -101,16 +103,18 @@ std::string Shape::trim(const std::string& str) const { // Helper: starts_with bool Shape::starts_with(const std::string& str, const std::string& prefix) const { - if (str.length() < prefix.length()) + if (str.length() < prefix.length()) { return false; + } return str.compare(0, prefix.length(), prefix) == 0; } // Helper: extract value after ':' std::string Shape::extract_value(const std::string& line) const { size_t colon = line.find(':'); - if (colon == std::string::npos) + if (colon == std::string::npos) { return ""; + } return line.substr(colon + 1); } diff --git a/source/core/graphics/starfield.cpp b/source/core/graphics/starfield.cpp index cb05ba9..b83f27d 100644 --- a/source/core/graphics/starfield.cpp +++ b/source/core/graphics/starfield.cpp @@ -69,7 +69,7 @@ Starfield::Starfield(SDL_Renderer* renderer, } // Inicialitzar una estrella (nova o regenerada) -void Starfield::inicialitzar_estrella(Estrella& estrella) { +void Starfield::inicialitzar_estrella(Estrella& estrella) const { // Angle aleatori des del punt de fuga cap a fora estrella.angle = (static_cast(rand()) / RAND_MAX) * 2.0F * Defaults::Math::PI; diff --git a/source/core/graphics/starfield.hpp b/source/core/graphics/starfield.hpp index 5135936..cf0a3d5 100644 --- a/source/core/graphics/starfield.hpp +++ b/source/core/graphics/starfield.hpp @@ -54,7 +54,7 @@ class Starfield { }; // Inicialitzar una estrella (nova o regenerada) - void inicialitzar_estrella(Estrella& estrella); + void inicialitzar_estrella(Estrella& estrella) const; // Verificar si una estrella està fora de l'àrea bool fora_area(const Estrella& estrella) const; diff --git a/source/core/graphics/vector_text.cpp b/source/core/graphics/vector_text.cpp index 99187bd..73477d3 100644 --- a/source/core/graphics/vector_text.cpp +++ b/source/core/graphics/vector_text.cpp @@ -178,11 +178,11 @@ std::string VectorText::get_shape_filename(char c) const { } bool VectorText::is_supported(char c) const { - return chars_.find(c) != chars_.end(); + return chars_.contains(c); } void VectorText::render(const std::string& text, const Punt& posicio, float escala, float spacing, float brightness) { - if (!renderer_) { + if (renderer_ == nullptr) { return; } diff --git a/source/core/input/input.cpp b/source/core/input/input.cpp index 63a4cbb..f89f3f7 100644 --- a/source/core/input/input.cpp +++ b/source/core/input/input.cpp @@ -506,7 +506,7 @@ void Input::applyPlayer1BindingsFromOptions() { std::shared_ptr gamepad = nullptr; if (Options::player1.gamepad_name.empty()) { // Fallback: usar primer gamepad disponible - gamepad = (gamepads_.size() > 0) ? gamepads_[0] : nullptr; + gamepad = (!gamepads_.empty()) ? gamepads_[0] : nullptr; } else { // Buscar por nombre gamepad = findAvailableGamepadByName(Options::player1.gamepad_name); diff --git a/source/core/rendering/line_renderer.cpp b/source/core/rendering/line_renderer.cpp index d802d31..c387288 100644 --- a/source/core/rendering/line_renderer.cpp +++ b/source/core/rendering/line_renderer.cpp @@ -20,10 +20,12 @@ bool linea(SDL_Renderer* renderer, int x1, int y1, int x2, int y2, bool dibuixar // Helper function: retorna el signe d'un nombre auto sign = [](int x) -> int { - if (x < 0) + if (x < 0) { return -1; - if (x > 0) + } + if (x > 0) { return 1; + } return 0; }; @@ -40,7 +42,7 @@ bool linea(SDL_Renderer* renderer, int x1, int y1, int x2, int y2, bool dibuixar bool colisio = false; // Dibuixar amb SDL3 (més eficient que Bresenham píxel a píxel) - if (dibuixar && renderer) { + if (dibuixar && (renderer != nullptr)) { // Transformar coordenades lògiques (640x480) a físiques (resolució real) float scale = g_current_scale_factor; int px1 = transform_x(x1, scale); diff --git a/source/core/rendering/sdl_manager.cpp b/source/core/rendering/sdl_manager.cpp index c415960..33c8a94 100644 --- a/source/core/rendering/sdl_manager.cpp +++ b/source/core/rendering/sdl_manager.cpp @@ -47,7 +47,7 @@ SDLManager::SDLManager() SDL_WINDOW_RESIZABLE // Permetre resize manual també ); - if (!finestra_) { + if (finestra_ == nullptr) { std::cerr << "Error creant finestra: " << SDL_GetError() << std::endl; SDL_Quit(); return; @@ -59,7 +59,7 @@ SDLManager::SDLManager() // Crear renderer amb acceleració renderer_ = SDL_CreateRenderer(finestra_, nullptr); - if (!renderer_) { + if (renderer_ == nullptr) { std::cerr << "Error creant renderer: " << SDL_GetError() << std::endl; SDL_DestroyWindow(finestra_); SDL_Quit(); @@ -114,7 +114,7 @@ SDLManager::SDLManager(int width, int height, bool fullscreen) // Crear finestra finestra_ = SDL_CreateWindow(window_title.c_str(), current_width_, current_height_, flags); - if (!finestra_) { + if (finestra_ == nullptr) { std::cerr << "Error creant finestra: " << SDL_GetError() << std::endl; SDL_Quit(); return; @@ -128,7 +128,7 @@ SDLManager::SDLManager(int width, int height, bool fullscreen) // Crear renderer amb acceleració renderer_ = SDL_CreateRenderer(finestra_, nullptr); - if (!renderer_) { + if (renderer_ == nullptr) { std::cerr << "Error creant renderer: " << SDL_GetError() << std::endl; SDL_DestroyWindow(finestra_); SDL_Quit(); @@ -157,12 +157,12 @@ SDLManager::SDLManager(int width, int height, bool fullscreen) } SDLManager::~SDLManager() { - if (renderer_) { + if (renderer_ != nullptr) { SDL_DestroyRenderer(renderer_); renderer_ = nullptr; } - if (finestra_) { + if (finestra_ != nullptr) { SDL_DestroyWindow(finestra_); finestra_ = nullptr; } @@ -175,7 +175,7 @@ void SDLManager::calculateMaxWindowSize() { SDL_DisplayID display = SDL_GetPrimaryDisplay(); const SDL_DisplayMode* mode = SDL_GetCurrentDisplayMode(display); - if (mode) { + if (mode != nullptr) { // Deixar marge de 100px per a decoracions de l'OS max_width_ = mode->w - 100; max_height_ = mode->h - 100; @@ -282,14 +282,15 @@ void SDLManager::updateViewport() { << std::endl; } -void SDLManager::updateRenderingContext() { +void SDLManager::updateRenderingContext() const { // Actualitzar el factor d'escala global per a totes les funcions de renderitzat Rendering::g_current_scale_factor = zoom_factor_; } void SDLManager::increaseWindowSize() { - if (is_fullscreen_) + if (is_fullscreen_) { return; + } float new_zoom = zoom_factor_ + Defaults::Window::ZOOM_INCREMENT; applyZoom(new_zoom); @@ -298,8 +299,9 @@ void SDLManager::increaseWindowSize() { } void SDLManager::decreaseWindowSize() { - if (is_fullscreen_) + if (is_fullscreen_) { return; + } float new_zoom = zoom_factor_ - Defaults::Window::ZOOM_INCREMENT; applyZoom(new_zoom); @@ -309,7 +311,8 @@ void SDLManager::decreaseWindowSize() { void SDLManager::applyWindowSize(int new_width, int new_height) { // Obtenir posició actual ABANS del resize - int old_x, old_y; + int old_x; + int old_y; SDL_GetWindowPosition(finestra_, &old_x, &old_y); int old_width = current_width_; @@ -396,8 +399,9 @@ bool SDLManager::handleWindowEvent(const SDL_Event& event) { } void SDLManager::neteja(uint8_t r, uint8_t g, uint8_t b) { - if (!renderer_) + if (renderer_ == nullptr) { return; + } // [MODIFICAT] Usar color oscil·lat del fons en lloc dels paràmetres (void)r; @@ -409,8 +413,9 @@ void SDLManager::neteja(uint8_t r, uint8_t g, uint8_t b) { } void SDLManager::presenta() { - if (!renderer_) + if (renderer_ == nullptr) { return; + } SDL_RenderPresent(renderer_); } @@ -444,7 +449,7 @@ void SDLManager::updateFPS(float delta_time) { fps_display_, vsync_state); - if (finestra_) { + if (finestra_ != nullptr) { SDL_SetWindowTitle(finestra_, title.c_str()); } } @@ -452,7 +457,7 @@ void SDLManager::updateFPS(float delta_time) { // [NUEVO] Actualitzar títol de la finestra void SDLManager::setWindowTitle(const std::string& title) { - if (finestra_) { + if (finestra_ != nullptr) { SDL_SetWindowTitle(finestra_, title.c_str()); } } @@ -463,7 +468,7 @@ void SDLManager::toggleVSync() { Options::rendering.vsync = (Options::rendering.vsync == 1) ? 0 : 1; // Aplicar a SDL - if (renderer_) { + if (renderer_ != nullptr) { SDL_SetRenderVSync(renderer_, Options::rendering.vsync); } diff --git a/source/core/rendering/sdl_manager.hpp b/source/core/rendering/sdl_manager.hpp index ecb5f7e..6de93d7 100644 --- a/source/core/rendering/sdl_manager.hpp +++ b/source/core/rendering/sdl_manager.hpp @@ -46,7 +46,7 @@ class SDLManager { void setWindowTitle(const std::string& title); // [NUEVO] Actualitzar context de renderitzat (factor d'escala global) - void updateRenderingContext(); + void updateRenderingContext() const; private: SDL_Window* finestra_; diff --git a/source/core/rendering/shape_renderer.cpp b/source/core/rendering/shape_renderer.cpp index 6059b97..e0f3e92 100644 --- a/source/core/rendering/shape_renderer.cpp +++ b/source/core/rendering/shape_renderer.cpp @@ -48,7 +48,7 @@ static Punt transform_point(const Punt& point, const Punt& shape_centre, const P float centered_y = point.y - shape_centre.y; // 2. Aplicar rotació 3D (si es proporciona) - if (rotation_3d && rotation_3d->has_rotation()) { + if ((rotation_3d != nullptr) && rotation_3d->has_rotation()) { Punt rotated_3d = apply_3d_rotation(centered_x, centered_y, *rotation_3d); centered_x = rotated_3d.x; centered_y = rotated_3d.y; diff --git a/source/core/resources/resource_pack.cpp b/source/core/resources/resource_pack.cpp index 84a2cdd..4c4adbd 100644 --- a/source/core/resources/resource_pack.cpp +++ b/source/core/resources/resource_pack.cpp @@ -197,7 +197,7 @@ bool Pack::loadPack(const std::string& pack_file) { file.read(reinterpret_cast(&name_len), sizeof(name_len)); std::string filename(name_len, '\0'); - file.read(&filename[0], name_len); + file.read(filename.data(), name_len); // Offset, mida, checksum ResourceEntry entry; @@ -258,7 +258,7 @@ std::vector Pack::getResource(const std::string& filename) { // Comprovar si existeix un recurs bool Pack::hasResource(const std::string& filename) const { - return resources_.find(filename) != resources_.end(); + return resources_.contains(filename); } // Obtenir llista de tots els recursos diff --git a/source/core/system/game_config.hpp b/source/core/system/game_config.hpp index c9c6fa4..ef0e907 100644 --- a/source/core/system/game_config.hpp +++ b/source/core/system/game_config.hpp @@ -42,8 +42,12 @@ struct ConfigPartida { // Retorna l'ID de l'únic jugador actiu (0 o 1) // Només vàlid si es_un_jugador() retorna true [[nodiscard]] uint8_t id_unic_jugador() const { - if (jugador1_actiu && !jugador2_actiu) return 0; - if (!jugador1_actiu && jugador2_actiu) return 1; + if (jugador1_actiu && !jugador2_actiu) { + return 0; + } + if (!jugador1_actiu && jugador2_actiu) { + return 1; + } return 0; // Fallback (cal comprovar es_un_jugador() primer) } }; diff --git a/source/core/utils/path_utils.cpp b/source/core/utils/path_utils.cpp index e21fcb3..e7d9214 100644 --- a/source/core/utils/path_utils.cpp +++ b/source/core/utils/path_utils.cpp @@ -15,7 +15,7 @@ static std::string executable_directory_; // Inicialitzar el sistema de rutes amb argv[0] void initializePathSystem(const char* argv0) { - if (!argv0) { + if (argv0 == nullptr) { std::cerr << "[PathUtils] ADVERTÈNCIA: argv[0] és nullptr\n"; executable_path_ = ""; executable_directory_ = "."; @@ -65,10 +65,8 @@ std::string getResourceBasePath() { // Bundle de macOS: recursos a ../Resources des de MacOS/ std::cout << "[PathUtils] Detectat bundle de macOS\n"; return exe_dir + "/../Resources"; - } else { - // Executable normal: recursos al mateix directori - return exe_dir; - } + } // Executable normal: recursos al mateix directori + return exe_dir; } // Normalitzar ruta (convertir barres, etc.) diff --git a/source/game/effects/debris_manager.cpp b/source/game/effects/debris_manager.cpp index 044949f..2471d4b 100644 --- a/source/game/effects/debris_manager.cpp +++ b/source/game/effects/debris_manager.cpp @@ -3,6 +3,7 @@ #include "debris_manager.hpp" +#include #include #include #include @@ -90,7 +91,7 @@ void DebrisManager::explotar(const std::shared_ptr& shape, // 2. Trobar slot lliure Debris* debris = trobar_slot_lliure(); - if (!debris) { + if (debris == nullptr) { std::cerr << "[DebrisManager] Warning: no debris slots disponibles\n"; return; // Pool ple } @@ -205,8 +206,9 @@ void DebrisManager::explotar(const std::shared_ptr& shape, void DebrisManager::actualitzar(float delta_time) { for (auto& debris : debris_pool_) { - if (!debris.actiu) + if (!debris.actiu) { continue; + } // 1. Actualitzar temps de vida debris.temps_vida += delta_time; @@ -229,8 +231,7 @@ void DebrisManager::actualitzar(float delta_time) { // Aplicar acceleració negativa (fricció) float nova_speed = speed + (debris.acceleracio * delta_time); - if (nova_speed < 0.0F) - nova_speed = 0.0F; + nova_speed = std::max(nova_speed, 0.0F); debris.velocitat.x = dir_x * nova_speed; debris.velocitat.y = dir_y * nova_speed; @@ -303,8 +304,9 @@ void DebrisManager::actualitzar(float delta_time) { void DebrisManager::dibuixar() const { for (const auto& debris : debris_pool_) { - if (!debris.actiu) + if (!debris.actiu) { continue; + } // Dibuixar segment de línia amb brightness heretat Rendering::linea(renderer_, @@ -372,8 +374,9 @@ void DebrisManager::reiniciar() { int DebrisManager::get_num_actius() const { int count = 0; for (const auto& debris : debris_pool_) { - if (debris.actiu) + if (debris.actiu) { count++; + } } return count; } diff --git a/source/game/effects/gestor_puntuacio_flotant.cpp b/source/game/effects/gestor_puntuacio_flotant.cpp index 3baf033..154af55 100644 --- a/source/game/effects/gestor_puntuacio_flotant.cpp +++ b/source/game/effects/gestor_puntuacio_flotant.cpp @@ -18,8 +18,9 @@ GestorPuntuacioFlotant::GestorPuntuacioFlotant(SDL_Renderer* renderer) void GestorPuntuacioFlotant::crear(int punts, const Punt& posicio) { // 1. Trobar slot lliure PuntuacioFlotant* pf = trobar_slot_lliure(); - if (!pf) + if (pf == nullptr) { return; // Pool ple (improbable) + } // 2. Inicialitzar puntuació flotant pf->text = std::to_string(punts); @@ -34,8 +35,9 @@ void GestorPuntuacioFlotant::crear(int punts, const Punt& posicio) { void GestorPuntuacioFlotant::actualitzar(float delta_time) { for (auto& pf : pool_) { - if (!pf.actiu) + if (!pf.actiu) { continue; + } // 1. Actualitzar posició (deriva cap amunt) pf.posicio.x += pf.velocitat.x * delta_time; @@ -57,8 +59,9 @@ void GestorPuntuacioFlotant::actualitzar(float delta_time) { void GestorPuntuacioFlotant::dibuixar() { for (const auto& pf : pool_) { - if (!pf.actiu) + if (!pf.actiu) { continue; + } // Renderitzar centrat amb brightness (fade) constexpr float escala = Defaults::FloatingScore::SCALE; @@ -77,16 +80,18 @@ void GestorPuntuacioFlotant::reiniciar() { int GestorPuntuacioFlotant::get_num_actius() const { int count = 0; for (const auto& pf : pool_) { - if (pf.actiu) + if (pf.actiu) { count++; + } } return count; } PuntuacioFlotant* GestorPuntuacioFlotant::trobar_slot_lliure() { for (auto& pf : pool_) { - if (!pf.actiu) + if (!pf.actiu) { return &pf; + } } return nullptr; // Pool ple } diff --git a/source/game/entities/bala.cpp b/source/game/entities/bala.cpp index 7102cd7..1a32dcc 100644 --- a/source/game/entities/bala.cpp +++ b/source/game/entities/bala.cpp @@ -4,6 +4,7 @@ #include "game/entities/bala.hpp" +#include #include #include @@ -71,9 +72,7 @@ void Bala::actualitzar(float delta_time) { // Decrementar grace timer if (grace_timer_ > 0.0F) { grace_timer_ -= delta_time; - if (grace_timer_ < 0.0F) { - grace_timer_ = 0.0F; - } + grace_timer_ = std::max(grace_timer_, 0.0F); } mou(delta_time); @@ -107,7 +106,10 @@ void Bala::mou(float delta_time) { // Desactivar si surt de la zona de joc (no rebota com els ORNIs) // CORRECCIÓ: Usar límits segurs amb radi de la bala - float min_x, max_x, min_y, max_y; + float min_x; + float max_x; + float min_y; + float max_y; Constants::obtenir_limits_zona_segurs(Defaults::Entities::BULLET_RADIUS, min_x, max_x, diff --git a/source/game/entities/enemic.cpp b/source/game/entities/enemic.cpp index 72d19f3..9d2d21d 100644 --- a/source/game/entities/enemic.cpp +++ b/source/game/entities/enemic.cpp @@ -4,6 +4,7 @@ #include "game/entities/enemic.hpp" +#include #include #include #include @@ -37,7 +38,8 @@ void Enemic::inicialitzar(TipusEnemic tipus, const Punt* ship_pos) { // Carregar forma segons el tipus const char* shape_file; - float drotacio_min, drotacio_max; + float drotacio_min; + float drotacio_max; switch (tipus_) { case TipusEnemic::PENTAGON: @@ -70,7 +72,10 @@ void Enemic::inicialitzar(TipusEnemic tipus, const Punt* ship_pos) { } // [MODIFIED] Posició aleatòria amb comprovació de seguretat - float min_x, max_x, min_y, max_y; + float min_x; + float max_x; + float min_y; + float max_y; Constants::obtenir_limits_zona_segurs(Defaults::Entities::ENEMY_RADIUS, min_x, max_x, @@ -82,7 +87,8 @@ void Enemic::inicialitzar(TipusEnemic tipus, const Punt* ship_pos) { bool found_safe_position = false; for (int attempt = 0; attempt < Defaults::Enemies::Spawn::MAX_SPAWN_ATTEMPTS; attempt++) { - float candidate_x, candidate_y; + float candidate_x; + float candidate_y; if (intent_spawn_safe(*ship_pos, candidate_x, candidate_y)) { centre_.x = candidate_x; @@ -138,9 +144,7 @@ void Enemic::actualitzar(float delta_time) { if (timer_invulnerabilitat_ > 0.0F) { timer_invulnerabilitat_ -= delta_time; - if (timer_invulnerabilitat_ < 0.0F) { - timer_invulnerabilitat_ = 0.0F; - } + timer_invulnerabilitat_ = std::max(timer_invulnerabilitat_, 0.0F); // [NEW] Update brightness with LERP during invulnerability float t_inv = timer_invulnerabilitat_ / Defaults::Enemies::Spawn::INVULNERABILITY_DURATION; @@ -202,7 +206,10 @@ void Enemic::comportament_pentagon(float delta_time) { float new_x = centre_.x + dx; // Obtenir límits segurs - float min_x, max_x, min_y, max_y; + float min_x; + float max_x; + float min_y; + float max_y; Constants::obtenir_limits_zona_segurs(Defaults::Entities::ENEMY_RADIUS, min_x, max_x, @@ -242,7 +249,7 @@ void Enemic::comportament_quadrat(float delta_time) { if (tracking_timer_ >= Defaults::Enemies::Quadrat::TRACKING_INTERVAL) { tracking_timer_ = 0.0F; - if (ship_position_) { + if (ship_position_ != nullptr) { // Calculate angle to ship float dx = ship_position_->x - centre_.x; float dy = ship_position_->y - centre_.y; @@ -252,8 +259,12 @@ void Enemic::comportament_quadrat(float delta_time) { float angle_diff = target_angle - angle_; // Normalize angle difference to [-π, π] - while (angle_diff > Constants::PI) angle_diff -= 2.0F * Constants::PI; - while (angle_diff < -Constants::PI) angle_diff += 2.0F * Constants::PI; + while (angle_diff > Constants::PI) { + angle_diff -= 2.0F * Constants::PI; + } + while (angle_diff < -Constants::PI) { + angle_diff += 2.0F * Constants::PI; + } // Apply tracking strength (uses member variable, defaults to 0.5) angle_ += angle_diff * tracking_strength_; @@ -269,7 +280,10 @@ void Enemic::comportament_quadrat(float delta_time) { float new_x = centre_.x + dx; // Obtenir límits segurs - float min_x, max_x, min_y, max_y; + float min_x; + float max_x; + float min_y; + float max_y; Constants::obtenir_limits_zona_segurs(Defaults::Entities::ENEMY_RADIUS, min_x, max_x, @@ -294,7 +308,7 @@ void Enemic::comportament_molinillo(float delta_time) { // Molinillo: agressiu (fast, straight lines, proximity spin-up) // Check proximity to ship for spin-up effect - if (ship_position_) { + if (ship_position_ != nullptr) { float dx = ship_position_->x - centre_.x; float dy = ship_position_->y - centre_.y; float distance = std::sqrt((dx * dx) + (dy * dy)); @@ -318,7 +332,10 @@ void Enemic::comportament_molinillo(float delta_time) { float new_x = centre_.x + dx; // Obtenir límits segurs - float min_x, max_x, min_y, max_y; + float min_x; + float max_x; + float min_y; + float max_y; Constants::obtenir_limits_zona_segurs(Defaults::Entities::ENEMY_RADIUS, min_x, max_x, @@ -491,7 +508,10 @@ void Enemic::set_tracking_strength(float strength) { // [NEW] Safe spawn helper - checks if position is away from ship bool Enemic::intent_spawn_safe(const Punt& ship_pos, float& out_x, float& out_y) { // Generate random position within safe bounds - float min_x, max_x, min_y, max_y; + float min_x; + float max_x; + float min_y; + float max_y; Constants::obtenir_limits_zona_segurs(Defaults::Entities::ENEMY_RADIUS, min_x, max_x, diff --git a/source/game/entities/nau.cpp b/source/game/entities/nau.cpp index 49a9a53..54ddc2d 100644 --- a/source/game/entities/nau.cpp +++ b/source/game/entities/nau.cpp @@ -6,6 +6,7 @@ #include +#include #include #include @@ -40,12 +41,13 @@ void Nau::inicialitzar(const Punt* spawn_point, bool activar_invulnerabilitat) { // fitxer Només inicialitzem l'estat de la instància // Use custom spawn point if provided, otherwise use center - if (spawn_point) { + if (spawn_point != nullptr) { centre_.x = spawn_point->x; centre_.y = spawn_point->y; } else { // Default: center of play area - float centre_x, centre_y; + float centre_x; + float centre_y; Constants::obtenir_centre_zona(centre_x, centre_y); centre_.x = static_cast(centre_x); centre_.y = static_cast(centre_y); @@ -69,8 +71,9 @@ void Nau::processar_input(float delta_time, uint8_t player_id) { // Processar input continu (com teclapuls() del Pascal original) // Basat en joc_asteroides.cpp línies 66-85 // Només processa input si la nau està viva - if (esta_tocada_) + if (esta_tocada_) { return; + } auto* input = Input::get(); @@ -88,9 +91,7 @@ void Nau::processar_input(float delta_time, uint8_t player_id) { if (input->checkActionPlayer1(InputAction::THRUST, Input::ALLOW_REPEAT)) { if (velocitat_ < Defaults::Physics::MAX_VELOCITY) { velocitat_ += Defaults::Physics::ACCELERATION * delta_time; - if (velocitat_ > Defaults::Physics::MAX_VELOCITY) { - velocitat_ = Defaults::Physics::MAX_VELOCITY; - } + velocitat_ = std::min(velocitat_, Defaults::Physics::MAX_VELOCITY); } } } else { @@ -106,9 +107,7 @@ void Nau::processar_input(float delta_time, uint8_t player_id) { if (input->checkActionPlayer2(InputAction::THRUST, Input::ALLOW_REPEAT)) { if (velocitat_ < Defaults::Physics::MAX_VELOCITY) { velocitat_ += Defaults::Physics::ACCELERATION * delta_time; - if (velocitat_ > Defaults::Physics::MAX_VELOCITY) { - velocitat_ = Defaults::Physics::MAX_VELOCITY; - } + velocitat_ = std::min(velocitat_, Defaults::Physics::MAX_VELOCITY); } } } @@ -116,15 +115,14 @@ void Nau::processar_input(float delta_time, uint8_t player_id) { void Nau::actualitzar(float delta_time) { // Només actualitzar si la nau està viva - if (esta_tocada_) + if (esta_tocada_) { return; + } // Decrementar timer de invulnerabilidad if (invulnerable_timer_ > 0.0F) { invulnerable_timer_ -= delta_time; - if (invulnerable_timer_ < 0.0F) { - invulnerable_timer_ = 0.0F; - } + invulnerable_timer_ = std::max(invulnerable_timer_, 0.0F); } // Aplicar física (moviment + fricció) @@ -133,8 +131,9 @@ void Nau::actualitzar(float delta_time) { void Nau::dibuixar() const { // Només dibuixar si la nau està viva - if (esta_tocada_) + if (esta_tocada_) { return; + } // Si invulnerable, parpadear (toggle on/off) if (es_invulnerable()) { @@ -149,8 +148,9 @@ void Nau::dibuixar() const { } } - if (!forma_) + if (!forma_) { return; + } // Escalar velocitat per l'efecte visual (200 px/s → ~6 px d'efecte) // El codi Pascal original sumava velocitat (0-6) al radi per donar @@ -182,7 +182,10 @@ void Nau::aplicar_fisica(float delta_time) { // Boundary checking amb radi de la nau // CORRECCIÓ: Usar límits segurs i inequalitats inclusives - float min_x, max_x, min_y, max_y; + float min_x; + float max_x; + float min_y; + float max_y; Constants::obtenir_limits_zona_segurs(Defaults::Entities::SHIP_RADIUS, min_x, max_x, @@ -201,8 +204,6 @@ void Nau::aplicar_fisica(float delta_time) { // Fricció - desacceleració gradual (time-based) if (velocitat_ > 0.1F) { velocitat_ -= Defaults::Physics::FRICTION * delta_time; - if (velocitat_ < 0.0F) { - velocitat_ = 0.0F; - } + velocitat_ = std::max(velocitat_, 0.0F); } } diff --git a/source/game/escenes/escena_joc.cpp b/source/game/escenes/escena_joc.cpp index 7a44e2a..10a3ebc 100644 --- a/source/game/escenes/escena_joc.cpp +++ b/source/game/escenes/escena_joc.cpp @@ -4,6 +4,7 @@ #include "escena_joc.hpp" +#include #include #include #include @@ -76,9 +77,7 @@ void EscenaJoc::executar() { last_time = current_time; // Limitar delta_time per evitar grans salts - if (delta_time > 0.05F) { - delta_time = 0.05F; - } + delta_time = std::min(delta_time, 0.05F); // Actualitzar comptador de FPS sdl_.updateFPS(delta_time); @@ -1036,9 +1035,15 @@ void EscenaJoc::detectar_col·lisio_naus_enemics() { // Check collision for BOTH players for (uint8_t i = 0; i < 2; i++) { // Skip collisions if player is dead or invulnerable - if (itocado_per_jugador_[i] > 0.0F) continue; - if (!naus_[i].esta_viva()) continue; - if (naus_[i].es_invulnerable()) continue; + if (itocado_per_jugador_[i] > 0.0F) { + continue; + } + if (!naus_[i].esta_viva()) { + continue; + } + if (naus_[i].es_invulnerable()) { + continue; + } const Punt& pos_nau = naus_[i].get_centre(); @@ -1099,14 +1104,22 @@ void EscenaJoc::detectar_col·lisions_bales_jugadors() { // Check collision with BOTH players for (uint8_t player_id = 0; player_id < 2; player_id++) { // Skip if player is dead, invulnerable, or inactive - if (itocado_per_jugador_[player_id] > 0.0F) continue; - if (!naus_[player_id].esta_viva()) continue; - if (naus_[player_id].es_invulnerable()) continue; + if (itocado_per_jugador_[player_id] > 0.0F) { + continue; + } + if (!naus_[player_id].esta_viva()) { + continue; + } + if (naus_[player_id].es_invulnerable()) { + continue; + } // Skip inactive players bool jugador_actiu = (player_id == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; - if (!jugador_actiu) continue; + if (!jugador_actiu) { + continue; + } const Punt& pos_nau = naus_[player_id].get_centre(); @@ -1236,8 +1249,12 @@ Punt EscenaJoc::obtenir_punt_spawn(uint8_t player_id) const { void EscenaJoc::disparar_bala(uint8_t player_id) { // Verificar que el jugador está vivo - if (itocado_per_jugador_[player_id] > 0.0F) return; - if (!naus_[player_id].esta_viva()) return; + if (itocado_per_jugador_[player_id] > 0.0F) { + return; + } + if (!naus_[player_id].esta_viva()) { + return; + } // Calcular posición en la punta de la nave const Punt& ship_centre = naus_[player_id].get_centre(); diff --git a/source/game/escenes/escena_logo.cpp b/source/game/escenes/escena_logo.cpp index f7bb5b3..e75876f 100644 --- a/source/game/escenes/escena_logo.cpp +++ b/source/game/escenes/escena_logo.cpp @@ -25,8 +25,9 @@ using Opcio = ContextEscenes::Opcio; // Helper: calcular el progrés individual d'una lletra // en funció del progrés global (efecte seqüencial) static float calcular_progress_letra(size_t letra_index, size_t num_letras, float global_progress, float threshold) { - if (num_letras == 0) + if (num_letras == 0) { return 1.0F; + } // Calcular temps per lletra float duration_per_letra = 1.0F / static_cast(num_letras); @@ -37,11 +38,11 @@ static float calcular_progress_letra(size_t letra_index, size_t num_letras, floa // Interpolar progrés if (global_progress < start) { return 0.0F; // Encara no ha començat - } else if (global_progress >= end) { - return 1.0F; // Completament apareguda - } else { - return (global_progress - start) / (end - start); } + if (global_progress >= end) { + return 1.0F; // Completament apareguda + } + return (global_progress - start) / (end - start); } EscenaLogo::EscenaLogo(SDLManager& sdl, ContextEscenes& context) @@ -79,9 +80,7 @@ void EscenaLogo::executar() { last_time = current_time; // Limitar delta_time per evitar grans salts - if (delta_time > 0.05F) { - delta_time = 0.05F; - } + delta_time = std::min(delta_time, 0.05F); // Actualitzar comptador de FPS sdl_.updateFPS(delta_time); @@ -395,7 +394,7 @@ void EscenaLogo::dibuixar() { // Dibuixar només lletres que NO han explotat for (size_t i = 0; i < lletres_.size(); i++) { - if (explotades.find(i) == explotades.end()) { + if (!explotades.contains(i)) { const auto& lletra = lletres_[i]; Rendering::render_shape( diff --git a/source/game/escenes/escena_titol.cpp b/source/game/escenes/escena_titol.cpp index c9b4518..4a1d1c1 100644 --- a/source/game/escenes/escena_titol.cpp +++ b/source/game/escenes/escena_titol.cpp @@ -3,6 +3,7 @@ #include "escena_titol.hpp" +#include #include #include #include @@ -265,9 +266,7 @@ void EscenaTitol::executar() { last_time = current_time; // Limitar delta_time per evitar grans salts - if (delta_time > 0.05F) { - delta_time = 0.05F; - } + delta_time = std::min(delta_time, 0.05F); // Actualitzar comptador de FPS sdl_.updateFPS(delta_time); @@ -567,7 +566,7 @@ void EscenaTitol::dibuixar() { // === Calcular i renderitzar ombra (només si animació activa) === if (animacio_activa_) { float temps_shadow = temps_animacio_ - SHADOW_DELAY; - if (temps_shadow < 0.0F) temps_shadow = 0.0F; // Evitar temps negatiu + temps_shadow = std::max(temps_shadow, 0.0F); // Evitar temps negatiu // Usar amplituds i freqüències completes per l'ombra float amplitude_x_shadow = ORBIT_AMPLITUDE_X; @@ -676,13 +675,17 @@ void EscenaTitol::dibuixar() { // Línea 1: Original (© 1999 Visente i Sergi) std::string copyright_original = Project::COPYRIGHT_ORIGINAL; for (char& c : copyright_original) { - if (c >= 'a' && c <= 'z') c = c - 32; // Uppercase + if (c >= 'a' && c <= 'z') { + c = c - 32; // Uppercase + } } // Línea 2: Port (© 2025 jaildesigner) std::string copyright_port = Project::COPYRIGHT_PORT; for (char& c : copyright_port) { - if (c >= 'a' && c <= 'z') c = c - 32; // Uppercase + if (c >= 'a' && c <= 'z') { + c = c - 32; // Uppercase + } } // Calcular posicions (anclatge des del top + separació) diff --git a/source/game/options.cpp b/source/game/options.cpp index 2251b2d..01e1bb1 100644 --- a/source/game/options.cpp +++ b/source/game/options.cpp @@ -448,76 +448,98 @@ static void loadAudioConfigFromYaml(const fkyaml::node& yaml) { // Carregar controls del jugador 1 des de YAML static void loadPlayer1ControlsFromYaml(const fkyaml::node& yaml) { - if (!yaml.contains("player1")) return; + if (!yaml.contains("player1")) { + return; + } const auto& p1 = yaml["player1"]; // Carregar controls de teclat if (p1.contains("keyboard")) { const auto& kb = p1["keyboard"]; - if (kb.contains("key_left")) + if (kb.contains("key_left")) { player1.keyboard.key_left = stringToScancode(kb["key_left"].get_value()); - if (kb.contains("key_right")) + } + if (kb.contains("key_right")) { player1.keyboard.key_right = stringToScancode(kb["key_right"].get_value()); - if (kb.contains("key_thrust")) + } + if (kb.contains("key_thrust")) { player1.keyboard.key_thrust = stringToScancode(kb["key_thrust"].get_value()); - if (kb.contains("key_shoot")) + } + if (kb.contains("key_shoot")) { player1.keyboard.key_shoot = stringToScancode(kb["key_shoot"].get_value()); + } } // Carregar controls de gamepad if (p1.contains("gamepad")) { const auto& gp = p1["gamepad"]; - if (gp.contains("button_left")) + if (gp.contains("button_left")) { player1.gamepad.button_left = stringToButton(gp["button_left"].get_value()); - if (gp.contains("button_right")) + } + if (gp.contains("button_right")) { player1.gamepad.button_right = stringToButton(gp["button_right"].get_value()); - if (gp.contains("button_thrust")) + } + if (gp.contains("button_thrust")) { player1.gamepad.button_thrust = stringToButton(gp["button_thrust"].get_value()); - if (gp.contains("button_shoot")) + } + if (gp.contains("button_shoot")) { player1.gamepad.button_shoot = stringToButton(gp["button_shoot"].get_value()); + } } // Carregar nom del gamepad - if (p1.contains("gamepad_name")) + if (p1.contains("gamepad_name")) { player1.gamepad_name = p1["gamepad_name"].get_value(); + } } // Carregar controls del jugador 2 des de YAML static void loadPlayer2ControlsFromYaml(const fkyaml::node& yaml) { - if (!yaml.contains("player2")) return; + if (!yaml.contains("player2")) { + return; + } const auto& p2 = yaml["player2"]; // Carregar controls de teclat if (p2.contains("keyboard")) { const auto& kb = p2["keyboard"]; - if (kb.contains("key_left")) + if (kb.contains("key_left")) { player2.keyboard.key_left = stringToScancode(kb["key_left"].get_value()); - if (kb.contains("key_right")) + } + if (kb.contains("key_right")) { player2.keyboard.key_right = stringToScancode(kb["key_right"].get_value()); - if (kb.contains("key_thrust")) + } + if (kb.contains("key_thrust")) { player2.keyboard.key_thrust = stringToScancode(kb["key_thrust"].get_value()); - if (kb.contains("key_shoot")) + } + if (kb.contains("key_shoot")) { player2.keyboard.key_shoot = stringToScancode(kb["key_shoot"].get_value()); + } } // Carregar controls de gamepad if (p2.contains("gamepad")) { const auto& gp = p2["gamepad"]; - if (gp.contains("button_left")) + if (gp.contains("button_left")) { player2.gamepad.button_left = stringToButton(gp["button_left"].get_value()); - if (gp.contains("button_right")) + } + if (gp.contains("button_right")) { player2.gamepad.button_right = stringToButton(gp["button_right"].get_value()); - if (gp.contains("button_thrust")) + } + if (gp.contains("button_thrust")) { player2.gamepad.button_thrust = stringToButton(gp["button_thrust"].get_value()); - if (gp.contains("button_shoot")) + } + if (gp.contains("button_shoot")) { player2.gamepad.button_shoot = stringToButton(gp["button_shoot"].get_value()); + } } // Carregar nom del gamepad - if (p2.contains("gamepad_name")) + if (p2.contains("gamepad_name")) { player2.gamepad_name = p2["gamepad_name"].get_value(); + } } // Carregar configuració des del fitxer YAML diff --git a/source/game/options.hpp b/source/game/options.hpp index d218863..3d019d6 100644 --- a/source/game/options.hpp +++ b/source/game/options.hpp @@ -70,7 +70,7 @@ struct GamepadControls { struct PlayerControls { KeyboardControls keyboard{}; GamepadControls gamepad{}; - std::string gamepad_name{""}; // Buit = auto-assignar per índex + std::string gamepad_name; // Buit = auto-assignar per índex }; // Variables globals (inline per evitar ODR violations) diff --git a/source/game/stage_system/spawn_controller.cpp b/source/game/stage_system/spawn_controller.cpp index 892894f..014aad8 100644 --- a/source/game/stage_system/spawn_controller.cpp +++ b/source/game/stage_system/spawn_controller.cpp @@ -19,7 +19,7 @@ void SpawnController::configurar(const ConfigStage* config) { } void SpawnController::iniciar() { - if (!config_) { + if (config_ == nullptr) { std::cerr << "[SpawnController] Error: config_ és null" << std::endl; return; } @@ -38,7 +38,7 @@ void SpawnController::reset() { } void SpawnController::actualitzar(float delta_time, std::array& orni_array, bool pausar) { - if (!config_ || spawn_queue_.empty()) { + if ((config_ == nullptr) || spawn_queue_.empty()) { return; } @@ -111,7 +111,7 @@ uint8_t SpawnController::get_enemics_spawnejats() const { } void SpawnController::generar_spawn_events() { - if (!config_) { + if (config_ == nullptr) { return; } @@ -126,7 +126,7 @@ void SpawnController::generar_spawn_events() { } TipusEnemic SpawnController::seleccionar_tipus_aleatori() const { - if (!config_) { + if (config_ == nullptr) { return TipusEnemic::PENTAGON; } @@ -135,11 +135,11 @@ TipusEnemic SpawnController::seleccionar_tipus_aleatori() const { if (rand_val < config_->distribucio.pentagon) { return TipusEnemic::PENTAGON; - } else if (rand_val < config_->distribucio.pentagon + config_->distribucio.quadrat) { - return TipusEnemic::QUADRAT; - } else { - return TipusEnemic::MOLINILLO; } + if (rand_val < config_->distribucio.pentagon + config_->distribucio.quadrat) { + return TipusEnemic::QUADRAT; + } + return TipusEnemic::MOLINILLO; } void SpawnController::spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Punt* ship_pos) { @@ -151,7 +151,7 @@ void SpawnController::spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Punt } void SpawnController::aplicar_multiplicadors(Enemic& enemic) const { - if (!config_) { + if (config_ == nullptr) { return; } diff --git a/source/game/stage_system/stage_loader.cpp b/source/game/stage_system/stage_loader.cpp index 11934c6..eecea6f 100644 --- a/source/game/stage_system/stage_loader.cpp +++ b/source/game/stage_system/stage_loader.cpp @@ -212,15 +212,16 @@ bool StageLoader::parse_multipliers(const fkyaml::node& yaml, MultiplicadorsDifi ModeSpawn StageLoader::parse_spawn_mode(const std::string& mode_str) { if (mode_str == "progressive") { return ModeSpawn::PROGRESSIVE; - } else if (mode_str == "immediate") { - return ModeSpawn::IMMEDIATE; - } else if (mode_str == "wave") { - return ModeSpawn::WAVE; - } else { - std::cerr << "[StageLoader] Warning: mode de spawn desconegut '" << mode_str - << "', usant PROGRESSIVE" << std::endl; - return ModeSpawn::PROGRESSIVE; } + if (mode_str == "immediate") { + return ModeSpawn::IMMEDIATE; + } + if (mode_str == "wave") { + return ModeSpawn::WAVE; + } + std::cerr << "[StageLoader] Warning: mode de spawn desconegut '" << mode_str + << "', usant PROGRESSIVE" << std::endl; + return ModeSpawn::PROGRESSIVE; } bool StageLoader::validar_config(const ConfigSistemaStages& config) { diff --git a/source/game/stage_system/stage_manager.cpp b/source/game/stage_system/stage_manager.cpp index 0993564..60e5b3e 100644 --- a/source/game/stage_system/stage_manager.cpp +++ b/source/game/stage_system/stage_manager.cpp @@ -15,7 +15,7 @@ StageManager::StageManager(const ConfigSistemaStages* config) estat_(EstatStage::LEVEL_START), stage_actual_(1), timer_transicio_(0.0F) { - if (!config_) { + if (config_ == nullptr) { std::cerr << "[StageManager] Error: config és null" << std::endl; } } @@ -153,7 +153,7 @@ void StageManager::processar_level_completed(float delta_time) { void StageManager::carregar_stage(uint8_t stage_id) { const ConfigStage* stage_config = config_->obte_stage(stage_id); - if (!stage_config) { + if (stage_config == nullptr) { std::cerr << "[StageManager] Error: no es pot trobar stage " << static_cast(stage_id) << std::endl; return; diff --git a/source/game/title/ship_animator.cpp b/source/game/title/ship_animator.cpp index 2b69591..802cf87 100644 --- a/source/game/title/ship_animator.cpp +++ b/source/game/title/ship_animator.cpp @@ -34,7 +34,9 @@ void ShipAnimator::inicialitzar() { void ShipAnimator::actualitzar(float delta_time) { // Dispatcher segons estat de cada nau for (auto& nau : naus_) { - if (!nau.visible) continue; + if (!nau.visible) { + continue; + } switch (nau.estat) { case EstatNau::ENTERING: @@ -52,7 +54,9 @@ void ShipAnimator::actualitzar(float delta_time) { void ShipAnimator::dibuixar() const { for (const auto& nau : naus_) { - if (!nau.visible) continue; + if (!nau.visible) { + continue; + } // Renderitzar nau (perspectiva ja incorporada a la forma) Rendering::render_shape(