Files
aee-arcade/source/utils/defaults.hpp
T

527 lines
29 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include <SDL3/SDL.h>
#include <cstdint>
namespace Defaults {
// Mode de presentació lògica (escala finestra). Mapeja als valors de
// SDL_RendererLogicalPresentation des de Screen via una funció helper,
// perquè aquest header no depengui de detalls de SDL3 més enllà del scancode.
enum class ScalingMode : std::uint8_t {
DISABLED = 0,
STRETCH = 1,
LETTERBOX = 2,
OVERSCAN = 3,
INTEGER = 4,
};
// Filtre de textura per a l'upscale final.
enum class TextureFilter : std::uint8_t {
NEAREST = 0,
LINEAR = 1,
};
// Posició de l'overlay RenderInfo: apagat, a dalt o a baix del canvas.
// Cicle OFF → TOP → BOTTOM → OFF amb la hotkey corresponent.
enum class RenderInfoPosition : std::uint8_t {
OFF = 0,
TOP = 1,
BOTTOM = 2,
};
constexpr int RENDER_INFO_POSITION_COUNT = 3;
namespace Window {
constexpr int ZOOM = 3;
constexpr bool FULLSCREEN = false;
} // namespace Window
namespace I18n {
constexpr const char* LOCALE = "ca"; // Idioma per defecte (codi ISO 639-1).
constexpr const char* LOCALE_DIR = "data/locale/"; // Carpeta amb els YAML per idioma.
} // namespace I18n
namespace Video {
constexpr bool VSYNC = true;
constexpr ScalingMode SCALING_MODE = ScalingMode::LETTERBOX;
constexpr TextureFilter TEXTURE_FILTER = TextureFilter::NEAREST;
constexpr bool GPU_ACCELERATION = true; // Path SDL3 GPU per defecte; fallback a SDL_Renderer si falla.
constexpr const char* GPU_PREFERRED_DRIVER = ""; // Buit = auto. Aplica a l'arrencada.
constexpr bool SHADER_ENABLED = true; // Aplica PostFX; si false, sempre passthrough.
constexpr const char* CURRENT_SHADER = "postfx"; // Shader actiu: "postfx" o "crtpi".
constexpr const char* POSTFX_DEFAULT_PRESET = "CRT"; // Preset inicial PostFX.
constexpr const char* CRTPI_DEFAULT_PRESET = "Default"; // Preset inicial CrtPi.
constexpr const char* POSTFX_FILE = "shaders/postfx.yaml"; // Relatiu a la carpeta de sistema.
constexpr const char* CRTPI_FILE = "shaders/crtpi.yaml"; // Relatiu a la carpeta de sistema.
constexpr RenderInfoPosition RENDER_INFO_POSITION = RenderInfoPosition::OFF; // Overlay de debug amagat per defecte.
constexpr bool RENDER_INFO_SHOW_TIME = true; // Si l'overlay és visible, mostra el temps de joc.
} // namespace Video
namespace Audio {
constexpr bool ENABLED = true;
constexpr float VOLUME = 1.0F;
constexpr bool MUSIC_ENABLED = true;
constexpr float MUSIC_VOLUME = 1.0F;
constexpr bool SOUND_ENABLED = true;
constexpr float SOUND_VOLUME = 0.2F;
constexpr float VOLUME_STEP = 0.05F; // Pas estàndard per a la UI (5%).
constexpr int FREQUENCY = 48000; // Freqüència de mostreig del dispositiu (Hz).
constexpr int CROSSFADE_MS = 1500; // Durada per defecte del crossfade entre pistes (ms).
constexpr SDL_AudioFormat FORMAT = SDL_AUDIO_S16; // Format PCM 16-bit signat natiu.
constexpr int CHANNELS = 2; // Nombre de canals de sortida (estèreo).
} // namespace Audio
namespace KeysGame {
constexpr SDL_Scancode UP = SDL_SCANCODE_UP;
constexpr SDL_Scancode DOWN = SDL_SCANCODE_DOWN;
constexpr SDL_Scancode LEFT = SDL_SCANCODE_LEFT;
constexpr SDL_Scancode RIGHT = SDL_SCANCODE_RIGHT;
constexpr SDL_Scancode JUMP = SDL_SCANCODE_M;
constexpr SDL_Scancode ATTACK = SDL_SCANCODE_N;
constexpr SDL_Scancode START = SDL_SCANCODE_1;
constexpr SDL_Scancode EXIT = SDL_SCANCODE_ESCAPE;
} // namespace KeysGame
// Tecles del segon jugador local (WASD). Simètriques a KeysGame però
// mapejades a la mà esquerra del teclat. Cada Player instancia amb els
// seus propis Controls, així que aquests són un recull de fàbrica:
// canviar-los ací canvia el mapatge per a qualsevol escena que els use.
namespace KeysGameP2 {
constexpr SDL_Scancode UP = SDL_SCANCODE_W;
constexpr SDL_Scancode DOWN = SDL_SCANCODE_S;
constexpr SDL_Scancode LEFT = SDL_SCANCODE_A;
constexpr SDL_Scancode RIGHT = SDL_SCANCODE_D;
constexpr SDL_Scancode JUMP = SDL_SCANCODE_V;
constexpr SDL_Scancode ATTACK = SDL_SCANCODE_C;
constexpr SDL_Scancode START = SDL_SCANCODE_2;
} // namespace KeysGameP2
namespace Player {
constexpr float SPEED_PX_PER_S = 60.0F; // Velocitat base del jugador (sense sprint / slow-zones).
// Factor multiplicatiu aplicat a la velocitat quan un jugador empenta
// l'altre (0.30 = el pusher es ralentitza al 30% i el pushed és
// arrossegat a la mateixa velocitat). Sobrescrivible des del YAML
// del mapa amb la clau `push_factor`.
constexpr float PUSH_FACTOR = 0.30F;
} // namespace Player
// Fallbacks del tema d'UI: índexs de paleta, timings (ms) i fonts.
// El tema en viu és a data/config/ui.yaml, carregat per UiConfig a
// l'arrencada; aquests valors només s'apliquen si el fitxer falta o
// li manca alguna clau. Ací només cal tocar-los si es vol canviar el
// fallback "de fàbrica".
namespace UI {
// Fonts d'UI centralitzades: un únic lloc per conèixer la carpeta
// (data/fonts/), el nom-clau al Resource::Cache i els fitxers .gif /
// .fnt de cada font. Afegir-ne una nova és una constant ací i ja.
namespace Font {
constexpr const char* DIR = "data/fonts/";
// HUD/Notifier/RenderInfo: font principal de UI del joc.
// El kerning és la separació extra entre glifs (sumat a l'amplada
// natural). 1 és el valor clàssic; valors negatius ajunten glifs
// per a fonts de display amb sidebearings amples.
constexpr const char* HUD_NAME = "8bithud";
constexpr const char* HUD_GIF = "data/fonts/8bithud.gif";
constexpr const char* HUD_FNT = "data/fonts/8bithud.fnt";
constexpr int HUD_KERNING = 1;
// Placeholders (LOGO / TITLE / INTRO): font temporal fins que els
// placeholders es substitueixin per les seues escenes finals.
constexpr const char* PLACEHOLDER_NAME = "ari-w9500-condensed-display";
constexpr const char* PLACEHOLDER_GIF = "data/fonts/ari-w9500-condensed-display.gif";
constexpr const char* PLACEHOLDER_FNT = "data/fonts/ari-w9500-condensed-display.fnt";
constexpr int PLACEHOLDER_KERNING = 1;
// Text de transició de sala (ROOM_INTRO "Piràmide N / Sala M" i
// ROOM_OUTRO "Fase completada"). Font temàtica diferenciada de la
// del HUD i de la dels placeholders perquè el rètol de fase tinga
// pes visual propi. La pausa segueix amb la PLACEHOLDER.
constexpr const char* ROOM_TEXT_NAME = "CaesarDressing-Regular";
constexpr const char* ROOM_TEXT_GIF = "data/fonts/CaesarDressing-Regular.gif";
constexpr const char* ROOM_TEXT_FNT = "data/fonts/CaesarDressing-Regular.fnt";
constexpr int ROOM_TEXT_KERNING = 1;
// Menú de servei (F9): títol en display normal, items en la
// variant condensed-display (més compacta, perquè caben més
// files sense encongir la caixa). Kerning 0 a totes dues perquè
// els glifs de display ja porten sidebearings generosos.
constexpr const char* MENU_TITLE_NAME = "ari-w9500-display";
constexpr const char* MENU_TITLE_GIF = "data/fonts/ari-w9500-display.gif";
constexpr const char* MENU_TITLE_FNT = "data/fonts/ari-w9500-display.fnt";
constexpr int MENU_TITLE_KERNING = 0;
constexpr const char* MENU_ITEMS_NAME = "ari-w9500-condensed-display";
constexpr const char* MENU_ITEMS_GIF = "data/fonts/ari-w9500-condensed-display.gif";
constexpr const char* MENU_ITEMS_FNT = "data/fonts/ari-w9500-condensed-display.fnt";
constexpr int MENU_ITEMS_KERNING = 0;
// Copyright al peu de la TITLE: pixel-art estricte, generat amb
// font-gen a partir de Tiny5-Regular size 5 (caixa 3×6 px). La
// separem de la `placeholder` (que la fa servir el "press start")
// per diferenciar tipogràficament jerarquia: prompt destacat amb
// outline gros, copyright net i micro a baix.
constexpr const char* COPYRIGHT_NAME = "Tiny5-Regular";
constexpr const char* COPYRIGHT_GIF = "data/fonts/Tiny5-Regular.gif";
constexpr const char* COPYRIGHT_FNT = "data/fonts/Tiny5-Regular.fnt";
constexpr int COPYRIGHT_KERNING = 0;
} // namespace Font
// Overlay de RenderInfo (F12).
constexpr Uint8 RENDER_INFO_TEXT = 58;
constexpr Uint8 RENDER_INFO_SHADOW = 16;
// Fons del canvas (zona fora del tilemap en letterbox/integer).
constexpr Uint8 CANVAS_BG = 72;
// Preset per defecte del Notifier.
constexpr Uint8 NOTIFICATION_TEXT = 232;
constexpr Uint8 NOTIFICATION_BG = 64;
constexpr int NOTIFICATION_TIME_MS = 4000;
// Geometria del Notifier (en píxels del canvas). Asimètric a
// propòsit: PADDING_TOP > PADDING_BOTTOM puja una mica el text
// dins la caixa i deixa la base més arrapada al vora inferior.
// MARGIN_TOP és la separació entre la vora superior del canvas i
// la línia exterior de la caixa. SLIDE_MS és la durada de l'entrada
// i de l'eixida (independent de la mida de la caixa, perquè el
// moviment va per temps i no per velocitat). Les corbes són noms
// del registre d'`Easing` (veure UiConfig::curveByName).
namespace Notifier {
constexpr int PADDING_H = 6;
constexpr int PADDING_TOP = 4;
constexpr int PADDING_BOTTOM = 3;
constexpr int LINE_GAP = 1;
constexpr int MARGIN_TOP = 3;
constexpr int BORDER_PX = 1;
constexpr int SLIDE_MS = 400;
constexpr const char* SLIDE_IN_CURVE = "outCubic";
constexpr const char* SLIDE_OUT_CURVE = "inCubic";
} // namespace Notifier
// Preset per a la confirmació d'eixida (ESC doble). La durada ha
// de coincidir amb la del Notifier perquè el missatge i la finestra
// de confirmació expiren alhora (veure GlobalInputs::onExit).
constexpr Uint8 EXIT_TEXT = 71;
constexpr Uint8 EXIT_BG = 2;
constexpr int EXIT_TIME_MS = 4000;
// Índexs de paleta per al menú de servei (F9).
constexpr Uint8 MENU_BG = 2; // Fons de la caixa.
constexpr Uint8 MENU_BORDER = 232; // Vora.
constexpr Uint8 MENU_TITLE = 237; // Títol i subtítol.
constexpr Uint8 MENU_LABEL = 58; // Etiquetes dels items.
constexpr Uint8 MENU_VALUE = 232; // Valor actual.
constexpr Uint8 MENU_CURSOR = 71; // Item seleccionat.
constexpr Uint8 MENU_DISABLED = 16; // Label en gris quan no aplica.
// Índexs de paleta per al marcador de joc (HUD de la GameScene).
// Arranca reciclant els colors del menú per coherència visual;
// separant els noms a constants pròpies, tocar-los a posteriori
// no afecta el menú.
constexpr Uint8 HUD_BG = 0; // Fons de cada bloc.
constexpr Uint8 HUD_LABEL = 58; // Etiquetes ("P1", "V", "T").
constexpr Uint8 HUD_VALUE = 187; // Valors (score, vides, tresors).
constexpr Uint8 HUD_FLASH = 237; // Color temporal del valor en flash.
// Rètol de transició de sala (ROOM_INTRO i ROOM_OUTRO).
// Independent dels colors de notificació perquè el rètol de
// fase és un canal visual diferent. `ROOM_TEXT_OUTLINE` és el
// contorn que abans estava hardcodejat al `renderRoomText`.
constexpr Uint8 ROOM_TEXT = 232;
constexpr Uint8 ROOM_TEXT_OUTLINE = 255;
// Timings d'animació del HUD. L'entrada són els tres blocs lliscant
// a la seua posició; flash i shake acompanyen un `player_hit`.
constexpr int HUD_ENTRY_MS = 400;
constexpr int HUD_FLASH_MS = 250;
constexpr int HUD_SHAKE_MS = 300;
// Pausa graduada de la GameScene: el món no para d'un colp, es
// frena amb una corba i torna a arrancar amb una altra. Els noms
// de corba han de coincidir amb els registrats a
// UiConfig::curveByName (linear / outQuad / inQuad / inOutQuad /
// outCubic / inCubic). Si un nom no es reconeix, es cau a
// Easing::linear.
constexpr int PAUSE_ENTER_MS = 400;
constexpr int PAUSE_EXIT_MS = 250;
constexpr const char* PAUSE_ENTER_CURVE = "outCubic";
constexpr const char* PAUSE_EXIT_CURVE = "inCubic";
// Sons del menú de servei. SELECT acompanya navegació (amunt/avall)
// i back; ACCEPT acompanya modificació d'opció (esq/dret/retorn).
// Els fitxers viuen a `data/audio/sounds/`; només es referencia el nom.
constexpr const char* MENU_SELECT_SOUND = "menu_select.wav";
constexpr const char* MENU_ACCEPT_SOUND = "menu_accept.wav";
// So disparat quan un jugador prem START a la TITLE (tant la
// primera pulsació que entra a STARTING com la del segon
// jugador que reseteja a BOTH dins de la finestra). Fitxer a
// `data/audio/sounds/`.
constexpr const char* PLAYER_START_SOUND = "player_start.wav";
// So curt de "soroll/scratch" disparat al constructor de LogoScene
// i sincronitzat amb la fase SCAN del scanline reveal. Playback
// únic via Audio::Group::INTERFACE; si dura més que el scan, la
// cua sona pinçada al començament de MIDDLE — pretès com a
// "eco" sonor de l'efecte.
constexpr const char* LOGO_GLITCH_SOUND = "glitch.wav";
// Escena TITLE (provisional fins que tinguem artwork). Colors
// referits a la paleta "ui" (uzebox.pal): BG_COLOR és el to més
// proper al negre sense ser-ho (índex 1 = 36,0,0); TEXT_COLOR és
// el taronja més pur de la paleta (índex 31 = 255,109,0). Els
// ms del cicle de parpadeig sumen el cicle complet del prompt
// "press start" — 80% visible / 20% ocult per defecte.
namespace Title {
constexpr int DURATION_MS = 30000;
constexpr Uint8 BG_COLOR = 1;
constexpr Uint8 TEXT_COLOR = 31;
// Color del text de "© 2026 JailDesigner": off-white càlid (índex
// 183 = 255,218,170, peach/cream) — ~90% blanc amb tint càlid.
constexpr Uint8 COPYRIGHT_COLOR = 183;
// Color de l'outline del prompt "PRESS START" (no del copyright,
// tot i compartir-se a versions antigues). Marró fosc càlid
// (índex 19 = 109,72,0) coherent amb la paleta del logo.
constexpr Uint8 PRESS_START_OUTLINE_COLOR = 19;
// Posicions Y dels tres elements verticals de la TITLE, en
// percentatge sobre `GameCanvas::HEIGHT`. El logo s'ancora pel
// seu top (la imatge cau cap avall des d'aquest Y); el prompt
// i el copyright es centren verticalment sobre la línia.
constexpr int LOGO_Y_PERCENT = 15;
constexpr int PROMPT_Y_PERCENT = 68;
constexpr int COPYRIGHT_Y_PERCENT = 92;
// Separació vertical entre el minilogo i el text del © al peu.
constexpr int MINI_LOGO_GAP_PX = 2;
constexpr int BLINK_VISIBLE_MS = 800;
constexpr int BLINK_HIDDEN_MS = 200;
// Fase STARTING: durada fixa entre la primera pulsació de
// START i la transició a la següent escena. Durant aquesta
// fase, el parpadeig del prompt commuta a un cicle simètric
// 50/50 (visible/ocult) amb període `STARTING_BLINK_PERIOD_MS`,
// pensat per a un ritme molt més ràpid que l'animació
// atràctil del IDLE (200 ms = 5 Hz).
constexpr int STARTING_MS = 3000;
constexpr int STARTING_BLINK_PERIOD_MS = 200;
// Fade-out estil mosaic dissolve dins l'última part de la
// fase STARTING. `FADE_OUT_MS` ha de ser <= STARTING_MS;
// si és més gran, comença ja a t=0 i acaba abans del salt.
// `FADE_OUT_MAX_BLOCK` és la mida màxima de bloc en píxels
// (32 al canvas de 320×240 dóna 10×8 blocs al final).
constexpr int FADE_OUT_MS = 800;
constexpr int FADE_OUT_MAX_BLOCK = 32;
// Fade-out de la música de la TITLE en entrar a STARTING.
// Independent del visual: no cal que coincidisca amb FADE_OUT_MS
// (la música pot acabar abans/després del mosaic).
constexpr int MUSIC_FADE_OUT_MS = 2000;
// Fade-to-black per a la sortida d'attract (timeout). És una
// capa negra lineal sobre el canvas — sense mosaic — perquè
// l'eixida silenciosa cap a LOGO siga neta. NO toca la música:
// el title.ogg continua sonant durant la transició; LOGO ja
// veurà què en fa.
constexpr int ATTRACT_FADE_TO_BLACK_MS = 800;
// Seqüència d'aparició dels elements de la TITLE en fase IDLE.
// Tots els temps són absoluts des de l'entrada a l'escena.
// `FADE_IN_MS` és la capa negra inicial que s'esvaeix cap al fons
// (mateixa convenció que `room_intro.fade_in_ms` del joc perquè
// l'arribada a la TITLE i a una sala de joc tinguin el mateix
// ritme). Els altres temps marquen quan apareix cada element;
// `SLIDE_*` defineixen el slide-in des del marge inferior amb
// la corba `SLIDE_CURVE`. Si l'usuari prem START durant la
// seqüència, aquesta es completa instantàniament.
namespace Intro {
constexpr int FADE_IN_MS = 500;
constexpr int GAME_LOGO_AT_MS = 1500;
constexpr int MINI_LOGO_AT_MS = 2000;
constexpr int MINI_LOGO_SLIDE_MS = 500;
constexpr int COPYRIGHT_AT_MS = 2200;
constexpr int COPYRIGHT_SLIDE_MS = 500;
constexpr const char* SLIDE_CURVE = "outCubic";
constexpr int PRESS_START_AT_MS = 3000;
} // namespace Intro
// Distorsió sinusoidal horitzontal de l'imatge de fons
// (efecte de calor del desert). `amplitude_px` és el
// desplaçament màxim per fila; `wavelength_px` la distància
// vertical entre dos pics; `speed_hz` la velocitat amb què
// avança la fase (cicles/segon). Si `enabled` és false el
// fons es pinta sense distorsió.
namespace HeatHaze {
constexpr bool ENABLED = true;
constexpr float AMPLITUDE_PX = 1.5F;
constexpr float WAVELENGTH_PX = 32.0F;
constexpr float SPEED_HZ = 0.6F;
} // namespace HeatHaze
} // namespace Title
// Escena LOGO (logotip de l'editora). La timeline és lineal i
// composta per fases independents amb durades configurables des
// del YAML (`logo.timeline.*`). L'efecte CRT de revelat (scan
// line + glitch tail) ho gestiona `Effects::ScanReveal` i les
// seves constants viuen al sub-namespace `Scan` d'aquí baix.
namespace Logo::Timeline {
// Negre inicial abans que comence el revelat. Permet entrar
// a l'escena des d'una transició/fade extern sense talls.
constexpr int BLACK_INTRO_MS = 2000;
// Silenci amb logo estable abans d'arrencar la música del
// títol — espai per "respirar" entre el glitch i la pista.
constexpr int HOLD_SILENT_MS = 1000;
// Logo estable amb música del títol sonant. Quan acaba,
// comença el fade-out.
constexpr int HOLD_WITH_MUSIC_MS = 2500;
// Fade lineal a negre.
constexpr int FADE_OUT_MS = 500;
// Negre final amb música encara sonant — la TitleScene
// continuarà la pista de manera idempotent.
constexpr int BLACK_OUTRO_MS = 1000;
} // namespace Logo::Timeline
// Constants del revelat CRT pròpiament dit. La banda lluminosa
// baixa de dalt a baix amb glitch al seu voltant i bursts VHS
// ocasionals damunt la part ja revelada. Quan la banda toca el
// peu del logo, un flash blanc remata l'efecte; després un
// "tail" manté el logo visible amb bursts durant `TAIL_GLITCH_MS`
// abans que `isFinished()` retorne true.
namespace Logo::Scan {
constexpr int DURATION_MS = 1500;
constexpr int TAIL_GLITCH_MS = 1500;
constexpr int BAND_HEIGHT_PX = 4;
constexpr int BAND_ALPHA = 200;
// Pulse de brillantor sinusoidal sobre l'alpha base de la
// banda — simula el ritme de refresc d'un CRT. La fase
// avança a `BAND_PULSE_HZ` cicles/segon i la profunditat
// marca quant cau l'alpha al ventre (0 = sense pulse,
// 1 = la banda arriba a alpha 0 als ventres). Valors per
// defecte: 20 Hz pulsacional ben visible a 60 fps sense
// aliasing dur, profunditat 0.45 (alpha oscil·la entre el
// 55% i el 100% de BAND_ALPHA).
constexpr float BAND_PULSE_HZ = 20.0F;
constexpr float BAND_PULSE_DEPTH = 0.45F;
// Glitch a la banda d'impacte: les files dins del radi
// reben un offset horitzontal aleatori d'amplitud
// decreixent amb la distància a la banda.
constexpr int GLITCH_AMPLITUDE_PX = 6;
constexpr int GLITCH_BAND_RADIUS_PX = 12;
// Bursts VHS damunt la part ja revelada: ocasionalment
// (~per_sec mitjà) una franja horitzontal es desplaça
// durant `duration_ms` per simular tracking error.
constexpr int VHS_BURST_PER_SEC = 3;
constexpr int VHS_BURST_DURATION_MS = 80;
constexpr int VHS_BURST_HEIGHT_PX = 8;
constexpr int VHS_BURST_AMPLITUDE_PX = 8;
// Flash blanc final quan la banda surt per sota — punt
// visual de tancament del scan abans d'entrar a MIDDLE.
constexpr int FLASH_MS = 100;
} // namespace Logo::Scan
} // namespace UI
#ifdef _DEBUG
// Constants de l'editor de tilemap. Només presents en Debug — en
// Release l'editor no existeix, així que ni les constants tenen sentit.
namespace Editor {
// Color del rectangle 1 px que envolta el canvas durant l'edició.
constexpr std::uint32_t BORDER_ARGB = 0xFF2244FFU;
// Píxels entre el canvas i el rectangle del TilePicker per totes
// les vores. Prou perquè el border blau de l'editor no es
// superpose amb la graella del picker.
constexpr int PICKER_MARGIN = 8;
// Píxels de separació entre tiles dins de la graella del picker.
// 1 px deixa veure clarament on acaba un tile i on comença l'altre,
// útil sobretot quan dos tiles veïns tenen colors molt similars.
constexpr int PICKER_SPACING = 1;
// Fons del TilePicker (blau fosc, prou contrastat amb els tiles
// de color clar i clarament diferent del canvas).
constexpr std::uint32_t PICKER_BG_ARGB = 0xFF101824U;
// Vora 1 px del tile sota el cursor al picker.
constexpr std::uint32_t PICKER_HOVER_ARGB = 0xFFFFFFFFU;
} // namespace Editor
#endif
// Configuració de l'escena de joc (timings i corbes de la FSM de sala).
// Independent de la piràmide concreta — quan un dia hi haja diferents
// ritmes per piràmide, aquest YAML pot adoptar variants per nivell.
namespace GameScene {
constexpr const char* GAME_YAML = "data/scenes/game/game.yaml";
} // namespace GameScene
// Rutes d'assets per piràmide. Centralitzats ací perquè `GameScene` no
// en contingui cap literal; afegir una piràmide nova serà un altre
// conjunt de constants + un Config distint passat al ctor.
namespace Pyramid {
// Índex ordenat de les 30 sales (5 piràmides × 6 sales). El consumeix
// `Levels::LevelManager` a la primera invocació; cada entrada apunta
// a un `data/maps/p<N>/r<M>.yaml`. Cap altre punt del codi hauria de
// hardcodejar el path d'una sala concreta — pregunteu-li al
// `LevelManager` (`currentPath()`) i deixeu que ell decidisca.
constexpr const char* LEVELS_YAML = "data/maps/levels.yaml";
constexpr const char* PLAYER_SAM_GIF = "data/entities/player/sam.gif";
constexpr const char* PLAYER_SAM_YAML = "data/entities/player/sam.yaml";
// Personatge del segon jugador. Clonat de sam amb repaletat (roig→blau);
// la geometria del sprite i les animacions coincideixen amb les de P1,
// així que Player::loadFrom només cal cridar-la amb un dels dos YAMLs.
constexpr const char* PLAYER_MORCUS_GIF = "data/entities/player/morcus.gif";
constexpr const char* PLAYER_MORCUS_YAML = "data/entities/player/morcus.yaml";
constexpr const char* MUSIC_TRACK = "playing.ogg";
} // namespace Pyramid
// Rutes a recursos sota `data/`. Centralitzades ací perquè cap `.cpp`
// tinga literals "data/..." hardcoded: si demà es reorganitza
// l'arbre de `data/`, només cal tocar aquest namespace.
//
// Convenció: les constants que acaben en `_DIR` són prefixos (acaben
// en `/`) pensats per concatenar amb una clau coneguda en runtime
// (p.ex. nom de fitxer carregat des d'un YAML). La resta són rutes
// completes a un fitxer concret.
namespace Paths {
// Arrel de tots els recursos del joc. La fan servir el carregador de
// packs (per a stripping al lookup) i qualsevol consumidor que
// necessite saber la prefix lògica abans del path real.
constexpr const char* DATA_ROOT = "data/";
// Directoris (per concatenació amb claus dinàmiques).
constexpr const char* AUDIO_MUSIC_DIR = "data/audio/music/";
constexpr const char* AUDIO_SOUNDS_DIR = "data/audio/sounds/";
constexpr const char* ENTITIES_DIR = "data/entities/";
constexpr const char* PLAYER_DIR = "data/entities/player/";
// Configuració global (tema, sons, input, editor).
constexpr const char* UI_YAML = "data/config/ui.yaml";
constexpr const char* SOUNDS_YAML = "data/config/sounds.yaml";
constexpr const char* INPUT_YAML = "data/config/input.yaml";
constexpr const char* EDITOR_YAML = "data/config/editor.yaml";
constexpr const char* UI_PALETTE = "data/palettes/uzebox.pal";
// Configuració d'escenes (yaml). El de la GameScene viu a
// `Defaults::GameScene::GAME_YAML` per coherència amb la resta de
// valors d'aquella escena.
constexpr const char* LOGO_YAML = "data/scenes/logo/logo.yaml";
constexpr const char* TITLE_YAML = "data/scenes/title/title.yaml";
// Música pre-carregada pel Director a l'arrencada.
constexpr const char* MUSIC_TITLE = "data/audio/music/title.ogg";
constexpr const char* MUSIC_PLAYING = "data/audio/music/playing.ogg";
constexpr const char* MUSIC_ROOM_INTRO = "data/audio/music/room_intro.ogg";
constexpr const char* MUSIC_ROOM_OUTRO = "data/audio/music/room_outro.ogg";
// Gràfics de logo / title pre-carregats pel Director.
constexpr const char* LOGO_MINI_GIF = "data/scenes/logo/logo_jailgames_mini.gif";
constexpr const char* LOGO_FULL_GIF = "data/scenes/logo/logo_jailgames.gif";
constexpr const char* TITLE_GAME_LOGO_GIF = "data/scenes/title/game_logo.gif";
constexpr const char* TITLE_BG_GIF = "data/scenes/title/title_bg.gif";
// Entitats pre-carregades a GameScene (dust + 4 direccions de whip).
constexpr const char* DUST_GIF = "data/entities/dust/dust.gif";
constexpr const char* WHIP_EAST_GIF = "data/entities/whip_attack/whip_east.gif";
constexpr const char* WHIP_WEST_GIF = "data/entities/whip_attack/whip_west.gif";
constexpr const char* WHIP_NORTH_GIF = "data/entities/whip_attack/whip_north.gif";
constexpr const char* WHIP_SOUTH_GIF = "data/entities/whip_attack/whip_south.gif";
} // namespace Paths
} // namespace Defaults