Fase 1e: cierre de naming sweep (#pragma once, locals, comentarios castellano)

Tres tareas de pulido para cerrar la Fase 1 por completo:

#pragma once uniforme:
- sdl_manager.hpp y game_scene.hpp pasan de #ifndef/#define guards
  a #pragma once. Los archivos externos (stb_vorbis.h, fkyaml_node.hpp)
  se mantienen intactos (codigo de terceros).

Variables locales y parametros restantes (catalan -> ingles):
- fitxer -> file, moviment -> movement, inici -> start
- comptador -> counter, escalada -> scaled
- missatges -> messages, llista -> list
- alçada -> height, amplada -> width, llargada -> length
- origen -> origin, distancia -> distance, valor -> value, desti -> target
- neteja -> clear, presenta -> present (SDLManager)
- total_enemics -> total_enemies, configurar -> configure, iniciar -> start

Comentarios catalan -> castellano:
- Cabeceras de fichero actualizadas con nombres nuevos
  (escena_joc.hpp -> game_scene.hpp, etc.)
- Palabras tecnicas: trasllacio->traslacion, col-lisio->colision,
  inicialitzacio->inicializacion, posicio->posicion, rotacio->rotacion,
  velocitat->velocidad, acceleracio->aceleracion, explosio->explosion,
  renderitzat->renderizado, calcul->calculo, transicio->transicion,
  comprovacio->comprobacion, substitucio->sustitucion,
  utilitzacio->utilizacion, opcio->opcion, configuracio->configuracion,
  funcio->funcion, distancia, animacio->animacion
- Determinantes y conectores: aquest->este, aquesta->esta,
  amb->con, sense->sin, pero->pero, mai->nunca, nomes->solo,
  tambe->tambien, sempre->siempre, ja->ya, mateix->mismo,
  vegada->vez, dintre->dentro, fora->fuera, dreta->derecha,
  esquerra->izquierda, sortir->salir, sortida->salida,
  petit->pequeno, gran->grande, nou->nuevo, vell->viejo,
  molt->mucho, els->los, les->las, totes les->todas las,
  d'->de, com->como, quan->cuando, mentre->mientras,
  despres->despues, abans->antes, durant->durante, fins->hasta,
  encara->aun, llavors->entonces, aixi->asi, perque->porque
- Sustantivos: classe->clase, metode->metodo, parametre->parametro,
  versio->version, entitat->entidad, joc->juego, nivell->nivel,
  enemic->enemigo, naus->naves, bales->balas, fitxer->archivo,
  pentagon->pentagono, pun- tuacio->puntuacion, flotant->flotante,
  titol->titulo, objectiu->objetivo, mostra->muestra, tipus->tipo

Strings literales preservados en valenciano segun decision del
usuario: el texto del HUD del juego (puntuaciones, mensajes en
pantalla, archivo de config) se mantiene en valenciano original.

70 fitxers tocats, +1117 / -1123. Compila i enllaca.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-19 12:12:30 +02:00
parent 7ee359b910
commit bf83f161b0
71 changed files with 1142 additions and 1148 deletions
+1 -1
View File
@@ -64,7 +64,7 @@ void Audio::playMusic(const std::string& name, const int loop) {
// Llamada al motor para reproducir la nueva pista
JA_PlayMusic(resource, loop);
// Actualizar estado y metadatos después de iniciar con éxito
// Actualizar estado y metadatos después de start con éxito
music_.name = name;
music_.loop = new_loop;
music_.state = MusicState::PLAYING;
+2 -2
View File
@@ -1,5 +1,5 @@
// audio_cache.cpp - Implementació del caché de sons i música
// © 2025 Port a C++20 amb SDL3
// © 2025 Port a C++20 con SDL3
#include "core/audio/audio_cache.hpp"
@@ -7,7 +7,7 @@
#include "core/resources/resource_helper.hpp"
// Inicialització de variables estàtiques
// Inicialización de variables estàtiques
std::unordered_map<std::string, JA_Sound_t*> AudioCache::sounds_;
std::unordered_map<std::string, JA_Music_t*> AudioCache::musics_;
std::string AudioCache::sounds_base_path_ = "data/sounds/";
+1 -1
View File
@@ -1,5 +1,5 @@
// audio_cache.hpp - Caché simplificado de sonidos y música
// © 2025 Port a C++20 amb SDL3
// © 2025 Port a C++20 con SDL3
#pragma once
+1 -1
View File
@@ -158,7 +158,7 @@ inline JA_Music_t* JA_LoadMusic(const Uint8* buffer, Uint32 length) {
}
inline JA_Music_t* JA_LoadMusic(const char* filename) {
// [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid.
// [RZC 28/08/22] Carreguem primer el arxiu en memòria y después el descomprimim. Es algo més rapid.
FILE* f = fopen(filename, "rb");
if (!f) return NULL; // Añadida comprobación de apertura
fseek(f, 0, SEEK_END);
+58 -58
View File
@@ -19,27 +19,27 @@ constexpr float ZOOM_INCREMENT = 0.1F; // 10% steps (F1/F2)
constexpr bool FULLSCREEN = true; // Pantalla completa activadapor defecto
} // namespace Window
// Dimensions base del joc (coordenades lògiques)
// Dimensions base del juego (coordenades lògiques)
namespace Game {
constexpr int WIDTH = 640;
constexpr int HEIGHT = 480;
} // namespace Game
// Zones del joc (SDL_FRect amb càlculs automàtics basat en percentatges)
// Zones del juego (SDL_FRect con cálculos automàtics basat en percentatges)
namespace Zones {
// --- CONFIGURACIÓ DE PORCENTATGES ---
// Totes les zones definides com a percentatges de Game::WIDTH (640) i Game::HEIGHT (480)
// Todas las zones definides como a percentatges de Game::WIDTH (640) i Game::HEIGHT (480)
// Percentatges d'alçada (divisió vertical)
// Percentatges de height (divisió vertical)
constexpr float SCOREBOARD_TOP_HEIGHT_PERCENT = 0.02F; // 10% superior
constexpr float MAIN_PLAYAREA_HEIGHT_PERCENT = 0.88F; // 80% central
constexpr float SCOREBOARD_BOTTOM_HEIGHT_PERCENT = 0.10F; // 10% inferior
// Padding horizontal per a PLAYAREA (dins de MAIN_PLAYAREA)
// Padding horizontal para PLAYAREA (dins de MAIN_PLAYAREA)
constexpr float PLAYAREA_PADDING_HORIZONTAL_PERCENT = 0.015F; // 5% a cada costat
// --- CÀLCULS AUTOMÀTICS DE PÍXELS ---
// Càlculs automàtics a partir dels percentatges
// Cálculos automàtics a partir dels percentatges
// Alçades
constexpr float SCOREBOARD_TOP_H = Game::HEIGHT * SCOREBOARD_TOP_HEIGHT_PERCENT;
@@ -56,7 +56,7 @@ constexpr float PLAYAREA_PADDING_H = Game::WIDTH * PLAYAREA_PADDING_HORIZONTAL_P
// --- ZONES FINALS (SDL_FRect) ---
// Marcador superior (reservat per a futur ús)
// Marcador superior (reservat para futur ús)
// Ocupa: 10% superior (0-48px)
constexpr SDL_FRect SCOREBOARD_TOP = {
0.0F, // x = 0.0
@@ -65,7 +65,7 @@ constexpr SDL_FRect SCOREBOARD_TOP = {
SCOREBOARD_TOP_H // h = 48.0
};
// Àrea de joc principal (contenidor del 80% central, sense padding)
// Àrea de juego principal (contenidor del 80% central, sin padding)
// Ocupa: 10-90% (48-432px), ample complet
constexpr SDL_FRect MAIN_PLAYAREA = {
0.0F, // x = 0.0
@@ -74,9 +74,9 @@ constexpr SDL_FRect MAIN_PLAYAREA = {
MAIN_PLAYAREA_H // h = 384.0
};
// Zona de joc real (amb padding horizontal del 5%)
// Ocupa: dins de MAIN_PLAYAREA, amb marges laterals
// S'utilitza per a límits del joc, col·lisions, spawn
// Zona de juego real (con padding horizontal del 5%)
// Ocupa: dins de MAIN_PLAYAREA, con marges laterals
// S'utilitza para límits del juego, colisiones, spawn
constexpr SDL_FRect PLAYAREA = {
PLAYAREA_PADDING_H, // x = 32.0
MAIN_PLAYAREA_Y, // y = 48.0 (igual que MAIN_PLAYAREA)
@@ -93,7 +93,7 @@ constexpr SDL_FRect SCOREBOARD = {
SCOREBOARD_BOTTOM_H // h = 48.0
};
// Padding horizontal del marcador (per alinear zones esquerra/dreta amb PLAYAREA)
// Padding horizontal del marcador (per alinear zones izquierda/derecha con PLAYAREA)
constexpr float SCOREBOARD_PADDING_H = 0.0F; // Game::WIDTH * 0.015f;
} // namespace Zones
@@ -211,11 +211,11 @@ constexpr float VELOCITY_SCALE = 20.0F; // factor conversión frame→tiempo
// Explosions (debris physics)
namespace Debris {
constexpr float VELOCITAT_BASE = 80.0F; // Velocitat inicial (px/s)
constexpr float VELOCITAT_BASE = 80.0F; // Velocidad inicial (px/s)
constexpr float VARIACIO_VELOCITAT = 40.0F; // ±variació aleatòria (px/s)
constexpr float ACCELERACIO = -60.0F; // Fricció/desacceleració (px/s²)
constexpr float ROTACIO_MIN = 0.1F; // Rotació mínima (rad/s ~5.7°/s)
constexpr float ROTACIO_MAX = 0.3F; // Rotació màxima (rad/s ~17.2°/s)
constexpr float ROTACIO_MIN = 0.1F; // Rotación mínima (rad/s ~5.7°/s)
constexpr float ROTACIO_MAX = 0.3F; // Rotación màxima (rad/s ~17.2°/s)
constexpr float TEMPS_VIDA = 2.0F; // Duració màxima (segons) - enemy/bullet debris
constexpr float TEMPS_VIDA_NAU = 3.0F; // Ship debris lifetime (matches DEATH_DURATION)
constexpr float SHRINK_RATE = 0.5F; // Reducció de mida (factor/s)
@@ -225,7 +225,7 @@ constexpr float FACTOR_HERENCIA_MIN = 0.7F; // Mínimo 70% del drotacio heredat
constexpr float FACTOR_HERENCIA_MAX = 1.0F; // Màxim 100% del drotacio heredat
constexpr float FRICCIO_ANGULAR = 0.5F; // Desacceleració angular (rad/s²)
// Angular velocity cap for trajectory inheritance
// Angular velocity sin for trajectory inheritance
// Excess above this threshold is converted to tangential linear velocity
// Prevents "vortex trap" problem with high-rotation enemies
constexpr float VELOCITAT_ROT_MAX = 1.5F; // rad/s (~86°/s)
@@ -261,21 +261,21 @@ constexpr uint8_t BACKGROUND_MAX_G = 15;
constexpr uint8_t BACKGROUND_MAX_B = 0;
} // namespace Color
// Brillantor (control de intensitat per cada type d'entitat)
// Brillantor (control de intensitat per cada type de entidad)
namespace Brightness {
// Brillantor estàtica per entitats de joc (0.0-1.0)
// Brillantor estàtica per entidades de juego (0.0-1.0)
constexpr float NAU = 1.0F; // Màxima visibilitat (player)
constexpr float ENEMIC = 0.7F; // 30% més tènue (destaca menys)
constexpr float BALA = 1.0F; // Brillo a tope (màxima visibilitat)
// Starfield: gradient segons distància al centre
// distancia_centre: 0.0 (centre) → 1.0 (vora pantalla)
// Starfield: gradient segons distancia al centro
// distancia_centre: 0.0 (centro) → 1.0 (vora pantalla)
// brightness = MIN + (MAX - MIN) * distancia_centre
constexpr float STARFIELD_MIN = 0.3F; // Estrelles llunyanes (prop del centre)
constexpr float STARFIELD_MIN = 0.3F; // Estrelles llunyanes (prop del centro)
constexpr float STARFIELD_MAX = 0.8F; // Estrelles properes (vora pantalla)
} // namespace Brightness
// Renderització (V-Sync i altres opcions de render)
// Renderització (V-Sync i altres opciones de render)
namespace Rendering {
constexpr int VSYNC_DEFAULT = 1; // 0=disabled, 1=enabled
} // namespace Rendering
@@ -327,7 +327,7 @@ constexpr SDL_Keycode SHOOT = SDLK_LSHIFT;
} // namespace P2
} // namespace Controls
// Enemy type configuration (type d'enemics)
// Enemy type configuration (type de enemigos)
namespace Enemies {
// Pentagon (esquivador - zigzag evasion)
namespace Pentagon {
@@ -339,15 +339,15 @@ constexpr float DROTACIO_MAX = 3.75F; // Max visual rotation (rad/s) [+50%]
constexpr const char* SHAPE_FILE = "enemy_pentagon.shp";
} // namespace Pentagon
// Quadrat (perseguidor - tracks player)
namespace Quadrat {
// Cuadrado (perseguidor - tracks player)
namespace Cuadrado {
constexpr float VELOCITAT = 40.0F; // px/s (medium speed)
constexpr float TRACKING_STRENGTH = 0.5F; // Interpolation toward player (0.0-1.0)
constexpr float TRACKING_INTERVAL = 1.0F; // Seconds between angle updates
constexpr float DROTACIO_MIN = 0.3F; // Slow rotation [+50%]
constexpr float DROTACIO_MAX = 1.5F; // [+50%]
constexpr const char* SHAPE_FILE = "enemy_square.shp";
} // namespace Quadrat
} // namespace Cuadrado
// Molinillo (agressiu - fast straight lines, proximity spin-up)
namespace Molinillo {
@@ -395,34 +395,34 @@ constexpr float INVULNERABILITY_SCALE_START = 0.0F; // Invisible
constexpr float INVULNERABILITY_SCALE_END = 1.0F; // Full size
} // namespace Spawn
// Scoring system (puntuació per type d'enemy)
// Scoring system (puntuación per type de enemy)
namespace Scoring {
constexpr int PENTAGON_SCORE = 100; // Pentàgon (esquivador, 35 px/s)
constexpr int QUADRAT_SCORE = 150; // Quadrat (perseguidor, 40 px/s)
constexpr int PENTAGON_SCORE = 100; // Pentágono (esquivador, 35 px/s)
constexpr int QUADRAT_SCORE = 150; // Cuadrado (perseguidor, 40 px/s)
constexpr int MOLINILLO_SCORE = 200; // Molinillo (agressiu, 50 px/s)
} // namespace Scoring
} // namespace Enemies
// Title scene ship animations (naus 3D flotants a l'escena de títol)
// Title scene ship animations (naves 3D flotantes a l'escena de título)
namespace Title {
namespace Ships {
// ============================================================
// PARÀMETRES BASE (ajustar aquí per experimentar)
// ============================================================
// 1. Escala global de les naus
// 1. Escala global de las naves
constexpr float SHIP_BASE_SCALE = 2.5F; // Multiplicador (1.0 = mida original del .shp)
// 2. Altura vertical (cercanía al centro)
// Ratio Y desde el centro de la pantalla (0.0 = centro, 1.0 = bottom de pantalla)
constexpr float TARGET_Y_RATIO = 0.15625F;
// 3. Radio orbital (distancia radial desde centro en coordenadas polares)
constexpr float CLOCK_RADIUS = 150.0F; // Distància des del centre
// 3. Radio orbital (distance radial desde centro en coordenadas polares)
constexpr float CLOCK_RADIUS = 150.0F; // Distancia des del centro
// 4. Ángulos de posición (clock positions en coordenadas polares)
// En coordenades de pantalla: 0° = dreta, 90° = baix, 180° = esquerra, 270° = dalt
// En coordenades de pantalla: 0° = derecha, 90° = baix, 180° = izquierda, 270° = dalt
constexpr float CLOCK_8_ANGLE = 150.0F * Math::PI / 180.0F; // 8 o'clock (bottom-left)
constexpr float CLOCK_4_ANGLE = 30.0F * Math::PI / 180.0F; // 4 o'clock (bottom-right)
@@ -436,13 +436,13 @@ constexpr float ENTRY_OFFSET_MARGIN = 227.5F; // Para offset total de ~340px (a
// VALORS DERIVATS (calculats automàticament - NO modificar)
// ============================================================
// Centre de la pantalla (point de referència)
// Centro de la pantalla (point de referència)
constexpr float CENTER_X = Game::WIDTH / 2.0F; // 320.0f
constexpr float CENTER_Y = Game::HEIGHT / 2.0F; // 240.0f
// Posicions target (calculades dinàmicament des dels paràmetres base)
// 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)
// Posicions target (calculades dinàmicament des dels parámetros base)
// Nota: std::cos/sin no són constexpr en C++20, pero funcionen en runtime
// Les funciones inline són optimitzades por el compilador (zero overhead)
inline float P1_TARGET_X() {
return CENTER_X + (CLOCK_RADIUS * std::cos(CLOCK_8_ANGLE));
}
@@ -456,15 +456,15 @@ inline float P2_TARGET_Y() {
return CENTER_Y + ((Game::HEIGHT / 2.0F) * TARGET_Y_RATIO);
}
// Escales d'animació (relatives a SHIP_BASE_SCALE)
constexpr float ENTRY_SCALE_START = 1.5F * SHIP_BASE_SCALE; // Entrada: 50% més gran
constexpr float FLOATING_SCALE = 1.0F * SHIP_BASE_SCALE; // Flotant: scale base
// Escales de animación (relatives a SHIP_BASE_SCALE)
constexpr float ENTRY_SCALE_START = 1.5F * SHIP_BASE_SCALE; // Entrada: 50% més grande
constexpr float FLOATING_SCALE = 1.0F * SHIP_BASE_SCALE; // Flotante: scale base
// Offset d'entrada (ajustat automàticament a l'scale)
// Fórmula: (radi màxim de la ship * scale d'entrada) + marge
// Offset de entrada (ajustat automàticament a l'scale)
// Fórmula: (radi màxim de la ship * scale de entrada) + marge
constexpr float ENTRY_OFFSET = (SHIP_MAX_RADIUS * ENTRY_SCALE_START) + ENTRY_OFFSET_MARGIN;
// Vec2 de fuga (centre per a l'animació de sortida)
// Vec2 de fuga (centro para l'animación de salida)
constexpr float VANISHING_POINT_X = CENTER_X; // 320.0f
constexpr float VANISHING_POINT_Y = CENTER_Y; // 240.0f
@@ -472,11 +472,11 @@ constexpr float VANISHING_POINT_Y = CENTER_Y; // 240.0f
// ANIMACIONS (durades, oscil·lacions, delays)
// ============================================================
// Durades d'animació
// Durades de animación
constexpr float ENTRY_DURATION = 2.0F; // Entrada (segons)
constexpr float EXIT_DURATION = 1.0F; // Sortida (segons)
constexpr float EXIT_DURATION = 1.0F; // Salida (segons)
// Flotació (oscil·lació reduïda i diferenciada per ship)
// Flotació (oscil·lació reduïda y diferenciada per ship)
constexpr float FLOAT_AMPLITUDE_X = 4.0F; // Amplitud X (píxels)
constexpr float FLOAT_AMPLITUDE_Y = 2.5F; // Amplitud Y (píxels)
@@ -485,21 +485,21 @@ constexpr float FLOAT_FREQUENCY_X_BASE = 0.5F; // Hz
constexpr float FLOAT_FREQUENCY_Y_BASE = 0.7F; // Hz
constexpr float FLOAT_PHASE_OFFSET = 1.57F; // π/2 (90°)
// Delays d'entrada (per a entrada escalonada)
// Delays de entrada (per a entrada escalonada)
constexpr float P1_ENTRY_DELAY = 0.0F; // P1 entra immediatament
constexpr float P2_ENTRY_DELAY = 0.5F; // P2 entra 0.5s després
constexpr float P2_ENTRY_DELAY = 0.5F; // P2 entra 0.5s después
// Delay global abans d'iniciar l'animació d'entrada al state MAIN
constexpr float ENTRANCE_DELAY = 5.0F; // Temps d'espera abans que les naus entrin
// Delay global antes de start l'animación de entrada al state MAIN
constexpr float ENTRANCE_DELAY = 5.0F; // Temps de espera antes que las naves entrin
// Multiplicadors de freqüència per a cada ship (variació sutil ±12%)
// Multiplicadors de freqüència para cada ship (variació sutil ±12%)
constexpr float P1_FREQUENCY_MULTIPLIER = 0.88F; // 12% més lenta
constexpr float P2_FREQUENCY_MULTIPLIER = 1.12F; // 12% més ràpida
} // namespace Ships
namespace Layout {
// Posicions verticals (anclatges des del TOP de pantalla lògica, 0.0-1.0)
// Posicions verticals (anclatges des del TOP de pantalla lógica, 0.0-1.0)
constexpr float LOGO_POS = 0.20F; // Logo "ORNI"
constexpr float PRESS_START_POS = 0.75F; // "PRESS START TO PLAY"
constexpr float COPYRIGHT1_POS = 0.90F; // Primera línia copyright
@@ -508,21 +508,21 @@ constexpr float COPYRIGHT1_POS = 0.90F; // Primera línia copyright
constexpr float LOGO_LINE_SPACING = 0.02F; // Entre "ORNI" i "ATTACK!" (10px)
constexpr float COPYRIGHT_LINE_SPACING = 0.0F; // Entre línies copyright (5px)
// Factors d'scale
// Factors de scale
constexpr float LOGO_SCALE = 0.6F; // Escala "ORNI ATTACK!"
constexpr float PRESS_START_SCALE = 1.0F; // Escala "PRESS START TO PLAY"
constexpr float COPYRIGHT_SCALE = 0.5F; // Escala copyright
// Espaiat entre caràcters (usat per VectorText)
// Espaiat entre caràcters (usado per VectorText)
constexpr float TEXT_SPACING = 2.0F;
} // namespace Layout
} // namespace Title
// Floating score numbers (números flotants de puntuació)
// Floating score numbers (números flotantes de puntuación)
namespace FloatingScore {
constexpr float LIFETIME = 2.0F; // Duració màxima (segons)
constexpr float VELOCITY_Y = -30.0F; // Velocitat vertical (px/s, negatiu = amunt)
constexpr float VELOCITY_X = 0.0F; // Velocitat horizontal (px/s)
constexpr float VELOCITY_Y = -30.0F; // Velocidad vertical (px/s, negatiu = amunt)
constexpr float VELOCITY_X = 0.0F; // Velocidad horizontal (px/s)
constexpr float SCALE = 0.45F; // Escala del text (0.6 = 60% del marcador)
constexpr float SPACING = 0.0F; // Espaiat entre caràcters
constexpr int MAX_CONCURRENT = 15; // Pool size (= MAX_ORNIS)
+6 -6
View File
@@ -1,5 +1,5 @@
// entitat.hpp - Classe base abstracta per a totes les entitats del joc
// © 2025 Orni Attack - Arquitectura d'entitats
// entity.hpp - Clase base abstracta para todas las entidades del juego
// © 2025 Orni Attack - Arquitectura de entidades
#pragma once
@@ -22,25 +22,25 @@ class Entity {
virtual void draw() const = 0;
[[nodiscard]] virtual bool isActive() const = 0;
// Interfície de col·lisió (override opcional)
// Interfície de colisión (override opcional)
[[nodiscard]] virtual float getCollisionRadius() const { return 0.0F; }
[[nodiscard]] virtual bool isCollidable() const { return false; }
// Getters comuns (inline, sense overhead)
// Getters comuns (inline, sin overhead)
[[nodiscard]] const Vec2& getCenter() const { return center_; }
[[nodiscard]] float getAngle() const { return angle_; }
[[nodiscard]] float getBrightness() const { return brightness_; }
[[nodiscard]] const std::shared_ptr<Graphics::Shape>& getShape() const { return shape_; }
protected:
// Estat comú (accés directe, sense overhead)
// Estat comú (accés directe, sin overhead)
SDL_Renderer* renderer_;
std::shared_ptr<Graphics::Shape> shape_;
Vec2 center_;
float angle_{0.0F};
float brightness_{1.0F};
// Constructor protegit (classe abstracta)
// Constructor protegit (clase abstracta)
Entity(SDL_Renderer* renderer = nullptr)
: renderer_(renderer),
center_({.x = 0.0F, .y = 0.0F}) {}
+6 -6
View File
@@ -1,5 +1,5 @@
// shape.cpp - Implementació del sistema de formes vectorials
// © 2025 Port a C++20 amb SDL3
// © 2025 Port a C++20 con SDL3
#include "core/graphics/shape.hpp"
@@ -18,14 +18,14 @@ Shape::Shape(const std::string& filepath)
}
bool Shape::load(const std::string& filepath) {
// Llegir fitxer
// Llegir file
std::ifstream file(filepath);
if (!file.is_open()) {
std::cerr << "[Shape] Error: no es pot obrir " << filepath << '\n';
return false;
}
// Llegir tot el contingut
// Llegir todo el contingut
std::stringstream buffer;
buffer << file.rdbuf();
std::string contingut = buffer.str();
@@ -65,7 +65,7 @@ bool Shape::parseFile(const std::string& contingut) {
if (points.size() >= 2) {
primitives_.push_back({PrimitiveType::POLYLINE, points});
} else {
std::cerr << "[Shape] Warning: polyline amb menys de 2 points ignorada"
std::cerr << "[Shape] Warning: polyline con menys de 2 points ignorada"
<< '\n';
}
} else if (starts_with(line, "line:")) {
@@ -81,7 +81,7 @@ bool Shape::parseFile(const std::string& contingut) {
}
if (primitives_.empty()) {
std::cerr << "[Shape] Error: cap primitiva carregada" << '\n';
std::cerr << "[Shape] Error: sin primitiva carregada" << '\n';
return false;
}
@@ -127,7 +127,7 @@ void Shape::parse_center(const std::string& value) {
center_.x = std::stof(trim(val.substr(0, comma)));
center_.y = std::stof(trim(val.substr(comma + 1)));
} catch (...) {
std::cerr << "[Shape] Warning: centre invàlid, usant (0,0)" << '\n';
std::cerr << "[Shape] Warning: centro invàlid, usant (0,0)" << '\n';
center_ = {.x = 0.0F, .y = 0.0F};
}
}
+7 -7
View File
@@ -1,5 +1,5 @@
// shape.hpp - Sistema de formes vectorials
// © 2025 Port a C++20 amb SDL3
// © 2025 Port a C++20 con SDL3
#pragma once
@@ -10,9 +10,9 @@
namespace Graphics {
// Tipus de primitiva dins d'una shape
// Tipo de primitiva dins de una shape
enum class PrimitiveType {
POLYLINE, // Seqüència de points connectats
POLYLINE, // Secuencia de points connectats
LINE // Línia individual (2 points)
};
@@ -22,17 +22,17 @@ struct ShapePrimitive {
std::vector<Vec2> points; // 2+ points per polyline, exactament 2 per line
};
// Classe Shape - representa una shape vectorial carregada des de .shp
// Clase Shape - representa una shape vectorial carregada desde .shp
class Shape {
public:
// Constructors
Shape() = default;
explicit Shape(const std::string& filepath);
// Carregar shape des de fitxer .shp
// Carregar shape desde file .shp
bool load(const std::string& filepath);
// Parsejar shape des de buffer de memòria (per al sistema de recursos)
// Parsejar shape desde buffer de memòria (per al sistema de recursos)
bool parseFile(const std::string& contingut);
// Getters
@@ -49,7 +49,7 @@ class Shape {
private:
std::vector<ShapePrimitive> primitives_;
Vec2 center_; // Centre/origen de la shape
Vec2 center_; // Centro/origin de la shape
float escala_defecte_; // Escala per defecte (normalment 1.0)
std::string nom_; // Nom de la shape (per depuració)
+6 -6
View File
@@ -1,5 +1,5 @@
// shape_loader.cpp - Implementació del carregador amb caché
// © 2025 Port a C++20 amb SDL3
// shape_loader.cpp - Implementació del carregador con caché
// © 2025 Port a C++20 con SDL3
#include "core/graphics/shape_loader.hpp"
@@ -9,7 +9,7 @@
namespace Graphics {
// Inicialització de variables estàtiques
// Inicialización de variables estàtiques
std::unordered_map<std::string, std::shared_ptr<Shape>> ShapeLoader::cache_;
std::string ShapeLoader::base_path_ = "data/shapes/";
@@ -69,17 +69,17 @@ void ShapeLoader::clear_cache() {
size_t ShapeLoader::get_cache_size() { return cache_.size(); }
std::string ShapeLoader::resolve_path(const std::string& filename) {
// Si és un path absolut (comença amb '/'), usar-lo directament
// Si es un path absolut (comença con '/'), usar-lo directament
if (!filename.empty() && filename[0] == '/') {
return filename;
}
// Si ja conté el prefix base_path, usar-lo directament
// Si ya conté el prefix base_path, usar-lo directament
if (filename.starts_with(base_path_)) {
return filename;
}
// Altrament, afegir base_path (ara suporta subdirectoris)
// Altrament, añadir base_path (ara suporta subdirectoris)
return base_path_ + filename;
}
+4 -4
View File
@@ -1,5 +1,5 @@
// shape_loader.hpp - Carregador estàtic de formes amb caché
// © 2025 Port a C++20 amb SDL3
// shape_loader.hpp - Carregador estàtic de formes con caché
// © 2025 Port a C++20 con SDL3
#pragma once
@@ -11,13 +11,13 @@
namespace Graphics {
// Carregador estàtic de formes amb caché
// Carregador estàtic de formes con caché
class ShapeLoader {
public:
// No instanciable (tot estàtic)
ShapeLoader() = delete;
// Carregar shape des de fitxer (amb caché)
// Carregar shape desde file (con caché)
// Retorna punter compartit (nullptr si error)
// Exemple: load("ship.shp") → busca a "data/shapes/ship.shp"
static std::shared_ptr<Shape> load(const std::string& filename);
+27 -27
View File
@@ -1,4 +1,4 @@
// starfield.cpp - Implementació del sistema d'estrelles de fons
// starfield.cpp - Implementació del sistema de estrelles de fons
// © 2025 Orni Attack
#include "core/graphics/starfield.hpp"
@@ -22,7 +22,7 @@ Starfield::Starfield(SDL_Renderer* renderer,
punt_fuga_(punt_fuga),
area_(area),
densitat_(densitat) {
// Carregar shape d'estrella amb ShapeLoader
// Carregar shape de estrella con ShapeLoader
shape_estrella_ = ShapeLoader::load("star.shp");
if (!shape_estrella_ || !shape_estrella_->isValid()) {
@@ -30,22 +30,22 @@ Starfield::Starfield(SDL_Renderer* renderer,
return;
}
// Configurar 3 capes amb diferents velocitats i escales
// Capa 0: Fons llunyà (lenta, petita)
// Configurar 3 capes con diferents velocitats i escales
// Capa 0: Fons llunyà (lenta, pequeña)
capes_.push_back({20.0F, 0.3F, 0.8F, densitat / 3});
// Capa 1: Profunditat mitjana
capes_.push_back({40.0F, 0.5F, 1.2F, densitat / 3});
// Capa 2: Primer pla (ràpida, gran)
// Capa 2: Primer pla (ràpida, grande)
capes_.push_back({80.0F, 0.8F, 2.0F, densitat / 3});
// Calcular radi màxim (distància del centre al racó més llunyà)
// Calcular radi màxim (distancia del centro al racó més llunyà)
float dx = std::max(punt_fuga_.x, area_.w - punt_fuga_.x);
float dy = std::max(punt_fuga_.y, area_.h - punt_fuga_.y);
radi_max_ = std::sqrt((dx * dx) + (dy * dy));
// Inicialitzar estrelles amb posicions distribuïdes (pre-omplir pantalla)
// Inicialitzar estrelles con posicions distribuïdes (pre-omplir pantalla)
for (int capa_idx = 0; capa_idx < 3; capa_idx++) {
int num = capes_[capa_idx].num_estrelles;
for (int i = 0; i < num; i++) {
@@ -55,10 +55,10 @@ Starfield::Starfield(SDL_Renderer* renderer,
// Angle aleatori
estrella.angle = (static_cast<float>(rand()) / RAND_MAX) * 2.0F * Defaults::Math::PI;
// Distància aleatòria (0.0 a 1.0) per omplir tota la pantalla
// Distancia aleatòria (0.0 a 1.0) per omplir toda la pantalla
estrella.distancia_centre = static_cast<float>(rand()) / RAND_MAX;
// Calcular posició des de la distància
// Calcular posición desde la distancia
float radi = estrella.distancia_centre * radi_max_;
estrella.position.x = punt_fuga_.x + (radi * std::cos(estrella.angle));
estrella.position.y = punt_fuga_.y + (radi * std::sin(estrella.angle));
@@ -68,21 +68,21 @@ Starfield::Starfield(SDL_Renderer* renderer,
}
}
// Inicialitzar una estrella (nova o regenerada)
// Inicialitzar una estrella (nueva o regenerada)
void Starfield::inicialitzar_estrella(Estrella& estrella) const {
// Angle aleatori des del point de fuga cap a fora
// Angle aleatori des del point de fuga hacia fuera
estrella.angle = (static_cast<float>(rand()) / RAND_MAX) * 2.0F * Defaults::Math::PI;
// Distància inicial petita (5% del radi màxim) - neix prop del centre
// Distancia inicial pequeña (5% del radi màxim) - neix prop del centro
estrella.distancia_centre = 0.05F;
// Posició inicial: molt prop del point de fuga
// Posición inicial: mucho prop del point de fuga
float radi = estrella.distancia_centre * radi_max_;
estrella.position.x = punt_fuga_.x + (radi * std::cos(estrella.angle));
estrella.position.y = punt_fuga_.y + (radi * std::sin(estrella.angle));
}
// Verificar si una estrella està fora de l'àrea
// Verificar si una estrella está fuera de l'àrea
bool Starfield::fora_area(const Estrella& estrella) const {
return (estrella.position.x < area_.x ||
estrella.position.x > area_.x + area_.w ||
@@ -90,20 +90,20 @@ bool Starfield::fora_area(const Estrella& estrella) const {
estrella.position.y > area_.y + area_.h);
}
// Calcular scale dinàmica segons distància del centre
// Calcular scale dinàmica segons distancia del centro
float Starfield::calcular_escala(const Estrella& estrella) const {
const CapaConfig& capa = capes_[estrella.capa];
// Interpolació lineal basada en distància del centre
// distancia_centre: 0.0 (centre) → 1.0 (vora)
// Interpolació lineal basada en distancia del centro
// distancia_centre: 0.0 (centro) → 1.0 (vora)
return capa.escala_min +
((capa.escala_max - capa.escala_min) * estrella.distancia_centre);
}
// Calcular brightness dinàmica segons distància del centre
// Calcular brightness dinàmica segons distancia del centro
float Starfield::calcular_brightness(const Estrella& estrella) const {
// Interpolació lineal: estrelles properes (vora) més brillants
// distancia_centre: 0.0 (centre, llunyanes) → 1.0 (vora, properes)
// distancia_centre: 0.0 (centro, llunyanes) → 1.0 (vora, properes)
float brightness_base = Defaults::Brightness::STARFIELD_MIN +
((Defaults::Brightness::STARFIELD_MAX - Defaults::Brightness::STARFIELD_MIN) *
estrella.distancia_centre);
@@ -112,13 +112,13 @@ float Starfield::calcular_brightness(const Estrella& estrella) const {
return std::min(1.0F, brightness_base * multiplicador_brightness_);
}
// Actualitzar posicions de les estrelles
// Actualitzar posicions de las estrelles
void Starfield::update(float delta_time) {
for (auto& estrella : estrelles_) {
// Obtenir configuració de la capa
// Obtenir configuración de la capa
const CapaConfig& capa = capes_[estrella.capa];
// Moure cap a fora des del centre
// Moure hacia fuera des del centro
float velocity = capa.velocitat_base;
float dx = velocity * std::cos(estrella.angle) * delta_time;
float dy = velocity * std::sin(estrella.angle) * delta_time;
@@ -126,7 +126,7 @@ void Starfield::update(float delta_time) {
estrella.position.x += dx;
estrella.position.y += dy;
// Actualitzar distància del centre
// Actualitzar distancia del centro
float dx_centre = estrella.position.x - punt_fuga_.x;
float dy_centre = estrella.position.y - punt_fuga_.y;
float dist_px = std::sqrt((dx_centre * dx_centre) + (dy_centre * dy_centre));
@@ -144,7 +144,7 @@ void Starfield::set_brightness(float multiplier) {
multiplicador_brightness_ = std::max(0.0F, multiplier); // Evitar valors negatius
}
// Dibuixar totes les estrelles
// Dibuixar todas las estrelles
void Starfield::draw() {
if (!shape_estrella_->isValid()) {
return;
@@ -155,14 +155,14 @@ void Starfield::draw() {
float scale = calcular_escala(estrella);
float brightness = calcular_brightness(estrella);
// Renderitzar estrella sense rotació
// Renderizar estrella sin rotación
Rendering::render_shape(
renderer_,
shape_estrella_,
estrella.position,
0.0F, // angle (les estrelles no giren)
0.0F, // angle (las estrelles no giren)
scale, // scale dinàmica
1.0F, // progress (sempre visible)
1.0F, // progress (siempre visible)
brightness // brightness dinàmica
);
}
+24 -24
View File
@@ -1,4 +1,4 @@
// starfield.hpp - Sistema d'estrelles de fons amb efecte de profunditat
// starfield.hpp - Sistema de estrelles de fons con efecte de profunditat
// © 2025 Orni Attack
#pragma once
@@ -13,69 +13,69 @@
namespace Graphics {
// Configuració per cada capa de profunditat
// Configuración per cada capa de profunditat
struct CapaConfig {
float velocitat_base; // Velocitat base d'aquesta capa (px/s)
float escala_min; // Escala mínima prop del centre
float velocitat_base; // Velocidad base de esta capa (px/s)
float escala_min; // Escala mínima prop del centro
float escala_max; // Escala màxima al límit de pantalla
int num_estrelles; // Nombre d'estrelles en aquesta capa
int num_estrelles; // Nombre de estrelles en esta capa
};
// Classe Starfield - camp d'estrelles animat amb efecte de profunditat
// Clase Starfield - camp de estrelles animat con efecte de profunditat
class Starfield {
public:
// Constructor
// - renderer: SDL renderer
// - punt_fuga: point d'origen/fuga des d'on surten les estrelles
// - area: rectangle on actuen les estrelles (SDL_FRect)
// - densitat: nombre total d'estrelles (es divideix entre capes)
// - punt_fuga: point de origin/fuga des de on surten las estrelles
// - area: rectangle on actuen las estrelles (SDL_FRect)
// - densitat: nombre total de estrelles (es divideix entre capes)
Starfield(SDL_Renderer* renderer,
const Vec2& punt_fuga,
const SDL_FRect& area,
int densitat = 150);
// Actualitzar posicions de les estrelles
// Actualitzar posicions de las estrelles
void update(float delta_time);
// Dibuixar totes les estrelles
// Dibuixar todas las estrelles
void draw();
// Setters per ajustar paràmetres en time real
// Setters per ajustar parámetros en time real
void set_punt_fuga(const Vec2& point) { punt_fuga_ = point; }
void set_brightness(float multiplier);
private:
// Estructura interna per cada estrella
struct Estrella {
Vec2 position; // Posició actual
float angle; // Angle de moviment (radians)
float distancia_centre; // Distància normalitzada del centre (0.0-1.0)
Vec2 position; // Posición actual
float angle; // Angle de movement (radians)
float distancia_centre; // Distancia normalitzada del centro (0.0-1.0)
int capa; // Índex de capa (0=lluny, 1=mitjà, 2=prop)
};
// Inicialitzar una estrella (nova o regenerada)
// Inicialitzar una estrella (nueva o regenerada)
void inicialitzar_estrella(Estrella& estrella) const;
// Verificar si una estrella està fora de l'àrea
// Verificar si una estrella está fuera de l'àrea
[[nodiscard]] bool fora_area(const Estrella& estrella) const;
// Calcular scale dinàmica segons distància del centre
// Calcular scale dinàmica segons distancia del centro
[[nodiscard]] float calcular_escala(const Estrella& estrella) const;
// Calcular brightness dinàmica segons distància del centre
// Calcular brightness dinàmica segons distancia del centro
[[nodiscard]] float calcular_brightness(const Estrella& estrella) const;
// Dades
std::vector<Estrella> estrelles_;
std::vector<CapaConfig> capes_; // Configuració de les 3 capes
std::vector<CapaConfig> capes_; // Configuración de las 3 capes
std::shared_ptr<Shape> shape_estrella_;
SDL_Renderer* renderer_;
// Configuració
Vec2 punt_fuga_; // Vec2 d'origen de les estrelles
// Configuración
Vec2 punt_fuga_; // Vec2 de origin de las estrelles
SDL_FRect area_; // Àrea activa
float radi_max_; // Distància màxima del centre al límit de pantalla
int densitat_; // Nombre total d'estrelles
float radi_max_; // Distancia màxima del centro al límit de pantalla
int densitat_; // Nombre total de estrelles
float multiplicador_brightness_{1.0F}; // Multiplicador de brightness (1.0 = default)
};
+9 -9
View File
@@ -1,5 +1,5 @@
// vector_text.cpp - Implementació del sistema de text vectorial
// © 2025 Port a C++20 amb SDL3
// © 2025 Port a C++20 con SDL3
// Test pre-commit hook
#include "core/graphics/vector_text.hpp"
@@ -11,7 +11,7 @@
namespace Graphics {
// Constants per a mides base dels caràcters
// Constants para mides base dels caràcters
constexpr float char_width = 20.0F; // Amplada base del caràcter
constexpr float char_height = 40.0F; // Altura base del caràcter
@@ -63,7 +63,7 @@ void VectorText::load_charset() {
}
// Cargar símbolo de copyright (©) - UTF-8 U+00A9
// Usem el segon byte (0xA9) com a key interna
// Usem el segon byte (0xA9) como a key interna
{
char c = '\xA9'; // 169 decimal
std::string filename = "font/char_copyright.shp";
@@ -82,7 +82,7 @@ void VectorText::load_charset() {
}
std::string VectorText::get_shape_filename(char c) const {
// Mapeo carácter → nombre de archivo (amb prefix "font/")
// Mapeo carácter → nombre de archivo (con prefix "font/")
switch (c) {
case '0':
case '1':
@@ -168,7 +168,7 @@ std::string VectorText::get_shape_filename(char c) const {
case '?':
return "font/char_question.shp";
case ' ':
return ""; // Espai es maneja sense load shape
return ""; // Espai es maneja sin load shape
case '\xA9': // Copyright symbol (©) - UTF-8 U+00A9
return "font/char_copyright.shp";
@@ -207,7 +207,7 @@ void VectorText::render(const std::string& text, const Vec2& position, float sca
// Detectar copyright UTF-8 (0xC2 0xA9)
if (c == 0xC2 && i + 1 < text.length() &&
static_cast<unsigned char>(text[i + 1]) == 0xA9) {
c = 0xA9; // Usar segon byte com a key
c = 0xA9; // Usar segon byte como a key
i++; // Saltar el següent byte
}
@@ -242,13 +242,13 @@ void VectorText::renderCentered(const std::string& text, const Vec2& centre_punt
float text_width = get_text_width(text, scale, spacing);
float text_height = get_text_height(scale);
// Calcular posició de l'esquina superior esquerra
// restant la meitat de les dimensions del point central
// Calcular posición de l'esquina superior izquierda
// restant la meitat de las dimensions del point central
Vec2 posicio_esquerra = {
.x = centre_punt.x - (text_width / 2.0F),
.y = centre_punt.y - (text_height / 2.0F)};
// Delegar al mètode render() existent
// Delegar al método render() existent
render(text, posicio_esquerra, scale, spacing, brightness);
}
+1 -1
View File
@@ -1,5 +1,5 @@
// vector_text.hpp - Sistema de texto vectorial con display de 7-segmentos
// © 2025 Port a C++20 amb SDL3
// © 2025 Port a C++20 con SDL3
#pragma once
+6 -6
View File
@@ -12,7 +12,7 @@ bool cursor_visible = false; // Estado del cursor (inicia ocult)
// SDLManager controla esto mediante llamadas a setForceHidden().
bool force_hidden = false;
// Temps d'inicialització per ignorar esdeveniments fantasma de SDL
// Temps de inicialización per ignorar esdeveniments fantasma de SDL
Uint32 initialization_time = 0;
constexpr Uint32 IGNORE_MOTION_DURATION = 1000; // Ignorar primers 1000ms
@@ -24,7 +24,7 @@ void forceHide() {
cursor_visible = false;
last_mouse_move_time = 0;
initialization_time = SDL_GetTicks(); // Marcar time per ignorar esdeveniments inicials
std::cout << "[Mouse::forceHide] Ignorant moviments durant " << IGNORE_MOTION_DURATION << "ms" << '\n';
std::cout << "[Mouse::forceHide] Ignorant moviments durante " << IGNORE_MOTION_DURATION << "ms" << '\n';
}
void setForceHidden(bool force) {
@@ -56,16 +56,16 @@ void handleEvent(const SDL_Event& event) {
if (event.type == SDL_EVENT_MOUSE_MOTION) {
Uint32 current_time = SDL_GetTicks();
// Ignorar esdeveniments fantasma de SDL durant el període inicial
// Ignorar esdeveniments fantasma de SDL durante el període inicial
if (initialization_time > 0 && (current_time - initialization_time < IGNORE_MOTION_DURATION)) {
std::cout << "[Mouse::handleEvent] Ignorant moviment fantasma de SDL. time=" << current_time
<< " (inicialització fa " << (current_time - initialization_time) << "ms)" << '\n';
std::cout << "[Mouse::handleEvent] Ignorant movement fantasma de SDL. time=" << current_time
<< " (inicialización hace " << (current_time - initialization_time) << "ms)" << '\n';
return;
}
last_mouse_move_time = current_time;
if (!cursor_visible) {
std::cout << "[Mouse::handleEvent] Mostrant cursor per moviment REAL. time=" << last_mouse_move_time << '\n';
std::cout << "[Mouse::handleEvent] Mostrant cursor per movement REAL. time=" << last_mouse_move_time << '\n';
SDL_ShowCursor();
cursor_visible = true;
}
+5 -5
View File
@@ -1,4 +1,4 @@
// easing.hpp - Funcions d'interpolació i easing
// easing.hpp - Funciones de interpolació i easing
// © 2025 Orni Attack
#pragma once
@@ -7,21 +7,21 @@ namespace Easing {
// Ease-out quadratic: empieza rápido, desacelera suavemente
// t = progreso normalizado [0.0 - 1.0]
// retorna valor interpolado [0.0 - 1.0]
// retorna value interpolado [0.0 - 1.0]
inline float ease_out_quad(float t) {
return 1.0F - ((1.0F - t) * (1.0F - t));
}
// Ease-in quadratic: empieza lento, acelera
// t = progreso normalizado [0.0 - 1.0]
// retorna valor interpolado [0.0 - 1.0]
// retorna value interpolado [0.0 - 1.0]
inline float ease_in_quad(float t) {
return t * t;
}
// Ease-in-out quadratic: acelera al inicio, desacelera al final
// t = progreso normalizado [0.0 - 1.0]
// retorna valor interpolado [0.0 - 1.0]
// retorna value interpolado [0.0 - 1.0]
inline float ease_in_out_quad(float t) {
return (t < 0.5F)
? 2.0F * t * t
@@ -30,7 +30,7 @@ inline float ease_in_out_quad(float t) {
// Ease-out cubic: desaceleración más suave que quadratic
// t = progreso normalizado [0.0 - 1.0]
// retorna valor interpolado [0.0 - 1.0]
// retorna value interpolado [0.0 - 1.0]
inline float ease_out_cubic(float t) {
float t1 = 1.0F - t;
return 1.0F - (t1 * t1 * t1);
+4 -4
View File
@@ -1,4 +1,4 @@
// collision.hpp - Utilitats de detecció de col·lisions
// collision.hpp - Utilitats de detecció de colisiones
// © 2025 Orni Attack - Sistema de física
#pragma once
@@ -8,18 +8,18 @@
namespace Physics {
// Comprovació genèrica de col·lisió entre dues entitats
// Comprobación genèrica de colisión entre dues entidades
inline bool check_collision(const Entities::Entity& a, const Entities::Entity& b, float amplifier = 1.0F) {
// Comprovar si ambdós són col·lisionables
if (!a.isCollidable() || !b.isCollidable()) {
return false;
}
// Calcular radi combinat (amb amplificador per hitbox generós)
// Calcular radi combinat (con amplificador per hitbox generós)
float suma_radis = (a.getCollisionRadius() + b.getCollisionRadius()) * amplifier;
float suma_radis_sq = suma_radis * suma_radis;
// Comprovació distància al quadrat (sense sqrt)
// Comprobación distancia al cuadrado (sin sqrt)
const Vec2& pos_a = a.getCenter();
const Vec2& pos_b = b.getCenter();
float dx = pos_a.x - pos_b.x;
+3 -3
View File
@@ -1,5 +1,5 @@
// color_oscillator.cpp - Implementació d'oscil·lació de color
// © 2025 Port a C++20 amb SDL3
// color_oscillator.cpp - Implementació de oscil·lació de color
// © 2025 Port a C++20 con SDL3
#include "core/rendering/color_oscillator.hpp"
@@ -11,7 +11,7 @@ namespace Rendering {
ColorOscillator::ColorOscillator()
: accumulated_time_(0.0F) {
// Inicialitzar amb el color mínim
// Inicialitzar con el color mínim
current_line_color_ = {.r = Defaults::Color::LINE_MIN_R,
.g = Defaults::Color::LINE_MIN_G,
.b = Defaults::Color::LINE_MIN_B,
+2 -2
View File
@@ -1,5 +1,5 @@
// color_oscillator.hpp - Sistema d'oscil·lació de color per efecte CRT
// © 2025 Port a C++20 amb SDL3
// color_oscillator.hpp - Sistema de oscil·lació de color per efecte CRT
// © 2025 Port a C++20 con SDL3
#pragma once
#include <SDL3/SDL.h>
@@ -1,11 +1,11 @@
// coordinate_transform.cpp - Inicialització de variables globals
// © 2025 Port a C++20 amb SDL3
// coordinate_transform.cpp - Inicialización de variables globals
// © 2025 Port a C++20 con SDL3
#include "core/rendering/coordinate_transform.hpp"
namespace Rendering {
// Factor d'scale global (inicialitzat a 1.0 per defecte)
// Factor de scale global (inicialitzat a 1.0 per defecte)
float g_current_scale_factor = 1.0F;
} // namespace Rendering
@@ -1,5 +1,5 @@
// coordinate_transform.hpp - Transformació de coordenades lògiques a físiques
// © 2025 Port a C++20 amb SDL3
// © 2025 Port a C++20 con SDL3
#pragma once
@@ -7,10 +7,10 @@
namespace Rendering {
// Factor d'scale global (actualitzat cada frame per SDLManager)
// Factor de scale global (actualitzat cada frame per SDLManager)
extern float g_current_scale_factor;
// Transforma coordenada lògica a física amb arrodoniment
// Transforma coordenada lógica a física con arrodoniment
inline int transform_x(int logical_x, float scale) {
return static_cast<int>(std::round(logical_x * scale));
}
@@ -19,7 +19,7 @@ inline int transform_y(int logical_y, float scale) {
return static_cast<int>(std::round(logical_y * scale));
}
// Variant que usa el factor d'scale global
// Variant que usa el factor de scale global
inline int transform_x(int logical_x) {
return transform_x(logical_x, g_current_scale_factor);
}
+3 -3
View File
@@ -1,6 +1,6 @@
// line_renderer.cpp - Implementació de renderitzat de línies
// © 1999 Visente i Sergi (versió Pascal)
// © 2025 Port a C++20 amb SDL3
// line_renderer.cpp - Implementació de renderizado de línies
// © 1999 Visente i Sergi (versión Pascal)
// © 2025 Port a C++20 con SDL3
#include "core/rendering/line_renderer.hpp"
+4 -4
View File
@@ -1,6 +1,6 @@
// line_renderer.hpp - Renderitzat de línies
// © 1999 Visente i Sergi (versió Pascal)
// © 2025 Port a C++20 amb SDL3
// line_renderer.hpp - Renderizado de línies
// © 1999 Visente i Sergi (versión Pascal)
// © 2025 Port a C++20 con SDL3
#pragma once
#include <SDL3/SDL.h>
@@ -11,7 +11,7 @@ namespace Rendering {
// brightness: factor de brightness (0.0-1.0, default 1.0 = màxima brightness).
void linea(SDL_Renderer* renderer, int x1, int y1, int x2, int y2, float brightness = 1.0F);
// Estableix el color global de les línies (utilitzat per ColorOscillator).
// Estableix el color global de las línies (utilitzat per ColorOscillator).
void setLineColor(SDL_Color color);
} // namespace Rendering
+31 -31
View File
@@ -1,5 +1,5 @@
// sdl_manager.cpp - Implementació del gestor SDL3
// © 2025 Port a C++20 amb SDL3
// © 2025 Port a C++20 con SDL3
#include "sdl_manager.hpp"
@@ -38,13 +38,13 @@ SDLManager::SDLManager()
// Calcular mida màxima des del display
calculateMaxWindowSize();
// Construir títol dinàmic
// Construir título dinàmic
std::string window_title = std::format("{} v{} ({})", Project::LONG_NAME, Project::VERSION, Project::COPYRIGHT);
// Crear finestra CENTRADA (SDL ho fa automàticament amb CENTERED)
// Crear finestra CENTRADA (SDL ho hace automàticament con CENTERED)
finestra_ =
SDL_CreateWindow(window_title.c_str(), current_width_, current_height_,
SDL_WINDOW_RESIZABLE // Permetre resize manual també
SDL_WINDOW_RESIZABLE // Permetre resize manual también
);
if (finestra_ == nullptr) {
@@ -56,7 +56,7 @@ SDLManager::SDLManager()
// IMPORTANT: Centrar explícitament la finestra
SDL_SetWindowPosition(finestra_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
// Crear renderer amb acceleració
// Crear renderer con aceleración
renderer_ = SDL_CreateRenderer(finestra_, nullptr);
if (renderer_ == nullptr) {
@@ -66,7 +66,7 @@ SDLManager::SDLManager()
return;
}
// Aplicar configuració de V-Sync
// Aplicar configuración de V-Sync
SDL_SetRenderVSync(renderer_, Options::rendering.vsync);
// CRÍTIC: Configurar viewport scaling
@@ -77,7 +77,7 @@ SDLManager::SDLManager()
<< Defaults::Game::HEIGHT << ")" << '\n';
}
// Constructor amb configuració
// Constructor con configuración
SDLManager::SDLManager(int width, int height, bool fullscreen)
: finestra_(nullptr),
renderer_(nullptr),
@@ -102,7 +102,7 @@ SDLManager::SDLManager(int width, int height, bool fullscreen)
// Calcular mida màxima des del display
calculateMaxWindowSize();
// Construir títol dinàmic
// Construir título dinàmic
std::string window_title = std::format("{} v{} ({})", Project::LONG_NAME, Project::VERSION, Project::COPYRIGHT);
// Configurar flags de la finestra
@@ -120,12 +120,12 @@ SDLManager::SDLManager(int width, int height, bool fullscreen)
return;
}
// Centrar explícitament la finestra (si no és fullscreen)
// Centrar explícitament la finestra (si no es fullscreen)
if (!is_fullscreen_) {
SDL_SetWindowPosition(finestra_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
}
// Crear renderer amb acceleració
// Crear renderer con aceleración
renderer_ = SDL_CreateRenderer(finestra_, nullptr);
if (renderer_ == nullptr) {
@@ -135,7 +135,7 @@ SDLManager::SDLManager(int width, int height, bool fullscreen)
return;
}
// Aplicar configuració de V-Sync
// Aplicar configuración de V-Sync
SDL_SetRenderVSync(renderer_, Options::rendering.vsync);
// Configurar viewport scaling
@@ -176,7 +176,7 @@ void SDLManager::calculateMaxWindowSize() {
const SDL_DisplayMode* mode = SDL_GetCurrentDisplayMode(display);
if (mode != nullptr) {
// Deixar marge de 100px per a decoracions de l'OS
// Deixar marge de 100px para decoracions de l'OS
max_width_ = mode->w - 100;
max_height_ = mode->h - 100;
std::cout << "Display detectat: " << mode->w << "x" << mode->h
@@ -253,9 +253,9 @@ void SDLManager::applyZoom(float new_zoom) {
}
void SDLManager::updateLogicalPresentation() {
// CANVIAT: Ja no usem SDL_SetRenderLogicalPresentation
// CANVIAT: Ya no usem SDL_SetRenderLogicalPresentation
// Ara renderitzem directament a resolució física per evitar pixelació irregular
// El viewport amb letterbox es configura a updateViewport()
// El viewport con letterbox es configura a updateViewport()
updateViewport();
}
@@ -265,7 +265,7 @@ void SDLManager::updateViewport() {
int scaled_width = static_cast<int>(std::round(Defaults::Game::WIDTH * scale));
int scaled_height = static_cast<int>(std::round(Defaults::Game::HEIGHT * scale));
// Càlcul de letterbox (centrar l'àrea escalada)
// Cálculo de letterbox (centrar l'àrea scaled)
int offset_x = (current_width_ - scaled_width) / 2;
int offset_y = (current_height_ - scaled_height) / 2;
@@ -273,7 +273,7 @@ void SDLManager::updateViewport() {
offset_x = std::max(offset_x, 0);
offset_y = std::max(offset_y, 0);
// Configurar viewport per al renderitzat
// Configurar viewport per al renderizado
SDL_Rect viewport = {offset_x, offset_y, scaled_width, scaled_height};
SDL_SetRenderViewport(renderer_, &viewport);
@@ -283,7 +283,7 @@ void SDLManager::updateViewport() {
}
void SDLManager::updateRenderingContext() const {
// Actualitzar el factor d'scale global per a totes les funcions de renderitzat
// Actualitzar el factor de scale global para todas las funciones de renderizado
Rendering::g_current_scale_factor = zoom_factor_;
}
@@ -310,7 +310,7 @@ void SDLManager::decreaseWindowSize() {
}
void SDLManager::applyWindowSize(int new_width, int new_height) {
// Obtenir posició actual ABANS del resize
// Obtenir posición actual ABANS del resize
int old_x;
int old_y;
SDL_GetWindowPosition(finestra_, &old_x, &old_y);
@@ -324,7 +324,7 @@ void SDLManager::applyWindowSize(int new_width, int new_height) {
current_height_ = new_height;
// CENTRADO INTEL·LIGENT (algoritme de pollo)
// Calcular nova posició per mantenir la finestra centrada sobre si mateixa
// Calcular nueva posición per mantenir la finestra centrada sobre si misma
int delta_width = old_width - new_width;
int delta_height = old_height - new_height;
@@ -332,13 +332,13 @@ void SDLManager::applyWindowSize(int new_width, int new_height) {
int new_y = old_y + (delta_height / 2);
// Evitar que la finestra surti de la pantalla
constexpr int TITLEBAR_HEIGHT = 35; // Alçada aproximada de la barra de títol
constexpr int TITLEBAR_HEIGHT = 35; // Alçada aproximada de la barra de título
new_x = std::max(new_x, 0);
new_y = std::max(new_y, TITLEBAR_HEIGHT);
SDL_SetWindowPosition(finestra_, new_x, new_y);
// Actualitzar viewport després del resize
// Actualitzar viewport después del resize
updateViewport();
}
@@ -368,7 +368,7 @@ void SDLManager::toggleFullscreen() {
Options::window.fullscreen = is_fullscreen_;
// Notificar al mòdul Mouse: Fullscreen requereix ocultació permanent del cursor.
// Quan es surt de fullscreen, restaurar el comportament normal d'auto-ocultació.
// Cuando es surt de fullscreen, restaurar el comportament normal de auto-ocultació.
Mouse::setForceHidden(is_fullscreen_);
}
@@ -387,7 +387,7 @@ bool SDLManager::handleWindowEvent(const SDL_Event& event) {
windowed_height_ = current_height_;
}
// Actualitzar viewport després del resize manual
// Actualitzar viewport después del resize manual
updateViewport();
std::cout << "Finestra redimensionada: " << current_width_
@@ -398,12 +398,12 @@ bool SDLManager::handleWindowEvent(const SDL_Event& event) {
return false;
}
void SDLManager::neteja(uint8_t r, uint8_t g, uint8_t b) {
void SDLManager::clear(uint8_t r, uint8_t g, uint8_t b) {
if (renderer_ == nullptr) {
return;
}
// [MODIFICAT] Usar color oscil·lat del fons en lloc dels paràmetres
// [MODIFICAT] Usar color oscil·lat del fons en lloc dels parámetros
(void)r;
(void)g;
(void)b; // Suprimir warnings
@@ -412,7 +412,7 @@ void SDLManager::neteja(uint8_t r, uint8_t g, uint8_t b) {
SDL_RenderClear(renderer_);
}
void SDLManager::presenta() {
void SDLManager::present() {
if (renderer_ == nullptr) {
return;
}
@@ -420,7 +420,7 @@ void SDLManager::presenta() {
SDL_RenderPresent(renderer_);
}
// [NUEVO] Actualitzar colors amb oscil·lació
// [NUEVO] Actualitzar colors con oscil·lació
void SDLManager::updateColors(float delta_time) {
color_oscillator_.update(delta_time);
@@ -428,7 +428,7 @@ void SDLManager::updateColors(float delta_time) {
Rendering::setLineColor(color_oscillator_.getCurrentLineColor());
}
// [NUEVO] Actualitzar comptador de FPS
// [NUEVO] Actualitzar counter de FPS
void SDLManager::updateFPS(float delta_time) {
// Acumular time i frames
fps_accumulator_ += delta_time;
@@ -440,7 +440,7 @@ void SDLManager::updateFPS(float delta_time) {
fps_frame_count_ = 0;
fps_accumulator_ = 0.0F;
// Actualitzar títol de la finestra
// Actualitzar título de la finestra
std::string vsync_state = (Options::rendering.vsync == 1) ? "ON" : "OFF";
std::string title = std::format("{} v{} ({}) - {} FPS - VSync: {}",
Project::LONG_NAME,
@@ -455,7 +455,7 @@ void SDLManager::updateFPS(float delta_time) {
}
}
// [NUEVO] Actualitzar títol de la finestra
// [NUEVO] Actualitzar título de la finestra
void SDLManager::setWindowTitle(const std::string& title) {
if (finestra_ != nullptr) {
SDL_SetWindowTitle(finestra_, title.c_str());
@@ -476,6 +476,6 @@ void SDLManager::toggleVSync() {
fps_accumulator_ = 0.0F;
fps_frame_count_ = 0;
// Guardar configuració
// Guardar configuración
Options::saveToFile();
}
+12 -15
View File
@@ -1,8 +1,7 @@
// sdl_manager.hpp - Gestor d'inicialització de SDL3
// © 2025 Port a C++20 amb SDL3
// sdl_manager.hpp - Gestor de inicialización de SDL3
// © 2025 Port a C++20 con SDL3
#ifndef SDL_MANAGER_HPP
#define SDL_MANAGER_HPP
#pragma once
#include <SDL3/SDL.h>
@@ -14,7 +13,7 @@
class SDLManager {
public:
SDLManager(); // Constructor per defecte (usa Defaults::)
SDLManager(int width, int height, bool fullscreen); // Constructor amb configuració
SDLManager(int width, int height, bool fullscreen); // Constructor con configuración
~SDLManager();
// No permetre còpia ni assignació
@@ -28,24 +27,24 @@ class SDLManager {
void toggleVSync(); // F4
bool handleWindowEvent(const SDL_Event& event); // Per a SDL_EVENT_WINDOW_RESIZED
// Funcions principals (renderitzat)
void neteja(uint8_t r = 0, uint8_t g = 0, uint8_t b = 0);
void presenta();
// Funciones principals (renderizado)
void clear(uint8_t r = 0, uint8_t g = 0, uint8_t b = 0);
void present();
// [NUEVO] Actualització de colors (oscil·lació)
void updateColors(float delta_time);
// [NUEVO] Actualitzar comptador de FPS
// [NUEVO] Actualitzar counter de FPS
void updateFPS(float delta_time);
// Getters
SDL_Renderer* getRenderer() { return renderer_; }
[[nodiscard]] float getScaleFactor() const { return zoom_factor_; }
// [NUEVO] Actualitzar títol de la finestra
// [NUEVO] Actualitzar título de la finestra
void setWindowTitle(const std::string& title);
// [NUEVO] Actualitzar context de renderitzat (factor d'scale global)
// [NUEVO] Actualitzar context de renderizado (factor de scale global)
void updateRenderingContext() const;
private:
@@ -70,16 +69,14 @@ class SDLManager {
int windowed_height_; // Saved size before fullscreen
float max_zoom_; // Maximum zoom (calculated from display)
// [NUEVO] Funcions internes
// [NUEVO] Funciones internes
void calculateMaxWindowSize(); // Llegir resolució del display
void calculateMaxZoom(); // Calculate max zoom from display
void applyZoom(float new_zoom); // Apply zoom and resize window
void applyWindowSize(int width, int height); // Canviar mida + centrar
void updateLogicalPresentation(); // Actualitzar viewport
void updateViewport(); // Configurar viewport amb letterbox
void updateViewport(); // Configurar viewport con letterbox
// [NUEVO] Oscil·lador de colors
Rendering::ColorOscillator color_oscillator_;
};
#endif // SDL_MANAGER_HPP
+20 -20
View File
@@ -1,5 +1,5 @@
// shape_renderer.cpp - Implementació del renderitzat de formes
// © 2025 Port a C++20 amb SDL3
// shape_renderer.cpp - Implementació del renderizado de formes
// © 2025 Port a C++20 con SDL3
#include "core/rendering/shape_renderer.hpp"
@@ -10,65 +10,65 @@
namespace Rendering {
// Helper: aplicar rotació 3D a un point 2D (assumeix Z=0)
// Helper: aplicar rotación 3D a un point 2D (assumeix Z=0)
static Vec2 apply_3d_rotation(float x, float y, const Rotation3D& rot) {
float z = 0.0F; // Tots els points 2D comencen a Z=0
float z = 0.0F; // Todos los points 2D comencen a Z=0
// Pitch (rotació eix X): cabeceo arriba/baix
// Pitch (rotación eix X): cabeceo arriba/baix
float cos_pitch = std::cos(rot.pitch);
float sin_pitch = std::sin(rot.pitch);
float y1 = (y * cos_pitch) - (z * sin_pitch);
float z1 = (y * sin_pitch) + (z * cos_pitch);
// Yaw (rotació eix Y): guiñada esquerra/dreta
// Yaw (rotación eix Y): guiñada izquierda/derecha
float cos_yaw = std::cos(rot.yaw);
float sin_yaw = std::sin(rot.yaw);
float x2 = (x * cos_yaw) + (z1 * sin_yaw);
float z2 = (-x * sin_yaw) + (z1 * cos_yaw);
// Roll (rotació eix Z): alabeo lateral
// Roll (rotación eix Z): alabeo lateral
float cos_roll = std::cos(rot.roll);
float sin_roll = std::sin(rot.roll);
float x3 = (x2 * cos_roll) - (y1 * sin_roll);
float y3 = (x2 * sin_roll) + (y1 * cos_roll);
// Proyecció perspectiva (Z-divide simple)
// Naus volen cap al point de fuga (320, 240) a "infinit" (Z → +∞)
// Z més gran = més lluny = més petit a pantalla
// Naves quieren hacia el point de fuga (320, 240) a "infinit" (Z → +∞)
// Z més grande = més lluny = més pequeño a pantalla
constexpr float perspective_factor = 500.0F;
float scale_factor = perspective_factor / (perspective_factor + z2);
return {.x = x3 * scale_factor, .y = y3 * scale_factor};
}
// Helper: transformar un point amb rotació, scale i trasllació
// Helper: transformar un point con rotación, scale i traslación
static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const Vec2& position, float angle, float scale, const Rotation3D* rotation_3d) {
// 1. Centrar el point respecte al centre de la shape
// 1. Centrar el point respecte al centro de la shape
float centered_x = point.x - shape_centre.x;
float centered_y = point.y - shape_centre.y;
// 2. Aplicar rotació 3D (si es proporciona)
// 2. Aplicar rotación 3D (si es proporciona)
if ((rotation_3d != nullptr) && rotation_3d->has_rotation()) {
Vec2 rotated_3d = apply_3d_rotation(centered_x, centered_y, *rotation_3d);
centered_x = rotated_3d.x;
centered_y = rotated_3d.y;
}
// 3. Aplicar scale al point (després de rotació 3D)
// 3. Aplicar scale al point (después de rotación 3D)
float scaled_x = centered_x * scale;
float scaled_y = centered_y * scale;
// 4. Aplicar rotació 2D (Z-axis, tradicional)
// IMPORTANT: En el sistema original, angle=0 apunta AMUNT (no dreta)
// 4. Aplicar rotación 2D (Z-axis, tradicional)
// IMPORTANT: En el sistema original, angle=0 apunta AMUNT (no derecha)
// Per això usem (angle - PI/2) per compensar
// Però aquí angle ja ve en el sistema correcte del joc
// Pero aquí angle ya ve en el sistema correcte del juego
float cos_a = std::cos(angle);
float sin_a = std::sin(angle);
float rotated_x = (scaled_x * cos_a) - (scaled_y * sin_a);
float rotated_y = (scaled_x * sin_a) + (scaled_y * cos_a);
// 5. Aplicar trasllació a posició mundial
// 5. Aplicar traslación a posición mundial
return {.x = rotated_x + position.x, .y = rotated_y + position.y};
}
@@ -80,7 +80,7 @@ void render_shape(SDL_Renderer* renderer,
float progress,
float brightness,
const Rotation3D* rotation_3d) {
// Verificar que la shape és vàlida
// Verificar que la shape es vàlida
if (!shape || !shape->isValid()) {
return;
}
@@ -90,10 +90,10 @@ void render_shape(SDL_Renderer* renderer,
return;
}
// Obtenir el centre de la shape per a transformacions
// Obtenir el centro de la shape para transformacions
const Vec2& shape_centre = shape->getCenter();
// Iterar sobre totes les primitives
// Iterar sobre todas las primitives
for (const auto& primitive : shape->get_primitives()) {
if (primitive.type == Graphics::PrimitiveType::POLYLINE) {
// POLYLINE: connectar points consecutius
+10 -10
View File
@@ -1,5 +1,5 @@
// shape_renderer.hpp - Renderitzat de formes vectorials
// © 2025 Port a C++20 amb SDL3
// shape_renderer.hpp - Renderizado de formes vectorials
// © 2025 Port a C++20 con SDL3
#pragma once
@@ -14,9 +14,9 @@ namespace Rendering {
// Estructura per rotacions 3D (pitch, yaw, roll)
struct Rotation3D {
float pitch; // Rotació eix X (cabeceo arriba/baix)
float yaw; // Rotació eix Y (guiñada esquerra/dreta)
float roll; // Rotació eix Z (alabeo lateral)
float pitch; // Rotación eix X (cabeceo arriba/baix)
float yaw; // Rotación eix Y (guiñada izquierda/derecha)
float roll; // Rotación eix Z (alabeo lateral)
Rotation3D()
: pitch(0.0F),
@@ -32,13 +32,13 @@ struct Rotation3D {
}
};
// Renderitzar shape amb transformacions
// Renderizar shape con transformacions
// - renderer: SDL renderer
// - shape: shape vectorial a draw
// - position: posició del centre en coordenades mundials
// - angle: rotació en radians (0 = amunt, sentit horari)
// - scale: factor d'scale (1.0 = mida original)
// - progress: progrés de l'animació (0.0-1.0, default 1.0 = tot visible)
// - position: posición del centro en coordenades mundials
// - angle: rotación en radians (0 = amunt, sentit horari)
// - scale: factor de scale (1.0 = mida original)
// - progress: progrés de l'animación (0.0-1.0, default 1.0 = tot visible)
// - brightness: factor de brightness (0.0-1.0, default 1.0 = màxima brightness)
void render_shape(SDL_Renderer* renderer,
const std::shared_ptr<Graphics::Shape>& shape,
+6 -6
View File
@@ -1,5 +1,5 @@
// resource_helper.cpp - Implementació de funcions d'ajuda
// © 2025 Port a C++20 amb SDL3
// resource_helper.cpp - Implementació de funciones de ajuda
// © 2025 Port a C++20 con SDL3
#include "resource_helper.hpp"
@@ -15,7 +15,7 @@ bool initializeResourceSystem(const std::string& pack_file, bool fallback) {
return Loader::get().initialize(pack_file, fallback);
}
// Carregar un fitxer
// Carregar un file
std::vector<uint8_t> loadFile(const std::string& filepath) {
// Normalitzar la ruta
std::string normalized = normalizePath(filepath);
@@ -24,7 +24,7 @@ std::vector<uint8_t> loadFile(const std::string& filepath) {
return Loader::get().loadResource(normalized);
}
// Comprovar si existeix un fitxer
// Comprovar si existeix un file
bool fileExists(const std::string& filepath) {
std::string normalized = normalizePath(filepath);
return Loader::get().resourceExists(normalized);
@@ -37,7 +37,7 @@ std::string getPackPath(const std::string& asset_path) {
// Eliminar rutes absolutes (detectar / o C:\ al principi)
if (!path.empty() && path[0] == '/') {
// Buscar "data/" i agafar el que ve després
// Buscar "data/" i agafar el que ve después
size_t data_pos = path.find("/data/");
if (data_pos != std::string::npos) {
path = path.substr(data_pos + 6); // Saltar "/data/"
@@ -73,7 +73,7 @@ std::string normalizePath(const std::string& path) {
return getPackPath(path);
}
// Comprovar si hi ha paquet carregat
// Comprovar si hay paquet carregat
bool isPackLoaded() {
return Loader::get().isPackLoaded();
}
+4 -4
View File
@@ -1,5 +1,5 @@
// resource_helper.hpp - Funcions d'ajuda per gestió de recursos
// © 2025 Port a C++20 amb SDL3
// resource_helper.hpp - Funciones de ajuda per gestió de recursos
// © 2025 Port a C++20 con SDL3
// API simplificada i normalització de rutes
#pragma once
@@ -10,10 +10,10 @@
namespace Resource::Helper {
// Inicialització del sistema
// Inicialización del sistema
bool initializeResourceSystem(const std::string& pack_file, bool fallback);
// Càrrega de fitxers
// Càrrega de archivos
std::vector<uint8_t> loadFile(const std::string& filepath);
bool fileExists(const std::string& filepath);
+11 -11
View File
@@ -1,5 +1,5 @@
// resource_loader.cpp - Implementació del carregador de recursos
// © 2025 Port a C++20 amb SDL3
// © 2025 Port a C++20 con SDL3
#include "resource_loader.hpp"
@@ -25,12 +25,12 @@ bool Loader::initialize(const std::string& pack_file, bool enable_fallback) {
if (!pack_->loadPack(pack_file)) {
if (!fallback_enabled_) {
std::cerr << "[ResourceLoader] ERROR FATAL: No es pot load " << pack_file
<< " i el fallback està desactivat\n";
<< " y el fallback está desactivat\n";
return false;
}
std::cout << "[ResourceLoader] Paquet no trobat, usant fallback al sistema de fitxers\n";
pack_.reset(); // No hi ha paquet
std::cout << "[ResourceLoader] Paquet no trobat, usant fallback al sistema de archivos\n";
pack_.reset(); // No hay paquet
return true;
}
@@ -51,7 +51,7 @@ std::vector<uint8_t> Loader::loadResource(const std::string& filename) {
<< "\n";
}
// Si no està al paquet i no hi ha fallback, falla
// Si no está al paquet y no hay fallback, falla
if (!fallback_enabled_) {
std::cerr << "[ResourceLoader] ERROR: Recurs no trobat al paquet i fallback desactivat: "
<< filename << "\n";
@@ -59,7 +59,7 @@ std::vector<uint8_t> Loader::loadResource(const std::string& filename) {
}
}
// Fallback al sistema de fitxers
// Fallback al sistema de archivos
if (fallback_enabled_) {
return loadFromFilesystem(filename);
}
@@ -74,7 +74,7 @@ bool Loader::resourceExists(const std::string& filename) {
return true;
}
// Comprovar al sistema de fitxers si està activat el fallback
// Comprovar al sistema de archivos si está activat el fallback
if (fallback_enabled_) {
std::string fullpath = base_path_.empty() ? "data/" + filename : base_path_ + "/data/" + filename;
return std::filesystem::exists(fullpath);
@@ -86,14 +86,14 @@ bool Loader::resourceExists(const std::string& filename) {
// Validar el paquet
bool Loader::validatePack() {
if (!pack_) {
std::cerr << "[ResourceLoader] Advertència: no hi ha paquet carregat per validar\n";
std::cerr << "[ResourceLoader] Advertència: no hay paquet carregat per validar\n";
return false;
}
return pack_->validatePack();
}
// Comprovar si hi ha paquet carregat
// Comprovar si hay paquet carregat
bool Loader::isPackLoaded() const {
return pack_ != nullptr;
}
@@ -109,7 +109,7 @@ std::string Loader::getBasePath() const {
return base_path_;
}
// Carregar des del sistema de fitxers (fallback)
// Carregar des del sistema de archivos (fallback)
std::vector<uint8_t> Loader::loadFromFilesystem(const std::string& filename) {
// The filename is already normalized (e.g., "shapes/logo/letra_j.shp")
// We need to prepend base_path + "data/"
@@ -136,7 +136,7 @@ std::vector<uint8_t> Loader::loadFromFilesystem(const std::string& filename) {
return {};
}
std::cout << "[ResourceLoader] Carregat des del sistema de fitxers: " << fullpath << "\n";
std::cout << "[ResourceLoader] Carregat des del sistema de archivos: " << fullpath << "\n";
return data;
}
+4 -4
View File
@@ -1,6 +1,6 @@
// resource_loader.hpp - Carregador de recursos (Singleton)
// © 2025 Port a C++20 amb SDL3
// Coordina càrrega des del paquet i/o sistema de fitxers
// © 2025 Port a C++20 con SDL3
// Coordina càrrega des del paquet i/o sistema de archivos
#pragma once
@@ -18,7 +18,7 @@ class Loader {
// Singleton
static Loader& get();
// Inicialització
// Inicialización
bool initialize(const std::string& pack_file, bool enable_fallback);
// Càrrega de recursos
@@ -46,7 +46,7 @@ class Loader {
bool fallback_enabled_ = false;
std::string base_path_;
// Funcions auxiliars
// Funciones auxiliars
std::vector<uint8_t> loadFromFilesystem(const std::string& filename);
};
+16 -16
View File
@@ -1,5 +1,5 @@
// resource_pack.cpp - Implementació del sistema d'empaquetament
// © 2025 Port a C++20 amb SDL3
// resource_pack.cpp - Implementació del sistema de empaquetament
// © 2025 Port a C++20 con SDL3
#include "resource_pack.hpp"
@@ -30,11 +30,11 @@ void Pack::encryptData(std::vector<uint8_t>& data, const std::string& key) {
}
void Pack::decryptData(std::vector<uint8_t>& data, const std::string& key) {
// XOR és simètric
// XOR es simètric
encryptData(data, key);
}
// Llegir fitxer complet a memòria
// Llegir file complet a memòria
std::vector<uint8_t> Pack::readFile(const std::string& filepath) {
std::ifstream file(filepath, std::ios::binary | std::ios::ate);
if (!file) {
@@ -54,7 +54,7 @@ std::vector<uint8_t> Pack::readFile(const std::string& filepath) {
return data;
}
// Afegir un fitxer individual al paquet
// Añadir un file individual al paquet
bool Pack::addFile(const std::string& filepath, const std::string& pack_name) {
auto file_data = readFile(filepath);
if (file_data.empty()) {
@@ -67,17 +67,17 @@ bool Pack::addFile(const std::string& filepath, const std::string& pack_name) {
.size = file_data.size(),
.checksum = calculateChecksum(file_data)};
// Afegir dades al bloc de dades
// Añadir dades al bloc de dades
data_.insert(data_.end(), file_data.begin(), file_data.end());
resources_[pack_name] = entry;
std::cout << "[ResourcePack] Afegit: " << pack_name << " (" << file_data.size()
std::cout << "[ResourcePack] Añadido: " << pack_name << " (" << file_data.size()
<< " bytes)\n";
return true;
}
// Afegir tots els fitxers d'un directori recursivament
// Añadir todos los archivos de un directori recursivament
bool Pack::addDirectory(const std::string& dir_path,
const std::string& base_path) {
namespace fs = std::filesystem;
@@ -100,7 +100,7 @@ bool Pack::addDirectory(const std::string& dir_path,
// Convertir barres invertides a normals (Windows)
std::ranges::replace(relative_path, '\\', '/');
// Saltar fitxers de desenvolupament
// Saltar archivos de desenvolupament
if (relative_path.find(".world") != std::string::npos ||
relative_path.find(".tsx") != std::string::npos ||
relative_path.find(".DS_Store") != std::string::npos ||
@@ -134,7 +134,7 @@ bool Pack::savePack(const std::string& pack_file) {
// Escriure metadades de recursos
for (const auto& [name, entry] : resources_) {
// Nom del fitxer
// Nom del file
auto name_len = static_cast<uint32_t>(entry.filename.length());
file.write(reinterpret_cast<const char*>(&name_len), sizeof(name_len));
file.write(entry.filename.c_str(), name_len);
@@ -149,7 +149,7 @@ bool Pack::savePack(const std::string& pack_file) {
std::vector<uint8_t> encrypted_data = data_;
encryptData(encrypted_data, DEFAULT_ENCRYPT_KEY);
// Escriure mida de dades i dades encriptades
// Escriure mida de dades y dades encriptades
auto data_size = static_cast<uint64_t>(encrypted_data.size());
file.write(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
file.write(reinterpret_cast<const char*>(encrypted_data.data()), encrypted_data.size());
@@ -160,7 +160,7 @@ bool Pack::savePack(const std::string& pack_file) {
return true;
}
// Carregar paquet des de disc
// Carregar paquet desde disc
bool Pack::loadPack(const std::string& pack_file) {
std::ifstream file(pack_file, std::ios::binary);
if (!file) {
@@ -180,7 +180,7 @@ bool Pack::loadPack(const std::string& pack_file) {
uint32_t version;
file.read(reinterpret_cast<char*>(&version), sizeof(version));
if (version != VERSION) {
std::cerr << "[ResourcePack] Error: versió incompatible (esperava " << VERSION
std::cerr << "[ResourcePack] Error: versión incompatible (esperava " << VERSION
<< ", trobat " << version << ")\n";
return false;
}
@@ -192,7 +192,7 @@ bool Pack::loadPack(const std::string& pack_file) {
// Llegir metadades de recursos
resources_.clear();
for (uint32_t i = 0; i < resource_count; ++i) {
// Nom del fitxer
// Nom del file
uint32_t name_len;
file.read(reinterpret_cast<char*>(&name_len), sizeof(name_len));
@@ -250,7 +250,7 @@ std::vector<uint8_t> Pack::getResource(const std::string& filename) {
std::cerr << "[ResourcePack] ADVERTÈNCIA: checksum invàlid per " << filename
<< " (esperat " << entry.checksum << ", calculat " << computed_checksum
<< ")\n";
// No falla, però adverteix
// No falla, pero adverteix
}
return resource_data;
@@ -261,7 +261,7 @@ bool Pack::hasResource(const std::string& filename) const {
return resources_.contains(filename);
}
// Obtenir llista de tots els recursos
// Obtenir list de todos los recursos
std::vector<std::string> Pack::getResourceList() const {
std::vector<std::string> list;
list.reserve(resources_.size());
+10 -10
View File
@@ -1,6 +1,6 @@
// resource_pack.hpp - Sistema d'empaquetament de recursos
// © 2025 Port a C++20 amb SDL3
// Basat en el sistema de "pollo" amb adaptacions per Orni Attack
// resource_pack.hpp - Sistema de empaquetament de recursos
// © 2025 Port a C++20 con SDL3
// Basat en el sistema de "pollo" con adaptacions per Orni Attack
#pragma once
@@ -11,27 +11,27 @@
namespace Resource {
// Capçalera del fitxer de paquet
// Capçalera del file de paquet
struct PackHeader {
char magic[4]; // "ORNI"
uint32_t version; // Versió del format (1)
uint32_t version; // Versión del format (1)
};
// Entrada de recurs dins el paquet
struct ResourceEntry {
std::string filename; // Nom del recurs (amb barres normals)
uint64_t offset; // Posició dins el bloc de dades
std::string filename; // Nom del recurs (con barres normals)
uint64_t offset; // Posición dins el bloc de dades
uint64_t size; // Mida en bytes
uint32_t checksum; // Checksum CRC32 per verificació
};
// Classe principal per gestionar paquets de recursos
// Clase principal per gestionar paquets de recursos
class Pack {
public:
Pack() = default;
~Pack() = default;
// Afegir fitxers al paquet
// Añadir archivos al paquet
bool addFile(const std::string& filepath, const std::string& pack_name);
bool addDirectory(const std::string& dir_path, const std::string& base_path = "");
@@ -57,7 +57,7 @@ class Pack {
std::unordered_map<std::string, ResourceEntry> resources_;
std::vector<uint8_t> data_;
// Funcions auxiliars
// Funciones auxiliars
std::vector<uint8_t> readFile(const std::string& filepath);
[[nodiscard]] uint32_t calculateChecksum(const std::vector<uint8_t>& data) const;
void encryptData(std::vector<uint8_t>& data, const std::string& key);
+27 -27
View File
@@ -36,7 +36,7 @@ using SceneType = SceneContext::SceneType;
Director::Director(std::vector<std::string> const& args) {
std::cout << "Orni Attack - Inici\n";
// Inicialitzar opcions amb valors per defecte
// Inicialitzar opciones con valors per defecte
Options::init();
// Comprovar arguments del programa
@@ -50,28 +50,28 @@ Director::Director(std::vector<std::string> const& args) {
// Inicialitzar sistema de recursos
#ifdef RELEASE_BUILD
// Mode release: paquet obligatori, sense fallback
// Mode release: paquet obligatori, sin fallback
std::string pack_path = resource_base + "/resources.pack";
if (!Resource::Helper::initializeResourceSystem(pack_path, false)) {
std::cerr << "ERROR FATAL: No es pot load " << pack_path << "\n";
std::cerr << "El joc no pot continuar sense els recursos.\n";
std::cerr << "El juego no pot continuar sin los recursos.\n";
std::exit(1);
}
// Validar integritat del paquet
if (!Resource::Loader::get().validatePack()) {
std::cerr << "ERROR FATAL: El paquet de recursos està corromput\n";
std::cerr << "ERROR FATAL: El paquet de recursos está corromput\n";
std::exit(1);
}
std::cout << "Sistema de recursos inicialitzat (mode release)\n";
#else
// Mode desenvolupament: intentar paquet amb fallback a data/
// Mode desenvolupament: intentar paquet con fallback a data/
std::string pack_path = resource_base + "/resources.pack";
Resource::Helper::initializeResourceSystem(pack_path, true);
if (Resource::Helper::isPackLoaded()) {
std::cout << "Sistema de recursos inicialitzat (mode dev amb paquet)\n";
std::cout << "Sistema de recursos inicialitzat (mode dev con paquet)\n";
} else {
std::cout << "Sistema de recursos inicialitzat (mode dev, fallback a data/)\n";
}
@@ -84,21 +84,21 @@ Director::Director(std::vector<std::string> const& args) {
createSystemFolder("jailgames");
createSystemFolder(std::string("jailgames/") + Project::NAME);
// Establir ruta del fitxer de configuració
// Establir ruta del file de configuración
Options::setConfigFile(system_folder_ + "/config.yaml");
// Carregar o crear configuració
// Carregar o crear configuración
Options::loadFromFile();
// Inicialitzar sistema d'input
// Inicialitzar sistema de input
Input::init("data/gamecontrollerdb.txt");
// Aplicar configuració de controls dels jugadors
// Aplicar configuración de controls dels jugadors
Input::get()->applyPlayer1BindingsFromOptions();
Input::get()->applyPlayer2BindingsFromOptions();
if (Options::console) {
std::cout << "Configuració carregada\n";
std::cout << "Configuración carregada\n";
std::cout << " Finestra: " << Options::window.width << "×"
<< Options::window.height << '\n';
std::cout << " Física: rotation=" << Options::physics.rotation_speed
@@ -111,7 +111,7 @@ Director::Director(std::vector<std::string> const& args) {
}
Director::~Director() {
// Guardar opcions
// Guardar opciones
Options::saveToFile();
// Cleanup input
@@ -138,7 +138,7 @@ auto Director::checkProgramArguments(std::vector<std::string> const& args)
} else if (argument == "--reset-config") {
Options::init();
Options::saveToFile();
std::cout << "Configuració restablida als valors per defecte\n";
std::cout << "Configuración restablida als valors per defecte\n";
}
}
@@ -188,7 +188,7 @@ void Director::createSystemFolder(const std::string& folder) {
exit(EXIT_FAILURE);
case EEXIST:
// La carpeta ja existeix (race condition), continuar
// La carpeta ya existeix (race condition), continuar
break;
case ENAMETOOLONG:
@@ -207,7 +207,7 @@ void Director::createSystemFolder(const std::string& folder) {
}
}
// Bucle principal del joc
// Bucle principal del juego
auto Director::run() -> int {
// Calculate initial size from saved zoom_factor
int initial_width = static_cast<int>(std::round(
@@ -215,16 +215,16 @@ auto Director::run() -> int {
int initial_height = static_cast<int>(std::round(
Defaults::Window::HEIGHT * Options::window.zoom_factor));
// Crear gestor SDL amb configuració de Options
// Crear gestor SDL con configuración de Options
SDLManager sdl(initial_width, initial_height, Options::window.fullscreen);
// CRÍTIC: Forçar ocultació del cursor DESPRÉS de tota la inicialització SDL
// Això evita que SDL mostre el cursor automàticament durant la creació de la finestra
// CRÍTIC: Forçar ocultació del cursor DESPRÉS de toda la inicialización SDL
// Això evita que SDL mostre el cursor automàticament durante la creació de la finestra
if (!Options::window.fullscreen) {
Mouse::forceHide();
}
// Inicialitzar sistema d'audio
// Inicialitzar sistema de audio
Audio::init();
Audio::get()->setMusicVolume(1.0);
Audio::get()->setSoundVolume(0.4);
@@ -234,10 +234,10 @@ auto Director::run() -> int {
AudioCache::getMusic("game.ogg");
if (Options::console) {
std::cout << "Música precachejada: "
<< AudioCache::getMusicCacheSize() << " fitxers\n";
<< AudioCache::getMusicCacheSize() << " archivos\n";
}
// Crear context d'escenes
// Crear context de escenes
SceneContext context;
#ifdef _DEBUG
context.setNextScene(SceneType::TITLE);
@@ -245,10 +245,10 @@ auto Director::run() -> int {
context.setNextScene(SceneType::LOGO);
#endif
// Bucle principal de gestió d'escenes
// Bucle principal de gestió de escenes
while (context.nextScene() != SceneType::EXIT) {
// Sincronitzar SceneManager::actual amb context
// (altres sistemes encara poden llegir SceneManager::actual)
// Sincronitzar SceneManager::actual con context
// (altres sistemes aún poden llegir SceneManager::actual)
SceneManager::actual = context.nextScene();
switch (context.nextScene()) {
@@ -265,8 +265,8 @@ auto Director::run() -> int {
}
case SceneType::GAME: {
GameScene joc(sdl, context);
joc.run();
GameScene juego(sdl, context);
juego.run();
break;
}
@@ -275,7 +275,7 @@ auto Director::run() -> int {
}
}
// Sincronitzar final amb SceneManager::actual
// Sincronitzar final con SceneManager::actual
SceneManager::actual = SceneType::EXIT;
return 0;
+11 -11
View File
@@ -4,32 +4,32 @@
namespace GameConfig {
// Mode de joc
// Mode de juego
enum class Mode {
NORMAL, // Partida normal
DEMO // Mode demostració (futur)
};
// Configuració d'una match
// Configuración de una match
struct MatchConfig {
bool jugador1_actiu{false}; // És active el player 1?
bool jugador2_actiu{false}; // És active el player 2?
Mode mode{Mode::NORMAL}; // Mode de joc
bool jugador1_actiu{false}; // Es active el player 1?
bool jugador2_actiu{false}; // Es active el player 2?
Mode mode{Mode::NORMAL}; // Mode de juego
// Mètodes auxiliars
// Métodos auxiliars
// Retorna true si només hi ha un player active
// Retorna true si solo hay un player active
[[nodiscard]] bool es_un_jugador() const {
return (jugador1_actiu && !jugador2_actiu) ||
(!jugador1_actiu && jugador2_actiu);
}
// Retorna true si hi ha dos jugadors active
// Retorna true si hay dos jugadors active
[[nodiscard]] bool son_dos_jugadors() const {
return jugador1_actiu && jugador2_actiu;
}
// Retorna true si no hi ha cap player active
// Retorna true si no hay sin player active
[[nodiscard]] bool cap_jugador() const {
return !jugador1_actiu && !jugador2_actiu;
}
@@ -40,7 +40,7 @@ struct MatchConfig {
}
// Retorna l'ID de l'únic player active (0 o 1)
// Només vàlid si es_un_jugador() retorna true
// Solo vàlid si es_un_jugador() retorna true
[[nodiscard]] uint8_t id_unic_jugador() const {
if (jugador1_actiu && !jugador2_actiu) {
return 0;
@@ -48,7 +48,7 @@ struct MatchConfig {
if (!jugador1_actiu && jugador2_actiu) {
return 1;
}
return 0; // Fallback (cal comprovar es_un_jugador() primer)
return 0; // Fallback (necesario comprovar es_un_jugador() primer)
}
};
+2 -2
View File
@@ -1,4 +1,4 @@
// global_events.hpp - Events globals del joc
// global_events.hpp - Events globals del juego
// Basat en el patró del projecte "pollo"
// © 2025 Port a C++20
@@ -14,6 +14,6 @@ class SceneContext;
namespace GlobalEvents {
// Processa events globals (F1/F2/F3/ESC/QUIT)
// Retorna true si l'event ha state processat i no cal seguir processant-lo
// Retorna true si l'event ha state processat y no necesario seguir processant-lo
bool handle(const SDL_Event& event, SDLManager& sdl, SceneManager::SceneContext& context);
} // namespace GlobalEvents
+24 -24
View File
@@ -1,4 +1,4 @@
// context_escenes.hpp - Sistema de gestió d'escenes i context de transicions
// scene_context.hpp - Sistema de gestió de escenes i context de transiciones
// © 2025 Port a C++20
#pragma once
@@ -7,29 +7,29 @@
namespace SceneManager {
// Context de transició entre escenes
// Conté l'escena destinació i opcions específiques per aquella escena
// Context de transición entre escenes
// Conté l'escena destinació i opciones específiques per aquella escena
class SceneContext {
public:
// Tipus d'escena del joc
// Tipo de escena del juego
enum class SceneType {
LOGO, // Pantalla d'inici (logo JAILGAMES)
TITLE, // Pantalla de títol amb menú
GAME, // Joc principal (Asteroids)
EXIT // Sortir del programa
LOGO, // Pantalla de start (logo JAILGAMES)
TITLE, // Pantalla de título con menú
GAME, // Juego principal (Asteroids)
EXIT // Salir del programa
};
// Opcions específiques per a cada escena
// Opciones específiques para cada escena
enum class Option {
NONE, // Sense opcions especials (comportament per defecte)
NONE, // Sin opciones especials (comportament per defecte)
JUMP_TO_TITLE_MAIN, // TITLE: Saltar directament a MAIN (starfield instantani)
// MODE_DEMO, // GAME: Mode demostració amb IA (futur)
// MODE_DEMO, // GAME: Mode demostració con IA (futur)
};
// Constructor inicial amb escena LOGO i sense opcions
// Constructor inicial con escena LOGO i sin opciones
SceneContext() = default;
// Canviar escena amb opció específica
// Canviar escena con opción específica
void setNextScene(SceneType next_scene, Option option = Option::NONE) {
next_scene_ = next_scene;
option_ = option;
@@ -40,42 +40,42 @@ class SceneContext {
return next_scene_;
}
// Consultar opció actual
// Consultar opción actual
[[nodiscard]] auto option() const -> Option {
return option_;
}
// Consumir opció (retorna valor i reseteja a NONE)
// Utilitzar quan l'escena processa l'opció
// Consumir opción (retorna value i reseteja a NONE)
// Utilitzar cuando l'escena processa l'opción
[[nodiscard]] auto consumeOption() -> Option {
Option valor = option_;
Option value = option_;
option_ = Option::NONE;
return valor;
return value;
}
// Reset opció a NONE (sense retornar valor)
// Reset opción a NONE (sin retornar value)
void resetOption() {
option_ = Option::NONE;
}
// Configurar match abans de transicionar a GAME
// Configurar match antes de transicionar a GAME
void setMatchConfig(const GameConfig::MatchConfig& config) {
match_config_ = config;
}
// Obtenir configuració de match (consumit per GameScene)
// Obtenir configuración de match (consumit per GameScene)
[[nodiscard]] const GameConfig::MatchConfig& getMatchConfig() const {
return match_config_;
}
private:
SceneType next_scene_{SceneType::LOGO}; // SceneType a la qual transicionar
Option option_{Option::NONE}; // Opció específica per l'escena
GameConfig::MatchConfig match_config_; // Configuració de match (jugadors active, mode)
Option option_{Option::NONE}; // Opción específica per l'escena
GameConfig::MatchConfig match_config_; // Configuración de match (jugadors active, mode)
};
// Variable global inline per gestionar l'escena actual (backward compatibility)
// Sincronitzada amb context.nextScene() pel Director
// Sincronitzada con context.nextScene() por el Director
inline SceneContext::SceneType actual = SceneContext::SceneType::LOGO;
} // namespace SceneManager
+7 -7
View File
@@ -1,5 +1,5 @@
// path_utils.cpp - Implementació de utilitats de rutes
// © 2025 Port a C++20 amb SDL3
// © 2025 Port a C++20 con SDL3
#include "path_utils.hpp"
@@ -13,10 +13,10 @@ namespace Utils {
static std::string executable_path_;
static std::string executable_directory_;
// Inicialitzar el sistema de rutes amb argv[0]
// Inicialitzar el sistema de rutes con argv[0]
void initializePathSystem(const char* argv0) {
if (argv0 == nullptr) {
std::cerr << "[PathUtils] ADVERTÈNCIA: argv[0] és nullptr\n";
std::cerr << "[PathUtils] ADVERTÈNCIA: argv[0] es nullptr\n";
executable_path_ = "";
executable_directory_ = ".";
return;
@@ -50,7 +50,7 @@ bool isMacOSBundle() {
#ifdef MACOS_BUNDLE
return true;
#else
// Detecció en time d'execució
// Detecció en time de execució
// Cercar ".app/Contents/MacOS" a la ruta de l'executable
std::string exe_dir = getExecutableDirectory();
return exe_dir.find(".app/Contents/MacOS") != std::string::npos;
@@ -62,10 +62,10 @@ std::string getResourceBasePath() {
std::string exe_dir = getExecutableDirectory();
if (isMacOSBundle()) {
// Bundle de macOS: recursos a ../Resources des de MacOS/
// Bundle de macOS: recursos a ../Resources desde MacOS/
std::cout << "[PathUtils] Detectat bundle de macOS\n";
return exe_dir + "/../Resources";
} // Executable normal: recursos al mateix directori
} // Executable normal: recursos al mismo directori
return exe_dir;
}
@@ -76,7 +76,7 @@ std::string normalizePath(const std::string& path) {
// Convertir barres invertides a normals
std::ranges::replace(normalized, '\\', '/');
// Simplificar rutes amb filesystem
// Simplificar rutes con filesystem
try {
std::filesystem::path fs_path(normalized);
normalized = fs_path.lexically_normal().string();
+2 -2
View File
@@ -1,5 +1,5 @@
// path_utils.hpp - Utilitats de gestió de rutes
// © 2025 Port a C++20 amb SDL3
// © 2025 Port a C++20 con SDL3
// Detecció de directoris i bundles multiplataforma
#pragma once
@@ -8,7 +8,7 @@
namespace Utils {
// Inicialització amb argv[0]
// Inicialización con argv[0]
void initializePathSystem(const char* argv0);
// Obtenció de rutes