From 1ce0d9c56cfe03a6d1bdeb44cf987fde1ac7e145 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 16 May 2026 14:15:25 +0200 Subject: [PATCH 01/13] refactor: JA_* a namespace Ja:: (estil aee_arcade) --- source/core/audio/audio.cpp | 54 +- source/core/audio/audio.hpp | 9 +- source/core/audio/audio_adapter.cpp | 4 +- source/core/audio/audio_adapter.hpp | 14 +- source/core/audio/jail_audio.hpp | 1224 ++++++++++------------ source/core/resources/resource_cache.cpp | 16 +- source/core/resources/resource_cache.hpp | 4 +- source/core/resources/resource_types.hpp | 23 +- source/game/scenes/banner_scene.hpp | 2 +- source/game/scenes/credits_scene.cpp | 2 +- source/game/scenes/secreta_scene.hpp | 2 +- source/game/scenes/slides_scene.cpp | 2 +- source/game/scenes/slides_scene.hpp | 2 +- source/game/scenes/timeline.hpp | 2 +- source/main.cpp | 4 +- 15 files changed, 645 insertions(+), 719 deletions(-) diff --git a/source/core/audio/audio.cpp b/source/core/audio/audio.cpp index da5800b..2efd9ff 100644 --- a/source/core/audio/audio.cpp +++ b/source/core/audio/audio.cpp @@ -40,15 +40,15 @@ Audio::Audio() { initSDLAudio(); } // Destructor Audio::~Audio() { - JA_Quit(); + Ja::quit(); } // Método principal void Audio::update() { - JA_Update(); + Ja::update(); // Sincronizar estado: detectar cuando la música se para (ej. fade-out completado) - if (instance && instance->music_.state == MusicState::PLAYING && JA_GetMusicState() != JA_MUSIC_PLAYING) { + if (instance && instance->music_.state == MusicState::PLAYING && Ja::getMusicState() != Ja::MusicState::PLAYING) { instance->music_.state = MusicState::STOPPED; } } @@ -72,12 +72,12 @@ void Audio::playMusic(const std::string& name, const int loop, const int crossfa } if (crossfade_ms > 0 && music_.state == MusicState::PLAYING) { - JA_CrossfadeMusic(resource, crossfade_ms, loop); + Ja::crossfadeMusic(resource, crossfade_ms, loop); } else { if (music_.state == MusicState::PLAYING) { - JA_StopMusic(); + Ja::stopMusic(); } - JA_PlayMusic(resource, loop); + Ja::playMusic(resource, loop); } music_.name = name; @@ -86,18 +86,18 @@ void Audio::playMusic(const std::string& name, const int loop, const int crossfa } // Reproduce la música por puntero (con crossfade opcional) -void Audio::playMusic(JA_Music_t* music, const int loop, const int crossfade_ms) { +void Audio::playMusic(Ja::Music* music, const int loop, const int crossfade_ms) { if (!music_enabled_ || music == nullptr) { return; } if (crossfade_ms > 0 && music_.state == MusicState::PLAYING) { - JA_CrossfadeMusic(music, crossfade_ms, loop); + Ja::crossfadeMusic(music, crossfade_ms, loop); } else { if (music_.state == MusicState::PLAYING) { - JA_StopMusic(); + Ja::stopMusic(); } - JA_PlayMusic(music, loop); + Ja::playMusic(music, loop); } music_.name.clear(); // nom desconegut quan es passa per punter @@ -108,7 +108,7 @@ void Audio::playMusic(JA_Music_t* music, const int loop, const int crossfade_ms) // Pausa la música void Audio::pauseMusic() { if (music_enabled_ && music_.state == MusicState::PLAYING) { - JA_PauseMusic(); + Ja::pauseMusic(); music_.state = MusicState::PAUSED; } } @@ -116,7 +116,7 @@ void Audio::pauseMusic() { // Continua la música pausada void Audio::resumeMusic() { if (music_enabled_ && music_.state == MusicState::PAUSED) { - JA_ResumeMusic(); + Ja::resumeMusic(); music_.state = MusicState::PLAYING; } } @@ -124,7 +124,7 @@ void Audio::resumeMusic() { // Detiene la música void Audio::stopMusic() { if (music_enabled_) { - JA_StopMusic(); + Ja::stopMusic(); music_.state = MusicState::STOPPED; } } @@ -132,42 +132,42 @@ void Audio::stopMusic() { // Reproduce un sonido por nombre void Audio::playSound(const std::string& name, Group group) const { if (sound_enabled_) { - JA_PlaySound(AudioResource::getSound(name), 0, static_cast(group)); + Ja::playSound(AudioResource::getSound(name), 0, static_cast(group)); } } // Reproduce un sonido por puntero directo -void Audio::playSound(JA_Sound_t* sound, Group group) const { +void Audio::playSound(Ja::Sound* sound, Group group) const { if (sound_enabled_ && sound != nullptr) { - JA_PlaySound(sound, 0, static_cast(group)); + Ja::playSound(sound, 0, static_cast(group)); } } // Detiene todos los sonidos void Audio::stopAllSounds() const { if (sound_enabled_) { - JA_StopChannel(-1); + Ja::stopChannel(-1); } } // Realiza un fundido de salida de la música void Audio::fadeOutMusic(int milliseconds) const { if (music_enabled_ && getRealMusicState() == MusicState::PLAYING) { - JA_FadeOutMusic(milliseconds); + Ja::fadeOutMusic(milliseconds); } } // Consulta directamente el estado real de la música en jailaudio auto Audio::getRealMusicState() -> MusicState { - JA_Music_state ja_state = JA_GetMusicState(); + Ja::MusicState ja_state = Ja::getMusicState(); switch (ja_state) { - case JA_MUSIC_PLAYING: + case Ja::MusicState::PLAYING: return MusicState::PLAYING; - case JA_MUSIC_PAUSED: + case Ja::MusicState::PAUSED: return MusicState::PAUSED; - case JA_MUSIC_STOPPED: - case JA_MUSIC_INVALID: - case JA_MUSIC_DISABLED: + case Ja::MusicState::STOPPED: + case Ja::MusicState::INVALID: + case Ja::MusicState::DISABLED: default: return MusicState::STOPPED; } @@ -178,7 +178,7 @@ void Audio::setSoundVolume(float sound_volume, Group group) const { sound_volume = std::clamp(sound_volume, MIN_VOLUME, MAX_VOLUME); const bool active = enabled_ && sound_enabled_; const float CONVERTED_VOLUME = active ? sound_volume * Options::audio.volume : 0.0F; - JA_SetSoundVolume(CONVERTED_VOLUME, static_cast(group)); + Ja::setSoundVolume(CONVERTED_VOLUME, static_cast(group)); } // Establece el volumen de la música (float 0.0..1.0) @@ -186,7 +186,7 @@ void Audio::setMusicVolume(float music_volume) const { music_volume = std::clamp(music_volume, MIN_VOLUME, MAX_VOLUME); const bool active = enabled_ && music_enabled_; const float CONVERTED_VOLUME = active ? music_volume * Options::audio.volume : 0.0F; - JA_SetMusicVolume(CONVERTED_VOLUME); + Ja::setMusicVolume(CONVERTED_VOLUME); } // Aplica la configuración @@ -207,7 +207,7 @@ void Audio::initSDLAudio() { if (!SDL_Init(SDL_INIT_AUDIO)) { std::cout << "SDL_AUDIO could not initialize! SDL Error: " << SDL_GetError() << '\n'; } else { - JA_Init(FREQUENCY, SDL_AUDIO_S16LE, 2); + Ja::init(FREQUENCY, SDL_AUDIO_S16LE, 2); enable(Options::audio.enabled); } } diff --git a/source/core/audio/audio.hpp b/source/core/audio/audio.hpp index ae795a1..3b76c00 100644 --- a/source/core/audio/audio.hpp +++ b/source/core/audio/audio.hpp @@ -6,6 +6,11 @@ #include // Para string #include // Para move +namespace Ja { + struct Music; + struct Sound; +} // namespace Ja + // --- Clase Audio: gestor de audio (singleton) --- // Implementació canònica, byte-idèntica entre projectes. // Els volums es manegen internament com a float 0.0–1.0; la capa de @@ -45,7 +50,7 @@ class Audio { // --- Control de música --- void playMusic(const std::string& name, int loop = -1, int crossfade_ms = 0); // Reproducir música por nombre (con crossfade opcional) - void playMusic(struct JA_Music_t* music, int loop = -1, int crossfade_ms = 0); // Reproducir música por puntero (con crossfade opcional) + void playMusic(Ja::Music* music, int loop = -1, int crossfade_ms = 0); // Reproducir música por puntero (con crossfade opcional) void pauseMusic(); // Pausar reproducción de música void resumeMusic(); // Continua la música pausada void stopMusic(); // Detener completamente la música @@ -53,7 +58,7 @@ class Audio { // --- Control de sonidos --- void playSound(const std::string& name, Group group = Group::GAME) const; // Reproducir sonido puntual por nombre - void playSound(struct JA_Sound_t* sound, Group group = Group::GAME) const; // Reproducir sonido puntual por puntero + void playSound(Ja::Sound* sound, Group group = Group::GAME) const; // Reproducir sonido puntual por puntero void stopAllSounds() const; // Detener todos los sonidos // --- Control de volumen (API interna: float 0.0..1.0) --- diff --git a/source/core/audio/audio_adapter.cpp b/source/core/audio/audio_adapter.cpp index 23a6b5c..287bb46 100644 --- a/source/core/audio/audio_adapter.cpp +++ b/source/core/audio/audio_adapter.cpp @@ -4,11 +4,11 @@ namespace AudioResource { - auto getMusic(const std::string& name) -> JA_Music_t* { + auto getMusic(const std::string& name) -> Ja::Music* { return Resource::Cache::get()->getMusic(name); } - auto getSound(const std::string& name) -> JA_Sound_t* { + auto getSound(const std::string& name) -> Ja::Sound* { return Resource::Cache::get()->getSound(name); } diff --git a/source/core/audio/audio_adapter.hpp b/source/core/audio/audio_adapter.hpp index 9c95864..7feda5a 100644 --- a/source/core/audio/audio_adapter.hpp +++ b/source/core/audio/audio_adapter.hpp @@ -1,17 +1,19 @@ #pragma once // --- Audio Resource Adapter --- -// Aquest fitxer exposa una interfície comuna a Audio per obtenir JA_Music_t* / -// JA_Sound_t* per nom. Cada projecte la implementa en audio_adapter.cpp +// Aquest fitxer exposa una interfície comuna a Audio per obtenir Ja::Music* / +// Ja::Sound* per nom. Cada projecte la implementa en audio_adapter.cpp // delegant al seu singleton de recursos (Resource::get(), Resource::Cache::get(), // etc.). Això permet que audio.hpp/audio.cpp siguin idèntics entre projectes. #include // Para string -struct JA_Music_t; -struct JA_Sound_t; +namespace Ja { + struct Music; + struct Sound; +} // namespace Ja namespace AudioResource { - auto getMusic(const std::string& name) -> JA_Music_t*; - auto getSound(const std::string& name) -> JA_Sound_t*; + auto getMusic(const std::string& name) -> Ja::Music*; + auto getSound(const std::string& name) -> Ja::Sound*; } // namespace AudioResource diff --git a/source/core/audio/jail_audio.hpp b/source/core/audio/jail_audio.hpp index edb3ee2..276841f 100644 --- a/source/core/audio/jail_audio.hpp +++ b/source/core/audio/jail_audio.hpp @@ -3,779 +3,697 @@ // --- Includes --- #include -#include // Para std::fill -#include // Para uint32_t, uint8_t -#include // Para NULL, fseek, fclose, fopen, fread, ftell, FILE, SEEK_END, SEEK_SET -#include // Para free, malloc -#include // Para std::cout -#include // Para std::unique_ptr -#include // Para std::string -#include // Para std::vector +#include +#include +#include +#include +#include +#include +#include +#include #define STB_VORBIS_HEADER_ONLY -#include "external/stb_vorbis.c" // NOLINT(bugprone-suspicious-include): stb header-only library +// NOLINTNEXTLINE(bugprone-suspicious-include) — stb_vorbis és single-file: la macro de dalt limita a només-declaracions. +#include "external/stb_vorbis.c" // Para stb_vorbis_open_memory i streaming // Deleter stateless per a buffers reservats amb `SDL_malloc` / `SDL_LoadWAV*`. -// Compatible amb `std::unique_ptr` — zero size +// Compatible amb `std::unique_ptr` — zero size // overhead gràcies a EBO, igual que un unique_ptr amb default_delete. -struct SDLFreeDeleter { +struct SdlFreeDeleter { void operator()(Uint8* p) const noexcept { - if (p != nullptr) { - SDL_free(p); - } + if (p != nullptr) { SDL_free(p); } } }; -// --- Public Enums --- -enum JA_Channel_state : std::uint8_t { - JA_CHANNEL_INVALID, - JA_CHANNEL_FREE, - JA_CHANNEL_PLAYING, - JA_CHANNEL_PAUSED, - JA_SOUND_DISABLED, -}; -enum JA_Music_state : std::uint8_t { - JA_MUSIC_INVALID, - JA_MUSIC_PLAYING, - JA_MUSIC_PAUSED, - JA_MUSIC_STOPPED, - JA_MUSIC_DISABLED, -}; +namespace Ja { -// --- Struct Definitions --- -enum : std::uint8_t { - JA_MAX_SIMULTANEOUS_CHANNELS = 20, - JA_MAX_GROUPS = 2 -}; + // --- Public Enums --- + enum class ChannelState : std::uint8_t { + INVALID, + FREE, + PLAYING, + PAUSED, + DISABLED, + }; -struct JA_Sound_t { - SDL_AudioSpec spec{SDL_AUDIO_S16, 2, 48000}; - Uint32 length{0}; - // Buffer descomprimit (PCM) propietat del sound. Reservat per SDL_LoadWAV - // via SDL_malloc; el deleter `SDLFreeDeleter` allibera amb SDL_free. - std::unique_ptr buffer; -}; + enum class MusicState : std::uint8_t { + INVALID, + PLAYING, + PAUSED, + STOPPED, + DISABLED, + }; -struct JA_Channel_t { - JA_Sound_t* sound{nullptr}; - SDL_AudioStream* stream{nullptr}; - int pos{0}; - int times{0}; - int group{0}; - JA_Channel_state state{JA_CHANNEL_FREE}; -}; + // --- Constants --- + inline constexpr int MAX_SIMULTANEOUS_CHANNELS = 20; + inline constexpr int MAX_GROUPS = 2; + inline constexpr SDL_AudioSpec DEFAULT_SPEC{.format = SDL_AUDIO_S16, .channels = 2, .freq = 48000}; -struct JA_Music_t { - SDL_AudioSpec spec{SDL_AUDIO_S16, 2, 48000}; + // --- Struct Definitions --- + struct Sound { + SDL_AudioSpec spec{DEFAULT_SPEC}; + Uint32 length{0}; + // Buffer descomprimit (PCM) propietat del sound. Reservat per SDL_LoadWAV + // via SDL_malloc; el deleter `SdlFreeDeleter` allibera amb SDL_free. + std::unique_ptr buffer; + }; - // OGG comprimit en memòria. Propietat nostra; es copia des del buffer - // d'entrada una sola vegada en JA_LoadMusic i es descomprimix en chunks - // per streaming. Com que stb_vorbis guarda un punter persistent al - // `.data()` d'aquest vector, no el podem resize'jar un cop establert - // (una reallocation invalidaria el punter que el decoder conserva). - std::vector ogg_data; - stb_vorbis* vorbis{nullptr}; // handle del decoder, viu tot el cicle del JA_Music_t + // L'ordre (punters primer, ints després, enum de 8 bits al final) minimitza + // el padding a 64-bit (evita avisos de clang-analyzer-optin.performance.Padding). + struct Channel { + Sound* sound{nullptr}; + SDL_AudioStream* stream{nullptr}; + int pos{0}; + int times{0}; + int group{0}; + ChannelState state{ChannelState::FREE}; + }; - std::string filename; + struct Music { + SDL_AudioSpec spec{DEFAULT_SPEC}; - int times{0}; // loops restants (-1 = infinit, 0 = un sol play) - SDL_AudioStream* stream{nullptr}; - JA_Music_state state{JA_MUSIC_INVALID}; -}; + // OGG comprimit en memòria. Propietat nostra; es copia des del buffer + // d'entrada una sola vegada en loadMusic i es descomprimix en chunks + // per streaming. Com que stb_vorbis guarda un punter persistent al + // `.data()` d'aquest vector, no el podem resize'jar un cop establert + // (una reallocation invalidaria el punter que el decoder conserva). + std::vector ogg_data; + stb_vorbis* vorbis{nullptr}; // handle del decoder, viu tot el cicle del Music -// --- Internal Global State (inline, C++17) --- + std::string filename; -inline JA_Music_t* current_music{nullptr}; -inline JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS]; + int times{0}; // loops restants (-1 = infinit, 0 = un sol play) + SDL_AudioStream* stream{nullptr}; + MusicState state{MusicState::INVALID}; + }; -inline SDL_AudioSpec JA_audioSpec{SDL_AUDIO_S16, 2, 48000}; -inline float JA_musicVolume{1.0F}; -inline float JA_soundVolume[JA_MAX_GROUPS]; -inline bool JA_musicEnabled{true}; -inline bool JA_soundEnabled{true}; -inline SDL_AudioDeviceID sdlAudioDevice{0}; + struct FadeState { + bool active{false}; + Uint64 start_time{0}; + int duration_ms{0}; + float initial_volume{0.0F}; + }; -// --- Crossfade / Fade State --- -struct JA_FadeState { - bool active{false}; - Uint64 start_time{0}; - int duration_ms{0}; - float initial_volume{0.0F}; -}; + struct OutgoingMusic { + SDL_AudioStream* stream{nullptr}; + FadeState fade; + }; -struct JA_OutgoingMusic { - SDL_AudioStream* stream{nullptr}; - JA_FadeState fade; -}; + // --- Internal Global State (inline, C++17) --- + inline Music* current_music{nullptr}; + inline Channel channels[MAX_SIMULTANEOUS_CHANNELS]; -inline JA_OutgoingMusic outgoing_music; -inline JA_FadeState incoming_fade; + inline SDL_AudioSpec audio_spec{DEFAULT_SPEC}; + inline float music_volume{1.0F}; + inline float sound_volume[MAX_GROUPS]; + inline bool music_enabled{true}; + inline bool sound_enabled{true}; + inline SDL_AudioDeviceID sdl_audio_device{0}; -// --- Forward Declarations --- -inline void JA_StopMusic(); -inline void JA_StopChannel(int channel); -inline auto JA_PlaySoundOnChannel(JA_Sound_t* sound, int channel, int loop = 0, int group = 0) -> int; -inline void JA_CrossfadeMusic(JA_Music_t* music, int crossfade_ms, int loop = -1); + inline OutgoingMusic outgoing_music; + inline FadeState incoming_fade; -// --- Music streaming internals --- -// Bytes-per-sample per canal (sempre s16) -static constexpr int JA_MUSIC_BYTES_PER_SAMPLE = 2; -// Quants shorts decodifiquem per crida a get_samples_short_interleaved. -// 8192 shorts = 4096 samples/channel en estèreo ≈ 85ms de so a 48kHz. -static constexpr int JA_MUSIC_CHUNK_SHORTS = 8192; -// Umbral d'audio per davant del cursor de reproducció. Mantenim ≥ 0.5 s a -// l'SDL_AudioStream per absorbir jitter de frame i evitar underruns. -static constexpr float JA_MUSIC_LOW_WATER_SECONDS = 0.5F; + // --- Forward Declarations --- + inline void stopMusic(); + inline void stopChannel(int channel); + inline auto playSoundOnChannel(Sound* sound, int channel, int loop = 0, int group = 0) -> int; + inline void crossfadeMusic(Music* music, int crossfade_ms, int loop = -1); -// Decodifica un chunk del vorbis i el volca a l'stream. Retorna samples -// decodificats per canal (0 = EOF de l'stream vorbis). -inline auto JA_FeedMusicChunk(JA_Music_t* music) -> int { - if ((music == nullptr) || (music->vorbis == nullptr) || (music->stream == nullptr)) { - return 0; + // --- Music streaming internals --- + // Bytes-per-sample per canal (sempre s16) + inline constexpr int MUSIC_BYTES_PER_SAMPLE = 2; + // Quants shorts decodifiquem per crida a get_samples_short_interleaved. + // 8192 shorts = 4096 samples/channel en estèreo ≈ 85ms de so a 48kHz. + inline constexpr int MUSIC_CHUNK_SHORTS = 8192; + // Umbral d'audio per davant del cursor de reproducció. Mantenim ≥ 0.5 s a + // l'SDL_AudioStream per absorbir jitter de frame i evitar underruns. + inline constexpr float MUSIC_LOW_WATER_SECONDS = 0.5F; + + // Decodifica un chunk del vorbis i el volca a l'stream. Retorna samples + // decodificats per canal (0 = EOF de l'stream vorbis). + inline auto feedMusicChunk(Music* music) -> int { + if ((music == nullptr) || (music->vorbis == nullptr) || (music->stream == nullptr)) { return 0; } + + short chunk[MUSIC_CHUNK_SHORTS]; + const int NUM_CHANNELS = music->spec.channels; + const int SAMPLES_PER_CHANNEL = stb_vorbis_get_samples_short_interleaved( + music->vorbis, + NUM_CHANNELS, + chunk, + MUSIC_CHUNK_SHORTS); + if (SAMPLES_PER_CHANNEL <= 0) { return 0; } + + const int BYTES = SAMPLES_PER_CHANNEL * NUM_CHANNELS * MUSIC_BYTES_PER_SAMPLE; + SDL_PutAudioStreamData(music->stream, chunk, BYTES); + return SAMPLES_PER_CHANNEL; } - short chunk[JA_MUSIC_CHUNK_SHORTS]; - const int num_channels = music->spec.channels; - const int samples_per_channel = stb_vorbis_get_samples_short_interleaved( - music->vorbis, - num_channels, - chunk, - JA_MUSIC_CHUNK_SHORTS); - if (samples_per_channel <= 0) { - return 0; - } + // Reompli l'stream fins que tinga ≥ MUSIC_LOW_WATER_SECONDS bufferats. + // En arribar a EOF del vorbis, aplica el loop (times) o deixa drenar. + inline void pumpMusic(Music* music) { + if ((music == nullptr) || (music->vorbis == nullptr) || (music->stream == nullptr)) { return; } - const int bytes = samples_per_channel * num_channels * JA_MUSIC_BYTES_PER_SAMPLE; - SDL_PutAudioStreamData(music->stream, chunk, bytes); - return samples_per_channel; -} + const int BYTES_PER_SECOND = music->spec.freq * music->spec.channels * MUSIC_BYTES_PER_SAMPLE; + const int LOW_WATER_BYTES = static_cast(MUSIC_LOW_WATER_SECONDS * static_cast(BYTES_PER_SECOND)); -// Reompli l'stream fins que tinga ≥ JA_MUSIC_LOW_WATER_SECONDS bufferats. -// En arribar a EOF del vorbis, aplica el loop (times) o deixa drenar. -inline void JA_PumpMusic(JA_Music_t* music) { - if ((music == nullptr) || (music->vorbis == nullptr) || (music->stream == nullptr)) { - return; - } + while (SDL_GetAudioStreamAvailable(music->stream) < LOW_WATER_BYTES) { + const int DECODED = feedMusicChunk(music); + if (DECODED > 0) { continue; } - const int bytes_per_second = music->spec.freq * music->spec.channels * JA_MUSIC_BYTES_PER_SAMPLE; - const int low_water_bytes = static_cast(JA_MUSIC_LOW_WATER_SECONDS * static_cast(bytes_per_second)); - - while (SDL_GetAudioStreamAvailable(music->stream) < low_water_bytes) { - const int decoded = JA_FeedMusicChunk(music); - if (decoded > 0) { - continue; - } - - // EOF: si queden loops, rebobinar; si no, tallar i deixar drenar. - if (music->times != 0) { - stb_vorbis_seek_start(music->vorbis); - if (music->times > 0) { - music->times--; + // EOF: si queden loops, rebobinar; si no, tallar i deixar drenar. + if (music->times != 0) { + stb_vorbis_seek_start(music->vorbis); + if (music->times > 0) { music->times--; } + } else { + break; } - } else { - break; } } -} -// Pre-carrega `duration_ms` de so dins l'stream actual abans que l'stream -// siga robat per outgoing_music (crossfade o fade-out). Imprescindible amb -// streaming: l'stream robat no es pot re-alimentar perquè perd la referència -// al seu vorbis decoder. No aplica loop — si el vorbis s'esgota abans, parem. -inline void JA_PreFillOutgoing(JA_Music_t* music, int duration_ms) { - if ((music == nullptr) || (music->vorbis == nullptr) || (music->stream == nullptr)) { - return; - } + // Pre-carrega `duration_ms` de so dins l'stream actual abans que l'stream + // siga robat per outgoing_music (crossfade o fade-out). Imprescindible amb + // streaming: l'stream robat no es pot re-alimentar perquè perd la referència + // al seu vorbis decoder. No aplica loop — si el vorbis s'esgota abans, parem. + inline void preFillOutgoing(Music* music, int duration_ms) { + if ((music == nullptr) || (music->vorbis == nullptr) || (music->stream == nullptr)) { return; } - const int bytes_per_second = music->spec.freq * music->spec.channels * JA_MUSIC_BYTES_PER_SAMPLE; - const int needed_bytes = static_cast((static_cast(duration_ms) * bytes_per_second) / 1000); + const int BYTES_PER_SECOND = music->spec.freq * music->spec.channels * MUSIC_BYTES_PER_SAMPLE; + const int NEEDED_BYTES = static_cast((static_cast(duration_ms) * BYTES_PER_SECOND) / 1000); - while (SDL_GetAudioStreamAvailable(music->stream) < needed_bytes) { - const int decoded = JA_FeedMusicChunk(music); - if (decoded <= 0) { - break; // EOF: deixem drenar el que hi haja + while (SDL_GetAudioStreamAvailable(music->stream) < NEEDED_BYTES) { + const int DECODED = feedMusicChunk(music); + if (DECODED <= 0) { break; } // EOF: deixem drenar el que hi haja } } -} -// --- Core Functions --- + // --- update() helpers --- + inline void updateOutgoingFade() { + if ((outgoing_music.stream == nullptr) || !outgoing_music.fade.active) { return; } -inline void JA_Update() { - // --- Outgoing music fade-out (crossfade o fade-out a silencio) --- - if ((outgoing_music.stream != nullptr) && outgoing_music.fade.active) { - Uint64 now = SDL_GetTicks(); - Uint64 elapsed = now - outgoing_music.fade.start_time; - if (elapsed >= (Uint64)outgoing_music.fade.duration_ms) { + const Uint64 NOW = SDL_GetTicks(); + const Uint64 ELAPSED = NOW - outgoing_music.fade.start_time; + if (ELAPSED >= static_cast(outgoing_music.fade.duration_ms)) { SDL_DestroyAudioStream(outgoing_music.stream); outgoing_music.stream = nullptr; outgoing_music.fade.active = false; } else { - float percent = (float)elapsed / (float)outgoing_music.fade.duration_ms; - SDL_SetAudioStreamGain(outgoing_music.stream, outgoing_music.fade.initial_volume * (1.0F - percent)); + const float PERCENT = static_cast(ELAPSED) / static_cast(outgoing_music.fade.duration_ms); + SDL_SetAudioStreamGain(outgoing_music.stream, outgoing_music.fade.initial_volume * (1.0F - PERCENT)); } } - // --- Current music --- - if (JA_musicEnabled && (current_music != nullptr) && current_music->state == JA_MUSIC_PLAYING) { - // Fade-in (parte de un crossfade) - if (incoming_fade.active) { - Uint64 now = SDL_GetTicks(); - Uint64 elapsed = now - incoming_fade.start_time; - if (elapsed >= (Uint64)incoming_fade.duration_ms) { - incoming_fade.active = false; - SDL_SetAudioStreamGain(current_music->stream, JA_musicVolume); - } else { - float percent = (float)elapsed / (float)incoming_fade.duration_ms; - SDL_SetAudioStreamGain(current_music->stream, JA_musicVolume * percent); - } + inline void updateIncomingFade() { + if (!incoming_fade.active) { return; } + + const Uint64 NOW = SDL_GetTicks(); + const Uint64 ELAPSED = NOW - incoming_fade.start_time; + if (ELAPSED >= static_cast(incoming_fade.duration_ms)) { + incoming_fade.active = false; + SDL_SetAudioStreamGain(current_music->stream, music_volume); + } else { + const float PERCENT = static_cast(ELAPSED) / static_cast(incoming_fade.duration_ms); + SDL_SetAudioStreamGain(current_music->stream, music_volume * PERCENT); } + } + + inline void updateCurrentMusic() { + if (!music_enabled || (current_music == nullptr) || current_music->state != MusicState::PLAYING) { return; } + + updateIncomingFade(); // Streaming: rellenem l'stream fins al low-water-mark i parem si el // vorbis s'ha esgotat i no queden loops. - JA_PumpMusic(current_music); + pumpMusic(current_music); if (current_music->times == 0 && SDL_GetAudioStreamAvailable(current_music->stream) == 0) { - JA_StopMusic(); + stopMusic(); } } - // --- Sound channels --- - if (JA_soundEnabled) { - for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; ++i) { - if (channels[i].state == JA_CHANNEL_PLAYING) { - if (channels[i].times != 0) { - if ((Uint32)SDL_GetAudioStreamAvailable(channels[i].stream) < (channels[i].sound->length / 2)) { - SDL_PutAudioStreamData(channels[i].stream, channels[i].sound->buffer.get(), channels[i].sound->length); - if (channels[i].times > 0) { - channels[i].times--; - } - } - } else { - if (SDL_GetAudioStreamAvailable(channels[i].stream) == 0) { - JA_StopChannel(i); - } + inline void updateSoundChannels() { + if (!sound_enabled) { return; } + + for (int i = 0; i < MAX_SIMULTANEOUS_CHANNELS; ++i) { + auto& ch = channels[i]; + if (ch.state != ChannelState::PLAYING) { continue; } + + if (ch.times != 0) { + if (static_cast(SDL_GetAudioStreamAvailable(ch.stream)) < (ch.sound->length / 2)) { + SDL_PutAudioStreamData(ch.stream, ch.sound->buffer.get(), ch.sound->length); + if (ch.times > 0) { ch.times--; } } + } else { + if (SDL_GetAudioStreamAvailable(ch.stream) == 0) { stopChannel(i); } } } } -} -inline void JA_Init(const int freq, const SDL_AudioFormat format, const int num_channels) { - JA_audioSpec = {.format = format, .channels = num_channels, .freq = freq}; - if (sdlAudioDevice != 0U) { - SDL_CloseAudioDevice(sdlAudioDevice); - } - sdlAudioDevice = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &JA_audioSpec); - if (sdlAudioDevice == 0) { - std::cout << "Failed to initialize SDL audio!" << '\n'; - } - for (auto& channel : channels) { - channel.state = JA_CHANNEL_FREE; - } - std::fill(std::begin(JA_soundVolume), std::end(JA_soundVolume), 0.5F); -} - -inline void JA_Quit() { - if (outgoing_music.stream != nullptr) { - SDL_DestroyAudioStream(outgoing_music.stream); - outgoing_music.stream = nullptr; - } - if (sdlAudioDevice != 0U) { - SDL_CloseAudioDevice(sdlAudioDevice); - } - sdlAudioDevice = 0; -} - -// --- Music Functions --- - -inline auto JA_LoadMusic(const Uint8* buffer, Uint32 length) -> JA_Music_t* { - if ((buffer == nullptr) || length == 0) { - return nullptr; + inline void update() { + updateOutgoingFade(); + updateCurrentMusic(); + updateSoundChannels(); } - // Allocem el JA_Music_t primer per aprofitar el seu `std::vector` - // com a propietari del OGG comprimit. stb_vorbis guarda un punter - // persistent al buffer; com que ací no el resize'jem, el .data() és - // estable durant tot el cicle de vida del music. - auto* music = new JA_Music_t(); - music->ogg_data.assign(buffer, buffer + length); - - int vorbis_error = 0; - music->vorbis = stb_vorbis_open_memory(music->ogg_data.data(), - static_cast(length), - &vorbis_error, - nullptr); - if (music->vorbis == nullptr) { - std::cout << "JA_LoadMusic: stb_vorbis_open_memory failed (error " << vorbis_error << ")" << '\n'; - delete music; - return nullptr; + inline void init(int freq, SDL_AudioFormat format, int num_channels) { + audio_spec = {.format = format, .channels = num_channels, .freq = freq}; + if (sdl_audio_device != 0) { SDL_CloseAudioDevice(sdl_audio_device); } + sdl_audio_device = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audio_spec); + if (sdl_audio_device == 0) { std::cout << "Failed to initialize SDL audio!" << '\n'; } + for (auto& ch : channels) { ch.state = ChannelState::FREE; } + std::fill(std::begin(sound_volume), std::end(sound_volume), 0.5F); } - const stb_vorbis_info info = stb_vorbis_get_info(music->vorbis); - music->spec.channels = info.channels; - music->spec.freq = static_cast(info.sample_rate); - music->spec.format = SDL_AUDIO_S16; - music->state = JA_MUSIC_STOPPED; - - return music; -} - -// Overload amb filename — els callers l'usen per poder comparar la música -// en curs amb JA_GetMusicFilename() i no rearrancar-la si ja és la mateixa. -inline auto JA_LoadMusic(Uint8* buffer, Uint32 length, const char* filename) -> JA_Music_t* { - JA_Music_t* music = JA_LoadMusic(static_cast(buffer), length); - if ((music != nullptr) && (filename != nullptr)) { - music->filename = filename; - } - return music; -} - -inline auto JA_LoadMusic(const char* filename) -> JA_Music_t* { - // Carreguem primer el arxiu en memòria i després el descomprimim. - FILE* f = fopen(filename, "rb"); - if (f == nullptr) { - return nullptr; - } - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - if (fsize <= 0) { - fclose(f); - return nullptr; - } - auto* buffer = static_cast(malloc(fsize + 1)); - if (buffer == nullptr) { - fclose(f); - return nullptr; - } - if (fread(buffer, fsize, 1, f) != 1) { - fclose(f); - free(buffer); - return nullptr; - } - fclose(f); - - JA_Music_t* music = JA_LoadMusic(static_cast(buffer), static_cast(fsize)); - if (music != nullptr) { - music->filename = filename; + inline void quit() { + if (outgoing_music.stream != nullptr) { + SDL_DestroyAudioStream(outgoing_music.stream); + outgoing_music.stream = nullptr; + } + if (sdl_audio_device != 0) { SDL_CloseAudioDevice(sdl_audio_device); } + sdl_audio_device = 0; } - free(buffer); + // --- Music Functions --- + inline auto loadMusic(const Uint8* buffer, Uint32 length) -> Music* { + if ((buffer == nullptr) || length == 0) { return nullptr; } - return music; -} + // Allocem el Music primer per aprofitar el seu `std::vector` + // com a propietari del OGG comprimit. stb_vorbis guarda un punter + // persistent al buffer; com que ací no el resize'jem, el .data() és + // estable durant tot el cicle de vida del music. + auto* music = new Music(); + music->ogg_data.assign(buffer, buffer + length); -inline void JA_PlayMusic(JA_Music_t* music, const int loop = -1) { - if (!JA_musicEnabled || (music == nullptr) || (music->vorbis == nullptr)) { - return; + int vorbis_error = 0; + music->vorbis = stb_vorbis_open_memory(music->ogg_data.data(), + static_cast(length), + &vorbis_error, + nullptr); + if (music->vorbis == nullptr) { + std::cout << "loadMusic: stb_vorbis_open_memory failed (error " << vorbis_error << ")" << '\n'; + delete music; + return nullptr; + } + + const stb_vorbis_info INFO = stb_vorbis_get_info(music->vorbis); + music->spec.channels = INFO.channels; + music->spec.freq = static_cast(INFO.sample_rate); + music->spec.format = SDL_AUDIO_S16; + music->state = MusicState::STOPPED; + + return music; } - JA_StopMusic(); - - current_music = music; - current_music->state = JA_MUSIC_PLAYING; - current_music->times = loop; - - // Rebobinem l'stream de vorbis al principi. Cobreix tant play-per-primera- - // vegada com replays/canvis de track que tornen a la mateixa pista. - stb_vorbis_seek_start(current_music->vorbis); - - current_music->stream = SDL_CreateAudioStream(¤t_music->spec, &JA_audioSpec); - if (current_music->stream == nullptr) { - std::cout << "Failed to create audio stream!" << '\n'; - current_music->state = JA_MUSIC_STOPPED; - return; - } - SDL_SetAudioStreamGain(current_music->stream, JA_musicVolume); - - // Pre-cargem el buffer abans de bindejar per evitar un underrun inicial. - JA_PumpMusic(current_music); - - if (!SDL_BindAudioStream(sdlAudioDevice, current_music->stream)) { - std::cout << "[ERROR] SDL_BindAudioStream failed!" << '\n'; - } -} - -inline auto JA_GetMusicFilename(const JA_Music_t* music = nullptr) -> const char* { - if (music == nullptr) { - music = current_music; - } - if ((music == nullptr) || music->filename.empty()) { - return nullptr; - } - return music->filename.c_str(); -} - -inline void JA_PauseMusic() { - if (!JA_musicEnabled) { - return; - } - if ((current_music == nullptr) || current_music->state != JA_MUSIC_PLAYING) { - return; + // Overload amb filename — els callers l'usen per poder comparar la música + // en curs amb getMusicFilename() i no rearrancar-la si ja és la mateixa. + inline auto loadMusic(Uint8* buffer, Uint32 length, const char* filename) -> Music* { + Music* music = loadMusic(static_cast(buffer), length); + if ((music != nullptr) && (filename != nullptr)) { music->filename = filename; } + return music; } - current_music->state = JA_MUSIC_PAUSED; - SDL_UnbindAudioStream(current_music->stream); -} + inline auto loadMusic(const char* filename) -> Music* { + // Carreguem primer el arxiu en memòria i després el descomprimim. + FILE* f = std::fopen(filename, "rb"); + if (f == nullptr) { return nullptr; } + std::fseek(f, 0, SEEK_END); + const long FSIZE = std::ftell(f); + std::fseek(f, 0, SEEK_SET); + if (FSIZE <= 0) { + std::fclose(f); + return nullptr; + } + auto* buffer = static_cast(std::malloc(static_cast(FSIZE) + 1)); + if (buffer == nullptr) { + std::fclose(f); + return nullptr; + } + if (std::fread(buffer, FSIZE, 1, f) != 1) { + std::fclose(f); + std::free(buffer); + return nullptr; + } + std::fclose(f); -inline void JA_ResumeMusic() { - if (!JA_musicEnabled) { - return; - } - if ((current_music == nullptr) || current_music->state != JA_MUSIC_PAUSED) { - return; + Music* music = loadMusic(static_cast(buffer), static_cast(FSIZE)); + if (music != nullptr) { music->filename = filename; } + + std::free(buffer); + + return music; } - current_music->state = JA_MUSIC_PLAYING; - SDL_BindAudioStream(sdlAudioDevice, current_music->stream); -} + inline void playMusic(Music* music, int loop = -1) { + if (!music_enabled || (music == nullptr) || (music->vorbis == nullptr)) { return; } -inline void JA_StopMusic() { - // Limpiar outgoing crossfade si existe - if (outgoing_music.stream != nullptr) { - SDL_DestroyAudioStream(outgoing_music.stream); - outgoing_music.stream = nullptr; - outgoing_music.fade.active = false; - } - incoming_fade.active = false; + stopMusic(); - if ((current_music == nullptr) || current_music->state == JA_MUSIC_INVALID || current_music->state == JA_MUSIC_STOPPED) { - return; - } + current_music = music; + current_music->state = MusicState::PLAYING; + current_music->times = loop; - current_music->state = JA_MUSIC_STOPPED; - if (current_music->stream != nullptr) { - SDL_DestroyAudioStream(current_music->stream); - current_music->stream = nullptr; - } - // Deixem el handle de vorbis viu — es tanca en JA_DeleteMusic. - // Rebobinem perquè un futur JA_PlayMusic comence des del principi. - if (current_music->vorbis != nullptr) { + // Rebobinem l'stream de vorbis al principi. Cobreix tant play-per-primera- + // vegada com replays/canvis de track que tornen a la mateixa pista. stb_vorbis_seek_start(current_music->vorbis); - } -} -inline void JA_FadeOutMusic(const int milliseconds) { - if (!JA_musicEnabled) { - return; - } - if ((current_music == nullptr) || current_music->state != JA_MUSIC_PLAYING) { - return; + current_music->stream = SDL_CreateAudioStream(¤t_music->spec, &audio_spec); + if (current_music->stream == nullptr) { + std::cout << "Failed to create audio stream!" << '\n'; + current_music->state = MusicState::STOPPED; + return; + } + SDL_SetAudioStreamGain(current_music->stream, music_volume); + + // Pre-cargem el buffer abans de bindejar per evitar un underrun inicial. + pumpMusic(current_music); + + if (!SDL_BindAudioStream(sdl_audio_device, current_music->stream)) { + std::cout << "[ERROR] SDL_BindAudioStream failed!" << '\n'; + } } - // Destruir outgoing anterior si existe - if (outgoing_music.stream != nullptr) { - SDL_DestroyAudioStream(outgoing_music.stream); - outgoing_music.stream = nullptr; + inline auto getMusicFilename(const Music* music = nullptr) -> const char* { + if (music == nullptr) { music = current_music; } + if ((music == nullptr) || music->filename.empty()) { return nullptr; } + return music->filename.c_str(); } - // Pre-omplim l'stream amb `milliseconds` de so: un cop robat, ja no - // tindrà accés al vorbis decoder i només podrà drenar el que tinga. - JA_PreFillOutgoing(current_music, milliseconds); + inline void pauseMusic() { + if (!music_enabled) { return; } + if ((current_music == nullptr) || current_music->state != MusicState::PLAYING) { return; } - // Robar el stream del current_music al outgoing - outgoing_music.stream = current_music->stream; - outgoing_music.fade = {.active = true, .start_time = SDL_GetTicks(), .duration_ms = milliseconds, .initial_volume = JA_musicVolume}; - - // Dejar current_music sin stream (ya lo tiene outgoing) - current_music->stream = nullptr; - current_music->state = JA_MUSIC_STOPPED; - if (current_music->vorbis != nullptr) { - stb_vorbis_seek_start(current_music->vorbis); - } - incoming_fade.active = false; -} - -inline void JA_CrossfadeMusic(JA_Music_t* music, const int crossfade_ms, const int loop) { - if (!JA_musicEnabled || (music == nullptr) || (music->vorbis == nullptr)) { - return; + current_music->state = MusicState::PAUSED; + SDL_UnbindAudioStream(current_music->stream); } - // Destruir outgoing anterior si existe (crossfade durante crossfade) - if (outgoing_music.stream != nullptr) { - SDL_DestroyAudioStream(outgoing_music.stream); - outgoing_music.stream = nullptr; - outgoing_music.fade.active = false; + inline void resumeMusic() { + if (!music_enabled) { return; } + if ((current_music == nullptr) || current_music->state != MusicState::PAUSED) { return; } + + current_music->state = MusicState::PLAYING; + SDL_BindAudioStream(sdl_audio_device, current_music->stream); } - // Robar el stream de la musica actual al outgoing para el fade-out. - // Pre-omplim amb `crossfade_ms` de so perquè no es quede en silenci - // abans d'acabar el fade (l'stream robat ja no pot alimentar-se). - if ((current_music != nullptr) && current_music->state == JA_MUSIC_PLAYING && (current_music->stream != nullptr)) { - JA_PreFillOutgoing(current_music, crossfade_ms); - outgoing_music.stream = current_music->stream; - outgoing_music.fade = {.active = true, .start_time = SDL_GetTicks(), .duration_ms = crossfade_ms, .initial_volume = JA_musicVolume}; - current_music->stream = nullptr; - current_music->state = JA_MUSIC_STOPPED; + inline void stopMusic() { + // Limpiar outgoing crossfade si existe + if (outgoing_music.stream != nullptr) { + SDL_DestroyAudioStream(outgoing_music.stream); + outgoing_music.stream = nullptr; + outgoing_music.fade.active = false; + } + incoming_fade.active = false; + + if ((current_music == nullptr) || current_music->state == MusicState::INVALID || current_music->state == MusicState::STOPPED) { return; } + + current_music->state = MusicState::STOPPED; + if (current_music->stream != nullptr) { + SDL_DestroyAudioStream(current_music->stream); + current_music->stream = nullptr; + } + // Deixem el handle de vorbis viu — es tanca en deleteMusic. + // Rebobinem perquè un futur playMusic comence des del principi. if (current_music->vorbis != nullptr) { stb_vorbis_seek_start(current_music->vorbis); } } - // Iniciar la nueva pista con gain=0 (el fade-in la sube gradualmente) - current_music = music; - current_music->state = JA_MUSIC_PLAYING; - current_music->times = loop; + inline void fadeOutMusic(int milliseconds) { + if (!music_enabled) { return; } + if ((current_music == nullptr) || current_music->state != MusicState::PLAYING) { return; } - stb_vorbis_seek_start(current_music->vorbis); - current_music->stream = SDL_CreateAudioStream(¤t_music->spec, &JA_audioSpec); - if (current_music->stream == nullptr) { - std::cout << "Failed to create audio stream for crossfade!" << '\n'; - current_music->state = JA_MUSIC_STOPPED; - return; - } - SDL_SetAudioStreamGain(current_music->stream, 0.0F); - JA_PumpMusic(current_music); // pre-carrega abans de bindejar - SDL_BindAudioStream(sdlAudioDevice, current_music->stream); - - // Configurar fade-in - incoming_fade = {.active = true, .start_time = SDL_GetTicks(), .duration_ms = crossfade_ms, .initial_volume = 0.0F}; -} - -inline auto JA_GetMusicState() -> JA_Music_state { - if (!JA_musicEnabled) { - return JA_MUSIC_DISABLED; - } - if (current_music == nullptr) { - return JA_MUSIC_INVALID; - } - - return current_music->state; -} - -inline void JA_DeleteMusic(JA_Music_t* music) { - if (music == nullptr) { - return; - } - if (current_music == music) { - JA_StopMusic(); - current_music = nullptr; - } - if (music->stream != nullptr) { - SDL_DestroyAudioStream(music->stream); - } - if (music->vorbis != nullptr) { - stb_vorbis_close(music->vorbis); - } - // ogg_data (std::vector) i filename (std::string) s'alliberen sols - // al destructor de JA_Music_t. - delete music; -} - -inline auto JA_SetMusicVolume(float volume) -> float { - JA_musicVolume = SDL_clamp(volume, 0.0F, 1.0F); - if ((current_music != nullptr) && (current_music->stream != nullptr)) { - SDL_SetAudioStreamGain(current_music->stream, JA_musicVolume); - } - return JA_musicVolume; -} - -inline void JA_SetMusicPosition(float /*value*/) { - // No implementat amb el backend de streaming. -} - -inline auto JA_GetMusicPosition() -> float { - return 0.0F; -} - -inline void JA_EnableMusic(const bool value) { - if (!value && (current_music != nullptr) && (current_music->state == JA_MUSIC_PLAYING)) { - JA_StopMusic(); - } - JA_musicEnabled = value; -} - -// --- Sound Functions --- - -inline auto JA_LoadSound(uint8_t* buffer, uint32_t size) -> JA_Sound_t* { - auto sound = std::make_unique(); - Uint8* raw = nullptr; - if (!SDL_LoadWAV_IO(SDL_IOFromMem(buffer, size), true, &sound->spec, &raw, &sound->length)) { - std::cout << "Failed to load WAV from memory: " << SDL_GetError() << '\n'; - return nullptr; - } - sound->buffer.reset(raw); // adopta el SDL_malloc'd buffer - return sound.release(); -} - -inline auto JA_LoadSound(const char* filename) -> JA_Sound_t* { - auto sound = std::make_unique(); - Uint8* raw = nullptr; - if (!SDL_LoadWAV(filename, &sound->spec, &raw, &sound->length)) { - std::cout << "Failed to load WAV file: " << SDL_GetError() << '\n'; - return nullptr; - } - sound->buffer.reset(raw); // adopta el SDL_malloc'd buffer - return sound.release(); -} - -inline auto JA_PlaySound(JA_Sound_t* sound, const int loop = 0, const int group = 0) -> int { - if (!JA_soundEnabled || (sound == nullptr)) { - return -1; - } - - int channel = 0; - while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; } - if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) { - // No hay canal libre, reemplazamos el primero - channel = 0; - } - - return JA_PlaySoundOnChannel(sound, channel, loop, group); -} - -inline auto JA_PlaySoundOnChannel(JA_Sound_t* sound, const int channel, const int loop, const int group) -> int { - if (!JA_soundEnabled || (sound == nullptr)) { - return -1; - } - if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) { - return -1; - } - - JA_StopChannel(channel); - - channels[channel].sound = sound; - channels[channel].times = loop; - channels[channel].pos = 0; - channels[channel].group = group; - channels[channel].state = JA_CHANNEL_PLAYING; - channels[channel].stream = SDL_CreateAudioStream(&channels[channel].sound->spec, &JA_audioSpec); - - if (channels[channel].stream == nullptr) { - std::cout << "Failed to create audio stream for sound!" << '\n'; - channels[channel].state = JA_CHANNEL_FREE; - return -1; - } - - SDL_PutAudioStreamData(channels[channel].stream, channels[channel].sound->buffer.get(), channels[channel].sound->length); - SDL_SetAudioStreamGain(channels[channel].stream, JA_soundVolume[group]); - SDL_BindAudioStream(sdlAudioDevice, channels[channel].stream); - - return channel; -} - -inline void JA_DeleteSound(JA_Sound_t* sound) { - if (sound == nullptr) { - return; - } - for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { - if (channels[i].sound == sound) { - JA_StopChannel(i); + // Destruir outgoing anterior si existe + if (outgoing_music.stream != nullptr) { + SDL_DestroyAudioStream(outgoing_music.stream); + outgoing_music.stream = nullptr; } - } - // buffer es destrueix automàticament via RAII (SDLFreeDeleter). - delete sound; -} -inline void JA_PauseChannel(const int channel) { - if (!JA_soundEnabled) { - return; + // Pre-omplim l'stream amb `milliseconds` de so: un cop robat, ja no + // tindrà accés al vorbis decoder i només podrà drenar el que tinga. + preFillOutgoing(current_music, milliseconds); + + // Robar el stream del current_music al outgoing + outgoing_music.stream = current_music->stream; + outgoing_music.fade = {.active = true, .start_time = SDL_GetTicks(), .duration_ms = milliseconds, .initial_volume = music_volume}; + + // Dejar current_music sin stream (ya lo tiene outgoing) + current_music->stream = nullptr; + current_music->state = MusicState::STOPPED; + if (current_music->vorbis != nullptr) { stb_vorbis_seek_start(current_music->vorbis); } + incoming_fade.active = false; } - if (channel == -1) { - for (auto& ch : channels) { - if (ch.state == JA_CHANNEL_PLAYING) { - ch.state = JA_CHANNEL_PAUSED; - SDL_UnbindAudioStream(ch.stream); - } + inline void crossfadeMusic(Music* music, int crossfade_ms, int loop) { + if (!music_enabled || (music == nullptr) || (music->vorbis == nullptr)) { return; } + + // Destruir outgoing anterior si existe (crossfade durante crossfade) + if (outgoing_music.stream != nullptr) { + SDL_DestroyAudioStream(outgoing_music.stream); + outgoing_music.stream = nullptr; + outgoing_music.fade.active = false; } - } else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) { - if (channels[channel].state == JA_CHANNEL_PLAYING) { - channels[channel].state = JA_CHANNEL_PAUSED; - SDL_UnbindAudioStream(channels[channel].stream); - } - } -} -inline void JA_ResumeChannel(const int channel) { - if (!JA_soundEnabled) { - return; + // Robar el stream de la musica actual al outgoing para el fade-out. + // Pre-omplim amb `crossfade_ms` de so perquè no es quede en silenci + // abans d'acabar el fade (l'stream robat ja no pot alimentar-se). + if ((current_music != nullptr) && current_music->state == MusicState::PLAYING && (current_music->stream != nullptr)) { + preFillOutgoing(current_music, crossfade_ms); + outgoing_music.stream = current_music->stream; + outgoing_music.fade = {.active = true, .start_time = SDL_GetTicks(), .duration_ms = crossfade_ms, .initial_volume = music_volume}; + current_music->stream = nullptr; + current_music->state = MusicState::STOPPED; + if (current_music->vorbis != nullptr) { stb_vorbis_seek_start(current_music->vorbis); } + } + + // Iniciar la nueva pista con gain=0 (el fade-in la sube gradualmente) + current_music = music; + current_music->state = MusicState::PLAYING; + current_music->times = loop; + + stb_vorbis_seek_start(current_music->vorbis); + current_music->stream = SDL_CreateAudioStream(¤t_music->spec, &audio_spec); + if (current_music->stream == nullptr) { + std::cout << "Failed to create audio stream for crossfade!" << '\n'; + current_music->state = MusicState::STOPPED; + return; + } + SDL_SetAudioStreamGain(current_music->stream, 0.0F); + pumpMusic(current_music); // pre-carrega abans de bindejar + SDL_BindAudioStream(sdl_audio_device, current_music->stream); + + // Configurar fade-in + incoming_fade = {.active = true, .start_time = SDL_GetTicks(), .duration_ms = crossfade_ms, .initial_volume = 0.0F}; } - if (channel == -1) { - for (auto& ch : channels) { - if (ch.state == JA_CHANNEL_PAUSED) { - ch.state = JA_CHANNEL_PLAYING; - SDL_BindAudioStream(sdlAudioDevice, ch.stream); - } - } - } else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) { - if (channels[channel].state == JA_CHANNEL_PAUSED) { - channels[channel].state = JA_CHANNEL_PLAYING; - SDL_BindAudioStream(sdlAudioDevice, channels[channel].stream); - } - } -} + inline auto getMusicState() -> MusicState { + if (!music_enabled) { return MusicState::DISABLED; } + if (current_music == nullptr) { return MusicState::INVALID; } -inline void JA_StopChannel(const int channel) { - if (channel == -1) { - for (auto& ch : channels) { - if (ch.state != JA_CHANNEL_FREE) { - if (ch.stream != nullptr) { - SDL_DestroyAudioStream(ch.stream); + return current_music->state; + } + + inline void deleteMusic(Music* music) { + if (music == nullptr) { return; } + if (current_music == music) { + stopMusic(); + current_music = nullptr; + } + if (music->stream != nullptr) { SDL_DestroyAudioStream(music->stream); } + if (music->vorbis != nullptr) { stb_vorbis_close(music->vorbis); } + // ogg_data (std::vector) i filename (std::string) s'alliberen sols + // al destructor de Music. + delete music; + } + + inline auto setMusicVolume(float volume) -> float { + music_volume = SDL_clamp(volume, 0.0F, 1.0F); + if ((current_music != nullptr) && (current_music->stream != nullptr)) { + SDL_SetAudioStreamGain(current_music->stream, music_volume); + } + return music_volume; + } + + inline void setMusicPosition(float /*value*/) { + // No implementat amb el backend de streaming. + } + + inline auto getMusicPosition() -> float { + return 0.0F; + } + + inline void enableMusic(bool value) { + if (!value && (current_music != nullptr) && (current_music->state == MusicState::PLAYING)) { stopMusic(); } + music_enabled = value; + } + + // --- Sound Functions --- + inline auto loadSound(std::uint8_t* buffer, std::uint32_t size) -> Sound* { + auto sound = std::make_unique(); + Uint8* raw = nullptr; + if (!SDL_LoadWAV_IO(SDL_IOFromMem(buffer, size), true, &sound->spec, &raw, &sound->length)) { + std::cout << "Failed to load WAV from memory: " << SDL_GetError() << '\n'; + return nullptr; + } + sound->buffer.reset(raw); // adopta el SDL_malloc'd buffer + return sound.release(); + } + + inline auto loadSound(const char* filename) -> Sound* { + auto sound = std::make_unique(); + Uint8* raw = nullptr; + if (!SDL_LoadWAV(filename, &sound->spec, &raw, &sound->length)) { + std::cout << "Failed to load WAV file: " << SDL_GetError() << '\n'; + return nullptr; + } + sound->buffer.reset(raw); // adopta el SDL_malloc'd buffer + return sound.release(); + } + + inline auto playSound(Sound* sound, int loop = 0, int group = 0) -> int { + if (!sound_enabled || (sound == nullptr)) { return -1; } + + int channel = 0; + while (channel < MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != ChannelState::FREE) { channel++; } + if (channel == MAX_SIMULTANEOUS_CHANNELS) { + // No hi ha canal lliure, reemplacem el primer + channel = 0; + } + + return playSoundOnChannel(sound, channel, loop, group); + } + + inline auto playSoundOnChannel(Sound* sound, int channel, int loop, int group) -> int { + if (!sound_enabled || (sound == nullptr)) { return -1; } + if (channel < 0 || channel >= MAX_SIMULTANEOUS_CHANNELS) { return -1; } + + stopChannel(channel); + + channels[channel].sound = sound; + channels[channel].times = loop; + channels[channel].pos = 0; + channels[channel].group = group; + channels[channel].state = ChannelState::PLAYING; + channels[channel].stream = SDL_CreateAudioStream(&channels[channel].sound->spec, &audio_spec); + + if (channels[channel].stream == nullptr) { + std::cout << "Failed to create audio stream for sound!" << '\n'; + channels[channel].state = ChannelState::FREE; + return -1; + } + + SDL_PutAudioStreamData(channels[channel].stream, channels[channel].sound->buffer.get(), channels[channel].sound->length); + SDL_SetAudioStreamGain(channels[channel].stream, sound_volume[group]); + SDL_BindAudioStream(sdl_audio_device, channels[channel].stream); + + return channel; + } + + inline void deleteSound(Sound* sound) { + if (sound == nullptr) { return; } + for (int i = 0; i < MAX_SIMULTANEOUS_CHANNELS; i++) { + if (channels[i].sound == sound) { stopChannel(i); } + } + // buffer es destrueix automàticament via RAII (SdlFreeDeleter). + delete sound; + } + + inline void pauseChannel(int channel) { + if (!sound_enabled) { return; } + + if (channel == -1) { + for (auto& ch : channels) { + if (ch.state == ChannelState::PLAYING) { + ch.state = ChannelState::PAUSED; + SDL_UnbindAudioStream(ch.stream); } - ch.stream = nullptr; - ch.state = JA_CHANNEL_FREE; - ch.pos = 0; - ch.sound = nullptr; + } + } else if (channel >= 0 && channel < MAX_SIMULTANEOUS_CHANNELS) { + if (channels[channel].state == ChannelState::PLAYING) { + channels[channel].state = ChannelState::PAUSED; + SDL_UnbindAudioStream(channels[channel].stream); } } - } else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) { - if (channels[channel].state != JA_CHANNEL_FREE) { - if (channels[channel].stream != nullptr) { - SDL_DestroyAudioStream(channels[channel].stream); + } + + inline void resumeChannel(int channel) { + if (!sound_enabled) { return; } + + if (channel == -1) { + for (auto& ch : channels) { + if (ch.state == ChannelState::PAUSED) { + ch.state = ChannelState::PLAYING; + SDL_BindAudioStream(sdl_audio_device, ch.stream); + } + } + } else if (channel >= 0 && channel < MAX_SIMULTANEOUS_CHANNELS) { + if (channels[channel].state == ChannelState::PAUSED) { + channels[channel].state = ChannelState::PLAYING; + SDL_BindAudioStream(sdl_audio_device, channels[channel].stream); } - channels[channel].stream = nullptr; - channels[channel].state = JA_CHANNEL_FREE; - channels[channel].pos = 0; - channels[channel].sound = nullptr; } } -} -inline auto JA_GetChannelState(const int channel) -> JA_Channel_state { - if (!JA_soundEnabled) { - return JA_SOUND_DISABLED; - } - if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) { - return JA_CHANNEL_INVALID; + inline void stopChannel(int channel) { + if (channel == -1) { + for (auto& ch : channels) { + if (ch.state != ChannelState::FREE) { + if (ch.stream != nullptr) { SDL_DestroyAudioStream(ch.stream); } + ch.stream = nullptr; + ch.state = ChannelState::FREE; + ch.pos = 0; + ch.sound = nullptr; + } + } + } else if (channel >= 0 && channel < MAX_SIMULTANEOUS_CHANNELS) { + if (channels[channel].state != ChannelState::FREE) { + if (channels[channel].stream != nullptr) { SDL_DestroyAudioStream(channels[channel].stream); } + channels[channel].stream = nullptr; + channels[channel].state = ChannelState::FREE; + channels[channel].pos = 0; + channels[channel].sound = nullptr; + } + } } - return channels[channel].state; -} + inline auto getChannelState(int channel) -> ChannelState { + if (!sound_enabled) { return ChannelState::DISABLED; } + if (channel < 0 || channel >= MAX_SIMULTANEOUS_CHANNELS) { return ChannelState::INVALID; } -inline auto JA_SetSoundVolume(float volume, const int group = -1) -> float { - const float v = SDL_clamp(volume, 0.0F, 1.0F); - - if (group == -1) { - std::fill(std::begin(JA_soundVolume), std::end(JA_soundVolume), v); - } else if (group >= 0 && group < JA_MAX_GROUPS) { - JA_soundVolume[group] = v; - } else { - return v; + return channels[channel].state; } - // Aplicar volum als canals actius. - for (auto& channel : channels) { - if ((channel.state == JA_CHANNEL_PLAYING) || (channel.state == JA_CHANNEL_PAUSED)) { - if (group == -1 || channel.group == group) { - if (channel.stream != nullptr) { - SDL_SetAudioStreamGain(channel.stream, JA_soundVolume[channel.group]); + inline auto setSoundVolume(float volume, int group = -1) -> float { + const float V = SDL_clamp(volume, 0.0F, 1.0F); + + if (group == -1) { + std::fill(std::begin(sound_volume), std::end(sound_volume), V); + } else if (group >= 0 && group < MAX_GROUPS) { + sound_volume[group] = V; + } else { + return V; + } + + // Aplicar volum als canals actius. + for (auto& ch : channels) { + if ((ch.state == ChannelState::PLAYING) || (ch.state == ChannelState::PAUSED)) { + if (group == -1 || ch.group == group) { + if (ch.stream != nullptr) { + SDL_SetAudioStreamGain(ch.stream, sound_volume[ch.group]); + } } } } + return V; } - return v; -} -inline void JA_EnableSound(const bool value) { - if (!value) { - JA_StopChannel(-1); + inline void enableSound(bool value) { + if (!value) { + stopChannel(-1); + } + sound_enabled = value; } - JA_soundEnabled = value; -} -inline auto JA_SetVolume(float volume) -> float { - float v = JA_SetMusicVolume(volume); - JA_SetSoundVolume(v, -1); - return v; -} + inline auto setVolume(float volume) -> float { + const float V = setMusicVolume(volume); + setSoundVolume(V, -1); + return V; + } + +} // namespace Ja diff --git a/source/core/resources/resource_cache.cpp b/source/core/resources/resource_cache.cpp index 681c813..14a0be9 100644 --- a/source/core/resources/resource_cache.cpp +++ b/source/core/resources/resource_cache.cpp @@ -33,7 +33,7 @@ namespace Resource { } } // namespace - auto Cache::getMusic(const std::string& name) -> JA_Music_t* { + auto Cache::getMusic(const std::string& name) -> Ja::Music* { auto it = std::ranges::find_if(musics_, [&](const auto& m) { return m.name == name; }); if (it != musics_.end()) { return it->music.get(); @@ -42,7 +42,7 @@ namespace Resource { throw std::runtime_error("Music not found: " + name); } - auto Cache::getSound(const std::string& name) -> JA_Sound_t* { + auto Cache::getSound(const std::string& name) -> Ja::Sound* { auto it = std::ranges::find_if(sounds_, [&](const auto& s) { return s.name == name; }); if (it != sounds_.end()) { return it->sound.get(); @@ -192,12 +192,12 @@ namespace Resource { std::cerr << "Resource::Cache: no s'ha pogut llegir " << path << '\n'; return; } - JA_Music_t* music = JA_LoadMusic(bytes.data(), static_cast(bytes.size()), path.c_str()); + Ja::Music* music = Ja::loadMusic(bytes.data(), static_cast(bytes.size()), path.c_str()); if (music == nullptr) { - std::cerr << "Resource::Cache: JA_LoadMusic ha fallat per " << path << '\n'; + std::cerr << "Resource::Cache: Ja::loadMusic ha fallat per " << path << '\n'; return; } - musics_.push_back(MusicResource{.name = name, .music = std::unique_ptr(music)}); + musics_.push_back(MusicResource{.name = name, .music = std::unique_ptr(music)}); ++loaded_count_; std::cout << " [music ] " << name << '\n'; } @@ -213,12 +213,12 @@ namespace Resource { std::cerr << "Resource::Cache: no s'ha pogut llegir " << path << '\n'; return; } - JA_Sound_t* sound = JA_LoadSound(bytes.data(), static_cast(bytes.size())); + Ja::Sound* sound = Ja::loadSound(bytes.data(), static_cast(bytes.size())); if (sound == nullptr) { - std::cerr << "Resource::Cache: JA_LoadSound ha fallat per " << path << '\n'; + std::cerr << "Resource::Cache: Ja::loadSound ha fallat per " << path << '\n'; return; } - sounds_.push_back(SoundResource{.name = name, .sound = std::unique_ptr(sound)}); + sounds_.push_back(SoundResource{.name = name, .sound = std::unique_ptr(sound)}); ++loaded_count_; std::cout << " [sound ] " << name << '\n'; } diff --git a/source/core/resources/resource_cache.hpp b/source/core/resources/resource_cache.hpp index 8f26959..28f1a80 100644 --- a/source/core/resources/resource_cache.hpp +++ b/source/core/resources/resource_cache.hpp @@ -27,8 +27,8 @@ namespace Resource { auto operator=(const Cache&) -> Cache& = delete; // Getters: throw runtime_error si el nom no existeix al cache. - auto getMusic(const std::string& name) -> JA_Music_t*; - auto getSound(const std::string& name) -> JA_Sound_t*; + auto getMusic(const std::string& name) -> Ja::Music*; + auto getSound(const std::string& name) -> Ja::Sound*; auto getSurfacePixels(const std::string& name) -> const std::vector&; auto getPaletteBytes(const std::string& name) -> const std::vector&; auto getTextFile(const std::string& name) -> const std::vector&; diff --git a/source/core/resources/resource_types.hpp b/source/core/resources/resource_types.hpp index 92727f9..77330fe 100644 --- a/source/core/resources/resource_types.hpp +++ b/source/core/resources/resource_types.hpp @@ -8,38 +8,39 @@ #include // Forward declarations to keep this header light. -struct JA_Music_t; -struct JA_Sound_t; - -void JA_DeleteMusic(JA_Music_t* music); -void JA_DeleteSound(JA_Sound_t* sound); +namespace Ja { + struct Music; + struct Sound; + void deleteMusic(Music* music); + void deleteSound(Sound* sound); +} // namespace Ja namespace Resource { struct MusicDeleter { - void operator()(JA_Music_t* music) const noexcept { + void operator()(Ja::Music* music) const noexcept { if (music != nullptr) { - JA_DeleteMusic(music); + Ja::deleteMusic(music); } } }; struct SoundDeleter { - void operator()(JA_Sound_t* sound) const noexcept { + void operator()(Ja::Sound* sound) const noexcept { if (sound != nullptr) { - JA_DeleteSound(sound); + Ja::deleteSound(sound); } } }; struct MusicResource { std::string name; - std::unique_ptr music; + std::unique_ptr music; }; struct SoundResource { std::string name; - std::unique_ptr sound; + std::unique_ptr sound; }; // Una entrada BITMAP descodifica un GIF i emmagatzema els seus diff --git a/source/game/scenes/banner_scene.hpp b/source/game/scenes/banner_scene.hpp index a56d272..8940e3b 100644 --- a/source/game/scenes/banner_scene.hpp +++ b/source/game/scenes/banner_scene.hpp @@ -15,7 +15,7 @@ namespace scenes { // 2. Pinta títol, subtítol i número de piràmide segons info::ctx.num_piramide. // 3. Fade-in de paleta. // 4. Mostra ~5s o fins que es polse una tecla. - // 5. JA_FadeOutMusic(250) + fade-out de paleta. + // 5. Ja::fadeOutMusic(250) + fade-out de paleta. // 6. Retorna nextState=0 per a entrar al ModuleGame. // // Registrat al SceneRegistry amb state_keys 2..5 (els num_piramide on diff --git a/source/game/scenes/credits_scene.cpp b/source/game/scenes/credits_scene.cpp index 83a460b..b0084ce 100644 --- a/source/game/scenes/credits_scene.cpp +++ b/source/game/scenes/credits_scene.cpp @@ -44,7 +44,7 @@ namespace scenes { // previ ("music/final.ogg"). Si l'escena s'arrenca directament (test // amb piramide_inicial=8) no hi ha res que heretar, així que // arranquem la mateixa pista només si no sona res. Inocu en el - // flux normal: JA_MUSIC_PLAYING fa que no la tornem a tocar. + // flux normal: Ja::MusicState::PLAYING fa que no la tornem a tocar. if (Audio::getRealMusicState() != Audio::MusicState::PLAYING) { playMusic("music/final.ogg"); } diff --git a/source/game/scenes/secreta_scene.hpp b/source/game/scenes/secreta_scene.hpp index ed976b1..775b040 100644 --- a/source/game/scenes/secreta_scene.hpp +++ b/source/game/scenes/secreta_scene.hpp @@ -22,7 +22,7 @@ namespace scenes { // i pinta un revelat horitzontal (~1.6 s + ~1.6 s de pausa). // 5. "Red pulse": anima els colors 253/254 incrementant el canal R // de 12 a 62 durant ~1 s (+ ~1 s de pausa). - // 6. FadeOut + JA_FadeOutMusic(250). + // 6. FadeOut + Ja::fadeOutMusic(250). // 7. Retorna nextState=0 per entrar al ModuleGame amb num_piramide=6. // // Registrada al SceneRegistry amb state_key = 6. diff --git a/source/game/scenes/slides_scene.cpp b/source/game/scenes/slides_scene.cpp index e354ba9..7031206 100644 --- a/source/game/scenes/slides_scene.cpp +++ b/source/game/scenes/slides_scene.cpp @@ -102,7 +102,7 @@ namespace scenes { void SlidesScene::tick(int delta_ms) { // Skip: qualsevol tecla salta directament al fade final. Per fidelitat // al vell doSlides, el skip NO atura la música explícitament — només - // el final natural crida JA_FadeOutMusic (beginFinalFade() distingeix). + // el final natural crida Ja::fadeOutMusic (beginFinalFade() distingeix). if (!skip_triggered_ && JI_AnyKey()) { skip_triggered_ = true; if (num_piramide_at_start_ != 7) { diff --git a/source/game/scenes/slides_scene.hpp b/source/game/scenes/slides_scene.hpp index 58b04f9..678d6cc 100644 --- a/source/game/scenes/slides_scene.hpp +++ b/source/game/scenes/slides_scene.hpp @@ -26,7 +26,7 @@ namespace scenes { // → FadeOut2 + clear + reset paleta // → Slide3Enter (1600 ms scroll dreta→centre) // → Slide3Hold (4600 ms) - // → FadeFinal (JA_FadeOutMusic si num_piramide != 7 + fade paleta) + // → FadeFinal (Ja::fadeOutMusic si num_piramide != 7 + fade paleta) // → Done // // Qualsevol tecla salta directament a FadeFinal (sense cortar la música diff --git a/source/game/scenes/timeline.hpp b/source/game/scenes/timeline.hpp index 2fd9ee3..22ccf79 100644 --- a/source/game/scenes/timeline.hpp +++ b/source/game/scenes/timeline.hpp @@ -12,7 +12,7 @@ namespace scenes { // .once([this] { JD8_ClearScreen(0); fade_.startFadeTo(pal); }) // .step(5000) // espera pura // .step(1000, [this](float p) { /*...*/ }) // animat amb progress - // .once([this] { JA_FadeOutMusic(250); }); + // .once([this] { Ja::fadeOutMusic(250); }); // // `tick(delta_ms)` avança el temps. Els passos one-shot s'executen al // moment d'entrar-hi i avancen immediatament. Els passos amb duració diff --git a/source/main.cpp b/source/main.cpp index 5b23e10..ecf0742 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -92,7 +92,7 @@ auto SDL_AppInit(void** /*appstate*/, int /*argc*/, char* /*argv*/[]) -> SDL_App JG_Init(); Screen::init(); JD8_Init(); - Audio::init(); // crida internament JA_Init i aplica Options::audio + Audio::init(); // crida internament Ja::init i aplica Options::audio Overlay::init(); Menu::init(); @@ -146,7 +146,7 @@ void SDL_AppQuit(void* /*appstate*/, SDL_AppResult /*result*/) { Overlay::destroy(); Resource::Cache::destroy(); Resource::List::destroy(); - Audio::destroy(); // el destructor del singleton crida JA_Quit + Audio::destroy(); // el destructor del singleton crida Ja::quit JD8_Quit(); Screen::destroy(); JG_Finalize(); From f37308a5f0790c70406977ba1a0dfc01acd4a932 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 16 May 2026 14:24:22 +0200 Subject: [PATCH 02/13] refactor: JD8_* a namespace Jd8:: --- source/core/jail/jdraw8.cpp | 78 +++++----- source/core/jail/jdraw8.hpp | 158 ++++++++++---------- source/core/system/director.cpp | 6 +- source/core/system/director.hpp | 2 +- source/game/bola.cpp | 2 +- source/game/bola.hpp | 2 +- source/game/engendro.cpp | 2 +- source/game/engendro.hpp | 2 +- source/game/mapa.cpp | 72 ++++----- source/game/mapa.hpp | 6 +- source/game/marcador.cpp | 28 ++-- source/game/marcador.hpp | 4 +- source/game/modulegame.cpp | 10 +- source/game/modulegame.hpp | 4 +- source/game/momia.cpp | 6 +- source/game/momia.hpp | 2 +- source/game/prota.cpp | 6 +- source/game/prota.hpp | 2 +- source/game/scenes/banner_scene.cpp | 10 +- source/game/scenes/boot_loader_scene.cpp | 16 +- source/game/scenes/credits_scene.cpp | 30 ++-- source/game/scenes/intro_new_logo_scene.cpp | 28 ++-- source/game/scenes/intro_new_logo_scene.hpp | 2 +- source/game/scenes/intro_scene.cpp | 20 +-- source/game/scenes/intro_scene.hpp | 2 +- source/game/scenes/intro_sprites_scene.cpp | 140 ++++++++--------- source/game/scenes/menu_scene.cpp | 32 ++-- source/game/scenes/mort_scene.cpp | 6 +- source/game/scenes/palette_fade.cpp | 6 +- source/game/scenes/palette_fade.hpp | 2 +- source/game/scenes/scene.hpp | 2 +- source/game/scenes/secreta_scene.cpp | 28 ++-- source/game/scenes/secreta_scene.hpp | 4 +- source/game/scenes/slides_scene.cpp | 10 +- source/game/scenes/slides_scene.hpp | 4 +- source/game/scenes/surface_handle.cpp | 18 +-- source/game/scenes/surface_handle.hpp | 24 +-- source/game/scenes/timeline.hpp | 2 +- source/game/sprite.cpp | 4 +- source/game/sprite.hpp | 4 +- source/main.cpp | 4 +- 41 files changed, 394 insertions(+), 396 deletions(-) diff --git a/source/core/jail/jdraw8.cpp b/source/core/jail/jdraw8.cpp index 33ad8e9..8f74420 100644 --- a/source/core/jail/jdraw8.cpp +++ b/source/core/jail/jdraw8.cpp @@ -21,17 +21,17 @@ #pragma GCC diagnostic pop #endif -JD8_Surface screen = nullptr; -JD8_Palette main_palette = nullptr; +Jd8::Surface screen = nullptr; +Jd8::Palette main_palette = nullptr; Uint32* pixel_data = nullptr; -void JD8_Init() { +void Jd8::init() { screen = new Uint8[64000]{}; main_palette = new Color[256]{}; pixel_data = new Uint32[std::size_t{320} * 200]{}; } -void JD8_Quit() { +void Jd8::quit() { delete[] screen; delete[] main_palette; delete[] pixel_data; @@ -40,30 +40,30 @@ void JD8_Quit() { pixel_data = nullptr; } -void JD8_ClearScreen(Uint8 color) { +void Jd8::clearScreen(Uint8 color) { memset(screen, color, 64000); } -auto JD8_NewSurface() -> JD8_Surface { +auto Jd8::newSurface() -> Jd8::Surface { return new Uint8[64000]{}; } // Helper intern: deriva el basename d'una ruta per a buscar al Cache. -static auto jd8_basename(const char* file) -> std::string { +static auto pathBasename(const char* file) -> std::string { std::string s = file; auto pos = s.find_last_of("/\\"); return pos == std::string::npos ? s : s.substr(pos + 1); } -auto JD8_LoadSurface(const char* file) -> JD8_Surface { +auto Jd8::loadSurface(const char* file) -> Jd8::Surface { // Prova primer el Resource::Cache. Si l'asset és precarregat, copiem // els 64KB des del cache (microsegons) i ens estalviem la decodificació // GIF. Mantenim el contracte de la funció: el caller rep un buffer - // fresc que ha d'alliberar amb JD8_FreeSurface. + // fresc que ha d'alliberar amb Jd8::freeSurface. if (Resource::Cache::get() != nullptr) { try { - const auto& cached = Resource::Cache::get()->getSurfacePixels(jd8_basename(file)); - JD8_Surface image = JD8_NewSurface(); + const auto& cached = Resource::Cache::get()->getSurfacePixels(pathBasename(file)); + Jd8::Surface image = Jd8::newSurface(); memcpy(image, cached.data(), 64000); return image; } catch (const std::exception&) { @@ -79,21 +79,21 @@ auto JD8_LoadSurface(const char* file) -> JD8_Surface { printf("Unable to load bitmap: %s\n", SDL_GetError()); exit(1); } - JD8_Surface image = JD8_NewSurface(); + Jd8::Surface image = Jd8::newSurface(); memcpy(image, pixels, 64000); free(pixels); return image; } -auto JD8_LoadPalette(const char* file) -> JD8_Palette { +auto Jd8::loadPalette(const char* file) -> Jd8::Palette { // Sempre retorna un buffer de 256 colors reservat amb `new Color[256]` // — el caller és responsable d'alliberar-lo amb `delete[]` (o lliurar-ne - // l'ownership a `JD8_SetScreenPalette`). + // l'ownership a `Jd8::setScreenPalette`). auto* palette = new Color[256]; if (Resource::Cache::get() != nullptr) { try { - const auto& cached = Resource::Cache::get()->getPaletteBytes(jd8_basename(file)); + const auto& cached = Resource::Cache::get()->getPaletteBytes(pathBasename(file)); memcpy(palette, cached.data(), 768); return palette; } catch (const std::exception&) { @@ -108,7 +108,7 @@ auto JD8_LoadPalette(const char* file) -> JD8_Palette { return palette; } -void JD8_SetScreenPalette(JD8_Palette palette) { +void Jd8::setScreenPalette(Jd8::Palette palette) { if (main_palette == palette) { return; } @@ -116,13 +116,13 @@ void JD8_SetScreenPalette(JD8_Palette palette) { main_palette = palette; } -void JD8_FillSquare(int ini, int height, Uint8 color) { +void Jd8::fillSquare(int ini, int height, Uint8 color) { const int offset = ini * 320; const int size = height * 320; memset(&screen[offset], color, size); } -void JD8_FillRect(int x, int y, int w, int h, Uint8 color) { +void Jd8::fillRect(int x, int y, int w, int h, Uint8 color) { if (x < 0) { w += x; x = 0; @@ -145,11 +145,11 @@ void JD8_FillRect(int x, int y, int w, int h, Uint8 color) { } } -void JD8_Blit(const Uint8* surface) { +void Jd8::blit(const Uint8* surface) { memcpy(screen, surface, 64000); } -void JD8_Blit(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh) { +void Jd8::blit(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh) { int src_pointer = sx + (sy * 320); int dst_pointer = x + (y * 320); for (int i = 0; i < sh; i++) { @@ -159,7 +159,7 @@ void JD8_Blit(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh } } -void JD8_BlitToSurface(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh, JD8_Surface dest) { +void Jd8::blitToSurface(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh, Jd8::Surface dest) { int src_pointer = sx + (sy * 320); int dst_pointer = x + (y * 320); for (int i = 0; i < sh; i++) { @@ -169,7 +169,7 @@ void JD8_BlitToSurface(int x, int y, const Uint8* surface, int sx, int sy, int s } } -void JD8_BlitCK(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh, Uint8 colorkey) { +void Jd8::blitCK(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh, Uint8 colorkey) { int src_pointer = sx + (sy * 320); int dst_pointer = x + (y * 320); for (int j = 0; j < sh; j++) { @@ -183,7 +183,7 @@ void JD8_BlitCK(int x, int y, const Uint8* surface, int sx, int sy, int sw, int } } -void JD8_BlitCKCut(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh, Uint8 colorkey) { +void Jd8::blitCKCut(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh, Uint8 colorkey) { int src_pointer = sx + (sy * 320); int dst_pointer = x + (y * 320); for (int j = 0; j < sh; j++) { @@ -197,7 +197,7 @@ void JD8_BlitCKCut(int x, int y, const Uint8* surface, int sx, int sy, int sw, i } } -void JD8_BlitCKScroll(int y, const Uint8* surface, int sx, int sy, int sh, Uint8 colorkey) { +void Jd8::blitCKScroll(int y, const Uint8* surface, int sx, int sy, int sh, Uint8 colorkey) { int dst_pointer = y * 320; for (int j = sy; j < sy + sh; j++) { for (int i = 0; i < 320; i++) { @@ -210,7 +210,7 @@ void JD8_BlitCKScroll(int y, const Uint8* surface, int sx, int sy, int sh, Uint8 } } -void JD8_BlitCKToSurface(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh, JD8_Surface dest, Uint8 colorkey) { +void Jd8::blitCKToSurface(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh, Jd8::Surface dest, Uint8 colorkey) { int src_pointer = sx + (sy * 320); int dst_pointer = x + (y * 320); for (int j = 0; j < sh; j++) { @@ -224,7 +224,7 @@ void JD8_BlitCKToSurface(int x, int y, const Uint8* surface, int sx, int sy, int } } -void JD8_Flip() { +void Jd8::flip() { // Converteix el framebuffer indexat (paletted) a ARGB (pixel_data). // El Director crida aquesta funció després del tick de cada escena // per preparar el frame abans de presentar-lo. Ja no fa yield — @@ -237,23 +237,23 @@ void JD8_Flip() { } } -auto JD8_GetFramebuffer() -> Uint32* { +auto Jd8::getFramebuffer() -> Uint32* { return pixel_data; } -void JD8_FreeSurface(JD8_Surface surface) { // NOLINT(readability-non-const-parameter): allibera memòria, no pot ser const +void Jd8::freeSurface(Jd8::Surface surface) { // NOLINT(readability-non-const-parameter): allibera memòria, no pot ser const delete[] surface; } -auto JD8_GetPixel(const Uint8* surface, int x, int y) -> Uint8 { +auto Jd8::getPixel(const Uint8* surface, int x, int y) -> Uint8 { return surface[x + (y * 320)]; } -void JD8_PutPixel(JD8_Surface surface, int x, int y, Uint8 pixel) { +void Jd8::putPixel(Jd8::Surface surface, int x, int y, Uint8 pixel) { surface[x + (y * 320)] = pixel; } -void JD8_SetPaletteColor(Uint8 index, Uint8 r, Uint8 g, Uint8 b) { +void Jd8::setPaletteColor(Uint8 index, Uint8 r, Uint8 g, Uint8 b) { main_palette[index].r = r << 2; main_palette[index].g = g << 2; main_palette[index].b = b << 2; @@ -300,22 +300,22 @@ namespace { } // namespace -void JD8_FadeStartOut() { +void Jd8::fadeStartOut() { fade_type = FadeType::Out; fade_step = 0; } -void JD8_FadeStartToPal(const Color* pal) { +void Jd8::fadeStartToPal(const Color* pal) { fade_type = FadeType::ToPal; memcpy(fade_target, pal, sizeof(Color) * 256); fade_step = 0; } -auto JD8_FadeIsActive() -> bool { +auto Jd8::fadeIsActive() -> bool { return fade_type != FadeType::None; } -auto JD8_FadeTickStep() -> bool { +auto Jd8::fadeTickStep() -> bool { if (fade_type == FadeType::None) { return true; } @@ -331,8 +331,8 @@ auto JD8_FadeTickStep() -> bool { } // Els shims bloquejants `JD8_FadeOut` i `JD8_FadeToPal` han estat -// eliminats a Phase B.2: feien un bucle de 32 iteracions amb `JD8_Flip` +// eliminats a Phase B.2: feien un bucle de 32 iteracions amb `Jd8::flip` // entre cada una que només funcionava mentre l'entorn tenia fibers i -// `JD8_Flip` cedia el control al Director. Ara tot fade es fa tick a -// tick via `scenes::PaletteFade` (que encapsula `JD8_FadeStartOut` / -// `JD8_FadeStartToPal` + `JD8_FadeTickStep`). +// `Jd8::flip` cedia el control al Director. Ara tot fade es fa tick a +// tick via `scenes::PaletteFade` (que encapsula `Jd8::fadeStartOut` / +// `Jd8::fadeStartToPal` + `Jd8::fadeTickStep`). diff --git a/source/core/jail/jdraw8.hpp b/source/core/jail/jdraw8.hpp index 554654d..3e8d3b1 100644 --- a/source/core/jail/jdraw8.hpp +++ b/source/core/jail/jdraw8.hpp @@ -1,80 +1,78 @@ -#pragma once -#include - -struct Color { - Uint8 r; - Uint8 g; - Uint8 b; -}; - -using JD8_Surface = Uint8*; -using JD8_Palette = Color*; - -void JD8_Init(); - -void JD8_Quit(); - -void JD8_ClearScreen(Uint8 color); - -auto JD8_NewSurface() -> JD8_Surface; - -auto JD8_LoadSurface(const char* file) -> JD8_Surface; - -auto JD8_LoadPalette(const char* file) -> JD8_Palette; - -void JD8_SetScreenPalette(JD8_Palette palette); - -void JD8_FillSquare(int ini, int height, Uint8 color); - -// Omple un rectangle arbitrari de la pantalla amb un color paletat. -// Pensat per a UI senzilla (barra de progrés del BootLoader, etc.). -void JD8_FillRect(int x, int y, int w, int h, Uint8 color); - -void JD8_Blit(const Uint8* surface); - -void JD8_Blit(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh); - -void JD8_BlitToSurface(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh, JD8_Surface dest); - -void JD8_BlitCK(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh, Uint8 colorkey); - -void JD8_BlitCKCut(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh, Uint8 colorkey); - -void JD8_BlitCKScroll(int y, const Uint8* surface, int sx, int sy, int sh, Uint8 colorkey); - -void JD8_BlitCKToSurface(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh, JD8_Surface dest, Uint8 colorkey); - -// Converteix la pantalla indexada a ARGB. El Director crida aquesta -// funció al final de cada tick i després llegeix el framebuffer via -// JD8_GetFramebuffer() per presentar-lo. -void JD8_Flip(); - -// Accés al framebuffer ARGB de 320x200 actualitzat per l'última crida a -// JD8_Flip(). Propietat de jdraw8 — el caller no ha de lliberar-lo. -auto JD8_GetFramebuffer() -> Uint32*; - -void JD8_FreeSurface(JD8_Surface surface); - -auto JD8_GetPixel(const Uint8* surface, int x, int y) -> Uint8; - -void JD8_PutPixel(JD8_Surface surface, int x, int y, Uint8 pixel); - -void JD8_SetPaletteColor(Uint8 index, Uint8 r, Uint8 g, Uint8 b); - -// API de fade no bloquejant (màquina d'estats). `FadeStart*` inicia el -// fade; `FadeTickStep` aplica un pas i retorna `true` quan el fade ha -// acabat. Un pas correspon visualment a una iteració del fade original -// (32 passos en total). El caller és responsable de fer el Flip entre -// passos si el vol veure animat. `FadeIsActive` permet saber si hi ha -// un fade en curs per a enllaçar-lo amb un altre subsistema. -// L'embolcall `scenes::PaletteFade` ho fa més idiomàtic per a escenes. -void JD8_FadeStartOut(); -void JD8_FadeStartToPal(const Color* pal); -auto JD8_FadeTickStep() -> bool; -auto JD8_FadeIsActive() -> bool; - -// JD_Font JD_LoadFont( char *file, int width, int height); - -// void JD_DrawText( int x, int y, JD_Font *source, char *text); - -// char *JD_GetFPS(); +#pragma once +#include + +struct Color { + Uint8 r; + Uint8 g; + Uint8 b; +}; + +namespace Jd8 { + + using Surface = Uint8*; + using Palette = Color*; + + void init(); + + void quit(); + + void clearScreen(Uint8 color); + + auto newSurface() -> Surface; + + auto loadSurface(const char* file) -> Surface; + + auto loadPalette(const char* file) -> Palette; + + void setScreenPalette(Palette palette); + + void fillSquare(int ini, int height, Uint8 color); + + // Omple un rectangle arbitrari de la pantalla amb un color paletat. + // Pensat per a UI senzilla (barra de progrés del BootLoader, etc.). + void fillRect(int x, int y, int w, int h, Uint8 color); + + void blit(const Uint8* surface); + + void blit(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh); + + void blitToSurface(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh, Surface dest); + + void blitCK(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh, Uint8 colorkey); + + void blitCKCut(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh, Uint8 colorkey); + + void blitCKScroll(int y, const Uint8* surface, int sx, int sy, int sh, Uint8 colorkey); + + void blitCKToSurface(int x, int y, const Uint8* surface, int sx, int sy, int sw, int sh, Surface dest, Uint8 colorkey); + + // Converteix la pantalla indexada a ARGB. El Director crida aquesta + // funció al final de cada tick i després llegeix el framebuffer via + // getFramebuffer() per presentar-lo. + void flip(); + + // Accés al framebuffer ARGB de 320x200 actualitzat per l'última crida a + // flip(). Propietat de jdraw8 — el caller no ha de lliberar-lo. + auto getFramebuffer() -> Uint32*; + + void freeSurface(Surface surface); + + auto getPixel(const Uint8* surface, int x, int y) -> Uint8; + + void putPixel(Surface surface, int x, int y, Uint8 pixel); + + void setPaletteColor(Uint8 index, Uint8 r, Uint8 g, Uint8 b); + + // API de fade no bloquejant (màquina d'estats). `fadeStart*` inicia el + // fade; `fadeTickStep` aplica un pas i retorna `true` quan el fade ha + // acabat. Un pas correspon visualment a una iteració del fade original + // (32 passos en total). El caller és responsable de fer el Flip entre + // passos si el vol veure animat. `fadeIsActive` permet saber si hi ha + // un fade en curs per a enllaçar-lo amb un altre subsistema. + // L'embolcall `scenes::PaletteFade` ho fa més idiomàtic per a escenes. + void fadeStartOut(); + void fadeStartToPal(const Color* pal); + auto fadeTickStep() -> bool; + auto fadeIsActive() -> bool; + +} // namespace Jd8 diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index f755bb1..83f0ed5 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -236,10 +236,10 @@ auto Director::iterate() -> bool { current_scene_->tick(delta_ms); // Converteix `screen` indexat → `pixel_data` ARGB amb la paleta - // actual. JD8_Flip ja no fa yield (Phase B.2 eliminà els fibers); + // actual. Jd8::flip ja no fa yield (Phase B.2 eliminà els fibers); // ara només omple el framebuffer perquè el Director l'aprofite. - JD8_Flip(); - std::memcpy(game_frame_, JD8_GetFramebuffer(), sizeof(game_frame_)); + Jd8::flip(); + std::memcpy(game_frame_, Jd8::getFramebuffer(), sizeof(game_frame_)); has_frame_ = true; } diff --git a/source/core/system/director.hpp b/source/core/system/director.hpp index 5f8a1e2..fb9c5b8 100644 --- a/source/core/system/director.hpp +++ b/source/core/system/director.hpp @@ -9,7 +9,7 @@ #include "game/scenes/scene.hpp" // El Director és l'únic thread del runtime. Cada iterate() fa input → -// tick de l'escena actual → JD8_Flip → overlay → present → sleep al frame +// tick de l'escena actual → Jd8::flip → overlay → present → sleep al frame // target. Totes les escenes (`scenes::Scene` i `ModuleGame`) són // tick-based i no bloquegen — no hi ha fibers, mutex ni condition_variable. // Compatible amb SDL_AppIterate i amb el futur port a emscripten. diff --git a/source/game/bola.cpp b/source/game/bola.cpp index 5beb1b5..a747072 100644 --- a/source/game/bola.cpp +++ b/source/game/bola.cpp @@ -4,7 +4,7 @@ #include "core/jail/jgame.hpp" -Bola::Bola(JD8_Surface gfx, Prota* sam) +Bola::Bola(Jd8::Surface gfx, Prota* sam) : Sprite(gfx) { this->sam = sam; diff --git a/source/game/bola.hpp b/source/game/bola.hpp index ff6873a..2f80ca2 100644 --- a/source/game/bola.hpp +++ b/source/game/bola.hpp @@ -6,7 +6,7 @@ class Bola : public Sprite { public: - explicit Bola(JD8_Surface gfx, Prota* sam); + explicit Bola(Jd8::Surface gfx, Prota* sam); void draw() override; void update(); diff --git a/source/game/engendro.cpp b/source/game/engendro.cpp index fd827a1..72d3fba 100644 --- a/source/game/engendro.cpp +++ b/source/game/engendro.cpp @@ -4,7 +4,7 @@ #include "core/jail/jgame.hpp" -Engendro::Engendro(JD8_Surface gfx, Uint16 x, Uint16 y) +Engendro::Engendro(Jd8::Surface gfx, Uint16 x, Uint16 y) : Sprite(gfx) { entitat.frames.reserve(4); for (int py = 50; py <= 65; py += 15) { diff --git a/source/game/engendro.hpp b/source/game/engendro.hpp index d06aad2..2319956 100644 --- a/source/game/engendro.hpp +++ b/source/game/engendro.hpp @@ -4,7 +4,7 @@ class Engendro : public Sprite { public: - explicit Engendro(JD8_Surface gfx, Uint16 x, Uint16 y); + explicit Engendro(Jd8::Surface gfx, Uint16 x, Uint16 y); auto update() -> bool; diff --git a/source/game/mapa.cpp b/source/game/mapa.cpp index 1a0e47c..3de4c94 100644 --- a/source/game/mapa.cpp +++ b/source/game/mapa.cpp @@ -6,7 +6,7 @@ #include "core/jail/jgame.hpp" #include "core/jail/jinput.hpp" -Mapa::Mapa(JD8_Surface gfx, Prota* sam) { +Mapa::Mapa(Jd8::Surface gfx, Prota* sam) { this->gfx = gfx; this->sam = sam; @@ -23,42 +23,42 @@ Mapa::Mapa(JD8_Surface gfx, Prota* sam) { } Mapa::~Mapa() { - JD8_FreeSurface(this->fondo); + Jd8::freeSurface(this->fondo); } void Mapa::draw() { if (info::ctx.num_piramide != 4) { switch (sam->o) { case 0: // Down - JD8_BlitCKToSurface(sam->x, sam->y, this->gfx, 15, 125 + sam->frame_pejades, 15, 1, this->fondo, 255); + Jd8::blitCKToSurface(sam->x, sam->y, this->gfx, 15, 125 + sam->frame_pejades, 15, 1, this->fondo, 255); break; case 1: // Up - JD8_BlitCKToSurface(sam->x, sam->y + 15, this->gfx, 0, 125 + (14 - sam->frame_pejades), 15, 1, this->fondo, 255); + Jd8::blitCKToSurface(sam->x, sam->y + 15, this->gfx, 0, 125 + (14 - sam->frame_pejades), 15, 1, this->fondo, 255); break; case 2: // Right - JD8_BlitCKToSurface(sam->x + 7, sam->y, this->gfx, 30 + sam->frame_pejades, 125, 1, 15, this->fondo, 255); + Jd8::blitCKToSurface(sam->x + 7, sam->y, this->gfx, 30 + sam->frame_pejades, 125, 1, 15, this->fondo, 255); break; case 3: // Left - JD8_BlitCKToSurface(sam->x + 8, sam->y, this->gfx, 45 + (14 - sam->frame_pejades), 125, 1, 15, this->fondo, 255); + Jd8::blitCKToSurface(sam->x + 8, sam->y, this->gfx, 45 + (14 - sam->frame_pejades), 125, 1, 15, this->fondo, 255); break; default: break; } } - JD8_Blit(this->fondo); + Jd8::blit(this->fondo); // Pinta tombes for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { - JD8_BlitCK(35 + (x * 65), 45 + (y * 35), this->gfx, this->tombes[x + (y * 4)].x, this->tombes[x + (y * 4)].y, 50, 20, 255); + Jd8::blitCK(35 + (x * 65), 45 + (y * 35), this->gfx, this->tombes[x + (y * 4)].x, this->tombes[x + (y * 4)].y, 50, 20, 255); } } - JD8_BlitCK(45, 15, this->gfx, 30 + (this->frame_torxes * 25), 80, 25, 15, 255); - JD8_BlitCK(95, 15, this->gfx, 30 + (this->frame_torxes * 25), 80, 25, 15, 255); - JD8_BlitCK(195, 15, this->gfx, 30 + (this->frame_torxes * 25), 80, 25, 15, 255); - JD8_BlitCK(245, 15, this->gfx, 30 + (this->frame_torxes * 25), 80, 25, 15, 255); + Jd8::blitCK(45, 15, this->gfx, 30 + (this->frame_torxes * 25), 80, 25, 15, 255); + Jd8::blitCK(95, 15, this->gfx, 30 + (this->frame_torxes * 25), 80, 25, 15, 255); + Jd8::blitCK(195, 15, this->gfx, 30 + (this->frame_torxes * 25), 80, 25, 15, 255); + Jd8::blitCK(245, 15, this->gfx, 30 + (this->frame_torxes * 25), 80, 25, 15, 255); }; void Mapa::update() { @@ -92,17 +92,17 @@ auto Mapa::novaMomia() -> bool { void Mapa::preparaFondoEstatic() { // Prepara el fondo est�tic de l'habitaci� - this->fondo = JD8_NewSurface(); + this->fondo = Jd8::newSurface(); if (info::ctx.num_piramide == 6) { - JD8_BlitToSurface(9, 2, this->gfx, 227, 185, 92, 7, this->fondo); // Text "SECRETA" + Jd8::blitToSurface(9, 2, this->gfx, 227, 185, 92, 7, this->fondo); // Text "SECRETA" } else { - JD8_BlitToSurface(9, 2, this->gfx, 60, 185, 39, 7, this->fondo); // Text "NIVELL" - JD8_BlitToSurface(72, 6, this->gfx, 153, 189, 3, 1, this->fondo); // Ralleta entre num piramide i num habitacio + Jd8::blitToSurface(9, 2, this->gfx, 60, 185, 39, 7, this->fondo); // Text "NIVELL" + Jd8::blitToSurface(72, 6, this->gfx, 153, 189, 3, 1, this->fondo); // Ralleta entre num piramide i num habitacio } - JD8_BlitToSurface(130, 2, this->gfx, 225, 192, 19, 8, this->fondo); // Montonet de monedes + signe '=' - JD8_BlitToSurface(220, 2, this->gfx, 160, 185, 48, 7, this->fondo); // Text "ENERGIA" + Jd8::blitToSurface(130, 2, this->gfx, 225, 192, 19, 8, this->fondo); // Montonet de monedes + signe '=' + Jd8::blitToSurface(220, 2, this->gfx, 160, 185, 48, 7, this->fondo); // Text "ENERGIA" if (info::ctx.diners >= 200) { - JD8_BlitToSurface(175, 3, this->gfx, 60, 193, 7, 6, this->fondo); + Jd8::blitToSurface(175, 3, this->gfx, 60, 193, 7, 6, this->fondo); } // Pinta taulells @@ -110,22 +110,22 @@ void Mapa::preparaFondoEstatic() { for (int x = 0; x < 19; x++) { switch (info::ctx.num_piramide) { case 1: - JD8_BlitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 0, 80, 15, 15, this->fondo); + Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 0, 80, 15, 15, this->fondo); break; case 2: - JD8_BlitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 25, 95, 15, 15, this->fondo); + Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 25, 95, 15, 15, this->fondo); break; case 3: - JD8_BlitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 40, 95, 15, 15, this->fondo); + Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 40, 95, 15, 15, this->fondo); break; case 4: - JD8_BlitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 175 + ((rand() % 3) * 15), 80, 15, 15, this->fondo); + Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 175 + ((rand() % 3) * 15), 80, 15, 15, this->fondo); break; case 5: - JD8_BlitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 130, 80, 15, 15, this->fondo); + Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 130, 80, 15, 15, this->fondo); break; case 6: - JD8_BlitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 145, 80, 15, 15, this->fondo); + Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 145, 80, 15, 15, this->fondo); break; default: break; @@ -134,28 +134,28 @@ void Mapa::preparaFondoEstatic() { } // Pinta vores de les parets - JD8_BlitCKToSurface(5, 15, this->gfx, 30, 110, 15, 15, this->fondo, 255); - JD8_BlitCKToSurface(295, 15, this->gfx, 45, 110, 15, 15, this->fondo, 255); - JD8_BlitCKToSurface(5, 180, this->gfx, 0, 155, 15, 20, this->fondo, 255); - JD8_BlitCKToSurface(295, 180, this->gfx, 15, 155, 15, 20, this->fondo, 255); + Jd8::blitCKToSurface(5, 15, this->gfx, 30, 110, 15, 15, this->fondo, 255); + Jd8::blitCKToSurface(295, 15, this->gfx, 45, 110, 15, 15, this->fondo, 255); + Jd8::blitCKToSurface(5, 180, this->gfx, 0, 155, 15, 20, this->fondo, 255); + Jd8::blitCKToSurface(295, 180, this->gfx, 15, 155, 15, 20, this->fondo, 255); // Pinta parets verticals for (int i = 0; i < 10; i++) { - JD8_BlitToSurface(5, 30 + (i * 15), this->gfx, 0, 110, 15, 15, this->fondo); - JD8_BlitToSurface(295, 30 + (i * 15), this->gfx, 15, 110, 15, 15, this->fondo); + Jd8::blitToSurface(5, 30 + (i * 15), this->gfx, 0, 110, 15, 15, this->fondo); + Jd8::blitToSurface(295, 30 + (i * 15), this->gfx, 15, 110, 15, 15, this->fondo); } // Pinta parets hortzintals for (int i = 0; i < 11; i++) { - JD8_BlitToSurface(20 + (i * 25), 185, this->gfx, 0, 95, 25, 15, this->fondo); - JD8_BlitToSurface(20 + (i * 25), 15, this->gfx, 0, 95, 25, 15, this->fondo); + Jd8::blitToSurface(20 + (i * 25), 185, this->gfx, 0, 95, 25, 15, this->fondo); + Jd8::blitToSurface(20 + (i * 25), 15, this->gfx, 0, 95, 25, 15, this->fondo); } // Pinta la porta - JD8_BlitCKToSurface(150, 18, this->gfx, 0, 143, 15, 12, this->fondo, 255); + Jd8::blitCKToSurface(150, 18, this->gfx, 0, 143, 15, 12, this->fondo, 255); if (info::ctx.num_piramide == 2) { - JD8_BlitToSurface(5, 100, this->gfx, 30, 140, 15, 15, this->fondo); + Jd8::blitToSurface(5, 100, this->gfx, 30, 140, 15, 15, this->fondo); } } @@ -296,7 +296,7 @@ void Mapa::comprovaCaixa(Uint8 num) { void Mapa::comprovaPorta() { if (this->clau && this->farao) { - JD8_BlitCKToSurface(150, 18, this->gfx, 15, 143, 15, 12, this->fondo, 255); + Jd8::blitCKToSurface(150, 18, this->gfx, 15, 143, 15, 12, this->fondo, 255); porta_oberta = true; } } diff --git a/source/game/mapa.hpp b/source/game/mapa.hpp index cfd1954..7031e6a 100644 --- a/source/game/mapa.hpp +++ b/source/game/mapa.hpp @@ -31,7 +31,7 @@ struct Vertex { class Mapa { public: - explicit Mapa(JD8_Surface gfx, Prota* sam); + explicit Mapa(Jd8::Surface gfx, Prota* sam); ~Mapa(); Mapa(const Mapa&) = delete; @@ -53,8 +53,8 @@ class Mapa { void comprovaUltimCami(); void comprovaPorta(); - JD8_Surface gfx; - JD8_Surface fondo; + Jd8::Surface gfx; + Jd8::Surface fondo; Vertex vertex; Vertex ultim_vertex; Uint8 frame_torxes; diff --git a/source/game/marcador.cpp b/source/game/marcador.cpp index 9192480..624d6fe 100644 --- a/source/game/marcador.cpp +++ b/source/game/marcador.cpp @@ -1,6 +1,6 @@ #include "game/marcador.hpp" -Marcador::Marcador(JD8_Surface gfx, Prota* sam) { +Marcador::Marcador(Jd8::Surface gfx, Prota* sam) { this->gfx = gfx; this->sam = sam; } @@ -16,46 +16,46 @@ void Marcador::draw() { this->pintaNumero(163, 2, info::ctx.diners % 10); if (this->sam->pergami) { - JD8_BlitCK(190, 1, this->gfx, 209, 185, 15, 14, 255); + Jd8::blitCK(190, 1, this->gfx, 209, 185, 15, 14, 255); } - JD8_BlitCK(271, 1, this->gfx, 0, 20, 15, info::ctx.vida * 3, 255); + Jd8::blitCK(271, 1, this->gfx, 0, 20, 15, info::ctx.vida * 3, 255); if (info::ctx.vida < 5) { - JD8_BlitCK(271, 1 + (info::ctx.vida * 3), this->gfx, 75, 20, 15, 15 - (info::ctx.vida * 3), 255); + Jd8::blitCK(271, 1 + (info::ctx.vida * 3), this->gfx, 75, 20, 15, 15 - (info::ctx.vida * 3), 255); } } void Marcador::pintaNumero(Uint16 x, Uint16 y, Uint8 num) { switch (num) { case 0: - JD8_BlitCK(x, y, this->gfx, 141, 193, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx, 141, 193, 10, 7, 255); break; case 1: - JD8_BlitCK(x, y, this->gfx, 100, 185, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx, 100, 185, 10, 7, 255); break; case 2: - JD8_BlitCK(x, y, this->gfx, 110, 185, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx, 110, 185, 10, 7, 255); break; case 3: - JD8_BlitCK(x, y, this->gfx, 120, 185, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx, 120, 185, 10, 7, 255); break; case 4: - JD8_BlitCK(x, y, this->gfx, 130, 185, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx, 130, 185, 10, 7, 255); break; case 5: - JD8_BlitCK(x, y, this->gfx, 140, 185, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx, 140, 185, 10, 7, 255); break; case 6: - JD8_BlitCK(x, y, this->gfx, 101, 193, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx, 101, 193, 10, 7, 255); break; case 7: - JD8_BlitCK(x, y, this->gfx, 111, 193, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx, 111, 193, 10, 7, 255); break; case 8: - JD8_BlitCK(x, y, this->gfx, 121, 193, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx, 121, 193, 10, 7, 255); break; case 9: - JD8_BlitCK(x, y, this->gfx, 131, 193, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx, 131, 193, 10, 7, 255); break; default: break; diff --git a/source/game/marcador.hpp b/source/game/marcador.hpp index af3ebd1..bbb45a1 100644 --- a/source/game/marcador.hpp +++ b/source/game/marcador.hpp @@ -6,7 +6,7 @@ class Marcador { public: - explicit Marcador(JD8_Surface gfx, Prota* sam); + explicit Marcador(Jd8::Surface gfx, Prota* sam); ~Marcador() = default; void draw(); @@ -14,6 +14,6 @@ class Marcador { protected: void pintaNumero(Uint16 x, Uint16 y, Uint8 num); - JD8_Surface gfx; + Jd8::Surface gfx; Prota* sam; }; diff --git a/source/game/modulegame.cpp b/source/game/modulegame.cpp index 9e60d35..a7ef235 100644 --- a/source/game/modulegame.cpp +++ b/source/game/modulegame.cpp @@ -8,7 +8,7 @@ #include "core/jail/jinput.hpp" ModuleGame::ModuleGame() { - this->gfx = JD8_LoadSurface(info::ctx.pepe_activat ? "gfx/frames2.gif" : "gfx/frames.gif"); + this->gfx = Jd8::loadSurface(info::ctx.pepe_activat ? "gfx/frames2.gif" : "gfx/frames.gif"); JG_SetUpdateTicks(10); this->sam = std::make_unique(this->gfx); @@ -22,7 +22,7 @@ ModuleGame::ModuleGame() { } ModuleGame::~ModuleGame() { - JD8_FreeSurface(this->gfx); + Jd8::freeSurface(this->gfx); } void ModuleGame::onEnter() { @@ -47,7 +47,7 @@ void ModuleGame::onEnter() { // Arranca el fade-in tick-based. El `PaletteFade` avança un pas (de // 32) per cada tick; durant aquesta fase el gameplay no corre, // només Draw+fade. Substituïx la crida bloquejant `JD8_FadeToPal`. - fade_.startFadeTo(JD8_LoadPalette(info::ctx.pepe_activat ? "gfx/frames2.gif" : "gfx/frames.gif")); + fade_.startFadeTo(Jd8::loadPalette(info::ctx.pepe_activat ? "gfx/frames2.gif" : "gfx/frames.gif")); phase_ = Phase::FadingIn; } @@ -55,7 +55,7 @@ void ModuleGame::tick(int delta_ms) { switch (phase_) { case Phase::FadingIn: // No redibuixem durant el fade: el `screen` ja va ser omplit - // per la Draw() d'onEnter. Només el JD8_Flip del caller muta + // per la Draw() d'onEnter. Només el Jd8::flip del caller muta // pixel_data segons la paleta que avança pas a pas. fade_.tick(delta_ms); if (fade_.done()) { @@ -119,7 +119,7 @@ void ModuleGame::applyFinalTransitions() const { } void ModuleGame::Draw() { - // No crida JD8_Flip — el caller (mini-loop del fiber, o Director a + // No crida Jd8::flip — el caller (mini-loop del fiber, o Director a // Phase B.2) ho fa després de cada tick. this->mapa->draw(); this->marcador->draw(); diff --git a/source/game/modulegame.hpp b/source/game/modulegame.hpp index 6decefd..3ed6b88 100644 --- a/source/game/modulegame.hpp +++ b/source/game/modulegame.hpp @@ -50,7 +50,7 @@ class ModuleGame : public scenes::Scene { Done, }; - void Draw(); // render a `screen`; no crida JD8_Flip (ho fa el caller) + void Draw(); // render a `screen`; no crida Jd8::flip (ho fa el caller) void Update(); // gated per JG_ShouldUpdate void iniciarMomies(); @@ -59,7 +59,7 @@ class ModuleGame : public scenes::Scene { Phase phase_{Phase::FadingIn}; scenes::PaletteFade fade_; Uint8 final_{0}; - JD8_Surface gfx{nullptr}; + Jd8::Surface gfx{nullptr}; std::unique_ptr mapa; std::unique_ptr sam; diff --git a/source/game/momia.cpp b/source/game/momia.cpp index a7e0396..362449a 100644 --- a/source/game/momia.cpp +++ b/source/game/momia.cpp @@ -4,7 +4,7 @@ #include "core/jail/jgame.hpp" -Momia::Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam) +Momia::Momia(Jd8::Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam) : Sprite(gfx) { this->dimoni = dimoni; this->sam = sam; @@ -75,9 +75,9 @@ void Momia::draw() { if (info::ctx.num_piramide == 4) { if ((JG_GetCycleCounter() % 40) < 20) { - JD8_BlitCK(this->x, this->y, this->gfx, 220, 80, 15, 15, 255); + Jd8::blitCK(this->x, this->y, this->gfx, 220, 80, 15, 15, 255); } else { - JD8_BlitCK(this->x, this->y, this->gfx, 235, 80, 15, 15, 255); + Jd8::blitCK(this->x, this->y, this->gfx, 235, 80, 15, 15, 255); } } } diff --git a/source/game/momia.hpp b/source/game/momia.hpp index 5c0ef27..9c91954 100644 --- a/source/game/momia.hpp +++ b/source/game/momia.hpp @@ -9,7 +9,7 @@ class Momia : public Sprite { public: - explicit Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam); + explicit Momia(Jd8::Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam); void draw() override; auto update() -> bool; diff --git a/source/game/prota.cpp b/source/game/prota.cpp index 38a942c..c81c29a 100644 --- a/source/game/prota.cpp +++ b/source/game/prota.cpp @@ -5,7 +5,7 @@ #include "core/jail/jgame.hpp" #include "core/jail/jinput.hpp" -Prota::Prota(JD8_Surface gfx) +Prota::Prota(Jd8::Surface gfx) : Sprite(gfx) { entitat.frames.reserve(82); @@ -92,9 +92,9 @@ void Prota::draw() { if (info::ctx.num_piramide == 4 && this->o != 4) { if ((JG_GetCycleCounter() % 40) < 20) { - JD8_BlitCK(this->x, this->y, this->gfx, 220, 80, 15, 15, 255); + Jd8::blitCK(this->x, this->y, this->gfx, 220, 80, 15, 15, 255); } else { - JD8_BlitCK(this->x, this->y, this->gfx, 235, 80, 15, 15, 255); + Jd8::blitCK(this->x, this->y, this->gfx, 235, 80, 15, 15, 255); } } } diff --git a/source/game/prota.hpp b/source/game/prota.hpp index 7b75738..8358c85 100644 --- a/source/game/prota.hpp +++ b/source/game/prota.hpp @@ -5,7 +5,7 @@ class Prota : public Sprite { public: - explicit Prota(JD8_Surface gfx); + explicit Prota(Jd8::Surface gfx); void draw() override; auto update() -> Uint8; diff --git a/source/game/scenes/banner_scene.cpp b/source/game/scenes/banner_scene.cpp index aed8539..96d8022 100644 --- a/source/game/scenes/banner_scene.cpp +++ b/source/game/scenes/banner_scene.cpp @@ -15,10 +15,10 @@ namespace scenes { gfx_ = SurfaceHandle("gfx/ffase.gif"); - JD8_ClearScreen(0); + Jd8::clearScreen(0); // Títols superior i inferior del banner (compartits per tots els nivells) - JD8_Blit(81, 24, gfx_, 81, 155, 168, 21); - JD8_Blit(39, 150, gfx_, 39, 175, 248, 20); + Jd8::blit(81, 24, gfx_, 81, 155, 168, 21); + Jd8::blit(39, 150, gfx_, 39, 175, 248, 20); // Número de piràmide: les 4 variants del vell `doBanner` es reduïxen // a coordenades (sx,sy) calculades a partir de l'índex 0..3. @@ -26,11 +26,11 @@ namespace scenes { if (idx >= 0 && idx <= 3) { const int sx = (idx % 2) * 160; const int sy = (idx / 2) * 75; - JD8_Blit(82, 60, gfx_, sx, sy, 160, 75); + Jd8::blit(82, 60, gfx_, sx, sy, 160, 75); } // PaletteFade copia internament amb memcpy; alliberem la paleta temporal. - JD8_Palette pal = JD8_LoadPalette("gfx/ffase.gif"); + Jd8::Palette pal = Jd8::loadPalette("gfx/ffase.gif"); fade_.startFadeTo(pal); delete[] pal; diff --git a/source/game/scenes/boot_loader_scene.cpp b/source/game/scenes/boot_loader_scene.cpp index c24f62b..7d55756 100644 --- a/source/game/scenes/boot_loader_scene.cpp +++ b/source/game/scenes/boot_loader_scene.cpp @@ -24,8 +24,8 @@ namespace scenes { // Inicialitza la paleta mínima per a la barra. La resta de // colors queden a negre — després cada escena del joc carregarà // la seua pròpia paleta. - JD8_SetPaletteColor(BG_COLOR, 0, 0, 0); - JD8_SetPaletteColor(BAR_COLOR, 63, 63, 63); + Jd8::setPaletteColor(BG_COLOR, 0, 0, 0); + Jd8::setPaletteColor(BAR_COLOR, 63, 63, 63); } void BootLoaderScene::tick(int /*delta_ms*/) { @@ -36,7 +36,7 @@ namespace scenes { } void BootLoaderScene::render() { - JD8_ClearScreen(BG_COLOR); + Jd8::clearScreen(BG_COLOR); if (!Options::game.show_preload) { return; @@ -46,14 +46,14 @@ namespace scenes { const int filled = static_cast(static_cast(BAR_W) * pct); // Vora de la barra (línia 1 píxel a dalt i a baix). - JD8_FillRect(BAR_X - 1, BAR_Y - 1, BAR_W + 2, 1, BAR_COLOR); - JD8_FillRect(BAR_X - 1, BAR_Y + BAR_H, BAR_W + 2, 1, BAR_COLOR); - JD8_FillRect(BAR_X - 1, BAR_Y, 1, BAR_H, BAR_COLOR); - JD8_FillRect(BAR_X + BAR_W, BAR_Y, 1, BAR_H, BAR_COLOR); + Jd8::fillRect(BAR_X - 1, BAR_Y - 1, BAR_W + 2, 1, BAR_COLOR); + Jd8::fillRect(BAR_X - 1, BAR_Y + BAR_H, BAR_W + 2, 1, BAR_COLOR); + Jd8::fillRect(BAR_X - 1, BAR_Y, 1, BAR_H, BAR_COLOR); + Jd8::fillRect(BAR_X + BAR_W, BAR_Y, 1, BAR_H, BAR_COLOR); // Ompliment proporcional al progrés. if (filled > 0) { - JD8_FillRect(BAR_X, BAR_Y, filled, BAR_H, BAR_COLOR); + Jd8::fillRect(BAR_X, BAR_Y, filled, BAR_H, BAR_COLOR); } } diff --git a/source/game/scenes/credits_scene.cpp b/source/game/scenes/credits_scene.cpp index b0084ce..fadc824 100644 --- a/source/game/scenes/credits_scene.cpp +++ b/source/game/scenes/credits_scene.cpp @@ -52,8 +52,8 @@ namespace scenes { vaddr2_ = SurfaceHandle("gfx/final.gif"); vaddr3_ = SurfaceHandle("gfx/finals.gif"); - JD8_Palette pal = JD8_LoadPalette("gfx/final.gif"); - JD8_SetScreenPalette(pal); + Jd8::Palette pal = Jd8::loadPalette("gfx/final.gif"); + Jd8::setScreenPalette(pal); // `pal` passa a ser propietat de main_palette — no l'alliberem. phase_ = Phase::Rolling; @@ -62,40 +62,40 @@ namespace scenes { } void CreditsScene::render() { - JD8_ClearScreen(BG_INDEX); + Jd8::clearScreen(BG_INDEX); // Columna 1: scroll vertical del bloc (0,0,80,200) pujant des de // y=200 fins que el contador supera 2750. if (contador_ < 2750) { - JD8_BlitCKCut(115, 200 - (contador_ / 6), vaddr2_, 0, 0, 80, 200, 0); + Jd8::blitCKCut(115, 200 - (contador_ / 6), vaddr2_, 0, 0, 80, 200, 0); } // Columna 2: scroll vertical del bloc (85,0,120,140), arrenca // a contador 1200 i s'atura (fix en y=20) a partir de 2250. if ((contador_ > 1200) && (contador_ < 2280)) { - JD8_BlitCKCut(100, 200 - ((contador_ - 1200) / 6), vaddr2_, 85, 0, 120, 140, 0); + Jd8::blitCKCut(100, 200 - ((contador_ - 1200) / 6), vaddr2_, 85, 0, 120, 140, 0); } else if (contador_ >= 2250) { - JD8_BlitCK(100, 20, vaddr2_, 85, 0, 120, 140, 0); + Jd8::blitCK(100, 20, vaddr2_, 85, 0, 120, 140, 0); } // Fons: 4 capes parallax + cotxe només si l'usuari ha aconseguit // tots els diamants (final "bo"). Altrament fons estàtic. if (info::ctx.diamants == 16) { - JD8_BlitCKScroll(50, vaddr3_, ((contador_ >> 3) % 320) + 1, 0, 50, 255); - JD8_BlitCKScroll(50, vaddr3_, ((contador_ >> 2) % 320) + 1, 50, 50, 255); - JD8_BlitCKScroll(50, vaddr3_, ((contador_ >> 1) % 320) + 1, 100, 50, 255); - JD8_BlitCKScroll(50, vaddr3_, (contador_ % 320) + 1, 150, 50, 255); + Jd8::blitCKScroll(50, vaddr3_, ((contador_ >> 3) % 320) + 1, 0, 50, 255); + Jd8::blitCKScroll(50, vaddr3_, ((contador_ >> 2) % 320) + 1, 50, 50, 255); + Jd8::blitCKScroll(50, vaddr3_, ((contador_ >> 1) % 320) + 1, 100, 50, 255); + Jd8::blitCKScroll(50, vaddr3_, (contador_ % 320) + 1, 150, 50, 255); const CocheFrame& cf = COCHE_FRAMES[coche_.frame()]; - JD8_BlitCK(100, 50, vaddr2_, cf.x, cf.y, 106, 48, 255); + Jd8::blitCK(100, 50, vaddr2_, cf.x, cf.y, 106, 48, 255); } else { - JD8_BlitCK(0, 50, vaddr3_, 0, 0, 320, 50, 255); - JD8_BlitCK(0, 50, vaddr3_, 0, 50, 320, 50, 255); + Jd8::blitCK(0, 50, vaddr3_, 0, 0, 320, 50, 255); + Jd8::blitCK(0, 50, vaddr3_, 0, 50, 320, 50, 255); } // Barres de marc que cobreixen els extrems del scroll vertical. - JD8_FillSquare(0, 50, BG_INDEX); - JD8_FillSquare(100, 10, BG_INDEX); + Jd8::fillSquare(0, 50, BG_INDEX); + Jd8::fillSquare(100, 10, BG_INDEX); } void CreditsScene::writeTrickIni() { diff --git a/source/game/scenes/intro_new_logo_scene.cpp b/source/game/scenes/intro_new_logo_scene.cpp index 8853695..745fc67 100644 --- a/source/game/scenes/intro_new_logo_scene.cpp +++ b/source/game/scenes/intro_new_logo_scene.cpp @@ -41,7 +41,7 @@ namespace scenes { IntroNewLogoScene::IntroNewLogoScene() = default; - // No alliberem `pal_`: JD8_SetScreenPalette n'ha pres ownership i el + // No alliberem `pal_`: Jd8::setScreenPalette n'ha pres ownership i el // proper SetScreenPalette / FadeToPal el lliurarà. Alliberar-lo ací // provocaria double free. IntroNewLogoScene::~IntroNewLogoScene() = default; @@ -50,15 +50,15 @@ namespace scenes { playMusic("music/menu.ogg"); gfx_ = SurfaceHandle("gfx/logo_new.gif"); - pal_ = JD8_LoadPalette("gfx/logo_new.gif"); - JD8_SetScreenPalette(pal_); + pal_ = Jd8::loadPalette("gfx/logo_new.gif"); + Jd8::setScreenPalette(pal_); // Surface auxiliar omplida amb el color del cursor — permet pintar // el "subratllat" amb un blit normal. - cursor_surf_.adopt(JD8_NewSurface()); + cursor_surf_.adopt(Jd8::newSurface()); std::memset(cursor_surf_.get(), CURSOR_COLOR, 64000); - JD8_ClearScreen(0); + Jd8::clearScreen(0); phase_ = Phase::Initial; phase_acc_ms_ = 0; @@ -70,30 +70,30 @@ namespace scenes { void IntroNewLogoScene::render() { switch (phase_) { case Phase::Initial: - JD8_ClearScreen(0); + Jd8::clearScreen(0); break; case Phase::Revealing: { - JD8_ClearScreen(0); - JD8_Blit(LOGO_DST_X, LOGO_DST_Y, gfx_, LOGO_SRC_X, LOGO_SRC_Y, LETTER_WIDTHS[reveal_letter_], LOGO_HEIGHT); + Jd8::clearScreen(0); + Jd8::blit(LOGO_DST_X, LOGO_DST_Y, gfx_, LOGO_SRC_X, LOGO_SRC_Y, LETTER_WIDTHS[reveal_letter_], LOGO_HEIGHT); if (reveal_cursor_visible_) { - JD8_Blit(CURSOR_X[reveal_letter_], CURSOR_Y, cursor_surf_, 0, 0, CURSOR_W, CURSOR_H); + Jd8::blit(CURSOR_X[reveal_letter_], CURSOR_Y, cursor_surf_, 0, 0, CURSOR_W, CURSOR_H); } break; } case Phase::FullLogoFlash: - JD8_ClearScreen(0); - JD8_Blit(LOGO_DST_X, LOGO_DST_Y, gfx_, LOGO_SRC_X, LOGO_SRC_Y, LETTER_WIDTHS[8], LOGO_HEIGHT); - JD8_Blit(CURSOR_X[8], CURSOR_Y, cursor_surf_, 0, 0, CURSOR_W, CURSOR_H); + Jd8::clearScreen(0); + Jd8::blit(LOGO_DST_X, LOGO_DST_Y, gfx_, LOGO_SRC_X, LOGO_SRC_Y, LETTER_WIDTHS[8], LOGO_HEIGHT); + Jd8::blit(CURSOR_X[8], CURSOR_Y, cursor_surf_, 0, 0, CURSOR_W, CURSOR_H); break; case Phase::PaletteCycle: case Phase::FinalWait: // Logo complet sense cursor — els pixels del cursor // ciclarien de color durant el cicle de paleta. - JD8_ClearScreen(0); - JD8_Blit(LOGO_DST_X, LOGO_DST_Y, gfx_, LOGO_SRC_X, LOGO_SRC_Y, LETTER_WIDTHS[8], LOGO_HEIGHT); + Jd8::clearScreen(0); + Jd8::blit(LOGO_DST_X, LOGO_DST_Y, gfx_, LOGO_SRC_X, LOGO_SRC_Y, LETTER_WIDTHS[8], LOGO_HEIGHT); break; case Phase::Sprites: diff --git a/source/game/scenes/intro_new_logo_scene.hpp b/source/game/scenes/intro_new_logo_scene.hpp index 4eb7441..e572025 100644 --- a/source/game/scenes/intro_new_logo_scene.hpp +++ b/source/game/scenes/intro_new_logo_scene.hpp @@ -55,7 +55,7 @@ namespace scenes { SurfaceHandle gfx_; SurfaceHandle cursor_surf_; - JD8_Palette pal_{nullptr}; // propietat transferida a main_palette via SetScreenPalette + Jd8::Palette pal_{nullptr}; // propietat transferida a main_palette via SetScreenPalette std::unique_ptr sprites_scene_; Phase phase_{Phase::Initial}; diff --git a/source/game/scenes/intro_scene.cpp b/source/game/scenes/intro_scene.cpp index 66122ef..488c75f 100644 --- a/source/game/scenes/intro_scene.cpp +++ b/source/game/scenes/intro_scene.cpp @@ -50,7 +50,7 @@ namespace { // IntroScene només s'activa quan use_new_logo == false, així que la // branca use_new_logo d'aquell helper aquí no es necessita. void drawWordmark(const Uint8* gfx) { - JD8_Blit(43, 78, gfx, 43, 155, 231, 45); + Jd8::blit(43, 78, gfx, 43, 155, 231, 45); } } // namespace @@ -59,7 +59,7 @@ namespace scenes { IntroScene::IntroScene() = default; - // No alliberem `pal_`: JD8_SetScreenPalette n'ha pres ownership i el + // No alliberem `pal_`: Jd8::setScreenPalette n'ha pres ownership i el // proper SetScreenPalette / FadeToPal la lliurarà. Alliberar-la ací // provocaria double free. IntroScene::~IntroScene() = default; @@ -68,10 +68,10 @@ namespace scenes { playMusic("music/menu.ogg"); gfx_ = SurfaceHandle("gfx/logo.gif"); - pal_ = JD8_LoadPalette("gfx/logo.gif"); - JD8_SetScreenPalette(pal_); + pal_ = Jd8::loadPalette("gfx/logo.gif"); + Jd8::setScreenPalette(pal_); - JD8_ClearScreen(0); + Jd8::clearScreen(0); phase_ = Phase::InitialWait; phase_acc_ms_ = 0; @@ -82,21 +82,21 @@ namespace scenes { void IntroScene::render() { switch (phase_) { case Phase::InitialWait: - JD8_ClearScreen(0); + Jd8::clearScreen(0); break; case Phase::Reveal: { const RevealStep& s = REVEAL_STEPS[reveal_index_]; if (s.clear) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); } if (s.wordmark) { drawWordmark(gfx_); } else if (s.body_w > 0) { - JD8_Blit(43, 78, gfx_, 43, 155, s.body_w, 45); + Jd8::blit(43, 78, gfx_, 43, 155, s.body_w, 45); } if (s.plane_x >= 0) { - JD8_Blit(s.plane_x, 78, gfx_, 274, 155, 27, 45); + Jd8::blit(s.plane_x, 78, gfx_, 274, 155, 27, 45); } break; } @@ -106,7 +106,7 @@ namespace scenes { // Wordmark complet fix mentre cicla la paleta — l'últim // pas del revelat (PAS 15) deixa la pantalla en aquest mateix // estat, i el vell doIntro no redibuixava durant el cicle. - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx_); break; diff --git a/source/game/scenes/intro_scene.hpp b/source/game/scenes/intro_scene.hpp index c78ef9b..a8813a6 100644 --- a/source/game/scenes/intro_scene.hpp +++ b/source/game/scenes/intro_scene.hpp @@ -54,7 +54,7 @@ namespace scenes { void advancePaletteCycle(); SurfaceHandle gfx_; - JD8_Palette pal_{nullptr}; // propietat transferida a main_palette via SetScreenPalette + Jd8::Palette pal_{nullptr}; // propietat transferida a main_palette via SetScreenPalette std::unique_ptr sprites_scene_; Phase phase_{Phase::InitialWait}; diff --git a/source/game/scenes/intro_sprites_scene.cpp b/source/game/scenes/intro_sprites_scene.cpp index 2fc0df9..5d045b6 100644 --- a/source/game/scenes/intro_sprites_scene.cpp +++ b/source/game/scenes/intro_sprites_scene.cpp @@ -55,9 +55,9 @@ namespace { void drawWordmark(const Uint8* gfx) { if (Options::game.use_new_logo) { // Centrat: (320 − 188) / 2 = 66 (IntroNewLogoScene usa la mateixa x). - JD8_Blit(66, 78, gfx, 60, 158, 188, 28); + Jd8::blit(66, 78, gfx, 60, 158, 188, 28); } else { - JD8_Blit(43, 78, gfx, 43, 155, 231, 45); + Jd8::blit(43, 78, gfx, 43, 155, 231, 45); } } @@ -79,70 +79,70 @@ namespace { // ========================================================================= void v0_walk_right(const Uint8* gfx, int i) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(i, 150, gfx, fr1[(i / 5) % 13], 0, 15, 15, 0); + Jd8::blitCK(i, 150, gfx, fr1[(i / 5) % 13], 0, 15, 15, 0); } void v0_pull_map_right(const Uint8* gfx, int i) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(200, 150, gfx, fr3[std::min(i / 5, 10)], 30, 15, 15, 0); + Jd8::blitCK(200, 150, gfx, fr3[std::min(i / 5, 10)], 30, 15, 15, 0); } void v0_walk_left_to_80(const Uint8* gfx, int i) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(i, 150, gfx, fr2[(i / 5) % 13], 15, 15, 15, 0); + Jd8::blitCK(i, 150, gfx, fr2[(i / 5) % 13], 15, 15, 15, 0); } void v0_pull_map_left(const Uint8* gfx, int i) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(80, 150, gfx, fr4[std::min(i / 5, 10)], 45, 15, 15, 0); + Jd8::blitCK(80, 150, gfx, fr4[std::min(i / 5, 10)], 45, 15, 15, 0); } void v0_momia_left(const Uint8* gfx, int i) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(i, 150, gfx, fr6[(i / 5) % 8], 60, 15, 15, 0); - JD8_BlitCK(80, 150, gfx, fr4[10], 45, 15, 15, 0); + Jd8::blitCK(i, 150, gfx, fr6[(i / 5) % 8], 60, 15, 15, 0); + Jd8::blitCK(80, 150, gfx, fr4[10], 45, 15, 15, 0); } void v0_turn(const Uint8* gfx, int /*i*/) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(80, 150, gfx, fr1[1], 0, 15, 15, 0); - JD8_BlitCK(95, 150, gfx, fr6[4], 60, 15, 15, 0); - JD8_BlitCK(80, 133, gfx, 0, INTERROGANT, 15, 15, 0); + Jd8::blitCK(80, 150, gfx, fr1[1], 0, 15, 15, 0); + Jd8::blitCK(95, 150, gfx, fr6[4], 60, 15, 15, 0); + Jd8::blitCK(80, 133, gfx, 0, INTERROGANT, 15, 15, 0); } void v0_jump1(const Uint8* gfx, int i) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(80, 150 - ((i % 50) / 5), gfx, fr5[std::min(i / 5, 19)], 45, 15, 15, 0); - JD8_BlitCK(95, 150, gfx, fr6[4], 60, 15, 15, 0); + Jd8::blitCK(80, 150 - ((i % 50) / 5), gfx, fr5[std::min(i / 5, 19)], 45, 15, 15, 0); + Jd8::blitCK(95, 150, gfx, fr6[4], 60, 15, 15, 0); } void v0_jump2(const Uint8* gfx, int i) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(80, 140 + ((i % 50) / 5), gfx, fr5[std::min(i / 5, 19)], 45, 15, 15, 0); - JD8_BlitCK(95, 150, gfx, fr6[4], 60, 15, 15, 0); + Jd8::blitCK(80, 140 + ((i % 50) / 5), gfx, fr5[std::min(i / 5, 19)], 45, 15, 15, 0); + Jd8::blitCK(95, 150, gfx, fr6[4], 60, 15, 15, 0); } void v0_walk_final(const Uint8* gfx, int i) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(i, 150, gfx, fr2[(i / 5) % 13], 15, 15, 15, 0); - JD8_BlitCK(95, 150, gfx, fr6[4], 60, 15, 15, 0); + Jd8::blitCK(i, 150, gfx, fr2[(i / 5) % 13], 15, 15, 15, 0); + Jd8::blitCK(95, 150, gfx, fr6[4], 60, 15, 15, 0); } void v0_final(const Uint8* gfx, int /*i*/) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(95, 150, gfx, fr6[4], 60, 15, 15, 0); - JD8_BlitCK(95, 133, gfx, 0, INTERROGANT, 15, 15, 0); + Jd8::blitCK(95, 150, gfx, fr6[4], 60, 15, 15, 0); + Jd8::blitCK(95, 133, gfx, 0, INTERROGANT, 15, 15, 0); } constexpr SpritePhase variant_0[] = { @@ -164,63 +164,63 @@ namespace { // ========================================================================= void v1_walk_right(const Uint8* gfx, int i) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(200, 155, gfx, 0, CREU, 15, 15, 255); - JD8_BlitCK(i, 150, gfx, fr1[(i / 5) % 13], 0, 15, 15, 255); + Jd8::blitCK(200, 155, gfx, 0, CREU, 15, 15, 255); + Jd8::blitCK(i, 150, gfx, fr1[(i / 5) % 13], 0, 15, 15, 255); } void v1_pull_map(const Uint8* gfx, int i) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(200, 155, gfx, 0, CREU, 15, 15, 255); - JD8_BlitCK(200, 150, gfx, fr3[std::min(i / 5, 10)], 30, 15, 15, 255); + Jd8::blitCK(200, 155, gfx, 0, CREU, 15, 15, 255); + Jd8::blitCK(200, 150, gfx, fr3[std::min(i / 5, 10)], 30, 15, 15, 255); } void v1_interrogant(const Uint8* gfx, int /*i*/) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(200, 155, gfx, 0, CREU, 15, 15, 255); - JD8_BlitCK(200, 134, gfx, 0, INTERROGANT, 15, 15, 255); - JD8_BlitCK(200, 150, gfx, fr3[10], 30, 15, 15, 255); + Jd8::blitCK(200, 155, gfx, 0, CREU, 15, 15, 255); + Jd8::blitCK(200, 134, gfx, 0, INTERROGANT, 15, 15, 255); + Jd8::blitCK(200, 150, gfx, fr3[10], 30, 15, 15, 255); } void v1_drop_map(const Uint8* gfx, int i) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(200, 155, gfx, 0, CREU, 15, 15, 255); + Jd8::blitCK(200, 155, gfx, 0, CREU, 15, 15, 255); const int idx = std::min(i / 5, 28); // fr7 té 29 frames dividits en dos grups: paper (idx 0..13, src_y=75) // i sombra (idx 14..28, src_y=105). El vell feia una branca al bucle. if (idx <= 13) { - JD8_BlitCK(200, 150, gfx, fr7[idx], 75, 15, 15, 255); + Jd8::blitCK(200, 150, gfx, fr7[idx], 75, 15, 15, 255); } else { - JD8_BlitCK(200, 150, gfx, fr7[idx], 105, 15, 15, 255); + Jd8::blitCK(200, 150, gfx, fr7[idx], 105, 15, 15, 255); } } void v1_stone_fall(const Uint8* gfx, int i) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(200, 155, gfx, 0, CREU, 15, 15, 255); - JD8_BlitCK(200, 150, gfx, fr7[28], 105, 15, 15, 255); - JD8_BlitCK(200, i * 2, gfx, fr8[0], 75, 15, 15, 255); + Jd8::blitCK(200, 155, gfx, 0, CREU, 15, 15, 255); + Jd8::blitCK(200, 150, gfx, fr7[28], 105, 15, 15, 255); + Jd8::blitCK(200, i * 2, gfx, fr8[0], 75, 15, 15, 255); } void v1_stone_break(const Uint8* gfx, int i) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(200, 155, gfx, 0, CREU, 15, 15, 255); - JD8_BlitCK(200, 150, gfx, fr8[i / 10], 75, 15, 15, 255); + Jd8::blitCK(200, 155, gfx, 0, CREU, 15, 15, 255); + Jd8::blitCK(200, 150, gfx, fr8[i / 10], 75, 15, 15, 255); } void v1_final(const Uint8* gfx, int /*i*/) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(200, 155, gfx, 0, CREU, 15, 15, 255); - JD8_BlitCK(200, 150, gfx, fr8[1], 75, 15, 15, 255); - JD8_BlitCK(185, 150, gfx, fr8[2], 75, 15, 15, 255); - JD8_BlitCK(215, 150, gfx, fr8[3], 75, 15, 15, 255); + Jd8::blitCK(200, 155, gfx, 0, CREU, 15, 15, 255); + Jd8::blitCK(200, 150, gfx, fr8[1], 75, 15, 15, 255); + Jd8::blitCK(185, 150, gfx, fr8[2], 75, 15, 15, 255); + Jd8::blitCK(215, 150, gfx, fr8[3], 75, 15, 15, 255); } constexpr SpritePhase variant_1[] = { @@ -238,33 +238,33 @@ namespace { // ========================================================================= void v2_approach(const Uint8* gfx, int i) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(i, 150, gfx, fr1[(i / 5) % 13], 0, 15, 15, 255); - JD8_BlitCK(304 - i, 150, gfx, fr6[(i / 10) % 8], 60, 15, 15, 255); + Jd8::blitCK(i, 150, gfx, fr1[(i / 5) % 13], 0, 15, 15, 255); + Jd8::blitCK(304 - i, 150, gfx, fr6[(i / 10) % 8], 60, 15, 15, 255); } void v2_still(const Uint8* gfx, int /*i*/) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(145, 150, gfx, fr1[1], 0, 15, 15, 255); - JD8_BlitCK(160, 150, gfx, fr6[1], 60, 15, 15, 255); + Jd8::blitCK(145, 150, gfx, fr1[1], 0, 15, 15, 255); + Jd8::blitCK(160, 150, gfx, fr6[1], 60, 15, 15, 255); } void v2_horn(const Uint8* gfx, int i) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(125, 150, gfx, fr11[(i / 10) % 2], 90, 15, 15, 255); - JD8_BlitCK(145, 150, gfx, fr1[1], 0, 15, 15, 255); - JD8_BlitCK(160, 150, gfx, fr6[1], 60, 15, 15, 255); + Jd8::blitCK(125, 150, gfx, fr11[(i / 10) % 2], 90, 15, 15, 255); + Jd8::blitCK(145, 150, gfx, fr1[1], 0, 15, 15, 255); + Jd8::blitCK(160, 150, gfx, fr6[1], 60, 15, 15, 255); } void v2_ball(const Uint8* gfx, int i) { - JD8_ClearScreen(0); + Jd8::clearScreen(0); drawWordmark(gfx); - JD8_BlitCK(145, 150, gfx, fr9[(i / 10) % 16], 120, 15, 15, 255); - JD8_BlitCK(160, 150, gfx, fr10[(i / 10) % 16], 135, 15, 15, 255); - JD8_BlitCK(125, 150, gfx, fr11[((i / 5) % 4) + 2], 90, 15, 15, 255); + Jd8::blitCK(145, 150, gfx, fr9[(i / 10) % 16], 120, 15, 15, 255); + Jd8::blitCK(160, 150, gfx, fr10[(i / 10) % 16], 135, 15, 15, 255); + Jd8::blitCK(125, 150, gfx, fr11[((i / 5) % 4) + 2], 90, 15, 15, 255); } constexpr SpritePhase variant_2[] = { @@ -330,7 +330,7 @@ namespace scenes { done_ = false; // Renderitzem ja el primer frame (step 0 de la primera fase) perquè - // el JD8_Flip del mini-loop del fiber el pinte al primer cicle. + // el Jd8::flip del mini-loop del fiber el pinte al primer cicle. const SpritePhase* phases = variant_table(variant_); phases[0].render(gfx_.get(), phase_current_i(phases[0], 0)); } diff --git a/source/game/scenes/menu_scene.cpp b/source/game/scenes/menu_scene.cpp index 1e4b048..045cd99 100644 --- a/source/game/scenes/menu_scene.cpp +++ b/source/game/scenes/menu_scene.cpp @@ -14,12 +14,12 @@ namespace scenes { // Pintat inicial (congelat durant el fade-in de paleta). El loop // d'animació repintarà tot des de zero en el primer tick de Showing. - JD8_Blit(fondo_); - JD8_BlitCK(100, 25, gfx_, 0, 74, 124, 68, 255); // logo - JD8_BlitCK(130, 100, gfx_, 0, 0, 80, 74, 255); // camell (frame 0) - JD8_BlitCK(0, 150, gfx_, 0, 150, 320, 50, 255); // base "jdes" + Jd8::blit(fondo_); + Jd8::blitCK(100, 25, gfx_, 0, 74, 124, 68, 255); // logo + Jd8::blitCK(130, 100, gfx_, 0, 0, 80, 74, 255); // camell (frame 0) + Jd8::blitCK(0, 150, gfx_, 0, 150, 320, 50, 255); // base "jdes" - JD8_Palette pal = JD8_LoadPalette("gfx/menu2.gif"); + Jd8::Palette pal = Jd8::loadPalette("gfx/menu2.gif"); fade_.startFadeTo(pal); delete[] pal; @@ -28,32 +28,32 @@ namespace scenes { void MenuScene::render() { // Cel estàtic (els primers 100 pixels verticals) - JD8_Blit(0, 0, fondo_, 0, 0, 320, 100); + Jd8::blit(0, 0, fondo_, 0, 0, 320, 100); // Fondo mòvil (horitzó) amb wrap a 320 - JD8_BlitCK(horitzo_, 100, fondo_, 0, 100, 320 - horitzo_, 100, 255); - JD8_BlitCK(0, 100, fondo_, 320 - horitzo_, 100, horitzo_, 100, 255); + Jd8::blitCK(horitzo_, 100, fondo_, 0, 100, 320 - horitzo_, 100, 255); + Jd8::blitCK(0, 100, fondo_, 320 - horitzo_, 100, horitzo_, 100, 255); // Logo i camell animat - JD8_BlitCK(100, 25, gfx_, 0, 74, 124, 68, 255); - JD8_BlitCK(130, 100, gfx_, camello_.frame() * 80, 0, 80, 74, 255); + Jd8::blitCK(100, 25, gfx_, 0, 74, 124, 68, 255); + Jd8::blitCK(130, 100, gfx_, camello_.frame() * 80, 0, 80, 74, 255); // Palmeres mòvils amb wrap a 320 - JD8_BlitCK(palmeres_, 150, gfx_, 0, 150, 320 - palmeres_, 50, 255); - JD8_BlitCK(0, 150, gfx_, 320 - palmeres_, 150, palmeres_, 50, 255); + Jd8::blitCK(palmeres_, 150, gfx_, 0, 150, 320 - palmeres_, 50, 255); + Jd8::blitCK(0, 150, gfx_, 320 - palmeres_, 150, palmeres_, 50, 255); // "jdes" estàtic (davant dels scrollers) i versió a la cantonada - JD8_BlitCK(87, 167, gfx_, 127, 124, 150, 24, 255); - JD8_BlitCK(303, 193, gfx_, 305, 143, 15, 5, 255); + Jd8::blitCK(87, 167, gfx_, 127, 124, 150, 24, 255); + Jd8::blitCK(303, 193, gfx_, 305, 143, 15, 5, 255); // "Polsa tecla" parpallejant. Al vell `contador % 100 > 30` amb // updateTicks=20 ms, el cicle són 2000 ms amb un llindar de 600 ms: // amagat els primers 600 ms, visible els següents 1400 ms. const bool blink_on = (blink_ms_ % 2000) > 600; if (blink_on) { - JD8_BlitCK(98, 130, gfx_, 161, 92, 127, 9, 255); + Jd8::blitCK(98, 130, gfx_, 161, 92, 127, 9, 255); if (info::ctx.nou_personatge) { - JD8_BlitCK(68, 141, gfx_, 128, 105, 189, 9, 255); + Jd8::blitCK(68, 141, gfx_, 128, 105, 189, 9, 255); } } } diff --git a/source/game/scenes/mort_scene.cpp b/source/game/scenes/mort_scene.cpp index c3b50e8..bcc2351 100644 --- a/source/game/scenes/mort_scene.cpp +++ b/source/game/scenes/mort_scene.cpp @@ -15,12 +15,12 @@ namespace scenes { info::ctx.vida = 5; gfx_ = SurfaceHandle("gfx/gameover.gif"); - JD8_ClearScreen(0); - JD8_Blit(gfx_); + Jd8::clearScreen(0); + Jd8::blit(gfx_); // PaletteFade en fa una còpia interna via memcpy, així que alliberem // la paleta temporal immediatament. - JD8_Palette pal = JD8_LoadPalette("gfx/gameover.gif"); + Jd8::Palette pal = Jd8::loadPalette("gfx/gameover.gif"); fade_.startFadeTo(pal); delete[] pal; diff --git a/source/game/scenes/palette_fade.cpp b/source/game/scenes/palette_fade.cpp index 91a8165..9ab981d 100644 --- a/source/game/scenes/palette_fade.cpp +++ b/source/game/scenes/palette_fade.cpp @@ -3,12 +3,12 @@ namespace scenes { void PaletteFade::startFadeOut() { - JD8_FadeStartOut(); + Jd8::fadeStartOut(); active_ = true; } void PaletteFade::startFadeTo(const Color* target) { - JD8_FadeStartToPal(target); + Jd8::fadeStartToPal(target); active_ = true; } @@ -22,7 +22,7 @@ namespace scenes { // de 500ms exactes independent del framerate") podem convertir la // màquina d'estats de jdraw8 a time-based ací sense tocar cap altre // call site. - if (JD8_FadeTickStep()) { + if (Jd8::fadeTickStep()) { active_ = false; } } diff --git a/source/game/scenes/palette_fade.hpp b/source/game/scenes/palette_fade.hpp index 721d90c..ed12a86 100644 --- a/source/game/scenes/palette_fade.hpp +++ b/source/game/scenes/palette_fade.hpp @@ -5,7 +5,7 @@ namespace scenes { // Embolcall fi damunt de la màquina d'estats de fade de jdraw8 - // (`JD8_FadeStart*` / `JD8_FadeTickStep`). Exposa una API time-based + // (`JD8_FadeStart*` / `Jd8::fadeTickStep`). Exposa una API time-based // però internament avança un pas del fade per cada crida a `tick()`. // La raó de tindre-ho com a classe a banda: que una escena no puga // cridar accidentalment a `JD8_FadeOut`/`JD8_FadeToPal` (els shims diff --git a/source/game/scenes/scene.hpp b/source/game/scenes/scene.hpp index 6117a58..50605c5 100644 --- a/source/game/scenes/scene.hpp +++ b/source/game/scenes/scene.hpp @@ -6,7 +6,7 @@ // cert, i llavors consulta `nextState()` per decidir la següent. // // Contracte: -// - `tick(delta_ms)` no pot bloquejar ni cridar JD8_Flip — el caller +// - `tick(delta_ms)` no pot bloquejar ni cridar Jd8::flip — el caller // s'encarrega de fer el flip després del tick. // - `done()` es consulta just després de cada tick. // - Els assets són propietat de l'escena (normalment via SurfaceHandle) diff --git a/source/game/scenes/secreta_scene.cpp b/source/game/scenes/secreta_scene.cpp index 97bf1cb..5c5e4c7 100644 --- a/source/game/scenes/secreta_scene.cpp +++ b/source/game/scenes/secreta_scene.cpp @@ -50,7 +50,7 @@ namespace scenes { fade_.startFadeOut(); gfx_ = SurfaceHandle("gfx/tomba1.gif"); - pal_aux_ = JD8_LoadPalette("gfx/tomba1.gif"); + pal_aux_ = Jd8::loadPalette("gfx/tomba1.gif"); pal_active_ = new Color[256]; std::memcpy(pal_active_, pal_aux_, 768); @@ -59,20 +59,20 @@ namespace scenes { } void SecretaScene::swapToTomba2() { - JD8_ClearScreen(255); + Jd8::clearScreen(255); gfx_.reset("gfx/tomba2.gif"); delete[] pal_aux_; - pal_aux_ = JD8_LoadPalette("gfx/tomba2.gif"); + pal_aux_ = Jd8::loadPalette("gfx/tomba2.gif"); // pal_active_ continua sent el mateix buffer: només actualitzem // el seu contingut. main_palette ja apunta ací. std::memcpy(pal_active_, pal_aux_, 768); } void SecretaScene::beginRedPulseSetup() { - JD8_ClearScreen(0); - JD8_SetPaletteColor(254, 12, 11, 11); - JD8_SetPaletteColor(253, 12, 11, 11); + Jd8::clearScreen(0); + Jd8::setPaletteColor(254, 12, 11, 11); + Jd8::setPaletteColor(253, 12, 11, 11); } void SecretaScene::beginFinalFade() { @@ -98,8 +98,8 @@ namespace scenes { // SetScreenPalette allibera la vella i adopta pal_active_ // — des d'ara main_palette == pal_active_, així que les // futures escriptures a pal_active_ afecten la pantalla. - JD8_SetScreenPalette(pal_active_); - JD8_ClearScreen(255); + Jd8::setScreenPalette(pal_active_); + Jd8::clearScreen(255); phase_ = Phase::Tomba1ScrollIn; phase_acc_ms_ = 0; } @@ -110,8 +110,8 @@ namespace scenes { const int contador = std::min(128, (phase_acc_ms_ / TICK_MS) + 1); // Dos blits solapats: el primer avança a velocitat completa, // el segon (contingut de la dreta del src) a meitat (contador>>1). - JD8_Blit(70, 60, gfx_, 0, contador, 178, 70); - JD8_BlitCK(70, 60, gfx_, 178, contador >> 1, 142, 70, 255); + Jd8::blit(70, 60, gfx_, 0, contador, 178, 70); + Jd8::blitCK(70, 60, gfx_, 178, contador >> 1, 142, 70, 255); if (phase_acc_ms_ >= TOMBA1_SCROLL_MS) { phase_ = Phase::Tomba1Hold; phase_acc_ms_ = 0; @@ -131,7 +131,7 @@ namespace scenes { case Phase::Tomba2ScrollIn: { phase_acc_ms_ += delta_ms; const int contador = std::min(94, (phase_acc_ms_ / TICK_MS) + 1); - JD8_Blit(55, 53, gfx_, 0, 158 - contador, 211, contador); + Jd8::blit(55, 53, gfx_, 0, 158 - contador, 211, contador); if (phase_acc_ms_ >= TOMBA2_SCROLL_MS) { phase_ = Phase::Tomba2Hold; phase_acc_ms_ = 0; @@ -153,7 +153,7 @@ namespace scenes { const int contador = std::min(80, (phase_acc_ms_ / TICK_MS) + 1); // Revelat horitzontal simètric: l'amplada creix 2px per tick // i el src_x es desplaça a l'esquerra el mateix. - JD8_Blit(80, 68, gfx_, 160 - (contador * 2), 0, contador * 2, 64); + Jd8::blit(80, 68, gfx_, 160 - (contador * 2), 0, contador * 2, 64); if (phase_acc_ms_ >= TOMBA2_REVEAL_MS) { phase_ = Phase::Tomba2RevealHold; phase_acc_ms_ = 0; @@ -174,8 +174,8 @@ namespace scenes { const int contador = std::min(51, phase_acc_ms_ / TICK_MS); // Anima el canal R dels índexs 254 i 253 (aquest a la meitat // de brillantor). Va de (12,11,11) fins a (63,11,11) / (31,11,11). - JD8_SetPaletteColor(254, contador + 12, 11, 11); - JD8_SetPaletteColor(253, (contador + 12) >> 1, 11, 11); + Jd8::setPaletteColor(254, contador + 12, 11, 11); + Jd8::setPaletteColor(253, (contador + 12) >> 1, 11, 11); if (phase_acc_ms_ >= RED_PULSE_MS) { phase_ = Phase::RedPulseHold; phase_acc_ms_ = 0; diff --git a/source/game/scenes/secreta_scene.hpp b/source/game/scenes/secreta_scene.hpp index 775b040..cd20ef2 100644 --- a/source/game/scenes/secreta_scene.hpp +++ b/source/game/scenes/secreta_scene.hpp @@ -56,8 +56,8 @@ namespace scenes { void beginFinalFade(); SurfaceHandle gfx_; - JD8_Palette pal_aux_{nullptr}; - JD8_Palette pal_active_{nullptr}; // propietat transferida a main_palette + Jd8::Palette pal_aux_{nullptr}; + Jd8::Palette pal_active_{nullptr}; // propietat transferida a main_palette PaletteFade fade_; Phase phase_{Phase::InitialFadeOut}; diff --git a/source/game/scenes/slides_scene.cpp b/source/game/scenes/slides_scene.cpp index 7031206..91bcd0b 100644 --- a/source/game/scenes/slides_scene.cpp +++ b/source/game/scenes/slides_scene.cpp @@ -48,7 +48,7 @@ namespace scenes { } gfx_ = SurfaceHandle(arxiu); - pal_aux_ = JD8_LoadPalette(arxiu); + pal_aux_ = Jd8::loadPalette(arxiu); // Còpia editable de la paleta. `pal_active_` comparteix memòria amb // main_palette després del SetScreenPalette — modificar-la modifica @@ -56,9 +56,9 @@ namespace scenes { // restaurar després de cada fade-out intermedi. pal_active_ = new Color[256]; std::memcpy(pal_active_, pal_aux_, 768); - JD8_SetScreenPalette(pal_active_); + Jd8::setScreenPalette(pal_active_); - JD8_ClearScreen(BG_COLOR_INDEX); + Jd8::clearScreen(BG_COLOR_INDEX); phase_ = Phase::Slide1Enter; phase_acc_ms_ = 0; @@ -83,7 +83,7 @@ namespace scenes { } if (w > 0) { - JD8_Blit(dst_x, SLIDE_Y, gfx_, src_x, src_y, w, SLIDE_H); + Jd8::blit(dst_x, SLIDE_Y, gfx_, src_x, src_y, w, SLIDE_H); } } @@ -169,7 +169,7 @@ namespace scenes { fade_.tick(delta_ms); if (fade_.done()) { restorePalette(); - JD8_ClearScreen(BG_COLOR_INDEX); + Jd8::clearScreen(BG_COLOR_INDEX); if (phase_ == Phase::FadeOut1) { phase_ = Phase::Slide2Enter; } else { diff --git a/source/game/scenes/slides_scene.hpp b/source/game/scenes/slides_scene.hpp index 678d6cc..7644ca7 100644 --- a/source/game/scenes/slides_scene.hpp +++ b/source/game/scenes/slides_scene.hpp @@ -67,8 +67,8 @@ namespace scenes { void beginFinalFade(); SurfaceHandle gfx_; - JD8_Palette pal_aux_{nullptr}; // còpia "neta" que preservem - JD8_Palette pal_active_{nullptr}; // propietat transferida a main_palette + Jd8::Palette pal_aux_{nullptr}; // còpia "neta" que preservem + Jd8::Palette pal_active_{nullptr}; // propietat transferida a main_palette PaletteFade fade_; Phase phase_{Phase::Slide1Enter}; diff --git a/source/game/scenes/surface_handle.cpp b/source/game/scenes/surface_handle.cpp index f5a9c14..b8cd0df 100644 --- a/source/game/scenes/surface_handle.cpp +++ b/source/game/scenes/surface_handle.cpp @@ -3,11 +3,11 @@ namespace scenes { SurfaceHandle::SurfaceHandle(const char* file) - : surface_(JD8_LoadSurface(file)) {} + : surface_(Jd8::loadSurface(file)) {} SurfaceHandle::~SurfaceHandle() { if (surface_ != nullptr) { - JD8_FreeSurface(surface_); + Jd8::freeSurface(surface_); } } @@ -19,7 +19,7 @@ namespace scenes { auto SurfaceHandle::operator=(SurfaceHandle&& other) noexcept -> SurfaceHandle& { if (this != &other) { if (surface_ != nullptr) { - JD8_FreeSurface(surface_); + Jd8::freeSurface(surface_); } surface_ = other.surface_; other.surface_ = nullptr; @@ -29,20 +29,20 @@ namespace scenes { void SurfaceHandle::reset(const char* file) { if (surface_ != nullptr) { - JD8_FreeSurface(surface_); + Jd8::freeSurface(surface_); } - surface_ = (file != nullptr) ? JD8_LoadSurface(file) : nullptr; + surface_ = (file != nullptr) ? Jd8::loadSurface(file) : nullptr; } - void SurfaceHandle::adopt(JD8_Surface raw) { + void SurfaceHandle::adopt(Jd8::Surface raw) { if (surface_ != nullptr) { - JD8_FreeSurface(surface_); + Jd8::freeSurface(surface_); } surface_ = raw; } - auto SurfaceHandle::release() -> JD8_Surface { - JD8_Surface r = surface_; + auto SurfaceHandle::release() -> Jd8::Surface { + Jd8::Surface r = surface_; surface_ = nullptr; return r; } diff --git a/source/game/scenes/surface_handle.hpp b/source/game/scenes/surface_handle.hpp index 78eca4e..4d71f50 100644 --- a/source/game/scenes/surface_handle.hpp +++ b/source/game/scenes/surface_handle.hpp @@ -4,10 +4,10 @@ namespace scenes { - // Wrapper RAII damunt de `JD8_Surface`. Allibera automàticament amb - // `JD8_FreeSurface` al destructor. Move-only per evitar dobles alliberaments. - // Converteix implícitament a `JD8_Surface` per a poder passar-lo - // directament a `JD8_Blit*` sense haver de cridar `.get()`. + // Wrapper RAII damunt de `Jd8::Surface`. Allibera automàticament amb + // `Jd8::freeSurface` al destructor. Move-only per evitar dobles alliberaments. + // Converteix implícitament a `Jd8::Surface` per a poder passar-lo + // directament a `Jd8::blit*` sense haver de cridar `.get()`. class SurfaceHandle { public: SurfaceHandle() = default; @@ -25,25 +25,25 @@ namespace scenes { // (p.ex. doSecreta que passa de tomba1 a tomba2). void reset(const char* file); - // Adopta una surface ja creada (p.ex. amb JD8_NewSurface). Pren ownership + // Adopta una surface ja creada (p.ex. amb Jd8::newSurface). Pren ownership // — la surface adoptada s'allibera al destructor o al següent reset/adopt. - void adopt(JD8_Surface raw); + void adopt(Jd8::Surface raw); // Allibera ownership sense destruir la surface. Retorna el pointer cru; // el caller passa a ser responsable d'alliberar-lo (o de passar-lo a un // altre propietari). Usat quan una escena delega a codi legacy que // també allibera la mateixa surface — cal "soltar" el ownership per // evitar double free. - [[nodiscard]] auto release() -> JD8_Surface; + [[nodiscard]] auto release() -> Jd8::Surface; - // Conversió implícita per al confort d'ús: JD8_Blit(handle) - // en lloc de JD8_Blit(handle.get()). - operator JD8_Surface() const { return surface_; } - [[nodiscard]] auto get() const -> JD8_Surface { return surface_; } + // Conversió implícita per al confort d'ús: Jd8::blit(handle) + // en lloc de Jd8::blit(handle.get()). + operator Jd8::Surface() const { return surface_; } + [[nodiscard]] auto get() const -> Jd8::Surface { return surface_; } [[nodiscard]] auto valid() const -> bool { return surface_ != nullptr; } private: - JD8_Surface surface_{nullptr}; + Jd8::Surface surface_{nullptr}; }; } // namespace scenes diff --git a/source/game/scenes/timeline.hpp b/source/game/scenes/timeline.hpp index 22ccf79..d23b279 100644 --- a/source/game/scenes/timeline.hpp +++ b/source/game/scenes/timeline.hpp @@ -9,7 +9,7 @@ namespace scenes { // ms i un callback. Exemple d'ús: // // timeline_ - // .once([this] { JD8_ClearScreen(0); fade_.startFadeTo(pal); }) + // .once([this] { Jd8::clearScreen(0); fade_.startFadeTo(pal); }) // .step(5000) // espera pura // .step(1000, [this](float p) { /*...*/ }) // animat amb progress // .once([this] { Ja::fadeOutMusic(250); }); diff --git a/source/game/sprite.cpp b/source/game/sprite.cpp index 9feaf51..f3a83c4 100644 --- a/source/game/sprite.cpp +++ b/source/game/sprite.cpp @@ -1,9 +1,9 @@ #include "game/sprite.hpp" -Sprite::Sprite(JD8_Surface gfx) +Sprite::Sprite(Jd8::Surface gfx) : gfx(gfx) {} void Sprite::draw() { const Frame& f = entitat.frames[entitat.animacions[o].frames[cur_frame]]; - JD8_BlitCK(x, y, gfx, f.x, f.y, f.w, f.h, 255); + Jd8::blitCK(x, y, gfx, f.x, f.y, f.w, f.h, 255); } diff --git a/source/game/sprite.hpp b/source/game/sprite.hpp index 04a7916..fa49365 100644 --- a/source/game/sprite.hpp +++ b/source/game/sprite.hpp @@ -22,7 +22,7 @@ struct Entitat { class Sprite { public: - explicit Sprite(JD8_Surface gfx); + explicit Sprite(Jd8::Surface gfx); virtual ~Sprite() = default; virtual void draw(); @@ -34,6 +34,6 @@ class Sprite { Uint16 o = 0; protected: - JD8_Surface gfx; + Jd8::Surface gfx; Uint8 cycles_per_frame = 1; }; diff --git a/source/main.cpp b/source/main.cpp index ecf0742..42f52b1 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -91,7 +91,7 @@ auto SDL_AppInit(void** /*appstate*/, int /*argc*/, char* /*argv*/[]) -> SDL_App JG_Init(); Screen::init(); - JD8_Init(); + Jd8::init(); Audio::init(); // crida internament Ja::init i aplica Options::audio Overlay::init(); Menu::init(); @@ -147,7 +147,7 @@ void SDL_AppQuit(void* /*appstate*/, SDL_AppResult /*result*/) { Resource::Cache::destroy(); Resource::List::destroy(); Audio::destroy(); // el destructor del singleton crida Ja::quit - JD8_Quit(); + Jd8::quit(); Screen::destroy(); JG_Finalize(); ResourceHelper::shutdownResourceSystem(); From ec3cb78f6b8d38323ae90f444a470b648aef191d Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 16 May 2026 14:32:25 +0200 Subject: [PATCH 03/13] =?UTF-8?q?fix:=20intro=5Fsprites=5Fscene=20snake=5F?= =?UTF-8?q?case=20=E2=86=92=20camelBack=20/=20UPPER=5FCASE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/game/scenes/intro_sprites_scene.cpp | 230 ++++++++++----------- 1 file changed, 115 insertions(+), 115 deletions(-) diff --git a/source/game/scenes/intro_sprites_scene.cpp b/source/game/scenes/intro_sprites_scene.cpp index 5d045b6..a3e0287 100644 --- a/source/game/scenes/intro_sprites_scene.cpp +++ b/source/game/scenes/intro_sprites_scene.cpp @@ -18,13 +18,13 @@ namespace { // Cada sprite ocupa 15×15 px, disposats horitzontalment per fila. // Els valors són els offsets x (la y la posa l'invocador al src_y). // Derivats dels `fr_ani_N[i] = ...` del vell doIntroSprites. - constexpr Uint16 fr1[] = {0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180}; // camina dreta (y=0) - constexpr Uint16 fr2[] = {0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180}; // camina esquerra (y=15) - constexpr Uint16 fr3[] = {0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150}; // trau mapa dreta (y=30) - constexpr Uint16 fr4[] = {0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150}; // trau mapa esquerra (y=45) - constexpr Uint16 fr5[] = {165, 180, 195, 210, 225, 240, 255, 270, 285, 300, 300, 285, 270, 255, 240, 225, 210, 195, 180, 165}; // bot de susto (y=45, mirror) - constexpr Uint16 fr6[] = {0, 15, 30, 45, 60, 75, 90, 105}; // momia (y=60) - constexpr Uint16 fr7[] = {75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225, 240, 255, 270, // paper (y=75, idx 0..13) + constexpr Uint16 FR1[] = {0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180}; // camina dreta (y=0) + constexpr Uint16 FR2[] = {0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180}; // camina esquerra (y=15) + constexpr Uint16 FR3[] = {0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150}; // trau mapa dreta (y=30) + constexpr Uint16 FR4[] = {0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150}; // trau mapa esquerra (y=45) + constexpr Uint16 FR5[] = {165, 180, 195, 210, 225, 240, 255, 270, 285, 300, 300, 285, 270, 255, 240, 225, 210, 195, 180, 165}; // bot de susto (y=45, mirror) + constexpr Uint16 FR6[] = {0, 15, 30, 45, 60, 75, 90, 105}; // momia (y=60) + constexpr Uint16 FR7[] = {75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225, 240, 255, 270, // paper (y=75, idx 0..13) 0, 15, 30, @@ -40,10 +40,10 @@ namespace { 180, 195, 210}; // sombra (y=105, idx 14..28) - constexpr Uint16 fr8[] = {15, 30, 45, 60}; // pedra (y=75) - constexpr Uint16 fr9[] = {0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225}; // prota ball (y=120) - constexpr Uint16 fr10[] = {0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225}; // momia ball (y=135) - constexpr Uint16 fr11[] = {15, 30, 45, 60, 75, 60}; // altaveu (y=90, [5]=[3] pel loop de 4) + constexpr Uint16 FR8[] = {15, 30, 45, 60}; // pedra (y=75) + constexpr Uint16 FR9[] = {0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225}; // prota ball (y=120) + constexpr Uint16 FR10[] = {0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225}; // momia ball (y=135) + constexpr Uint16 FR11[] = {15, 30, 45, 60, 75, 60}; // altaveu (y=90, [5]=[3] pel loop de 4) constexpr Uint16 CREU = 75; // src_y de la creu (overlay) constexpr Uint16 INTERROGANT = 90; // src_y del signe d'interrogant @@ -78,237 +78,237 @@ namespace { // Variant 0 — Interrogant / Momia // ========================================================================= - void v0_walk_right(const Uint8* gfx, int i) { + void v0WalkRight(const Uint8* gfx, int i) { Jd8::clearScreen(0); drawWordmark(gfx); - Jd8::blitCK(i, 150, gfx, fr1[(i / 5) % 13], 0, 15, 15, 0); + Jd8::blitCK(i, 150, gfx, FR1[(i / 5) % 13], 0, 15, 15, 0); } - void v0_pull_map_right(const Uint8* gfx, int i) { + void v0PullMapRight(const Uint8* gfx, int i) { Jd8::clearScreen(0); drawWordmark(gfx); - Jd8::blitCK(200, 150, gfx, fr3[std::min(i / 5, 10)], 30, 15, 15, 0); + Jd8::blitCK(200, 150, gfx, FR3[std::min(i / 5, 10)], 30, 15, 15, 0); } - void v0_walk_left_to_80(const Uint8* gfx, int i) { + void v0WalkLeftTo80(const Uint8* gfx, int i) { Jd8::clearScreen(0); drawWordmark(gfx); - Jd8::blitCK(i, 150, gfx, fr2[(i / 5) % 13], 15, 15, 15, 0); + Jd8::blitCK(i, 150, gfx, FR2[(i / 5) % 13], 15, 15, 15, 0); } - void v0_pull_map_left(const Uint8* gfx, int i) { + void v0PullMapLeft(const Uint8* gfx, int i) { Jd8::clearScreen(0); drawWordmark(gfx); - Jd8::blitCK(80, 150, gfx, fr4[std::min(i / 5, 10)], 45, 15, 15, 0); + Jd8::blitCK(80, 150, gfx, FR4[std::min(i / 5, 10)], 45, 15, 15, 0); } - void v0_momia_left(const Uint8* gfx, int i) { + void v0MomiaLeft(const Uint8* gfx, int i) { Jd8::clearScreen(0); drawWordmark(gfx); - Jd8::blitCK(i, 150, gfx, fr6[(i / 5) % 8], 60, 15, 15, 0); - Jd8::blitCK(80, 150, gfx, fr4[10], 45, 15, 15, 0); + Jd8::blitCK(i, 150, gfx, FR6[(i / 5) % 8], 60, 15, 15, 0); + Jd8::blitCK(80, 150, gfx, FR4[10], 45, 15, 15, 0); } - void v0_turn(const Uint8* gfx, int /*i*/) { + void v0Turn(const Uint8* gfx, int /*i*/) { Jd8::clearScreen(0); drawWordmark(gfx); - Jd8::blitCK(80, 150, gfx, fr1[1], 0, 15, 15, 0); - Jd8::blitCK(95, 150, gfx, fr6[4], 60, 15, 15, 0); + Jd8::blitCK(80, 150, gfx, FR1[1], 0, 15, 15, 0); + Jd8::blitCK(95, 150, gfx, FR6[4], 60, 15, 15, 0); Jd8::blitCK(80, 133, gfx, 0, INTERROGANT, 15, 15, 0); } - void v0_jump1(const Uint8* gfx, int i) { + void v0Jump1(const Uint8* gfx, int i) { Jd8::clearScreen(0); drawWordmark(gfx); - Jd8::blitCK(80, 150 - ((i % 50) / 5), gfx, fr5[std::min(i / 5, 19)], 45, 15, 15, 0); - Jd8::blitCK(95, 150, gfx, fr6[4], 60, 15, 15, 0); + Jd8::blitCK(80, 150 - ((i % 50) / 5), gfx, FR5[std::min(i / 5, 19)], 45, 15, 15, 0); + Jd8::blitCK(95, 150, gfx, FR6[4], 60, 15, 15, 0); } - void v0_jump2(const Uint8* gfx, int i) { + void v0Jump2(const Uint8* gfx, int i) { Jd8::clearScreen(0); drawWordmark(gfx); - Jd8::blitCK(80, 140 + ((i % 50) / 5), gfx, fr5[std::min(i / 5, 19)], 45, 15, 15, 0); - Jd8::blitCK(95, 150, gfx, fr6[4], 60, 15, 15, 0); + Jd8::blitCK(80, 140 + ((i % 50) / 5), gfx, FR5[std::min(i / 5, 19)], 45, 15, 15, 0); + Jd8::blitCK(95, 150, gfx, FR6[4], 60, 15, 15, 0); } - void v0_walk_final(const Uint8* gfx, int i) { + void v0WalkFinal(const Uint8* gfx, int i) { Jd8::clearScreen(0); drawWordmark(gfx); - Jd8::blitCK(i, 150, gfx, fr2[(i / 5) % 13], 15, 15, 15, 0); - Jd8::blitCK(95, 150, gfx, fr6[4], 60, 15, 15, 0); + Jd8::blitCK(i, 150, gfx, FR2[(i / 5) % 13], 15, 15, 15, 0); + Jd8::blitCK(95, 150, gfx, FR6[4], 60, 15, 15, 0); } - void v0_final(const Uint8* gfx, int /*i*/) { + void v0Final(const Uint8* gfx, int /*i*/) { Jd8::clearScreen(0); drawWordmark(gfx); - Jd8::blitCK(95, 150, gfx, fr6[4], 60, 15, 15, 0); + Jd8::blitCK(95, 150, gfx, FR6[4], 60, 15, 15, 0); Jd8::blitCK(95, 133, gfx, 0, INTERROGANT, 15, 15, 0); } - constexpr SpritePhase variant_0[] = { - {.start_i = 0, .end_i = 200, .render = v0_walk_right, .skippable = true}, - {.start_i = 0, .end_i = 200, .render = v0_pull_map_right, .skippable = true}, - {.start_i = 200, .end_i = 0, .render = v0_pull_map_right, .skippable = true}, // guarda el mapa (reprodueix inversament) - {.start_i = 200, .end_i = 80, .render = v0_walk_left_to_80, .skippable = true}, - {.start_i = 0, .end_i = 200, .render = v0_pull_map_left, .skippable = true}, - {.start_i = 300, .end_i = 95, .render = v0_momia_left, .skippable = true}, - {.start_i = 0, .end_i = 50, .render = v0_turn, .skippable = true}, - {.start_i = 0, .end_i = 49, .render = v0_jump1, .skippable = true}, - {.start_i = 50, .end_i = 99, .render = v0_jump2, .skippable = true}, - {.start_i = 80, .end_i = 0, .render = v0_walk_final, .skippable = true}, - {.start_i = 0, .end_i = 150, .render = v0_final, .skippable = true}, + constexpr SpritePhase VARIANT_0[] = { + {.start_i = 0, .end_i = 200, .render = v0WalkRight, .skippable = true}, + {.start_i = 0, .end_i = 200, .render = v0PullMapRight, .skippable = true}, + {.start_i = 200, .end_i = 0, .render = v0PullMapRight, .skippable = true}, // guarda el mapa (reprodueix inversament) + {.start_i = 200, .end_i = 80, .render = v0WalkLeftTo80, .skippable = true}, + {.start_i = 0, .end_i = 200, .render = v0PullMapLeft, .skippable = true}, + {.start_i = 300, .end_i = 95, .render = v0MomiaLeft, .skippable = true}, + {.start_i = 0, .end_i = 50, .render = v0Turn, .skippable = true}, + {.start_i = 0, .end_i = 49, .render = v0Jump1, .skippable = true}, + {.start_i = 50, .end_i = 99, .render = v0Jump2, .skippable = true}, + {.start_i = 80, .end_i = 0, .render = v0WalkFinal, .skippable = true}, + {.start_i = 0, .end_i = 150, .render = v0Final, .skippable = true}, }; // ========================================================================= // Variant 1 — Creu / Pedra // ========================================================================= - void v1_walk_right(const Uint8* gfx, int i) { + void v1WalkRight(const Uint8* gfx, int i) { Jd8::clearScreen(0); drawWordmark(gfx); Jd8::blitCK(200, 155, gfx, 0, CREU, 15, 15, 255); - Jd8::blitCK(i, 150, gfx, fr1[(i / 5) % 13], 0, 15, 15, 255); + Jd8::blitCK(i, 150, gfx, FR1[(i / 5) % 13], 0, 15, 15, 255); } - void v1_pull_map(const Uint8* gfx, int i) { + void v1PullMap(const Uint8* gfx, int i) { Jd8::clearScreen(0); drawWordmark(gfx); Jd8::blitCK(200, 155, gfx, 0, CREU, 15, 15, 255); - Jd8::blitCK(200, 150, gfx, fr3[std::min(i / 5, 10)], 30, 15, 15, 255); + Jd8::blitCK(200, 150, gfx, FR3[std::min(i / 5, 10)], 30, 15, 15, 255); } - void v1_interrogant(const Uint8* gfx, int /*i*/) { + void v1Interrogant(const Uint8* gfx, int /*i*/) { Jd8::clearScreen(0); drawWordmark(gfx); Jd8::blitCK(200, 155, gfx, 0, CREU, 15, 15, 255); Jd8::blitCK(200, 134, gfx, 0, INTERROGANT, 15, 15, 255); - Jd8::blitCK(200, 150, gfx, fr3[10], 30, 15, 15, 255); + Jd8::blitCK(200, 150, gfx, FR3[10], 30, 15, 15, 255); } - void v1_drop_map(const Uint8* gfx, int i) { + void v1DropMap(const Uint8* gfx, int i) { Jd8::clearScreen(0); drawWordmark(gfx); Jd8::blitCK(200, 155, gfx, 0, CREU, 15, 15, 255); - const int idx = std::min(i / 5, 28); - // fr7 té 29 frames dividits en dos grups: paper (idx 0..13, src_y=75) + const int IDX = std::min(i / 5, 28); + // FR7 té 29 frames dividits en dos grups: paper (idx 0..13, src_y=75) // i sombra (idx 14..28, src_y=105). El vell feia una branca al bucle. - if (idx <= 13) { - Jd8::blitCK(200, 150, gfx, fr7[idx], 75, 15, 15, 255); + if (IDX <= 13) { + Jd8::blitCK(200, 150, gfx, FR7[IDX], 75, 15, 15, 255); } else { - Jd8::blitCK(200, 150, gfx, fr7[idx], 105, 15, 15, 255); + Jd8::blitCK(200, 150, gfx, FR7[IDX], 105, 15, 15, 255); } } - void v1_stone_fall(const Uint8* gfx, int i) { + void v1StoneFall(const Uint8* gfx, int i) { Jd8::clearScreen(0); drawWordmark(gfx); Jd8::blitCK(200, 155, gfx, 0, CREU, 15, 15, 255); - Jd8::blitCK(200, 150, gfx, fr7[28], 105, 15, 15, 255); - Jd8::blitCK(200, i * 2, gfx, fr8[0], 75, 15, 15, 255); + Jd8::blitCK(200, 150, gfx, FR7[28], 105, 15, 15, 255); + Jd8::blitCK(200, i * 2, gfx, FR8[0], 75, 15, 15, 255); } - void v1_stone_break(const Uint8* gfx, int i) { + void v1StoneBreak(const Uint8* gfx, int i) { Jd8::clearScreen(0); drawWordmark(gfx); Jd8::blitCK(200, 155, gfx, 0, CREU, 15, 15, 255); - Jd8::blitCK(200, 150, gfx, fr8[i / 10], 75, 15, 15, 255); + Jd8::blitCK(200, 150, gfx, FR8[i / 10], 75, 15, 15, 255); } - void v1_final(const Uint8* gfx, int /*i*/) { + void v1Final(const Uint8* gfx, int /*i*/) { Jd8::clearScreen(0); drawWordmark(gfx); Jd8::blitCK(200, 155, gfx, 0, CREU, 15, 15, 255); - Jd8::blitCK(200, 150, gfx, fr8[1], 75, 15, 15, 255); - Jd8::blitCK(185, 150, gfx, fr8[2], 75, 15, 15, 255); - Jd8::blitCK(215, 150, gfx, fr8[3], 75, 15, 15, 255); + Jd8::blitCK(200, 150, gfx, FR8[1], 75, 15, 15, 255); + Jd8::blitCK(185, 150, gfx, FR8[2], 75, 15, 15, 255); + Jd8::blitCK(215, 150, gfx, FR8[3], 75, 15, 15, 255); } - constexpr SpritePhase variant_1[] = { - {.start_i = 0, .end_i = 200, .render = v1_walk_right, .skippable = true}, - {.start_i = 0, .end_i = 300, .render = v1_pull_map, .skippable = true}, - {.start_i = 0, .end_i = 100, .render = v1_interrogant, .skippable = true}, - {.start_i = 0, .end_i = 200, .render = v1_drop_map, .skippable = true}, - {.start_i = 0, .end_i = 75, .render = v1_stone_fall, .skippable = true}, - {.start_i = 0, .end_i = 19, .render = v1_stone_break, .skippable = true}, - {.start_i = 0, .end_i = 200, .render = v1_final, .skippable = true}, + constexpr SpritePhase VARIANT_1[] = { + {.start_i = 0, .end_i = 200, .render = v1WalkRight, .skippable = true}, + {.start_i = 0, .end_i = 300, .render = v1PullMap, .skippable = true}, + {.start_i = 0, .end_i = 100, .render = v1Interrogant, .skippable = true}, + {.start_i = 0, .end_i = 200, .render = v1DropMap, .skippable = true}, + {.start_i = 0, .end_i = 75, .render = v1StoneFall, .skippable = true}, + {.start_i = 0, .end_i = 19, .render = v1StoneBreak, .skippable = true}, + {.start_i = 0, .end_i = 200, .render = v1Final, .skippable = true}, }; // ========================================================================= // Variant 2 — Ball de carnaval // ========================================================================= - void v2_approach(const Uint8* gfx, int i) { + void v2Approach(const Uint8* gfx, int i) { Jd8::clearScreen(0); drawWordmark(gfx); - Jd8::blitCK(i, 150, gfx, fr1[(i / 5) % 13], 0, 15, 15, 255); - Jd8::blitCK(304 - i, 150, gfx, fr6[(i / 10) % 8], 60, 15, 15, 255); + Jd8::blitCK(i, 150, gfx, FR1[(i / 5) % 13], 0, 15, 15, 255); + Jd8::blitCK(304 - i, 150, gfx, FR6[(i / 10) % 8], 60, 15, 15, 255); } - void v2_still(const Uint8* gfx, int /*i*/) { + void v2Still(const Uint8* gfx, int /*i*/) { Jd8::clearScreen(0); drawWordmark(gfx); - Jd8::blitCK(145, 150, gfx, fr1[1], 0, 15, 15, 255); - Jd8::blitCK(160, 150, gfx, fr6[1], 60, 15, 15, 255); + Jd8::blitCK(145, 150, gfx, FR1[1], 0, 15, 15, 255); + Jd8::blitCK(160, 150, gfx, FR6[1], 60, 15, 15, 255); } - void v2_horn(const Uint8* gfx, int i) { + void v2Horn(const Uint8* gfx, int i) { Jd8::clearScreen(0); drawWordmark(gfx); - Jd8::blitCK(125, 150, gfx, fr11[(i / 10) % 2], 90, 15, 15, 255); - Jd8::blitCK(145, 150, gfx, fr1[1], 0, 15, 15, 255); - Jd8::blitCK(160, 150, gfx, fr6[1], 60, 15, 15, 255); + Jd8::blitCK(125, 150, gfx, FR11[(i / 10) % 2], 90, 15, 15, 255); + Jd8::blitCK(145, 150, gfx, FR1[1], 0, 15, 15, 255); + Jd8::blitCK(160, 150, gfx, FR6[1], 60, 15, 15, 255); } - void v2_ball(const Uint8* gfx, int i) { + void v2Ball(const Uint8* gfx, int i) { Jd8::clearScreen(0); drawWordmark(gfx); - Jd8::blitCK(145, 150, gfx, fr9[(i / 10) % 16], 120, 15, 15, 255); - Jd8::blitCK(160, 150, gfx, fr10[(i / 10) % 16], 135, 15, 15, 255); - Jd8::blitCK(125, 150, gfx, fr11[((i / 5) % 4) + 2], 90, 15, 15, 255); + Jd8::blitCK(145, 150, gfx, FR9[(i / 10) % 16], 120, 15, 15, 255); + Jd8::blitCK(160, 150, gfx, FR10[(i / 10) % 16], 135, 15, 15, 255); + Jd8::blitCK(125, 150, gfx, FR11[((i / 5) % 4) + 2], 90, 15, 15, 255); } - constexpr SpritePhase variant_2[] = { - {.start_i = 0, .end_i = 145, .render = v2_approach, .skippable = true}, - {.start_i = 0, .end_i = 100, .render = v2_still, .skippable = true}, - {.start_i = 0, .end_i = 50, .render = v2_horn, .skippable = true}, - {.start_i = 0, .end_i = 800, .render = v2_ball, .skippable = true}, + constexpr SpritePhase VARIANT_2[] = { + {.start_i = 0, .end_i = 145, .render = v2Approach, .skippable = true}, + {.start_i = 0, .end_i = 100, .render = v2Still, .skippable = true}, + {.start_i = 0, .end_i = 50, .render = v2Horn, .skippable = true}, + {.start_i = 0, .end_i = 800, .render = v2Ball, .skippable = true}, }; // ========================================================================= // Dispatch per variant // ========================================================================= - auto variant_table(int variant) -> const SpritePhase* { + auto variantTable(int variant) -> const SpritePhase* { switch (variant) { case 0: - return variant_0; + return VARIANT_0; case 1: - return variant_1; + return VARIANT_1; case 2: - return variant_2; + return VARIANT_2; default: - return variant_0; + return VARIANT_0; } } - auto variant_length(int variant) -> int { + auto variantLength(int variant) -> int { switch (variant) { case 0: - return sizeof(variant_0) / sizeof(variant_0[0]); + return sizeof(VARIANT_0) / sizeof(VARIANT_0[0]); case 1: - return sizeof(variant_1) / sizeof(variant_1[0]); + return sizeof(VARIANT_1) / sizeof(VARIANT_1[0]); case 2: - return sizeof(variant_2) / sizeof(variant_2[0]); + return sizeof(VARIANT_2) / sizeof(VARIANT_2[0]); default: return 0; } } - auto phase_step_count(const SpritePhase& p) -> int { + auto phaseStepCount(const SpritePhase& p) -> int { return std::abs(p.end_i - p.start_i) + 1; } - auto phase_current_i(const SpritePhase& p, int step) -> int { + auto phaseCurrentI(const SpritePhase& p, int step) -> int { return p.end_i >= p.start_i ? p.start_i + step : p.start_i - step; } @@ -331,8 +331,8 @@ namespace scenes { // Renderitzem ja el primer frame (step 0 de la primera fase) perquè // el Jd8::flip del mini-loop del fiber el pinte al primer cicle. - const SpritePhase* phases = variant_table(variant_); - phases[0].render(gfx_.get(), phase_current_i(phases[0], 0)); + const SpritePhase* phases = variantTable(variant_); + phases[0].render(gfx_.get(), phaseCurrentI(phases[0], 0)); } void IntroSpritesScene::tick(int delta_ms) { @@ -340,11 +340,11 @@ namespace scenes { return; } - const SpritePhase* phases = variant_table(variant_); - const int num_phases = variant_length(variant_); + const SpritePhase* phases = variantTable(variant_); + const int NUM_PHASES = variantLength(variant_); // Skip per tecla. Durant la fase marcada com a no skippable (només - // v0_final al vell codi) s'ignora — preserva la semàntica del vell + // v0Final al vell codi) s'ignora — preserva la semàntica del vell // bucle final de la variant 0 que no cridava wait_frame_or_skip. if (phases[phase_].skippable && JI_AnyKey()) { done_ = true; @@ -355,16 +355,16 @@ namespace scenes { while (step_acc_ms_ >= TICK_MS && !done_) { step_acc_ms_ -= TICK_MS; ++phase_step_; - if (phase_step_ >= phase_step_count(phases[phase_])) { + if (phase_step_ >= phaseStepCount(phases[phase_])) { ++phase_; phase_step_ = 0; - if (phase_ >= num_phases) { + if (phase_ >= NUM_PHASES) { done_ = true; return; } } } - phases[phase_].render(gfx_.get(), phase_current_i(phases[phase_], phase_step_)); + phases[phase_].render(gfx_.get(), phaseCurrentI(phases[phase_], phase_step_)); } } // namespace scenes From 7789c1c21784a8570774c0227f5bf562cff15311 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 16 May 2026 14:35:28 +0200 Subject: [PATCH 04/13] fix: menu.cpp enums UPPER_CASE i statics sense sufix --- source/core/rendering/menu.cpp | 374 ++++++++++++++++----------------- 1 file changed, 187 insertions(+), 187 deletions(-) diff --git a/source/core/rendering/menu.cpp b/source/core/rendering/menu.cpp index c302423..ebddb33 100644 --- a/source/core/rendering/menu.cpp +++ b/source/core/rendering/menu.cpp @@ -49,20 +49,20 @@ namespace Menu { static constexpr float HEIGHT_RATE = 12.0F; // smoothing exponencial de l'alçada (~150 ms al 90%) // --- Items --- - enum class ItemKind : std::uint8_t { Toggle, - Cycle, - IntRange, - Submenu, - KeyBind, - Action }; + enum class ItemKind : std::uint8_t { TOGGLE, + CYCLE, + INT_RANGE, + SUBMENU, + KEY_BIND, + ACTION }; struct Item { const char* label; ItemKind kind; - std::function getValue; // opcional - std::function change; // per Toggle/Cycle/IntRange - std::function enter; // per Submenu i Action - SDL_Scancode* scancode{nullptr}; // per KeyBind + std::function get_value; // opcional + std::function change; // per TOGGLE/CYCLE/INT_RANGE + std::function enter; // per SUBMENU i ACTION + SDL_Scancode* scancode{nullptr}; // per KEY_BIND std::function visible; // nullptr ⇒ sempre visible }; @@ -78,12 +78,12 @@ namespace Menu { // Troba el pròxim ítem visible en direcció `dir` (±1) a partir de `from`. // Si cap és visible retorna `from`. static auto nextVisibleCursor(const Page& p, int from, int dir) -> int { - const int n = static_cast(p.items.size()); - if (n <= 0) { + const int N = static_cast(p.items.size()); + if (N <= 0) { return from; } - for (int i = 1; i <= n; ++i) { - int idx = ((from + dir * i) % n + n) % n; + for (int i = 1; i <= N; ++i) { + int idx = ((from + dir * i) % N + N) % N; if (isVisible(p.items[idx])) { return idx; } @@ -92,35 +92,35 @@ namespace Menu { } // --- Estat --- - static std::vector stack_; - static std::unique_ptr font_; - static float open_anim_{0.0F}; // 0 = tancat, 1 = obert - static float animated_h_{0.0F}; // alçada actual animada (smoothing cap al target visible) - static Uint32 last_ticks_{0}; - static SDL_Scancode* capturing_{nullptr}; // != null → esperant tecla per assignar - static bool closing_{false}; // true mentre l'animació de tancament és en curs + static std::vector stack; + static std::unique_ptr font; + static float open_anim{0.0F}; // 0 = tancat, 1 = obert + static float animated_h{0.0F}; // alçada actual animada (smoothing cap al target visible) + static Uint32 last_ticks{0}; + static SDL_Scancode* capturing{nullptr}; // != null → esperant tecla per assignar + static bool closing{false}; // true mentre l'animació de tancament és en curs // --- Transició entre pàgines --- static constexpr float TRANSITION_SPEED = 5.5F; // ~180 ms - static Page transition_outgoing_{.title = "", .items = {}, .cursor = 0}; - static bool transition_active_{false}; - static float transition_progress_{1.0F}; - static int transition_dir_{+1}; // +1 endavant, -1 enrere + static Page transition_outgoing{.title = "", .items = {}, .cursor = 0}; + static bool transition_active{false}; + static float transition_progress{1.0F}; + static int transition_dir{+1}; // +1 endavant, -1 enrere // Helpers per triggerar transicions - static void pushPage(Page newPage) { - transition_outgoing_ = stack_.back(); - stack_.push_back(std::move(newPage)); - transition_active_ = true; - transition_progress_ = 0.0F; - transition_dir_ = +1; + static void pushPage(Page new_page) { + transition_outgoing = stack.back(); + stack.push_back(std::move(new_page)); + transition_active = true; + transition_progress = 0.0F; + transition_dir = +1; } static void popPage() { - transition_outgoing_ = stack_.back(); - stack_.pop_back(); - transition_active_ = true; - transition_progress_ = 0.0F; - transition_dir_ = -1; + transition_outgoing = stack.back(); + stack.pop_back(); + transition_active = true; + transition_progress = 0.0F; + transition_dir = -1; } // --- Helpers --- @@ -138,11 +138,11 @@ namespace Menu { static auto buildRoot() -> Page { Page p{.title = Locale::get("menu.titles.root"), .items = {}, .cursor = 0}; - p.items.push_back({Locale::get("menu.items.video"), ItemKind::Submenu, nullptr, nullptr, [] { pushPage(buildVideo()); }, nullptr}); - p.items.push_back({Locale::get("menu.items.audio"), ItemKind::Submenu, nullptr, nullptr, [] { pushPage(buildAudio()); }, nullptr}); - p.items.push_back({Locale::get("menu.items.controls"), ItemKind::Submenu, nullptr, nullptr, [] { pushPage(buildControls()); }, nullptr}); - p.items.push_back({Locale::get("menu.items.game"), ItemKind::Submenu, nullptr, nullptr, [] { pushPage(buildGame()); }, nullptr}); - p.items.push_back({Locale::get("menu.items.system"), ItemKind::Submenu, nullptr, nullptr, [] { pushPage(buildSystem()); }, nullptr}); + p.items.push_back({Locale::get("menu.items.video"), ItemKind::SUBMENU, nullptr, nullptr, [] { pushPage(buildVideo()); }, nullptr}); + p.items.push_back({Locale::get("menu.items.audio"), ItemKind::SUBMENU, nullptr, nullptr, [] { pushPage(buildAudio()); }, nullptr}); + p.items.push_back({Locale::get("menu.items.controls"), ItemKind::SUBMENU, nullptr, nullptr, [] { pushPage(buildControls()); }, nullptr}); + p.items.push_back({Locale::get("menu.items.game"), ItemKind::SUBMENU, nullptr, nullptr, [] { pushPage(buildGame()); }, nullptr}); + p.items.push_back({Locale::get("menu.items.system"), ItemKind::SUBMENU, nullptr, nullptr, [] { pushPage(buildSystem()); }, nullptr}); return p; } @@ -151,7 +151,7 @@ namespace Menu { // Zoom i fullscreen: sense sentit a WASM (el navegador posseix el canvas) #ifndef __EMSCRIPTEN__ - p.items.push_back({Locale::get("menu.items.zoom"), ItemKind::IntRange, [] { + p.items.push_back({Locale::get("menu.items.zoom"), ItemKind::INT_RANGE, [] { char buf[16]; std::snprintf(buf, sizeof(buf), "%dX", Screen::get()->getZoom()); return std::string(buf); }, [](int dir) { @@ -159,15 +159,15 @@ namespace Menu { } else if (dir > 0) { Screen::get()->incZoom(); } }, nullptr, nullptr}); - p.items.push_back({Locale::get("menu.items.screen"), ItemKind::Toggle, [] { return std::string(Screen::get()->isFullscreen() ? Locale::get("menu.values.fullscreen") : Locale::get("menu.values.windowed")); }, [](int) { Screen::get()->toggleFullscreen(); }, nullptr, nullptr, nullptr}); + p.items.push_back({Locale::get("menu.items.screen"), ItemKind::TOGGLE, [] { return std::string(Screen::get()->isFullscreen() ? Locale::get("menu.values.fullscreen") : Locale::get("menu.values.windowed")); }, [](int) { Screen::get()->toggleFullscreen(); }, nullptr, nullptr, nullptr}); #endif // Opcions visuals generals (sempre visibles) - p.items.push_back({Locale::get("menu.items.aspect_4_3"), ItemKind::Toggle, [] { return yesNo(Options::video.aspect_ratio_4_3); }, [](int) { Screen::get()->toggleAspectRatio(); }, nullptr, nullptr, nullptr}); + p.items.push_back({Locale::get("menu.items.aspect_4_3"), ItemKind::TOGGLE, [] { return yesNo(Options::video.aspect_ratio_4_3); }, [](int) { Screen::get()->toggleAspectRatio(); }, nullptr, nullptr, nullptr}); - p.items.push_back({Locale::get("menu.items.vsync"), ItemKind::Toggle, [] { return onOff(Options::video.vsync); }, [](int) { Screen::get()->toggleVSync(); }, nullptr, nullptr, nullptr}); + p.items.push_back({Locale::get("menu.items.vsync"), ItemKind::TOGGLE, [] { return onOff(Options::video.vsync); }, [](int) { Screen::get()->toggleVSync(); }, nullptr, nullptr, nullptr}); - p.items.push_back({Locale::get("menu.items.scaling_mode"), ItemKind::Cycle, [] { + p.items.push_back({Locale::get("menu.items.scaling_mode"), ItemKind::CYCLE, [] { switch (Options::video.scaling_mode) { case Options::ScalingMode::DISABLED: return std::string(Locale::get("menu.values.scaling_disabled")); case Options::ScalingMode::STRETCH: return std::string(Locale::get("menu.values.scaling_stretch")); @@ -177,30 +177,30 @@ namespace Menu { } return std::string(Locale::get("menu.values.scaling_integer")); }, [](int dir) { Screen::get()->cycleScalingMode(dir); }, nullptr, nullptr, nullptr}); - p.items.push_back({Locale::get("menu.items.texture_filter"), ItemKind::Cycle, [] { return std::string(Options::video.texture_filter == Options::TextureFilter::LINEAR + p.items.push_back({Locale::get("menu.items.texture_filter"), ItemKind::CYCLE, [] { return std::string(Options::video.texture_filter == Options::TextureFilter::LINEAR ? Locale::get("menu.values.linear") : Locale::get("menu.values.nearest")); }, [](int dir) { Screen::get()->cycleTextureFilter(dir); }, nullptr, nullptr, nullptr}); - p.items.push_back({Locale::get("menu.items.internal_resolution"), ItemKind::IntRange, [] { + p.items.push_back({Locale::get("menu.items.internal_resolution"), ItemKind::INT_RANGE, [] { char buf[16]; std::snprintf(buf, sizeof(buf), "%dX", Options::video.internal_resolution); return std::string(buf); }, [](int dir) { Screen::get()->changeInternalResolution(dir); }, nullptr, nullptr, nullptr}); // Bloc shaders: no disponible a WASM (NO_SHADERS, sense SDL3 GPU a WebGL2) #ifndef __EMSCRIPTEN__ - p.items.push_back({Locale::get("menu.items.shader"), ItemKind::Toggle, [] { return onOff(Options::video.shader_enabled); }, [](int) { Screen::get()->toggleShaders(); }, nullptr, nullptr, nullptr}); + p.items.push_back({Locale::get("menu.items.shader"), ItemKind::TOGGLE, [] { return onOff(Options::video.shader_enabled); }, [](int) { Screen::get()->toggleShaders(); }, nullptr, nullptr, nullptr}); - p.items.push_back({Locale::get("menu.items.shader_type"), ItemKind::Cycle, [] { return std::string(Screen::get()->getActiveShaderName()); }, [](int dir) { + p.items.push_back({Locale::get("menu.items.shader_type"), ItemKind::CYCLE, [] { return std::string(Screen::get()->getActiveShaderName()); }, [](int dir) { if (dir < 0) { Screen::get()->prevShaderType(); } else { Screen::get()->nextShaderType(); } }, nullptr, nullptr, [] { return Options::video.shader_enabled; }}); - p.items.push_back({Locale::get("menu.items.preset"), ItemKind::Cycle, [] { return std::string(Screen::get()->getCurrentPresetName()); }, [](int dir) { + p.items.push_back({Locale::get("menu.items.preset"), ItemKind::CYCLE, [] { return std::string(Screen::get()->getCurrentPresetName()); }, [](int dir) { if (dir < 0) { Screen::get()->prevPreset(); } else { Screen::get()->nextPreset(); } }, nullptr, nullptr, [] { return Options::video.shader_enabled; }}); - p.items.push_back({Locale::get("menu.items.supersampling"), ItemKind::Toggle, [] { return onOff(Options::video.supersampling); }, [](int) { Screen::get()->toggleSupersampling(); }, nullptr, nullptr, [] { + p.items.push_back({Locale::get("menu.items.supersampling"), ItemKind::TOGGLE, [] { return onOff(Options::video.supersampling); }, [](int) { Screen::get()->toggleSupersampling(); }, nullptr, nullptr, [] { if (!Options::video.shader_enabled) { return false; } const char* name = Screen::get()->getActiveShaderName(); @@ -208,7 +208,7 @@ namespace Menu { #endif // Informació de render - p.items.push_back({Locale::get("menu.items.render_info"), ItemKind::Cycle, [] { + p.items.push_back({Locale::get("menu.items.render_info"), ItemKind::CYCLE, [] { switch (Options::render_info.position) { case Options::RenderInfoPosition::OFF: return std::string(Locale::get("menu.values.off")); case Options::RenderInfoPosition::TOP: return std::string(Locale::get("menu.values.top")); @@ -216,7 +216,7 @@ namespace Menu { } return std::string(Locale::get("menu.values.off")); }, [](int dir) { Overlay::cycleRenderInfo(dir); }, nullptr, nullptr, nullptr}); - p.items.push_back({Locale::get("menu.items.uptime"), ItemKind::Toggle, [] { return onOff(Options::render_info.show_time); }, [](int) { Options::render_info.show_time = !Options::render_info.show_time; }, nullptr, nullptr, [] { return Options::render_info.position != Options::RenderInfoPosition::OFF; }}); + p.items.push_back({Locale::get("menu.items.uptime"), ItemKind::TOGGLE, [] { return onOff(Options::render_info.show_time); }, [](int) { Options::render_info.show_time = !Options::render_info.show_time; }, nullptr, nullptr, [] { return Options::render_info.position != Options::RenderInfoPosition::OFF; }}); return p; } @@ -241,34 +241,34 @@ namespace Menu { static auto buildControls() -> Page { Page p{.title = Locale::get("menu.titles.controls"), .items = {}, .cursor = 0}; - p.items.push_back({Locale::get("menu.items.move_up"), ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_game.up}); - p.items.push_back({Locale::get("menu.items.move_down"), ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_game.down}); - p.items.push_back({Locale::get("menu.items.move_left"), ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_game.left}); - p.items.push_back({Locale::get("menu.items.move_right"), ItemKind::KeyBind, nullptr, nullptr, nullptr, &Options::keys_game.right}); - p.items.push_back({Locale::get("menu.items.menu_key"), ItemKind::KeyBind, nullptr, nullptr, nullptr, KeyConfig::scancodePtr("menu_toggle")}); + p.items.push_back({Locale::get("menu.items.move_up"), ItemKind::KEY_BIND, nullptr, nullptr, nullptr, &Options::keys_game.up}); + p.items.push_back({Locale::get("menu.items.move_down"), ItemKind::KEY_BIND, nullptr, nullptr, nullptr, &Options::keys_game.down}); + p.items.push_back({Locale::get("menu.items.move_left"), ItemKind::KEY_BIND, nullptr, nullptr, nullptr, &Options::keys_game.left}); + p.items.push_back({Locale::get("menu.items.move_right"), ItemKind::KEY_BIND, nullptr, nullptr, nullptr, &Options::keys_game.right}); + p.items.push_back({Locale::get("menu.items.menu_key"), ItemKind::KEY_BIND, nullptr, nullptr, nullptr, KeyConfig::scancodePtr("menu_toggle")}); return p; } static auto buildAudio() -> Page { Page p{.title = Locale::get("menu.titles.audio"), .items = {}, .cursor = 0}; - p.items.push_back({Locale::get("menu.items.master_enable"), ItemKind::Toggle, [] { return onOff(Options::audio.enabled); }, [](int) { + p.items.push_back({Locale::get("menu.items.master_enable"), ItemKind::TOGGLE, [] { return onOff(Options::audio.enabled); }, [](int) { Options::audio.enabled = !Options::audio.enabled; Options::applyAudio(); }, nullptr}); - p.items.push_back({Locale::get("menu.items.master_volume"), ItemKind::IntRange, [] { return volPct(Options::audio.volume); }, [](int dir) { stepVolume(Options::audio.volume, dir); }, nullptr}); + p.items.push_back({Locale::get("menu.items.master_volume"), ItemKind::INT_RANGE, [] { return volPct(Options::audio.volume); }, [](int dir) { stepVolume(Options::audio.volume, dir); }, nullptr}); - p.items.push_back({Locale::get("menu.items.music"), ItemKind::Toggle, [] { return onOff(Options::audio.music.enabled); }, [](int) { + p.items.push_back({Locale::get("menu.items.music"), ItemKind::TOGGLE, [] { return onOff(Options::audio.music.enabled); }, [](int) { Options::audio.music.enabled = !Options::audio.music.enabled; Options::applyAudio(); }, nullptr}); - p.items.push_back({Locale::get("menu.items.music_volume"), ItemKind::IntRange, [] { return volPct(Options::audio.music.volume); }, [](int dir) { stepVolume(Options::audio.music.volume, dir); }, nullptr}); + p.items.push_back({Locale::get("menu.items.music_volume"), ItemKind::INT_RANGE, [] { return volPct(Options::audio.music.volume); }, [](int dir) { stepVolume(Options::audio.music.volume, dir); }, nullptr}); - p.items.push_back({Locale::get("menu.items.sounds"), ItemKind::Toggle, [] { return onOff(Options::audio.sound.enabled); }, [](int) { + p.items.push_back({Locale::get("menu.items.sounds"), ItemKind::TOGGLE, [] { return onOff(Options::audio.sound.enabled); }, [](int) { Options::audio.sound.enabled = !Options::audio.sound.enabled; Options::applyAudio(); }, nullptr}); - p.items.push_back({Locale::get("menu.items.sounds_volume"), ItemKind::IntRange, [] { return volPct(Options::audio.sound.volume); }, [](int dir) { stepVolume(Options::audio.sound.volume, dir); }, nullptr}); + p.items.push_back({Locale::get("menu.items.sounds_volume"), ItemKind::INT_RANGE, [] { return volPct(Options::audio.sound.volume); }, [](int dir) { stepVolume(Options::audio.sound.volume, dir); }, nullptr}); return p; } @@ -276,11 +276,11 @@ namespace Menu { static auto buildGame() -> Page { Page p{.title = Locale::get("menu.titles.game"), .items = {}, .cursor = 0}; - p.items.push_back({Locale::get("menu.items.use_new_logo"), ItemKind::Toggle, [] { return yesNo(Options::game.use_new_logo); }, [](int) { Options::game.use_new_logo = !Options::game.use_new_logo; }, nullptr}); + p.items.push_back({Locale::get("menu.items.use_new_logo"), ItemKind::TOGGLE, [] { return yesNo(Options::game.use_new_logo); }, [](int) { Options::game.use_new_logo = !Options::game.use_new_logo; }, nullptr}); - p.items.push_back({Locale::get("menu.items.show_title_credits"), ItemKind::Toggle, [] { return yesNo(Options::game.show_title_credits); }, [](int) { Options::game.show_title_credits = !Options::game.show_title_credits; }, nullptr}); + p.items.push_back({Locale::get("menu.items.show_title_credits"), ItemKind::TOGGLE, [] { return yesNo(Options::game.show_title_credits); }, [](int) { Options::game.show_title_credits = !Options::game.show_title_credits; }, nullptr}); - p.items.push_back({Locale::get("menu.items.show_preload"), ItemKind::Toggle, [] { return yesNo(Options::game.show_preload); }, [](int) { Options::game.show_preload = !Options::game.show_preload; }, nullptr}); + p.items.push_back({Locale::get("menu.items.show_preload"), ItemKind::TOGGLE, [] { return yesNo(Options::game.show_preload); }, [](int) { Options::game.show_preload = !Options::game.show_preload; }, nullptr}); return p; } @@ -289,7 +289,7 @@ namespace Menu { Page p{.title = Locale::get("menu.titles.system"), .items = {}, .cursor = 0}; p.subtitle = std::string("v") + Texts::VERSION + " (" + Version::GIT_HASH + ")"; - p.items.push_back({Locale::get("menu.items.restart"), ItemKind::Action, nullptr, nullptr, [] { + p.items.push_back({Locale::get("menu.items.restart"), ItemKind::ACTION, nullptr, nullptr, [] { if (Director::get()) { Director::get()->requestRestart(); } @@ -298,7 +298,7 @@ namespace Menu { nullptr}); #ifndef __EMSCRIPTEN__ - p.items.push_back({Locale::get("menu.items.exit_game"), ItemKind::Action, nullptr, nullptr, [] { + p.items.push_back({Locale::get("menu.items.exit_game"), ItemKind::ACTION, nullptr, nullptr, [] { if (Director::get()) { Director::get()->requestQuit(); } @@ -314,11 +314,11 @@ namespace Menu { // Alpha blending per pixel sobre el buffer ARGB (ABGR en memòria) static void blendRect(Uint32* buf, int x, int y, int w, int h, Uint32 src_argb, Uint8 src_alpha) { - const Uint8 sa = src_alpha; - const Uint8 sr = src_argb & 0xFF; - const Uint8 sg = (src_argb >> 8) & 0xFF; - const Uint8 sb = (src_argb >> 16) & 0xFF; - const Uint8 inv = 255 - sa; + const Uint8 SA = src_alpha; + const Uint8 SR = src_argb & 0xFF; + const Uint8 SG = (src_argb >> 8) & 0xFF; + const Uint8 SB = (src_argb >> 16) & 0xFF; + const Uint8 INV = 255 - SA; for (int row = y; row < y + h; row++) { if (row < 0 || row >= SCREEN_H) { continue; @@ -332,9 +332,9 @@ namespace Menu { Uint8 dr = dst & 0xFF; Uint8 dg = (dst >> 8) & 0xFF; Uint8 db = (dst >> 16) & 0xFF; - Uint8 r = (sr * sa + dr * inv) / 255; - Uint8 g = (sg * sa + dg * inv) / 255; - Uint8 b = (sb * sa + db * inv) / 255; + Uint8 r = (SR * SA + dr * INV) / 255; + Uint8 g = (SG * SA + dg * INV) / 255; + Uint8 b = (SB * SA + db * INV) / 255; *p = 0xFF000000U | (static_cast(b) << 16) | (static_cast(g) << 8) | r; } } @@ -365,8 +365,8 @@ namespace Menu { // body = (N-1) * ITEM_SPACING + charH — així BOTTOM_PAD és el buit real // sota el text del darrer ítem, no un buit extra per sobre d'un "slot" buit. static auto boxHeight(const Page& page) -> int { - const int n = static_cast(std::count_if(page.items.begin(), page.items.end(), [](const auto& it) { return isVisible(it); })); - int body = (n == 0) ? 8 : ((n - 1) * ITEM_SPACING) + 8; + const int N = static_cast(std::count_if(page.items.begin(), page.items.end(), [](const auto& it) { return isVisible(it); })); + int body = (N == 0) ? 8 : ((N - 1) * ITEM_SPACING) + 8; int header = HEADER_H + (page.subtitle.empty() ? 0 : SUBTITLE_H); return header + body + BOTTOM_PAD; } @@ -374,89 +374,89 @@ namespace Menu { // --- API pública --- void init() { - font_ = std::make_unique("fonts/8bithud.fnt", "fonts/8bithud.gif"); - stack_.clear(); - open_anim_ = 0.0F; - closing_ = false; - last_ticks_ = SDL_GetTicks(); + font = std::make_unique("fonts/8bithud.fnt", "fonts/8bithud.gif"); + stack.clear(); + open_anim = 0.0F; + closing = false; + last_ticks = SDL_GetTicks(); } void destroy() { - font_.reset(); - stack_.clear(); - closing_ = false; + font.reset(); + stack.clear(); + closing = false; } // "Actiu": accepta input. Durant l'animació de tancament la pila encara // té pàgines però ja no ha de processar tecles. auto isOpen() -> bool { - return !stack_.empty() && !closing_; + return !stack.empty() && !closing; } // "Visible": encara hi ha caixa per pintar (incloent close animation). auto isVisible() -> bool { - return !stack_.empty(); + return !stack.empty(); } void toggle() { - if (closing_ && !stack_.empty()) { + if (closing && !stack.empty()) { // Cancel·la el tancament en curs — continua l'animació cap a "obert" - // des del valor actual d'open_anim_. - closing_ = false; - last_ticks_ = SDL_GetTicks(); + // des del valor actual d'open_anim. + closing = false; + last_ticks = SDL_GetTicks(); return; } if (isOpen()) { close(); } else { - stack_.push_back(buildRoot()); - open_anim_ = 0.0F; - closing_ = false; - animated_h_ = static_cast(boxHeight(stack_.back())); - last_ticks_ = SDL_GetTicks(); + stack.push_back(buildRoot()); + open_anim = 0.0F; + closing = false; + animated_h = static_cast(boxHeight(stack.back())); + last_ticks = SDL_GetTicks(); } } - // close() no buida la pila immediatament: marca closing_ i deixa que - // render() faça decréixer open_anim_ fins a 0. En aquell moment es neteja + // close() no buida la pila immediatament: marca closing i deixa que + // render() faça decréixer open_anim fins a 0. En aquell moment es neteja // l'estat. Si es crida estant ja tancat o tancant-se, no-op. void close() { - if (stack_.empty() || closing_) { + if (stack.empty() || closing) { return; } - closing_ = true; - capturing_ = nullptr; - transition_active_ = false; - transition_progress_ = 1.0F; - last_ticks_ = SDL_GetTicks(); + closing = true; + capturing = nullptr; + transition_active = false; + transition_progress = 1.0F; + last_ticks = SDL_GetTicks(); } auto isCapturing() -> bool { - return capturing_ != nullptr; + return capturing != nullptr; } void captureKey(SDL_Scancode sc) { - if (capturing_ == nullptr) { + if (capturing == nullptr) { return; } if (sc == SDL_SCANCODE_ESCAPE) { // Cancel·la - capturing_ = nullptr; + capturing = nullptr; return; } - *capturing_ = sc; - capturing_ = nullptr; + *capturing = sc; + capturing = nullptr; } void handleKey(SDL_Scancode sc) { if (!isOpen()) { return; } - Page& page = stack_.back(); + Page& page = stack.back(); if (page.items.empty()) { // Pàgina buida — només backspace surt if (sc == SDL_SCANCODE_BACKSPACE) { - if (stack_.size() > 1) { + if (stack.size() > 1) { popPage(); } else { close(); @@ -477,32 +477,32 @@ namespace Menu { page.cursor = nextVisibleCursor(page, page.cursor, +1); break; case SDL_SCANCODE_LEFT: - if (page.items[page.cursor].kind != ItemKind::Submenu && + if (page.items[page.cursor].kind != ItemKind::SUBMENU && page.items[page.cursor].change) { page.items[page.cursor].change(-1); } break; case SDL_SCANCODE_RIGHT: - if (page.items[page.cursor].kind != ItemKind::Submenu && + if (page.items[page.cursor].kind != ItemKind::SUBMENU && page.items[page.cursor].change) { page.items[page.cursor].change(+1); } break; case SDL_SCANCODE_RETURN: case SDL_SCANCODE_KP_ENTER: - if (page.items[page.cursor].kind == ItemKind::Submenu || - page.items[page.cursor].kind == ItemKind::Action) { + if (page.items[page.cursor].kind == ItemKind::SUBMENU || + page.items[page.cursor].kind == ItemKind::ACTION) { if (page.items[page.cursor].enter) { page.items[page.cursor].enter(); } - } else if (page.items[page.cursor].kind == ItemKind::KeyBind) { - capturing_ = page.items[page.cursor].scancode; + } else if (page.items[page.cursor].kind == ItemKind::KEY_BIND) { + capturing = page.items[page.cursor].scancode; } else if (page.items[page.cursor].change) { page.items[page.cursor].change(+1); } break; case SDL_SCANCODE_BACKSPACE: - if (stack_.size() > 1) { + if (stack.size() > 1) { popPage(); } else { close(); @@ -514,8 +514,8 @@ namespace Menu { // Després de qualsevol acció, si el cursor quedara sobre un ítem ocult // (possible si una acció ha canviat la visibilitat pròpia de l'ítem actual, // edge case defensiu), salta al següent visible. - if (!stack_.empty()) { - Page& top = stack_.back(); + if (!stack.empty()) { + Page& top = stack.back(); if (!top.items.empty() && !isVisible(top.items[top.cursor])) { top.cursor = nextVisibleCursor(top, top.cursor, +1); } @@ -527,12 +527,12 @@ namespace Menu { // clip_x_min/clip_x_max limiten on es dibuixa text i la línia separadora. static void renderPageContent(Uint32* pixel_data, const Page& page, int box_x, int box_y, int x_offset, int clip_x_min, int clip_x_max, int clip_y_min, int clip_y_max) { // Títol - int title_w = font_->width(page.title); + int title_w = font->width(page.title); int title_x = box_x + ((BOX_W - title_w) / 2) + x_offset; - font_->drawClipped(pixel_data, title_x, box_y + TITLE_PAD_Y, page.title, TITLE_COLOR, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + font->drawClipped(pixel_data, title_x, box_y + TITLE_PAD_Y, page.title, TITLE_COLOR, clip_x_min, clip_x_max, clip_y_min, clip_y_max); // Línia sota el títol (també lliscada) — clippada manualment - int title_line_y = box_y + TITLE_PAD_Y + font_->charHeight() + 2; + int title_line_y = box_y + TITLE_PAD_Y + font->charHeight() + 2; if (title_line_y >= clip_y_min && title_line_y < clip_y_max) { int line_x = box_x + 4 + x_offset; int line_w = BOX_W - 8; @@ -546,17 +546,17 @@ namespace Menu { // Subtítol opcional (sota la línia del títol, abans dels items) int items_y = title_line_y + 4; if (!page.subtitle.empty()) { - int sub_w = font_->width(page.subtitle.c_str()); + int sub_w = font->width(page.subtitle.c_str()); int sub_x = box_x + ((BOX_W - sub_w) / 2) + x_offset; - font_->drawClipped(pixel_data, sub_x, items_y, page.subtitle.c_str(), LABEL_COLOR, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + font->drawClipped(pixel_data, sub_x, items_y, page.subtitle.c_str(), LABEL_COLOR, clip_x_min, clip_x_max, clip_y_min, clip_y_max); items_y += SUBTITLE_H; } // Compta visibles — si cap, dibuixa placeholder (caixa totalment col·lapsada però oberta) - const int visible_count = static_cast(std::count_if(page.items.begin(), page.items.end(), [](const auto& it) { return isVisible(it); })); - if (visible_count == 0) { + const int VISIBLE_COUNT = static_cast(std::count_if(page.items.begin(), page.items.end(), [](const auto& it) { return isVisible(it); })); + if (VISIBLE_COUNT == 0) { const char* empty_text = Locale::get("menu.values.empty"); - int ew = font_->width(empty_text); - font_->drawClipped(pixel_data, box_x + ((BOX_W - ew) / 2) + x_offset, items_y + 2, empty_text, EMPTY_COLOR, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + int ew = font->width(empty_text); + font->drawClipped(pixel_data, box_x + ((BOX_W - ew) / 2) + x_offset, items_y + 2, empty_text, EMPTY_COLOR, clip_x_min, clip_x_max, clip_y_min, clip_y_max); return; } @@ -571,30 +571,30 @@ namespace Menu { bool selected = (static_cast(i) == page.cursor); Uint32 label_color = selected ? CURSOR_COLOR : LABEL_COLOR; - // Action: sense valor a la dreta — centrem el label amb el cursor just a l'esquerra. - if (item.kind == ItemKind::Action) { - int lw = font_->width(item.label); + // ACTION: sense valor a la dreta — centrem el label amb el cursor just a l'esquerra. + if (item.kind == ItemKind::ACTION) { + int lw = font->width(item.label); int lx = box_x + ((BOX_W - lw) / 2) + x_offset; if (selected) { - font_->drawClipped(pixel_data, lx - font_->width("> "), y, ">", CURSOR_COLOR, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + font->drawClipped(pixel_data, lx - font->width("> "), y, ">", CURSOR_COLOR, clip_x_min, clip_x_max, clip_y_min, clip_y_max); } - font_->drawClipped(pixel_data, lx, y, item.label, label_color, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + font->drawClipped(pixel_data, lx, y, item.label, label_color, clip_x_min, clip_x_max, clip_y_min, clip_y_max); continue; } if (selected) { - font_->drawClipped(pixel_data, box_x + 4 + x_offset, y, ">", CURSOR_COLOR, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + font->drawClipped(pixel_data, box_x + 4 + x_offset, y, ">", CURSOR_COLOR, clip_x_min, clip_x_max, clip_y_min, clip_y_max); } - font_->drawClipped(pixel_data, box_x + ITEM_PAD_X + x_offset, y, item.label, label_color, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + font->drawClipped(pixel_data, box_x + ITEM_PAD_X + x_offset, y, item.label, label_color, clip_x_min, clip_x_max, clip_y_min, clip_y_max); - if (item.kind == ItemKind::Submenu) { + if (item.kind == ItemKind::SUBMENU) { const char* arrow = ">>"; - int aw = font_->width(arrow); + int aw = font->width(arrow); Uint32 ac = selected ? CURSOR_COLOR : VALUE_COLOR; - font_->drawClipped(pixel_data, box_x + BOX_W - ITEM_PAD_X - aw + x_offset, y, arrow, ac, clip_x_min, clip_x_max, clip_y_min, clip_y_max); - } else if (item.kind == ItemKind::KeyBind) { - bool this_capturing = (capturing_ == item.scancode); + font->drawClipped(pixel_data, box_x + BOX_W - ITEM_PAD_X - aw + x_offset, y, arrow, ac, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + } else if (item.kind == ItemKind::KEY_BIND) { + bool this_capturing = (capturing == item.scancode); const char* text = nullptr; if (this_capturing) { text = Locale::get("menu.values.press_key"); @@ -606,83 +606,83 @@ namespace Menu { if ((text == nullptr) || (*text == 0)) { text = Locale::get("menu.values.unknown"); } - int tw = font_->width(text); + int tw = font->width(text); Uint32 tc = 0; if (this_capturing) { tc = 0xFF00FFFF; } else { tc = selected ? CURSOR_COLOR : VALUE_COLOR; } - font_->drawClipped(pixel_data, box_x + BOX_W - ITEM_PAD_X - tw + x_offset, y, text, tc, clip_x_min, clip_x_max, clip_y_min, clip_y_max); - } else if (item.getValue) { - std::string value = item.getValue(); - int value_w = font_->width(value.c_str()); + font->drawClipped(pixel_data, box_x + BOX_W - ITEM_PAD_X - tw + x_offset, y, text, tc, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + } else if (item.get_value) { + std::string value = item.get_value(); + int value_w = font->width(value.c_str()); Uint32 value_color = selected ? CURSOR_COLOR : VALUE_COLOR; - font_->drawClipped(pixel_data, box_x + BOX_W - ITEM_PAD_X - value_w + x_offset, y, value.c_str(), value_color, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + font->drawClipped(pixel_data, box_x + BOX_W - ITEM_PAD_X - value_w + x_offset, y, value.c_str(), value_color, clip_x_min, clip_x_max, clip_y_min, clip_y_max); } } } void render(Uint32* pixel_data) { - if (!isVisible() || !font_ || (pixel_data == nullptr)) { + if (!isVisible() || !font || (pixel_data == nullptr)) { return; } // Delta time Uint32 now = SDL_GetTicks(); - float dt = static_cast(now - last_ticks_) / 1000.0F; - last_ticks_ = now; - if (closing_) { - open_anim_ -= CLOSE_SPEED * dt; - if (open_anim_ <= 0.0F) { + float dt = static_cast(now - last_ticks) / 1000.0F; + last_ticks = now; + if (closing) { + open_anim -= CLOSE_SPEED * dt; + if (open_anim <= 0.0F) { // Animació de tancament completada — buida l'estat de veritat. - open_anim_ = 0.0F; - stack_.clear(); - animated_h_ = 0.0F; - closing_ = false; + open_anim = 0.0F; + stack.clear(); + animated_h = 0.0F; + closing = false; return; } - } else if (open_anim_ < 1.0F) { - open_anim_ += OPEN_SPEED * dt; - open_anim_ = std::min(open_anim_, 1.0F); + } else if (open_anim < 1.0F) { + open_anim += OPEN_SPEED * dt; + open_anim = std::min(open_anim, 1.0F); } // Avança transició - if (transition_active_) { - transition_progress_ += TRANSITION_SPEED * dt; - if (transition_progress_ >= 1.0F) { - transition_progress_ = 1.0F; - transition_active_ = false; + if (transition_active) { + transition_progress += TRANSITION_SPEED * dt; + if (transition_progress >= 1.0F) { + transition_progress = 1.0F; + transition_active = false; } } - const Page& page = stack_.back(); - const int current_h = boxHeight(page); + const Page& page = stack.back(); + const int CURRENT_H = boxHeight(page); // Smoothing exponencial de l'alçada cap al target (pàgina actual + ítems visibles). // Permet que el menú reaccione amb animació quan una opció canvia la visibilitat // d'altres ítems en calent (p. ex. shader=off → shader_type/preset/supersampling). - if (animated_h_ <= 0.0F) { - animated_h_ = static_cast(current_h); + if (animated_h <= 0.0F) { + animated_h = static_cast(CURRENT_H); } else { - float diff = static_cast(current_h) - animated_h_; + float diff = static_cast(CURRENT_H) - animated_h; if (std::fabs(diff) < 0.5F) { - animated_h_ = static_cast(current_h); + animated_h = static_cast(CURRENT_H); } else { float t = HEIGHT_RATE * dt; t = std::min(t, 1.0F); - animated_h_ += diff * t; + animated_h += diff * t; } } - float eased = Easing::outQuad(open_anim_); + float eased = Easing::outQuad(open_anim); // Calcula alçada (amb transició si escau) - int target_h = static_cast(animated_h_); - if (transition_active_) { - int outgoing_h = boxHeight(transition_outgoing_); - float tp = Easing::outQuad(transition_progress_); - target_h = Easing::lerpInt(outgoing_h, static_cast(animated_h_), tp); + int target_h = static_cast(animated_h); + if (transition_active) { + int outgoing_h = boxHeight(transition_outgoing); + float tp = Easing::outQuad(transition_progress); + target_h = Easing::lerpInt(outgoing_h, static_cast(animated_h), tp); } // Caixa creix verticalment durant l'obertura @@ -696,17 +696,17 @@ namespace Menu { blendRect(pixel_data, box_x, box_y, BOX_W, box_h, BG_COLOR, alpha); // El contingut només apareix quan la caixa és prou gran - if (open_anim_ >= 0.9F) { + if (open_anim >= 0.9F) { int clip_x_min = box_x + 1; int clip_x_max = box_x + BOX_W - 1; int clip_y_min = box_y + 1; int clip_y_max = box_y + box_h - 1; - if (transition_active_) { - float tp = Easing::outQuad(transition_progress_); - int out_offset = static_cast(-transition_dir_ * BOX_W * tp); - int new_offset = static_cast(transition_dir_ * BOX_W * (1.0F - tp)); - renderPageContent(pixel_data, transition_outgoing_, box_x, box_y, out_offset, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + if (transition_active) { + float tp = Easing::outQuad(transition_progress); + int out_offset = static_cast(-transition_dir * BOX_W * tp); + int new_offset = static_cast(transition_dir * BOX_W * (1.0F - tp)); + renderPageContent(pixel_data, transition_outgoing, box_x, box_y, out_offset, clip_x_min, clip_x_max, clip_y_min, clip_y_max); renderPageContent(pixel_data, page, box_x, box_y, new_offset, clip_x_min, clip_x_max, clip_y_min, clip_y_max); } else { renderPageContent(pixel_data, page, box_x, box_y, 0, clip_x_min, clip_x_max, clip_y_min, clip_y_max); From 1e00f5c3a40008c0a7a88aac31d72f70b5152b10 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 16 May 2026 14:37:56 +0200 Subject: [PATCH 05/13] fix: tidy gamepad/overlay/jfile (statics sense sufix, locals UPPER_CASE) --- source/core/input/gamepad.cpp | 134 ++++++++++---------- source/core/jail/jfile.cpp | 52 ++++---- source/core/rendering/overlay.cpp | 196 +++++++++++++++--------------- 3 files changed, 191 insertions(+), 191 deletions(-) diff --git a/source/core/input/gamepad.cpp b/source/core/input/gamepad.cpp index 3edbebd..6a9679e 100644 --- a/source/core/input/gamepad.cpp +++ b/source/core/input/gamepad.cpp @@ -11,8 +11,8 @@ namespace Gamepad { - static SDL_Gamepad* pad_ = nullptr; - static SDL_JoystickID pad_id_ = 0; + static SDL_Gamepad* pad = nullptr; + static SDL_JoystickID pad_id = 0; // Emscripten-only: SDL 3.4+ ja no casa el GUID dels mandos web (el gamepad.id // de Chrome/Android no porta Vendor/Product, el parser extreu valors @@ -54,9 +54,9 @@ namespace Gamepad { // elimina espais finals i talla a 25 caràcters. static auto prettyName(const char* raw) -> std::string { std::string name = ((raw != nullptr) && (*raw != 0)) ? raw : "Gamepad"; - const auto pos = name.find_first_of("(["); - if (pos != std::string::npos) { - name.erase(pos); + const auto POS = name.find_first_of("(["); + if (POS != std::string::npos) { + name.erase(POS); } while (!name.empty() && name.back() == ' ') { name.pop_back(); @@ -74,16 +74,16 @@ namespace Gamepad { static constexpr Sint16 STICK_DEADZONE = 12000; // Estat previ per a detecció de flanc (edge-triggered) - static bool prev_up_ = false; - static bool prev_down_ = false; - static bool prev_left_ = false; - static bool prev_right_ = false; - static bool prev_south_ = false; - static bool prev_east_ = false; - static bool prev_west_ = false; - static bool prev_north_ = false; - static bool prev_start_ = false; - static bool prev_back_ = false; + static bool prev_up = false; + static bool prev_down = false; + static bool prev_left = false; + static bool prev_right = false; + static bool prev_south = false; + static bool prev_east = false; + static bool prev_west = false; + static bool prev_north = false; + static bool prev_start = false; + static bool prev_back = false; static void notify(const std::string& name, const char* status_key) { std::string msg = name.empty() ? "Gamepad" : name; @@ -106,10 +106,10 @@ namespace Gamepad { if (!SDL_IsGamepad(ids[i])) { continue; } - pad_ = SDL_OpenGamepad(ids[i]); - if (pad_ != nullptr) { - pad_id_ = ids[i]; - SDL_Log("Gamepad connectat: %s", SDL_GetGamepadName(pad_)); + pad = SDL_OpenGamepad(ids[i]); + if (pad != nullptr) { + pad_id = ids[i]; + SDL_Log("Gamepad connectat: %s", SDL_GetGamepadName(pad)); break; } } @@ -132,16 +132,16 @@ namespace Gamepad { } void destroy() { - if (pad_ != nullptr) { - SDL_CloseGamepad(pad_); - pad_ = nullptr; - pad_id_ = 0; + if (pad != nullptr) { + SDL_CloseGamepad(pad); + pad = nullptr; + pad_id = 0; } SDL_QuitSubSystem(SDL_INIT_GAMEPAD); } auto isConnected() -> bool { - return pad_ != nullptr; + return pad != nullptr; } void handleEvent(const SDL_Event& event) { @@ -149,27 +149,27 @@ namespace Gamepad { // GAMEPAD_ADDED) perquè SDL no reconeix el GUID. Escoltem els dos i // injectem el mapping estàndard abans d'obrir el mando. if (event.type == SDL_EVENT_GAMEPAD_ADDED || event.type == SDL_EVENT_JOYSTICK_ADDED) { - if (pad_ == nullptr) { + if (pad == nullptr) { SDL_JoystickID jid = event.jdevice.which; installWebStandardMapping(jid); if (!SDL_IsGamepad(jid)) { return; } - pad_ = SDL_OpenGamepad(jid); - if (pad_ != nullptr) { - pad_id_ = jid; - std::string name = prettyName(SDL_GetGamepadName(pad_)); + pad = SDL_OpenGamepad(jid); + if (pad != nullptr) { + pad_id = jid; + std::string name = prettyName(SDL_GetGamepadName(pad)); SDL_Log("Gamepad connectat: %s", name.c_str()); notifyConnected(name); } } } else if (event.type == SDL_EVENT_GAMEPAD_REMOVED || event.type == SDL_EVENT_JOYSTICK_REMOVED) { - if ((pad_ != nullptr) && event.jdevice.which == pad_id_) { - std::string saved_name = prettyName(SDL_GetGamepadName(pad_)); + if ((pad != nullptr) && event.jdevice.which == pad_id) { + std::string saved_name = prettyName(SDL_GetGamepadName(pad)); SDL_Log("Gamepad desconnectat: %s", saved_name.c_str()); - SDL_CloseGamepad(pad_); - pad_ = nullptr; - pad_id_ = 0; + SDL_CloseGamepad(pad); + pad = nullptr; + pad_id = 0; // Neteja qualsevol tecla virtual que poguera estar premuda JI_SetVirtualKey(SDL_SCANCODE_UP, JI_VSRC_GAMEPAD, false); JI_SetVirtualKey(SDL_SCANCODE_DOWN, JI_VSRC_GAMEPAD, false); @@ -196,19 +196,19 @@ namespace Gamepad { } void update() { - if (pad_ == nullptr) { + if (pad == nullptr) { return; } // D-pad - bool dup = SDL_GetGamepadButton(pad_, SDL_GAMEPAD_BUTTON_DPAD_UP); - bool ddn = SDL_GetGamepadButton(pad_, SDL_GAMEPAD_BUTTON_DPAD_DOWN); - bool dlt = SDL_GetGamepadButton(pad_, SDL_GAMEPAD_BUTTON_DPAD_LEFT); - bool drt = SDL_GetGamepadButton(pad_, SDL_GAMEPAD_BUTTON_DPAD_RIGHT); + bool dup = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_DPAD_UP); + bool ddn = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_DPAD_DOWN); + bool dlt = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_DPAD_LEFT); + bool drt = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_DPAD_RIGHT); // Stick esquerre amb dead-zone - Sint16 lx = SDL_GetGamepadAxis(pad_, SDL_GAMEPAD_AXIS_LEFTX); - Sint16 ly = SDL_GetGamepadAxis(pad_, SDL_GAMEPAD_AXIS_LEFTY); + Sint16 lx = SDL_GetGamepadAxis(pad, SDL_GAMEPAD_AXIS_LEFTX); + Sint16 ly = SDL_GetGamepadAxis(pad, SDL_GAMEPAD_AXIS_LEFTY); bool sup = ly < -STICK_DEADZONE; bool sdn = ly > STICK_DEADZONE; bool slt = lx < -STICK_DEADZONE; @@ -220,41 +220,41 @@ namespace Gamepad { bool rt = drt || srt; // Botons frontals (layout SDL: SOUTH=A/Cross, EAST=B/Circle, WEST=X/Square, NORTH=Y/Triangle) - bool south = SDL_GetGamepadButton(pad_, SDL_GAMEPAD_BUTTON_SOUTH); - bool east = SDL_GetGamepadButton(pad_, SDL_GAMEPAD_BUTTON_EAST); - bool west = SDL_GetGamepadButton(pad_, SDL_GAMEPAD_BUTTON_WEST); - bool north = SDL_GetGamepadButton(pad_, SDL_GAMEPAD_BUTTON_NORTH); - bool start = SDL_GetGamepadButton(pad_, SDL_GAMEPAD_BUTTON_START); - bool back = SDL_GetGamepadButton(pad_, SDL_GAMEPAD_BUTTON_BACK); + bool south = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_SOUTH); + bool east = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_EAST); + bool west = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_WEST); + bool north = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_NORTH); + bool start = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_START); + bool back = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_BACK); // Select (Back) → obre/tanca menú de servei (flanc) - if (back && !prev_back_) { + if (back && !prev_back) { pushKey(KeyConfig::scancode("menu_toggle")); } // Start → pausa (flanc) - if (start && !prev_start_) { + if (start && !prev_start) { pushKey(KeyConfig::scancode("pause_toggle")); } if (Menu::isOpen()) { // Navegació del menú per flanc - if (up && !prev_up_) { + if (up && !prev_up) { pushKey(SDL_SCANCODE_UP); } - if (dn && !prev_down_) { + if (dn && !prev_down) { pushKey(SDL_SCANCODE_DOWN); } - if (lt && !prev_left_) { + if (lt && !prev_left) { pushKey(SDL_SCANCODE_LEFT); } - if (rt && !prev_right_) { + if (rt && !prev_right) { pushKey(SDL_SCANCODE_RIGHT); } // EAST accepta, SOUTH cancela / endarrere - if (east && !prev_east_) { + if (east && !prev_east) { pushKey(SDL_SCANCODE_RETURN); } - if (south && !prev_south_) { + if (south && !prev_south) { pushKey(SDL_SCANCODE_BACKSPACE); } @@ -270,22 +270,22 @@ namespace Gamepad { JI_SetVirtualKey(SDL_SCANCODE_LEFT, JI_VSRC_GAMEPAD, lt); JI_SetVirtualKey(SDL_SCANCODE_RIGHT, JI_VSRC_GAMEPAD, rt); // Qualsevol dels 4 botons frontals avança escenes (JI_AnyKey via Enter sintètic) - if ((south && !prev_south_) || (east && !prev_east_) || - (west && !prev_west_) || (north && !prev_north_)) { + if ((south && !prev_south) || (east && !prev_east) || + (west && !prev_west) || (north && !prev_north)) { pushKey(SDL_SCANCODE_RETURN); } } - prev_up_ = up; - prev_down_ = dn; - prev_left_ = lt; - prev_right_ = rt; - prev_south_ = south; - prev_east_ = east; - prev_west_ = west; - prev_north_ = north; - prev_start_ = start; - prev_back_ = back; + prev_up = up; + prev_down = dn; + prev_left = lt; + prev_right = rt; + prev_south = south; + prev_east = east; + prev_west = west; + prev_north = north; + prev_start = start; + prev_back = back; } } // namespace Gamepad diff --git a/source/core/jail/jfile.cpp b/source/core/jail/jfile.cpp index e52d51f..48ec485 100644 --- a/source/core/jail/jfile.cpp +++ b/source/core/jail/jfile.cpp @@ -15,36 +15,36 @@ namespace { - struct keyvalue { + struct Keyvalue { std::string key; std::string value; }; - std::vector config; + std::vector config; std::string resource_folder; std::string config_folder; - void load_config_values() { + void loadConfigValues() { config.clear(); - const std::string config_file = config_folder + "/config.txt"; - std::ifstream fi(config_file); + const std::string CONFIG_FILE = config_folder + "/config.txt"; + std::ifstream fi(CONFIG_FILE); if (!fi.is_open()) { return; } std::string line; while (std::getline(fi, line)) { - const auto eq = line.find('='); - if (eq == std::string::npos) { + const auto EQ = line.find('='); + if (EQ == std::string::npos) { continue; } - config.push_back({line.substr(0, eq), line.substr(eq + 1)}); + config.push_back({line.substr(0, EQ), line.substr(EQ + 1)}); } } - void save_config_values() { - const std::string config_file = config_folder + "/config.txt"; - std::ofstream fo(config_file); + void saveConfigValues() { + const std::string CONFIG_FILE = config_folder + "/config.txt"; + std::ofstream fo(CONFIG_FILE); if (!fo.is_open()) { return; } @@ -103,34 +103,34 @@ void file_setconfigfolder(const char* foldername) { } auto file_getconfigfolder() -> const char* { - thread_local std::string folder; - folder = config_folder + "/"; - return folder.c_str(); + thread_local std::string folder_; + folder_ = config_folder + "/"; + return folder_.c_str(); } auto file_getconfigvalue(const char* key) -> const char* { if (config.empty()) { - load_config_values(); + loadConfigValues(); } - const auto it = std::find_if(config.begin(), config.end(), [key](const keyvalue& pair) { return pair.key == key; }); - if (it != config.end()) { - thread_local std::string value_cache; - value_cache = it->value; - return value_cache.c_str(); + const auto IT = std::find_if(config.begin(), config.end(), [key](const Keyvalue& pair) { return pair.key == key; }); + if (IT != config.end()) { + thread_local std::string value_cache_; + value_cache_ = IT->value; + return value_cache_.c_str(); } return nullptr; } void file_setconfigvalue(const char* key, const char* value) { if (config.empty()) { - load_config_values(); + loadConfigValues(); } - const auto it = std::find_if(config.begin(), config.end(), [key](const keyvalue& pair) { return pair.key == key; }); - if (it != config.end()) { - it->value = value; - save_config_values(); + const auto IT = std::find_if(config.begin(), config.end(), [key](const Keyvalue& pair) { return pair.key == key; }); + if (IT != config.end()) { + IT->value = value; + saveConfigValues(); return; } config.push_back({std::string(key), std::string(value)}); - save_config_values(); + saveConfigValues(); } diff --git a/source/core/rendering/overlay.cpp b/source/core/rendering/overlay.cpp index ffbc285..498f9e2 100644 --- a/source/core/rendering/overlay.cpp +++ b/source/core/rendering/overlay.cpp @@ -14,7 +14,7 @@ namespace Overlay { - static std::unique_ptr font_; + static std::unique_ptr font; // --- Aspecte de la notificació --- static constexpr Uint32 NOTIF_BG_COLOR = 0xFF2E1A1A; // Fons blau fosc (ABGR) @@ -52,12 +52,12 @@ namespace Overlay { int box_h{0}; // Alçada de la caixa (calculat al crear) }; - static std::vector notifications_; - static Uint32 last_ticks_ = 0; + static std::vector notifications; + static Uint32 last_ticks = 0; // --- Render info --- - static Options::RenderInfoPosition info_visible_pos_ = Options::RenderInfoPosition::OFF; - static float info_anim_ = 0.0F; // 0 = fora de pantalla, 1 = posició final + static Options::RenderInfoPosition info_visible_pos = Options::RenderInfoPosition::OFF; + static float info_anim = 0.0F; // 0 = fora de pantalla, 1 = posició final static constexpr float INFO_SLIDE_SPEED = 5.0F; // Segments del render info — cadascú amb la seva pròpia visibilitat animada @@ -69,7 +69,7 @@ namespace Overlay { bool visible{false}; bool mono_digits{false}; // si true, dígits amb amplada fixa (la resta natural) }; - static InfoSegment info_segments_[INFO_SEGMENT_COUNT]; + static InfoSegment info_segments[INFO_SEGMENT_COUNT]; // --- Crèdits cinematogràfics --- // Usen el sistema de notificacions en posició TOP_CENTER_DROP. @@ -78,8 +78,8 @@ namespace Overlay { PLAYING_1, GAP, PLAYING_2 }; - static CreditsPhase credits_phase_ = CreditsPhase::IDLE; - static float credits_timer_ = 0.0F; // segons dins la phase actual + static CreditsPhase credits_phase = CreditsPhase::IDLE; + static float credits_timer = 0.0F; // segons dins la phase actual static constexpr float CREDITS_DELAY = 2.0F; static constexpr float CREDITS_GAP = 0.4F; static constexpr float CREDITS_HOLD = 7.5F; @@ -87,16 +87,16 @@ namespace Overlay { static constexpr Uint32 CREDITS_FG = NOTIF_TEXT_COLOR; // mateix cian // --- Doble ESC per a eixir --- - static bool esc_waiting_ = false; + static bool esc_waiting = false; void init() { - font_ = std::make_unique("fonts/8bithud.fnt", "fonts/8bithud.gif"); - last_ticks_ = SDL_GetTicks(); + font = std::make_unique("fonts/8bithud.fnt", "fonts/8bithud.gif"); + last_ticks = SDL_GetTicks(); } void destroy() { - font_.reset(); - notifications_.clear(); + font.reset(); + notifications.clear(); } // Pinta un rectangle sòlid dins els límits de la pantalla @@ -115,17 +115,17 @@ namespace Overlay { } void render(Uint32* pixel_data) { - if (!font_ || (pixel_data == nullptr)) { + if (!font || (pixel_data == nullptr)) { return; } // Calcula delta time Uint32 now = SDL_GetTicks(); - float dt = static_cast(now - last_ticks_) / 1000.0F; - last_ticks_ = now; + float dt = static_cast(now - last_ticks) / 1000.0F; + last_ticks = now; // Actualitza i pinta cada notificació - for (auto& notif : notifications_) { + for (auto& notif : notifications) { switch (notif.status) { case Status::RISING: notif.anim += SLIDE_SPEED * dt; @@ -184,52 +184,52 @@ namespace Overlay { } // Pinta el text línia a línia (amb ombra o contorn segons style) - int line_h = font_->charHeight(); + int line_h = font->charHeight(); int line_y = box_y + NOTIF_PADDING_V; for (const auto& line : notif.lines) { - int line_w = font_->width(line.c_str()); + int line_w = font->width(line.c_str()); int line_x = box_x + ((notif.box_w - line_w) / 2); // centrat dins la caixa if (notif.style == NotifStyle::SHADOW) { - font_->draw(pixel_data, line_x + 1, line_y + 1, line.c_str(), notif.accent_color); + font->draw(pixel_data, line_x + 1, line_y + 1, line.c_str(), notif.accent_color); } else if (notif.style == NotifStyle::OUTLINE) { // Contorn 4-direccional (N, S, E, W) - font_->draw(pixel_data, line_x, line_y - 1, line.c_str(), notif.accent_color); - font_->draw(pixel_data, line_x, line_y + 1, line.c_str(), notif.accent_color); - font_->draw(pixel_data, line_x - 1, line_y, line.c_str(), notif.accent_color); - font_->draw(pixel_data, line_x + 1, line_y, line.c_str(), notif.accent_color); + font->draw(pixel_data, line_x, line_y - 1, line.c_str(), notif.accent_color); + font->draw(pixel_data, line_x, line_y + 1, line.c_str(), notif.accent_color); + font->draw(pixel_data, line_x - 1, line_y, line.c_str(), notif.accent_color); + font->draw(pixel_data, line_x + 1, line_y, line.c_str(), notif.accent_color); } - font_->draw(pixel_data, line_x, line_y, line.c_str(), notif.text_color); + font->draw(pixel_data, line_x, line_y, line.c_str(), notif.text_color); line_y += line_h + 1; } } // Render info (FPS, driver, shader) — animat amb slide vertical - // State machine: visible_pos s'actualitza cap a desired quan anim arriba a 0 + // State machine: visible_pos s'actualitza cap a DESIRED quan anim arriba a 0 { - const auto desired = Options::render_info.position; - if (desired == info_visible_pos_) { + const auto DESIRED = Options::render_info.position; + if (DESIRED == info_visible_pos) { // Mateix lloc: entra fins a 1 - if (info_anim_ < 1.0F) { - info_anim_ += INFO_SLIDE_SPEED * dt; - info_anim_ = std::min(info_anim_, 1.0F); + if (info_anim < 1.0F) { + info_anim += INFO_SLIDE_SPEED * dt; + info_anim = std::min(info_anim, 1.0F); } } else { // Canvi: si visible_pos està OFF, commuta directament - if (info_visible_pos_ == Options::RenderInfoPosition::OFF) { - info_visible_pos_ = desired; - info_anim_ = 0.0F; + if (info_visible_pos == Options::RenderInfoPosition::OFF) { + info_visible_pos = DESIRED; + info_anim = 0.0F; } else { // Ix del lloc actual - info_anim_ -= INFO_SLIDE_SPEED * dt; - if (info_anim_ <= 0.0F) { - info_anim_ = 0.0F; - info_visible_pos_ = desired; + info_anim -= INFO_SLIDE_SPEED * dt; + if (info_anim <= 0.0F) { + info_anim = 0.0F; + info_visible_pos = DESIRED; } } } // Actualitza animacions individuals dels segments - for (auto& seg : info_segments_) { + for (auto& seg : info_segments) { float target = seg.visible ? 1.0F : 0.0F; if (seg.anim < target) { seg.anim += SEG_SPEED * dt; @@ -241,25 +241,25 @@ namespace Overlay { } // Render si hi ha alguna cosa visible - if (info_visible_pos_ != Options::RenderInfoPosition::OFF && info_anim_ > 0.0F) { - const int DIGIT_CELL = font_->charBoxWidth() - 1; // amplada uniforme per dígit + if (info_visible_pos != Options::RenderInfoPosition::OFF && info_anim > 0.0F) { + const int DIGIT_CELL = font->charBoxWidth() - 1; // amplada uniforme per dígit // Calcula amplada total interpolant cada segment per la seva anim float total_w = 0.0F; - for (const auto& seg : info_segments_) { + for (const auto& seg : info_segments) { if (seg.anim > 0.0F && !seg.text.empty()) { int w = seg.mono_digits - ? font_->widthMonoDigits(seg.text.c_str(), DIGIT_CELL) - : font_->width(seg.text.c_str()); + ? font->widthMonoDigits(seg.text.c_str(), DIGIT_CELL) + : font->width(seg.text.c_str()); total_w += w * Easing::outQuad(seg.anim); } } if (total_w > 0.0F) { - float eased_y = Easing::outQuad(info_anim_); - int ch = font_->charHeight(); + float eased_y = Easing::outQuad(info_anim); + int ch = font->charHeight(); int final_y; int start_y; - if (info_visible_pos_ == Options::RenderInfoPosition::TOP) { + if (info_visible_pos == Options::RenderInfoPosition::TOP) { final_y = 1; start_y = -ch - 1; } else { @@ -270,18 +270,18 @@ namespace Overlay { // Dibuixa cada segment en la seva posició x acumulada float cur_x = (SCREEN_W - total_w) / 2.0F; - for (const auto& seg : info_segments_) { + for (const auto& seg : info_segments) { if (seg.anim > 0.01F && !seg.text.empty()) { int xi = static_cast(cur_x); int seg_w = seg.mono_digits - ? font_->widthMonoDigits(seg.text.c_str(), DIGIT_CELL) - : font_->width(seg.text.c_str()); + ? font->widthMonoDigits(seg.text.c_str(), DIGIT_CELL) + : font->width(seg.text.c_str()); if (seg.mono_digits) { - font_->drawMonoDigits(pixel_data, xi + 1, info_y + 1, seg.text.c_str(), Options::render_info.shadow_color, DIGIT_CELL); - font_->drawMonoDigits(pixel_data, xi, info_y, seg.text.c_str(), Options::render_info.text_color, DIGIT_CELL); + font->drawMonoDigits(pixel_data, xi + 1, info_y + 1, seg.text.c_str(), Options::render_info.shadow_color, DIGIT_CELL); + font->drawMonoDigits(pixel_data, xi, info_y, seg.text.c_str(), Options::render_info.text_color, DIGIT_CELL); } else { - font_->draw(pixel_data, xi + 1, info_y + 1, seg.text.c_str(), Options::render_info.shadow_color); - font_->draw(pixel_data, xi, info_y, seg.text.c_str(), Options::render_info.text_color); + font->draw(pixel_data, xi + 1, info_y + 1, seg.text.c_str(), Options::render_info.shadow_color); + font->draw(pixel_data, xi, info_y, seg.text.c_str(), Options::render_info.text_color); } cur_x += seg_w * Easing::outQuad(seg.anim); } @@ -291,34 +291,34 @@ namespace Overlay { } // Elimina les acabades - std::erase_if(notifications_, [](const Notification& n) { return n.status == Status::FINISHED; }); + std::erase_if(notifications, [](const Notification& n) { return n.status == Status::FINISHED; }); // Si la notificació d'ESC ha desaparegut, reseteja l'estat - if (esc_waiting_ && notifications_.empty()) { - esc_waiting_ = false; + if (esc_waiting && notifications.empty()) { + esc_waiting = false; } // Indicador de pausa persistent (cantó superior dret) if ((Director::get() != nullptr) && Director::get()->isPaused()) { const char* pause_text = Locale::get("notifications.pause"); - int w = font_->width(pause_text); + int w = font->width(pause_text); int x = SCREEN_W - w - 4; int y = 4; // Contorn blanc 4-direccional - font_->draw(pixel_data, x, y - 1, pause_text, 0xFFFFFFFF); - font_->draw(pixel_data, x, y + 1, pause_text, 0xFFFFFFFF); - font_->draw(pixel_data, x - 1, y, pause_text, 0xFFFFFFFF); - font_->draw(pixel_data, x + 1, y, pause_text, 0xFFFFFFFF); + font->draw(pixel_data, x, y - 1, pause_text, 0xFFFFFFFF); + font->draw(pixel_data, x, y + 1, pause_text, 0xFFFFFFFF); + font->draw(pixel_data, x - 1, y, pause_text, 0xFFFFFFFF); + font->draw(pixel_data, x + 1, y, pause_text, 0xFFFFFFFF); // Text en roig - font_->draw(pixel_data, x, y, pause_text, 0xFF0000FF); + font->draw(pixel_data, x, y, pause_text, 0xFF0000FF); } // Crèdits seqüencials — dispara notificacions TOP_CENTER_DROP una darrere l'altra. - if (credits_phase_ != CreditsPhase::IDLE) { - credits_timer_ += dt; - switch (credits_phase_) { + if (credits_phase != CreditsPhase::IDLE) { + credits_timer += dt; + switch (credits_phase) { case CreditsPhase::DELAY: - if (credits_timer_ >= CREDITS_DELAY) { + if (credits_timer >= CREDITS_DELAY) { showNotification( {std::string(Locale::get("credits.port_role")), std::string(Locale::get("credits.port_name"))}, @@ -327,18 +327,18 @@ namespace Overlay { NotifStyle::OUTLINE, CREDITS_BG, CREDITS_FG); - credits_phase_ = CreditsPhase::PLAYING_1; - credits_timer_ = 0.0F; + credits_phase = CreditsPhase::PLAYING_1; + credits_timer = 0.0F; } break; case CreditsPhase::PLAYING_1: - if (notifications_.empty()) { - credits_phase_ = CreditsPhase::GAP; - credits_timer_ = 0.0F; + if (notifications.empty()) { + credits_phase = CreditsPhase::GAP; + credits_timer = 0.0F; } break; case CreditsPhase::GAP: - if (credits_timer_ >= CREDITS_GAP) { + if (credits_timer >= CREDITS_GAP) { showNotification( {std::string(Locale::get("credits.modern_role")), std::string(Locale::get("credits.modern_name"))}, @@ -347,14 +347,14 @@ namespace Overlay { NotifStyle::OUTLINE, CREDITS_BG, CREDITS_FG); - credits_phase_ = CreditsPhase::PLAYING_2; - credits_timer_ = 0.0F; + credits_phase = CreditsPhase::PLAYING_2; + credits_timer = 0.0F; } break; case CreditsPhase::PLAYING_2: - if (notifications_.empty()) { - credits_phase_ = CreditsPhase::IDLE; - credits_timer_ = 0.0F; + if (notifications.empty()) { + credits_phase = CreditsPhase::IDLE; + credits_timer = 0.0F; } break; case CreditsPhase::IDLE: @@ -363,7 +363,7 @@ namespace Overlay { } // Neteja notificacions finalitzades - std::erase_if(notifications_, [](const Notification& n) { return n.status == Status::FINISHED; }); + std::erase_if(notifications, [](const Notification& n) { return n.status == Status::FINISHED; }); // Menú flotant per damunt de tot (isVisible inclou l'animació de tancament) if (Menu::isVisible()) { @@ -382,7 +382,7 @@ namespace Overlay { Uint32 accent_color, Uint32 text_color) { // Reemplaça la notificació anterior - notifications_.clear(); + notifications.clear(); Notification notif; notif.lines = lines; @@ -395,15 +395,15 @@ namespace Overlay { // Calcula l'amplada màxima de les línies int max_w = 0; for (const auto& line : lines) { - int w = font_->width(line.c_str()); + int w = font->width(line.c_str()); max_w = std::max(w, max_w); } notif.box_w = max_w + NOTIF_PADDING_H * 2; - int line_h = font_->charHeight(); + int line_h = font->charHeight(); int line_count = static_cast(lines.size()); notif.box_h = line_count * line_h + (line_count - 1) * 1 + NOTIF_PADDING_V * 2; - notifications_.push_back(notif); + notifications.push_back(notif); } void toggleRenderInfo() { cycleRenderInfo(+1); } @@ -418,47 +418,47 @@ namespace Overlay { void setRenderInfoSegments(const char* s0, const char* s1, const char* s2, const char* s3, unsigned int mono_mask) { const char* segs[INFO_SEGMENT_COUNT] = {s0, s1, s2, s3}; for (int i = 0; i < INFO_SEGMENT_COUNT; i++) { - info_segments_[i].mono_digits = (((mono_mask >> i) & 1U) != 0U); + info_segments[i].mono_digits = (((mono_mask >> i) & 1U) != 0U); if (segs[i] != nullptr && *segs[i] != '\0') { - info_segments_[i].text = segs[i]; - info_segments_[i].visible = true; + info_segments[i].text = segs[i]; + info_segments[i].visible = true; } else { - info_segments_[i].visible = false; + info_segments[i].visible = false; } } } void startCredits() { - if (credits_phase_ != CreditsPhase::IDLE) { + if (credits_phase != CreditsPhase::IDLE) { return; } - credits_phase_ = CreditsPhase::DELAY; - credits_timer_ = 0.0F; + credits_phase = CreditsPhase::DELAY; + credits_timer = 0.0F; } void cancelCredits() { - credits_phase_ = CreditsPhase::IDLE; - credits_timer_ = 0.0F; - notifications_.clear(); + credits_phase = CreditsPhase::IDLE; + credits_timer = 0.0F; + notifications.clear(); } auto creditsActive() -> bool { - return credits_phase_ != CreditsPhase::IDLE; + return credits_phase != CreditsPhase::IDLE; } auto isEscConsumed() -> bool { - return esc_waiting_; + return esc_waiting; } auto handleEscape() -> bool { - if (!esc_waiting_) { + if (!esc_waiting) { // Primera pulsació: mostra avís i consumeix - esc_waiting_ = true; + esc_waiting = true; showNotification(Locale::get("notifications.exit_double_esc"), 2.0F); return true; // Consumit } // Segona pulsació: deixa passar - esc_waiting_ = false; + esc_waiting = false; return false; } From 9d30dd538c87c464ccf21661d3daf429fa5238f3 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 16 May 2026 14:40:18 +0200 Subject: [PATCH 06/13] fix: tidy modulegame (enums UPPER_CASE, draw/update camelBack, membres _) --- source/game/modulegame.cpp | 78 +++++++++++++++++++------------------- source/game/modulegame.hpp | 32 ++++++++-------- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/source/game/modulegame.cpp b/source/game/modulegame.cpp index a7ef235..a706275 100644 --- a/source/game/modulegame.cpp +++ b/source/game/modulegame.cpp @@ -8,28 +8,28 @@ #include "core/jail/jinput.hpp" ModuleGame::ModuleGame() { - this->gfx = Jd8::loadSurface(info::ctx.pepe_activat ? "gfx/frames2.gif" : "gfx/frames.gif"); + this->gfx_ = Jd8::loadSurface(info::ctx.pepe_activat ? "gfx/frames2.gif" : "gfx/frames.gif"); JG_SetUpdateTicks(10); - this->sam = std::make_unique(this->gfx); - this->mapa = std::make_unique(this->gfx, this->sam.get()); - this->marcador = std::make_unique(this->gfx, this->sam.get()); + this->sam_ = std::make_unique(this->gfx_); + this->mapa_ = std::make_unique(this->gfx_, this->sam_.get()); + this->marcador_ = std::make_unique(this->gfx_, this->sam_.get()); if (info::ctx.num_piramide == 2) { - this->bola = std::make_unique(this->gfx, this->sam.get()); + this->bola_ = std::make_unique(this->gfx_, this->sam_.get()); } this->iniciarMomies(); } ModuleGame::~ModuleGame() { - Jd8::freeSurface(this->gfx); + Jd8::freeSurface(this->gfx_); } void ModuleGame::onEnter() { // Primera Draw per omplir `screen` amb el contingut del gameplay // abans que el fade-in arranque. Si no, les primeres iteracions del // fade interpolarien cap a una paleta amb pantalla buida. - this->Draw(); + this->draw(); // Audio::playMusic ja és idempotent: si la pista actual coincideix amb la // demanada, no fa res. Per això podem cridar-lo cada onEnter sense @@ -48,32 +48,32 @@ void ModuleGame::onEnter() { // 32) per cada tick; durant aquesta fase el gameplay no corre, // només Draw+fade. Substituïx la crida bloquejant `JD8_FadeToPal`. fade_.startFadeTo(Jd8::loadPalette(info::ctx.pepe_activat ? "gfx/frames2.gif" : "gfx/frames.gif")); - phase_ = Phase::FadingIn; + phase_ = Phase::FADING_IN; } void ModuleGame::tick(int delta_ms) { switch (phase_) { - case Phase::FadingIn: + case Phase::FADING_IN: // No redibuixem durant el fade: el `screen` ja va ser omplit // per la Draw() d'onEnter. Només el Jd8::flip del caller muta // pixel_data segons la paleta que avança pas a pas. fade_.tick(delta_ms); if (fade_.done()) { - phase_ = Phase::Playing; + phase_ = Phase::PLAYING; } break; - case Phase::Playing: - this->Draw(); - this->Update(); + case Phase::PLAYING: + this->draw(); + this->update(); if (this->final_ != 0) { this->applyFinalTransitions(); fade_.startFadeOut(); - phase_ = Phase::FadingOut; + phase_ = Phase::FADING_OUT; } break; - case Phase::FadingOut: + case Phase::FADING_OUT: // No redibuixem: el `screen` té l'últim frame pintat per la // fase Playing (just abans que Update() setegés `final_`). // El vell `JD8_FadeOut` feia exactament això — flips amb @@ -82,11 +82,11 @@ void ModuleGame::tick(int delta_ms) { // "tornant" davant la porta després d'haver eixit). fade_.tick(delta_ms); if (fade_.done()) { - phase_ = Phase::Done; + phase_ = Phase::DONE; } break; - case Phase::Done: + case Phase::DONE: break; } } @@ -118,33 +118,33 @@ void ModuleGame::applyFinalTransitions() const { } } -void ModuleGame::Draw() { +void ModuleGame::draw() { // No crida Jd8::flip — el caller (mini-loop del fiber, o Director a // Phase B.2) ho fa després de cada tick. - this->mapa->draw(); - this->marcador->draw(); - this->sam->draw(); - for (auto& m : this->momies) { + this->mapa_->draw(); + this->marcador_->draw(); + this->sam_->draw(); + for (auto& m : this->momies_) { m->draw(); } - if (this->bola) { - this->bola->draw(); + if (this->bola_) { + this->bola_->draw(); } } -void ModuleGame::Update() { +void ModuleGame::update() { if (JG_ShouldUpdate()) { JI_Update(); - this->final_ = this->sam->update(); - const auto erased = std::erase_if(this->momies, [](auto& m) { return m->update(); }); + this->final_ = this->sam_->update(); + const auto erased = std::erase_if(this->momies_, [](auto& m) { return m->update(); }); info::ctx.momies -= static_cast(erased); - if (this->bola) { - this->bola->update(); + if (this->bola_) { + this->bola_->update(); } - this->mapa->update(); - if (this->mapa->novaMomia()) { - this->momies.emplace_back(std::make_unique(this->gfx, true, 0, 0, this->sam.get())); + this->mapa_->update(); + if (this->mapa_->novaMomia()) { + this->momies_.emplace_back(std::make_unique(this->gfx_, true, 0, 0, this->sam_.get())); info::ctx.momies++; } @@ -152,16 +152,16 @@ void ModuleGame::Update() { info::ctx.vida = 5; } if (JI_CheatActivated("alone")) { - this->momies.clear(); + this->momies_.clear(); info::ctx.momies = 0; } if (JI_CheatActivated("obert")) { for (int i = 0; i < 16; i++) { - this->mapa->tombes[i].costat[0] = true; - this->mapa->tombes[i].costat[1] = true; - this->mapa->tombes[i].costat[2] = true; - this->mapa->tombes[i].costat[3] = true; - this->mapa->comprovaCaixa(i); + this->mapa_->tombes[i].costat[0] = true; + this->mapa_->tombes[i].costat[1] = true; + this->mapa_->tombes[i].costat[2] = true; + this->mapa_->tombes[i].costat[3] = true; + this->mapa_->comprovaCaixa(i); } } @@ -185,7 +185,7 @@ void ModuleGame::iniciarMomies() { int y = 170; bool dimonis = info::ctx.num_piramide == 6; for (int i = 0; i < info::ctx.momies; i++) { - this->momies.emplace_back(std::make_unique(this->gfx, dimonis, x, y, this->sam.get())); + this->momies_.emplace_back(std::make_unique(this->gfx_, dimonis, x, y, this->sam_.get())); x += 65; if (x == 345) { x = 20; diff --git a/source/game/modulegame.hpp b/source/game/modulegame.hpp index 3ed6b88..7502311 100644 --- a/source/game/modulegame.hpp +++ b/source/game/modulegame.hpp @@ -20,11 +20,11 @@ // abans de retornar el next state. // // Tres fases internes: -// 1. FadingIn — fade-in 32 passos mentre el render segueix viu. +// 1. FADING_IN — fade-in 32 passos mentre el render segueix viu. // 2. Playing — gameplay normal; `final_` es setja quan el prota mor // o canvia de sala. `Update()` només avança cada 10 ms // via `JG_ShouldUpdate` (ticker fix del jail). -// 3. FadingOut — fade-out 32 passos mantenint l'últim frame visible +// 3. FADING_OUT — fade-out 32 passos mantenint l'últim frame visible // (substituïx el `JD8_FadeOut` bloquejant que feia el // destructor legacy). class ModuleGame : public scenes::Scene { @@ -39,31 +39,31 @@ class ModuleGame : public scenes::Scene { void onEnter() override; void tick(int delta_ms) override; - [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::Done; } + [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::DONE; } [[nodiscard]] auto nextState() const -> int override; private: enum class Phase : std::uint8_t { - FadingIn, - Playing, - FadingOut, - Done, + FADING_IN, + PLAYING, + FADING_OUT, + DONE, }; - void Draw(); // render a `screen`; no crida Jd8::flip (ho fa el caller) - void Update(); // gated per JG_ShouldUpdate + void draw(); // render a `screen`; no crida Jd8::flip (ho fa el caller) + void update(); // gated per JG_ShouldUpdate void iniciarMomies(); void applyFinalTransitions() const; // muta info::ctx quan final_ passa a !=0 - Phase phase_{Phase::FadingIn}; + Phase phase_{Phase::FADING_IN}; scenes::PaletteFade fade_; Uint8 final_{0}; - Jd8::Surface gfx{nullptr}; + Jd8::Surface gfx_{nullptr}; - std::unique_ptr mapa; - std::unique_ptr sam; - std::unique_ptr marcador; - std::vector> momies; - std::unique_ptr bola; + std::unique_ptr mapa_; + std::unique_ptr sam_; + std::unique_ptr marcador_; + std::vector> momies_; + std::unique_ptr bola_; }; From bbcc10da81d356d915eda8b7016819f447e1c4a5 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 16 May 2026 14:43:16 +0200 Subject: [PATCH 07/13] refactor: JI_* a Ji:: i JG_* a Jg:: --- source/core/input/gamepad.cpp | 26 ++++----- source/core/input/global_inputs.cpp | 20 +++---- source/core/input/global_inputs.hpp | 2 +- source/core/input/key_remap.cpp | 4 +- source/core/jail/jgame.cpp | 24 ++++---- source/core/jail/jgame.hpp | 44 +++++++------- source/core/jail/jinput.cpp | 27 ++++----- source/core/jail/jinput.hpp | 63 ++++++++++++--------- source/core/system/director.cpp | 31 +++++----- source/core/system/director.hpp | 6 +- source/game/bola.cpp | 2 +- source/game/engendro.cpp | 2 +- source/game/mapa.cpp | 4 +- source/game/modulegame.cpp | 18 +++--- source/game/modulegame.hpp | 6 +- source/game/momia.cpp | 6 +- source/game/prota.cpp | 14 ++--- source/game/scenes/banner_scene.cpp | 2 +- source/game/scenes/credits_scene.cpp | 6 +- source/game/scenes/intro_new_logo_scene.cpp | 2 +- source/game/scenes/intro_scene.cpp | 4 +- source/game/scenes/intro_sprites_scene.cpp | 4 +- source/game/scenes/menu_scene.cpp | 6 +- source/game/scenes/mort_scene.cpp | 4 +- source/game/scenes/secreta_scene.cpp | 4 +- source/game/scenes/slides_scene.cpp | 2 +- source/main.cpp | 4 +- 27 files changed, 174 insertions(+), 163 deletions(-) diff --git a/source/core/input/gamepad.cpp b/source/core/input/gamepad.cpp index 6a9679e..6e5af71 100644 --- a/source/core/input/gamepad.cpp +++ b/source/core/input/gamepad.cpp @@ -171,10 +171,10 @@ namespace Gamepad { pad = nullptr; pad_id = 0; // Neteja qualsevol tecla virtual que poguera estar premuda - JI_SetVirtualKey(SDL_SCANCODE_UP, JI_VSRC_GAMEPAD, false); - JI_SetVirtualKey(SDL_SCANCODE_DOWN, JI_VSRC_GAMEPAD, false); - JI_SetVirtualKey(SDL_SCANCODE_LEFT, JI_VSRC_GAMEPAD, false); - JI_SetVirtualKey(SDL_SCANCODE_RIGHT, JI_VSRC_GAMEPAD, false); + Ji::setVirtualKey(SDL_SCANCODE_UP, Ji::VirtualSource::GAMEPAD, false); + Ji::setVirtualKey(SDL_SCANCODE_DOWN, Ji::VirtualSource::GAMEPAD, false); + Ji::setVirtualKey(SDL_SCANCODE_LEFT, Ji::VirtualSource::GAMEPAD, false); + Ji::setVirtualKey(SDL_SCANCODE_RIGHT, Ji::VirtualSource::GAMEPAD, false); notifyDisconnected(saved_name); } } @@ -259,17 +259,17 @@ namespace Gamepad { } // Assegura que el joc no rep tecles de moviment mentre el menú està obert - JI_SetVirtualKey(SDL_SCANCODE_UP, JI_VSRC_GAMEPAD, false); - JI_SetVirtualKey(SDL_SCANCODE_DOWN, JI_VSRC_GAMEPAD, false); - JI_SetVirtualKey(SDL_SCANCODE_LEFT, JI_VSRC_GAMEPAD, false); - JI_SetVirtualKey(SDL_SCANCODE_RIGHT, JI_VSRC_GAMEPAD, false); + Ji::setVirtualKey(SDL_SCANCODE_UP, Ji::VirtualSource::GAMEPAD, false); + Ji::setVirtualKey(SDL_SCANCODE_DOWN, Ji::VirtualSource::GAMEPAD, false); + Ji::setVirtualKey(SDL_SCANCODE_LEFT, Ji::VirtualSource::GAMEPAD, false); + Ji::setVirtualKey(SDL_SCANCODE_RIGHT, Ji::VirtualSource::GAMEPAD, false); } else { // Moviment al joc — level-triggered (polling) - JI_SetVirtualKey(SDL_SCANCODE_UP, JI_VSRC_GAMEPAD, up); - JI_SetVirtualKey(SDL_SCANCODE_DOWN, JI_VSRC_GAMEPAD, dn); - JI_SetVirtualKey(SDL_SCANCODE_LEFT, JI_VSRC_GAMEPAD, lt); - JI_SetVirtualKey(SDL_SCANCODE_RIGHT, JI_VSRC_GAMEPAD, rt); - // Qualsevol dels 4 botons frontals avança escenes (JI_AnyKey via Enter sintètic) + Ji::setVirtualKey(SDL_SCANCODE_UP, Ji::VirtualSource::GAMEPAD, up); + Ji::setVirtualKey(SDL_SCANCODE_DOWN, Ji::VirtualSource::GAMEPAD, dn); + Ji::setVirtualKey(SDL_SCANCODE_LEFT, Ji::VirtualSource::GAMEPAD, lt); + Ji::setVirtualKey(SDL_SCANCODE_RIGHT, Ji::VirtualSource::GAMEPAD, rt); + // Qualsevol dels 4 botons frontals avança escenes (Ji::anyKey via Enter sintètic) if ((south && !prev_south) || (east && !prev_east) || (west && !prev_west) || (north && !prev_north)) { pushKey(SDL_SCANCODE_RETURN); diff --git a/source/core/input/global_inputs.cpp b/source/core/input/global_inputs.cpp index e83a31f..c004848 100644 --- a/source/core/input/global_inputs.cpp +++ b/source/core/input/global_inputs.cpp @@ -27,7 +27,7 @@ namespace GlobalInputs { bool consumed = false; // F1 — Reduir zoom - bool dec_zoom = JI_KeyPressed(KeyConfig::scancode("dec_zoom")); + bool dec_zoom = Ji::keyPressed(KeyConfig::scancode("dec_zoom")); if (dec_zoom && !dec_zoom_prev) { Screen::get()->decZoom(); char msg[32]; @@ -40,7 +40,7 @@ namespace GlobalInputs { dec_zoom_prev = dec_zoom; // F2 — Augmentar zoom - bool inc_zoom = JI_KeyPressed(KeyConfig::scancode("inc_zoom")); + bool inc_zoom = Ji::keyPressed(KeyConfig::scancode("inc_zoom")); if (inc_zoom && !inc_zoom_prev) { Screen::get()->incZoom(); char msg[32]; @@ -53,7 +53,7 @@ namespace GlobalInputs { inc_zoom_prev = inc_zoom; // F3 — Toggle pantalla completa - bool fullscreen = JI_KeyPressed(KeyConfig::scancode("fullscreen")); + bool fullscreen = Ji::keyPressed(KeyConfig::scancode("fullscreen")); if (fullscreen && !fullscreen_prev) { Screen::get()->toggleFullscreen(); Overlay::showNotification(Screen::get()->isFullscreen() ? Locale::get("notifications.fullscreen") : Locale::get("notifications.windowed")); @@ -64,7 +64,7 @@ namespace GlobalInputs { fullscreen_prev = fullscreen; // F4 — Toggle shaders - bool shader = JI_KeyPressed(KeyConfig::scancode("toggle_shader")); + bool shader = Ji::keyPressed(KeyConfig::scancode("toggle_shader")); if (shader && !shader_prev) { Screen::get()->toggleShaders(); Overlay::showNotification(Options::video.shader_enabled ? Locale::get("notifications.shader_on") : Locale::get("notifications.shader_off")); @@ -75,7 +75,7 @@ namespace GlobalInputs { shader_prev = shader; // F5 — Toggle aspect ratio 4:3 - bool aspect = JI_KeyPressed(KeyConfig::scancode("toggle_aspect_ratio")); + bool aspect = Ji::keyPressed(KeyConfig::scancode("toggle_aspect_ratio")); if (aspect && !aspect_prev) { Screen::get()->toggleAspectRatio(); Overlay::showNotification(Options::video.aspect_ratio_4_3 ? Locale::get("notifications.aspect_43") : Locale::get("notifications.aspect_square")); @@ -86,7 +86,7 @@ namespace GlobalInputs { aspect_prev = aspect; // F6 — Toggle supersampling - bool ss = JI_KeyPressed(KeyConfig::scancode("toggle_supersampling")); + bool ss = Ji::keyPressed(KeyConfig::scancode("toggle_supersampling")); if (ss && !ss_prev) { if (Screen::get()->toggleSupersampling()) { Overlay::showNotification(Options::video.supersampling ? Locale::get("notifications.ss_on") : Locale::get("notifications.ss_off")); @@ -98,7 +98,7 @@ namespace GlobalInputs { ss_prev = ss; // F7 — Canviar tipus de shader (PostFX ↔ CrtPi) - bool next_shader = JI_KeyPressed(KeyConfig::scancode("next_shader")); + bool next_shader = Ji::keyPressed(KeyConfig::scancode("next_shader")); if (next_shader && !next_shader_prev) { if (Screen::get()->nextShaderType()) { char msg[64]; @@ -112,7 +112,7 @@ namespace GlobalInputs { next_shader_prev = next_shader; // F8 — Pròxim preset del shader actiu - bool next_preset = JI_KeyPressed(KeyConfig::scancode("next_shader_preset")); + bool next_preset = Ji::keyPressed(KeyConfig::scancode("next_shader_preset")); if (next_preset && !next_preset_prev) { if (Screen::get()->nextPreset()) { char msg[64]; @@ -126,7 +126,7 @@ namespace GlobalInputs { next_preset_prev = next_preset; // F9 — Cicla filtre de textura (NEAREST ↔ LINEAR), sempre aplicat - bool texture_filter = JI_KeyPressed(KeyConfig::scancode("cycle_texture_filter")); + bool texture_filter = Ji::keyPressed(KeyConfig::scancode("cycle_texture_filter")); if (texture_filter && !texture_filter_prev) { Screen::get()->cycleTextureFilter(+1); Overlay::showNotification(Options::video.texture_filter == Options::TextureFilter::LINEAR @@ -139,7 +139,7 @@ namespace GlobalInputs { texture_filter_prev = texture_filter; // F10 — Toggle render info (FPS, driver, shader) - bool render_info = JI_KeyPressed(KeyConfig::scancode("toggle_render_info")); + bool render_info = Ji::keyPressed(KeyConfig::scancode("toggle_render_info")); if (render_info && !render_info_prev) { Overlay::toggleRenderInfo(); } diff --git a/source/core/input/global_inputs.hpp b/source/core/input/global_inputs.hpp index 754cbfb..b96463b 100644 --- a/source/core/input/global_inputs.hpp +++ b/source/core/input/global_inputs.hpp @@ -1,7 +1,7 @@ #pragma once namespace GlobalInputs { - // Comprovar una vegada per frame, després de JI_Update() + // Comprovar una vegada per frame, després de Ji::update() // Retorna true si ha consumit alguna tecla (per suprimir-la de la capa de joc) auto handle() -> bool; } // namespace GlobalInputs diff --git a/source/core/input/key_remap.cpp b/source/core/input/key_remap.cpp index 8a43cbe..4c10f46 100644 --- a/source/core/input/key_remap.cpp +++ b/source/core/input/key_remap.cpp @@ -9,10 +9,10 @@ namespace KeyRemap { static void mirror(SDL_Scancode custom, SDL_Scancode standard, const bool* ks) { if (custom == standard || custom == SDL_SCANCODE_UNKNOWN) { - JI_SetVirtualKey(standard, JI_VSRC_REMAP, false); + Ji::setVirtualKey(standard, Ji::VirtualSource::REMAP, false); return; } - JI_SetVirtualKey(standard, JI_VSRC_REMAP, ks[custom]); + Ji::setVirtualKey(standard, Ji::VirtualSource::REMAP, ks[custom]); } void update() { diff --git a/source/core/jail/jgame.cpp b/source/core/jail/jgame.cpp index 7e7d8be..28d1f49 100644 --- a/source/core/jail/jgame.cpp +++ b/source/core/jail/jgame.cpp @@ -2,7 +2,7 @@ namespace { - bool quitting = false; + bool is_quitting = false; Uint32 update_ticks = 0; Uint32 update_time = 0; Uint32 cycle_counter = 0; @@ -10,29 +10,29 @@ namespace { } // namespace -void JG_Init() { +void Jg::init() { SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); update_time = SDL_GetTicks(); last_delta_time = update_time; } -void JG_Finalize() { +void Jg::finalize() { SDL_Quit(); } -void JG_QuitSignal() { - quitting = true; +void Jg::quitSignal() { + is_quitting = true; } -auto JG_Quitting() -> bool { - return quitting; +auto Jg::quitting() -> bool { + return is_quitting; } -void JG_SetUpdateTicks(Uint32 milliseconds) { +void Jg::setUpdateTicks(Uint32 milliseconds) { update_ticks = milliseconds; } -auto JG_ShouldUpdate() -> bool { +auto Jg::shouldUpdate() -> bool { const Uint32 now = SDL_GetTicks(); if (now - update_time > update_ticks) { update_time = now; @@ -40,16 +40,16 @@ auto JG_ShouldUpdate() -> bool { return true; } // No toca update — retornem false sense més. Des de Phase B.2 ja no - // hi ha fibers: cap caller fa spin-waits (`while (!JG_ShouldUpdate())`) + // hi ha fibers: cap caller fa spin-waits (`while (!Jg::shouldUpdate())`) // i el Director pren el control del main loop frame a frame. return false; } -auto JG_GetCycleCounter() -> Uint32 { +auto Jg::getCycleCounter() -> Uint32 { return cycle_counter; } -auto JG_GetDeltaMs() -> Uint32 { +auto Jg::getDeltaMs() -> Uint32 { const Uint32 now = SDL_GetTicks(); const Uint32 delta = now - last_delta_time; last_delta_time = now; diff --git a/source/core/jail/jgame.hpp b/source/core/jail/jgame.hpp index 62b2125..0d651cc 100644 --- a/source/core/jail/jgame.hpp +++ b/source/core/jail/jgame.hpp @@ -1,20 +1,24 @@ -#pragma once -#include - -void JG_Init(); - -void JG_Finalize(); - -void JG_QuitSignal(); - -auto JG_Quitting() -> bool; - -void JG_SetUpdateTicks(Uint32 milliseconds); - -auto JG_ShouldUpdate() -> bool; - -auto JG_GetCycleCounter() -> Uint32; - -// Temps transcorregut (en ms) des de l'última crida a JG_GetDeltaMs. -// Helper per a la migració progressiva a time-based (Fase 4+). -auto JG_GetDeltaMs() -> Uint32; +#pragma once +#include + +namespace Jg { + + void init(); + + void finalize(); + + void quitSignal(); + + auto quitting() -> bool; + + void setUpdateTicks(Uint32 milliseconds); + + auto shouldUpdate() -> bool; + + auto getCycleCounter() -> Uint32; + + // Temps transcorregut (en ms) des de l'última crida a Jg::getDeltaMs. + // Helper per a la migració progressiva a time-based (Fase 4+). + auto getDeltaMs() -> Uint32; + +} // namespace Jg diff --git a/source/core/jail/jinput.cpp b/source/core/jail/jinput.cpp index 9f1329a..98fecc5 100644 --- a/source/core/jail/jinput.cpp +++ b/source/core/jail/jinput.cpp @@ -17,18 +17,18 @@ namespace { bool key_pressed = false; - // Temps restant en mil·lisegons durant el qual JI_KeyPressed/JI_AnyKey + // Temps restant en mil·lisegons durant el qual Ji::keyPressed/Ji::anyKey // retornen false. Utilitzat per a evitar que pulsacions fortuïtes // saltin cinemàtiques al començament. float wait_ms = 0.0F; - // Per a calcular el delta entre crides a JI_Update sense que els callers + // Per a calcular el delta entre crides a Ji::update sense que els callers // hagen de passar-lo explícitament. Es reinicia a la primera crida. Uint64 last_update_tick = 0; bool input_blocked = false; - Uint8 virtual_keystates[JI_VSRC_COUNT][SDL_SCANCODE_COUNT] = {{0}}; + Uint8 virtual_keystates[static_cast(Ji::VirtualSource::COUNT)][SDL_SCANCODE_COUNT] = {{0}}; auto scancode_to_ascii(Uint8 scancode) -> Uint8 { if (scancode >= SDL_SCANCODE_A && scancode <= SDL_SCANCODE_Z) { @@ -39,25 +39,26 @@ namespace { } // namespace -void JI_DisableKeyboard(Uint32 time) { +void Ji::disableKeyboard(Uint32 time) { wait_ms = static_cast(time); } -void JI_SetInputBlocked(bool blocked) { +void Ji::setInputBlocked(bool blocked) { input_blocked = blocked; } -void JI_SetVirtualKey(int scancode, int source, bool pressed) { +void Ji::setVirtualKey(int scancode, VirtualSource source, bool pressed) { if (scancode < 0 || scancode >= SDL_SCANCODE_COUNT) { return; } - if (source < 0 || source >= JI_VSRC_COUNT) { + const auto src_idx = static_cast(source); + if (src_idx >= static_cast(VirtualSource::COUNT)) { return; } - virtual_keystates[source][scancode] = pressed ? 1 : 0; + virtual_keystates[src_idx][scancode] = pressed ? 1 : 0; } -void JI_moveCheats(Uint8 scancode) { +void Ji::moveCheats(Uint8 scancode) { cheat[0] = cheat[1]; cheat[1] = cheat[2]; cheat[2] = cheat[3]; @@ -65,7 +66,7 @@ void JI_moveCheats(Uint8 scancode) { cheat[4] = scancode_to_ascii(scancode); } -void JI_Update() { +void Ji::update() { // El director ha processat tots els events. Ací només refresquem // el snapshot del teclat i consumim el flag de tecla polsada. if (keystates == nullptr) { @@ -88,7 +89,7 @@ void JI_Update() { key_pressed = Director::get()->consumeKeyPressed(); } -auto JI_KeyPressed(int key) -> bool { +auto Ji::keyPressed(int key) -> bool { if (wait_ms > 0.0F || keystates == nullptr) { return false; } @@ -109,7 +110,7 @@ auto JI_KeyPressed(int key) -> bool { return std::ranges::any_of(virtual_keystates, [key](const auto& vk) { return vk[key] != 0; }); } -auto JI_CheatActivated(const char* cheat_code) -> bool { +auto Ji::cheatActivated(const char* cheat_code) -> bool { const size_t len = std::strlen(cheat_code); if (len > sizeof(cheat)) { return false; @@ -125,6 +126,6 @@ auto JI_CheatActivated(const char* cheat_code) -> bool { return true; } -auto JI_AnyKey() -> bool { +auto Ji::anyKey() -> bool { return wait_ms > 0.0F ? false : key_pressed; } diff --git a/source/core/jail/jinput.hpp b/source/core/jail/jinput.hpp index d6072ce..e8966ca 100644 --- a/source/core/jail/jinput.hpp +++ b/source/core/jail/jinput.hpp @@ -1,27 +1,36 @@ -#pragma once -#include - -#include - -void JI_DisableKeyboard(Uint32 time); - -// Bloqueja tot l'input cap al joc (JI_KeyPressed retorna false per a tot) -void JI_SetInputBlocked(bool blocked); - -// Estableix l'estat d'una tecla virtual. Múltiples fonts (gamepad, remap) -// s'agrupen per OR. JI_KeyPressed retorna true si el teclat real O qualsevol -// font virtual està premuda. -enum JI_VirtualSource : std::uint8_t { - JI_VSRC_GAMEPAD = 0, - JI_VSRC_REMAP = 1, - JI_VSRC_COUNT = 2 -}; -void JI_SetVirtualKey(int scancode, int source, bool pressed); - -void JI_Update(); - -auto JI_KeyPressed(int key) -> bool; - -auto JI_CheatActivated(const char* cheat_code) -> bool; - -auto JI_AnyKey() -> bool; +#pragma once +#include + +#include + +namespace Ji { + + void disableKeyboard(Uint32 time); + + // Bloqueja tot l'input cap al joc (Ji::keyPressed retorna false per a tot) + void setInputBlocked(bool blocked); + + // Estableix l'estat d'una tecla virtual. Múltiples fonts (gamepad, remap) + // s'agrupen per OR. Ji::keyPressed retorna true si el teclat real O qualsevol + // font virtual està premuda. + enum class VirtualSource : std::uint8_t { + GAMEPAD = 0, + REMAP = 1, + COUNT = 2 + }; + void setVirtualKey(int scancode, VirtualSource source, bool pressed); + + void update(); + + // Avança el buffer rotatori de cheats afegint `scancode` per detectar + // seqüències com "reviu", "alone", "obert". Usat pel Director quan rep + // un KEY_DOWN; el joc no l'ha de cridar directament. + void moveCheats(Uint8 scancode); + + auto keyPressed(int key) -> bool; + + auto cheatActivated(const char* cheat_code) -> bool; + + auto anyKey() -> bool; + +} // namespace Ji diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 83f0ed5..c968064 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -32,9 +32,6 @@ #include "game/scenes/secreta_scene.hpp" #include "game/scenes/slides_scene.hpp" -// Cheats del joc original — declarats a jinput.cpp -extern void JI_moveCheats(Uint8 new_key); - std::unique_ptr Director::instance_; Director::~Director() = default; @@ -141,7 +138,7 @@ void Director::setup() { auto Director::iterate() -> bool { if (quit_requested_) { - JG_QuitSignal(); + Jg::quitSignal(); current_scene_.reset(); // destrueix l'escena actual ordenadament return false; } @@ -162,7 +159,7 @@ auto Director::iterate() -> bool { game_state_ = 1; // 1 = dispatch via SceneRegistry per num_piramide has_frame_ = false; Menu::close(); - JI_SetInputBlocked(false); // el menú ho havia bloquejat — cal desfer-ho + Ji::setInputBlocked(false); // el menú ho havia bloquejat — cal desfer-ho } if (!context_initialized_) { @@ -207,7 +204,7 @@ auto Director::iterate() -> bool { // Transicions: si l'escena actual ha acabat (o s'ha senyalat // quit), llegim el seu next state i la destruïm per crear la // següent a continuació. - if (current_scene_ && (current_scene_->done() || JG_Quitting())) { + if (current_scene_ && (current_scene_->done() || Jg::quitting())) { game_state_ = current_scene_->nextState(); current_scene_.reset(); } @@ -216,7 +213,7 @@ auto Director::iterate() -> bool { // game_state_ i info::ctx. Si és impossible (game_state_ == -1, // quit, o state no registrat), eixim del loop. if (!current_scene_) { - if (game_state_ == -1 || JG_Quitting()) { + if (game_state_ == -1 || Jg::quitting()) { return false; } current_scene_ = createNextScene(); @@ -227,9 +224,9 @@ auto Director::iterate() -> bool { last_tick_ms_ = SDL_GetTicks(); } - // Tick de l'escena. JI_Update refresca key_pressed/any_key; el + // Tick de l'escena. Ji::update refresca key_pressed/any_key; el // delta_ms és el temps real transcorregut des de l'últim tick. - JI_Update(); + Ji::update(); const Uint32 now = SDL_GetTicks(); const int delta_ms = static_cast(now - last_tick_ms_); last_tick_ms_ = now; @@ -266,7 +263,7 @@ void Director::teardown() { // Senyal de quit i descàrrega ordenada de l'escena en curs. Els // destructors de cada escena són no-bloquejants — ja no fan fades // bloquejants. La resta de cleanup la gestiona `destroy()`. - JG_QuitSignal(); + Jg::quitSignal(); current_scene_.reset(); } @@ -290,7 +287,7 @@ void Director::pollAllEvents() { void Director::handleEvent(const SDL_Event& event) { if (event.type == SDL_EVENT_QUIT) { - JG_QuitSignal(); + Jg::quitSignal(); requestQuit(); } // Hot-plug de gamepad (a Emscripten els dispositius web entren com @@ -325,7 +322,7 @@ void Director::handleEvent(const SDL_Event& event) { if (event.type == SDL_EVENT_KEY_DOWN && !event.key.repeat && event.key.scancode == KeyConfig::scancode("menu_toggle")) { Menu::toggle(); - JI_SetInputBlocked(Menu::isOpen()); + Ji::setInputBlocked(Menu::isOpen()); menu_keys_held_[event.key.scancode] = true; return; } @@ -333,14 +330,14 @@ void Director::handleEvent(const SDL_Event& event) { if (Menu::isOpen() && event.type == SDL_EVENT_KEY_DOWN && !event.key.repeat) { if (event.key.scancode == SDL_SCANCODE_ESCAPE) { Menu::close(); - JI_SetInputBlocked(false); + Ji::setInputBlocked(false); // Empassa l'ESC fins al release perquè el joc no la veja per polling esc_swallow_until_release_ = true; } else { Menu::handleKey(event.key.scancode); // El menú pot haver-se tancat (p.ex. Backspace al nivell arrel) if (!Menu::isOpen()) { - JI_SetInputBlocked(false); + Ji::setInputBlocked(false); } } menu_keys_held_[event.key.scancode] = true; @@ -372,7 +369,7 @@ void Director::handleEvent(const SDL_Event& event) { // Segona pulsació: senyal d'eixida al joc esc_blocked_ = false; key_pressed_ = true; - JG_QuitSignal(); + Jg::quitSignal(); // Si estem en pausa, la desactivem: el fiber del joc està // congelat i necessita ser reprès per veure la senyal de // quit i poder tornar de forma natural. @@ -392,7 +389,7 @@ void Director::handleEvent(const SDL_Event& event) { const auto sc = event.key.scancode; if (!KeyConfig::isGuiKey(sc)) { key_pressed_ = true; - JI_moveCheats(sc); + Ji::moveCheats(sc); } } Mouse::handleEvent(event); @@ -400,7 +397,7 @@ void Director::handleEvent(const SDL_Event& event) { void Director::requestQuit() { quit_requested_ = true; - JG_QuitSignal(); + Jg::quitSignal(); } void Director::requestRestart() { diff --git a/source/core/system/director.hpp b/source/core/system/director.hpp index fb9c5b8..b37bd19 100644 --- a/source/core/system/director.hpp +++ b/source/core/system/director.hpp @@ -41,7 +41,7 @@ class Director { // iterate() per evitar manipular l'escena des d'una lambda del menú. void requestRestart(); - // Consumeix el flag de "tecla polsada" (com l'antic JI_AnyKey) + // Consumeix el flag de "tecla polsada" (com l'antic Ji::anyKey) auto consumeKeyPressed() -> bool; // Indica si ESC està bloquejada (el joc no l'ha de veure) @@ -88,9 +88,9 @@ class Director { std::atomic esc_blocked_{false}; std::atomic paused_{false}; // Quan el menú tanca amb ESC, empassem-nos l'ESC fins que l'usuari la deixe anar, - // per no fer eixir el joc al proper poll de JI_KeyPressed. + // per no fer eixir el joc al proper poll de Ji::keyPressed. std::atomic esc_swallow_until_release_{false}; // Tecles consumides pel menú (KEY_DOWN): el KEY_UP associat cal empassar-lo - // per evitar que el joc (JI_AnyKey / JI_moveCheats) les veja quan el menú tanca. + // per evitar que el joc (Ji::anyKey / Ji::moveCheats) les veja quan el menú tanca. bool menu_keys_held_[SDL_SCANCODE_COUNT]{}; }; diff --git a/source/game/bola.cpp b/source/game/bola.cpp index a747072..3513c3f 100644 --- a/source/game/bola.cpp +++ b/source/game/bola.cpp @@ -38,7 +38,7 @@ void Bola::update() { } // Augmentem el frame - if (JG_GetCycleCounter() % this->cycles_per_frame == 0) { + if (Jg::getCycleCounter() % this->cycles_per_frame == 0) { this->cur_frame++; if (this->cur_frame == entitat.animacions[this->o].frames.size()) { this->cur_frame = 0; diff --git a/source/game/engendro.cpp b/source/game/engendro.cpp index 72d3fba..74dd5da 100644 --- a/source/game/engendro.cpp +++ b/source/game/engendro.cpp @@ -32,7 +32,7 @@ Engendro::Engendro(Jd8::Surface gfx, Uint16 x, Uint16 y) auto Engendro::update() -> bool { bool mort = false; - if (JG_GetCycleCounter() % this->cycles_per_frame == 0) { + if (Jg::getCycleCounter() % this->cycles_per_frame == 0) { this->cur_frame++; if (this->cur_frame == entitat.animacions[this->o].frames.size()) { this->cur_frame = 0; diff --git a/source/game/mapa.cpp b/source/game/mapa.cpp index 3de4c94..5b272f3 100644 --- a/source/game/mapa.cpp +++ b/source/game/mapa.cpp @@ -72,13 +72,13 @@ void Mapa::update() { } if (this->porta_oberta && sam->x == 150 && sam->y == 30) { - if (JI_KeyPressed(SDL_SCANCODE_UP)) { + if (Ji::keyPressed(SDL_SCANCODE_UP)) { this->sam->o = 4; this->sam->y -= 15; } } - if (JG_GetCycleCounter() % 8 == 0) { + if (Jg::getCycleCounter() % 8 == 0) { this->frame_torxes++; this->frame_torxes = this->frame_torxes % 4; } diff --git a/source/game/modulegame.cpp b/source/game/modulegame.cpp index a706275..a404ee7 100644 --- a/source/game/modulegame.cpp +++ b/source/game/modulegame.cpp @@ -9,7 +9,7 @@ ModuleGame::ModuleGame() { this->gfx_ = Jd8::loadSurface(info::ctx.pepe_activat ? "gfx/frames2.gif" : "gfx/frames.gif"); - JG_SetUpdateTicks(10); + Jg::setUpdateTicks(10); this->sam_ = std::make_unique(this->gfx_); this->mapa_ = std::make_unique(this->gfx_, this->sam_.get()); @@ -92,7 +92,7 @@ void ModuleGame::tick(int delta_ms) { } auto ModuleGame::nextState() const -> int { - if (JG_Quitting()) { + if (Jg::quitting()) { return -1; } if (info::ctx.num_habitacio == 1 || @@ -133,8 +133,8 @@ void ModuleGame::draw() { } void ModuleGame::update() { - if (JG_ShouldUpdate()) { - JI_Update(); + if (Jg::shouldUpdate()) { + Ji::update(); this->final_ = this->sam_->update(); const auto erased = std::erase_if(this->momies_, [](auto& m) { return m->update(); }); @@ -148,14 +148,14 @@ void ModuleGame::update() { info::ctx.momies++; } - if (JI_CheatActivated("reviu")) { + if (Ji::cheatActivated("reviu")) { info::ctx.vida = 5; } - if (JI_CheatActivated("alone")) { + if (Ji::cheatActivated("alone")) { this->momies_.clear(); info::ctx.momies = 0; } - if (JI_CheatActivated("obert")) { + if (Ji::cheatActivated("obert")) { for (int i = 0; i < 16; i++) { this->mapa_->tombes[i].costat[0] = true; this->mapa_->tombes[i].costat[1] = true; @@ -165,8 +165,8 @@ void ModuleGame::update() { } } - if (JI_KeyPressed(SDL_SCANCODE_ESCAPE)) { - JG_QuitSignal(); + if (Ji::keyPressed(SDL_SCANCODE_ESCAPE)) { + Jg::quitSignal(); } } } diff --git a/source/game/modulegame.hpp b/source/game/modulegame.hpp index 7502311..5abea50 100644 --- a/source/game/modulegame.hpp +++ b/source/game/modulegame.hpp @@ -16,14 +16,14 @@ // Escena de gameplay pur. Reemplaça el vell `Go()` bloquejant amb // l'interfície `scenes::Scene` tick-based: `onEnter()` arranca la // música i un fade-in, el `tick()` avança un frame (Draw + Update -// gated per JG_ShouldUpdate), i quan la partida acaba fa un fade-out +// gated per Jg::shouldUpdate), i quan la partida acaba fa un fade-out // abans de retornar el next state. // // Tres fases internes: // 1. FADING_IN — fade-in 32 passos mentre el render segueix viu. // 2. Playing — gameplay normal; `final_` es setja quan el prota mor // o canvia de sala. `Update()` només avança cada 10 ms -// via `JG_ShouldUpdate` (ticker fix del jail). +// via `Jg::shouldUpdate` (ticker fix del jail). // 3. FADING_OUT — fade-out 32 passos mantenint l'últim frame visible // (substituïx el `JD8_FadeOut` bloquejant que feia el // destructor legacy). @@ -51,7 +51,7 @@ class ModuleGame : public scenes::Scene { }; void draw(); // render a `screen`; no crida Jd8::flip (ho fa el caller) - void update(); // gated per JG_ShouldUpdate + void update(); // gated per Jg::shouldUpdate void iniciarMomies(); void applyFinalTransitions() const; // muta info::ctx quan final_ passa a !=0 diff --git a/source/game/momia.cpp b/source/game/momia.cpp index 362449a..4e34466 100644 --- a/source/game/momia.cpp +++ b/source/game/momia.cpp @@ -74,7 +74,7 @@ void Momia::draw() { Sprite::draw(); if (info::ctx.num_piramide == 4) { - if ((JG_GetCycleCounter() % 40) < 20) { + if ((Jg::getCycleCounter() % 40) < 20) { Jd8::blitCK(this->x, this->y, this->gfx, 220, 80, 15, 15, 255); } else { Jd8::blitCK(this->x, this->y, this->gfx, 235, 80, 15, 15, 255); @@ -93,7 +93,7 @@ auto Momia::update() -> bool { return morta; } - if (this->sam->o < 4 && (this->dimoni || info::ctx.num_piramide == 5 || JG_GetCycleCounter() % 2 == 0)) { + if (this->sam->o < 4 && (this->dimoni || info::ctx.num_piramide == 5 || Jg::getCycleCounter() % 2 == 0)) { if ((this->x - 20) % 65 == 0 && (this->y - 30) % 35 == 0) { if (this->dimoni) { if (rand() % 2 == 0) { @@ -147,7 +147,7 @@ auto Momia::update() -> bool { break; } - if (JG_GetCycleCounter() % this->cycles_per_frame == 0) { + if (Jg::getCycleCounter() % this->cycles_per_frame == 0) { this->cur_frame++; if (this->cur_frame == entitat.animacions[this->o].frames.size()) { this->cur_frame = 0; diff --git a/source/game/prota.cpp b/source/game/prota.cpp index c81c29a..95e81e8 100644 --- a/source/game/prota.cpp +++ b/source/game/prota.cpp @@ -91,7 +91,7 @@ void Prota::draw() { Sprite::draw(); if (info::ctx.num_piramide == 4 && this->o != 4) { - if ((JG_GetCycleCounter() % 40) < 20) { + if ((Jg::getCycleCounter() % 40) < 20) { Jd8::blitCK(this->x, this->y, this->gfx, 220, 80, 15, 15, 255); } else { Jd8::blitCK(this->x, this->y, this->gfx, 235, 80, 15, 15, 255); @@ -104,25 +104,25 @@ auto Prota::update() -> Uint8 { if (this->o < 4) { Uint8 dir = 4; - if (JI_KeyPressed(SDL_SCANCODE_DOWN)) { + if (Ji::keyPressed(SDL_SCANCODE_DOWN)) { if ((this->x - 20) % 65 == 0) { this->o = 0; } dir = this->o; } - if (JI_KeyPressed(SDL_SCANCODE_UP)) { + if (Ji::keyPressed(SDL_SCANCODE_UP)) { if ((this->x - 20) % 65 == 0) { this->o = 1; } dir = this->o; } - if (JI_KeyPressed(SDL_SCANCODE_RIGHT)) { + if (Ji::keyPressed(SDL_SCANCODE_RIGHT)) { if ((this->y - 30) % 35 == 0) { this->o = 2; } dir = this->o; } - if (JI_KeyPressed(SDL_SCANCODE_LEFT)) { + if (Ji::keyPressed(SDL_SCANCODE_LEFT)) { if ((this->y - 30) % 35 == 0) { this->o = 3; } @@ -161,7 +161,7 @@ auto Prota::update() -> Uint8 { if (this->frame_pejades == 15) { this->frame_pejades = 0; } - if (JG_GetCycleCounter() % this->cycles_per_frame == 0) { + if (Jg::getCycleCounter() % this->cycles_per_frame == 0) { this->cur_frame++; if (this->cur_frame == entitat.animacions[this->o].frames.size()) { this->cur_frame = 0; @@ -170,7 +170,7 @@ auto Prota::update() -> Uint8 { } eixir = 0U; } else { - if (JG_GetCycleCounter() % this->cycles_per_frame == 0) { + if (Jg::getCycleCounter() % this->cycles_per_frame == 0) { this->cur_frame++; if (this->cur_frame == entitat.animacions[this->o].frames.size()) { if (this->o == 4) { diff --git a/source/game/scenes/banner_scene.cpp b/source/game/scenes/banner_scene.cpp index 96d8022..66b1a0b 100644 --- a/source/game/scenes/banner_scene.cpp +++ b/source/game/scenes/banner_scene.cpp @@ -48,7 +48,7 @@ namespace scenes { break; case Phase::Showing: - if (JI_AnyKey()) { + if (Ji::anyKey()) { remaining_ms_ = 0; } else { remaining_ms_ -= delta_ms; diff --git a/source/game/scenes/credits_scene.cpp b/source/game/scenes/credits_scene.cpp index fadc824..35ba37c 100644 --- a/source/game/scenes/credits_scene.cpp +++ b/source/game/scenes/credits_scene.cpp @@ -29,7 +29,7 @@ namespace { }; constexpr int CONTADOR_MAX = 3100; // ~62 s de crèdits a 20 ms/tick - constexpr int TICK_MS = 20; // JG_SetUpdateTicks heretat del doSlides previ + constexpr int TICK_MS = 20; // Jg::setUpdateTicks heretat del doSlides previ constexpr int BG_INDEX = 255; } // namespace @@ -111,7 +111,7 @@ namespace scenes { switch (phase_) { case Phase::Rolling: { // Avancem el contador en passos discrets de 20 ms, igual - // que feia JG_ShouldUpdate(20) al vell doCredits. + // que feia Jg::shouldUpdate(20) al vell doCredits. contador_acc_ms_ += delta_ms; while (contador_acc_ms_ >= TICK_MS) { contador_acc_ms_ -= TICK_MS; @@ -121,7 +121,7 @@ namespace scenes { coche_.tick(delta_ms); render(); - if (JI_AnyKey() || contador_ >= CONTADOR_MAX) { + if (Ji::anyKey() || contador_ >= CONTADOR_MAX) { writeTrickIni(); fade_.startFadeOut(); phase_ = Phase::FadingOut; diff --git a/source/game/scenes/intro_new_logo_scene.cpp b/source/game/scenes/intro_new_logo_scene.cpp index 745fc67..47d9807 100644 --- a/source/game/scenes/intro_new_logo_scene.cpp +++ b/source/game/scenes/intro_new_logo_scene.cpp @@ -137,7 +137,7 @@ namespace scenes { // TOTA la intro (inclou saltar la fase de sprites). Durant Sprites // deixem que la sub-escena gestione el seu propi skip (que a més // respecta la fase "final" no skippable de la variant 0). - if (phase_ != Phase::Sprites && phase_ != Phase::Done && JI_AnyKey()) { + if (phase_ != Phase::Sprites && phase_ != Phase::Done && Ji::anyKey()) { info::ctx.num_piramide = 0; phase_ = Phase::Done; return; diff --git a/source/game/scenes/intro_scene.cpp b/source/game/scenes/intro_scene.cpp index 488c75f..978d3ff 100644 --- a/source/game/scenes/intro_scene.cpp +++ b/source/game/scenes/intro_scene.cpp @@ -7,7 +7,7 @@ namespace { - // Timings idèntics als del vell `doIntro()`: el JG_SetUpdateTicks(1000) + // Timings idèntics als del vell `doIntro()`: el Jg::setUpdateTicks(1000) // inicial, (100) per a les 3 primeres lletres (J, A, I), (200) per a // "JAIL" i el seu clear, (100) per a les 4 lletres centrals // (G, A, M, E) i (200) per a la resta fins al cicle de paleta. @@ -152,7 +152,7 @@ namespace scenes { // (inclou saltar la fase de sprites). Durant Sprites deixem que // la sub-escena gestione el seu propi skip internament, que a més // respecta la fase "final" no skippable de la variant 0. - if (phase_ != Phase::Sprites && phase_ != Phase::Done && JI_AnyKey()) { + if (phase_ != Phase::Sprites && phase_ != Phase::Done && Ji::anyKey()) { info::ctx.num_piramide = 0; phase_ = Phase::Done; return; diff --git a/source/game/scenes/intro_sprites_scene.cpp b/source/game/scenes/intro_sprites_scene.cpp index a3e0287..367c1f1 100644 --- a/source/game/scenes/intro_sprites_scene.cpp +++ b/source/game/scenes/intro_sprites_scene.cpp @@ -9,7 +9,7 @@ namespace { - // Duració d'un pas. El vell doIntroSprites feia JG_SetUpdateTicks(20); + // Duració d'un pas. El vell doIntroSprites feia Jg::setUpdateTicks(20); // cada iteració del seu for (i) consumia un tick de 20 ms. constexpr int TICK_MS = 20; @@ -346,7 +346,7 @@ namespace scenes { // Skip per tecla. Durant la fase marcada com a no skippable (només // v0Final al vell codi) s'ignora — preserva la semàntica del vell // bucle final de la variant 0 que no cridava wait_frame_or_skip. - if (phases[phase_].skippable && JI_AnyKey()) { + if (phases[phase_].skippable && Ji::anyKey()) { done_ = true; return; } diff --git a/source/game/scenes/menu_scene.cpp b/source/game/scenes/menu_scene.cpp index 045cd99..676be1a 100644 --- a/source/game/scenes/menu_scene.cpp +++ b/source/game/scenes/menu_scene.cpp @@ -98,9 +98,9 @@ namespace scenes { // Qualsevol tecla tanca el menú. Llegim 'P' explícitament abans // de reiniciar el flag de input perquè `info::ctx.pepe_activat` // reflecteixca si l'usuari estava polsant P al moment d'eixir. - if (JI_AnyKey() || JI_KeyPressed(SDL_SCANCODE_P)) { - info::ctx.pepe_activat = JI_KeyPressed(SDL_SCANCODE_P); - JI_DisableKeyboard(60); + if (Ji::anyKey() || Ji::keyPressed(SDL_SCANCODE_P)) { + info::ctx.pepe_activat = Ji::keyPressed(SDL_SCANCODE_P); + Ji::disableKeyboard(60); info::ctx.num_piramide = 1; fade_.startFadeOut(); phase_ = Phase::FadingOut; diff --git a/source/game/scenes/mort_scene.cpp b/source/game/scenes/mort_scene.cpp index bcc2351..9a323c4 100644 --- a/source/game/scenes/mort_scene.cpp +++ b/source/game/scenes/mort_scene.cpp @@ -11,7 +11,7 @@ namespace scenes { void MortScene::onEnter() { playMusic("music/mort.ogg"); - JI_DisableKeyboard(60); + Ji::disableKeyboard(60); info::ctx.vida = 5; gfx_ = SurfaceHandle("gfx/gameover.gif"); @@ -38,7 +38,7 @@ namespace scenes { break; case Phase::Showing: - if (JI_AnyKey()) { + if (Ji::anyKey()) { remaining_ms_ = 0; } else { remaining_ms_ -= delta_ms; diff --git a/source/game/scenes/secreta_scene.cpp b/source/game/scenes/secreta_scene.cpp index 5c5e4c7..b95330a 100644 --- a/source/game/scenes/secreta_scene.cpp +++ b/source/game/scenes/secreta_scene.cpp @@ -12,7 +12,7 @@ namespace { - constexpr int TICK_MS = 20; // JG_SetUpdateTicks(20) del vell doSecreta + constexpr int TICK_MS = 20; // Jg::setUpdateTicks(20) del vell doSecreta // Durades per fase, derivades dels contador-thresholds del vell: // tomba1 scroll: 127 passos (contador 1→128) × 20ms @@ -85,7 +85,7 @@ namespace scenes { // Skip per tecla (després del fade inicial, no mentre). Salta // directament al FinalFadeOut. Mateix patró que el vell, on // qualsevol tecla sortia del loop. - if (!skip_triggered_ && phase_ != Phase::InitialFadeOut && JI_AnyKey()) { + if (!skip_triggered_ && phase_ != Phase::InitialFadeOut && Ji::anyKey()) { skip_triggered_ = true; beginFinalFade(); } diff --git a/source/game/scenes/slides_scene.cpp b/source/game/scenes/slides_scene.cpp index 91bcd0b..3273d69 100644 --- a/source/game/scenes/slides_scene.cpp +++ b/source/game/scenes/slides_scene.cpp @@ -103,7 +103,7 @@ namespace scenes { // Skip: qualsevol tecla salta directament al fade final. Per fidelitat // al vell doSlides, el skip NO atura la música explícitament — només // el final natural crida Ja::fadeOutMusic (beginFinalFade() distingeix). - if (!skip_triggered_ && JI_AnyKey()) { + if (!skip_triggered_ && Ji::anyKey()) { skip_triggered_ = true; if (num_piramide_at_start_ != 7) { Audio::get()->fadeOutMusic(250); diff --git a/source/main.cpp b/source/main.cpp index 42f52b1..d256b3d 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -89,7 +89,7 @@ auto SDL_AppInit(void** /*appstate*/, int /*argc*/, char* /*argv*/[]) -> SDL_App Options::setCrtPiFile(std::string(file_getconfigfolder()) + "crtpi.yaml"); Options::loadCrtPiFromFile(); - JG_Init(); + Jg::init(); Screen::init(); Jd8::init(); Audio::init(); // crida internament Ja::init i aplica Options::audio @@ -149,6 +149,6 @@ void SDL_AppQuit(void* /*appstate*/, SDL_AppResult /*result*/) { Audio::destroy(); // el destructor del singleton crida Ja::quit Jd8::quit(); Screen::destroy(); - JG_Finalize(); + Jg::finalize(); ResourceHelper::shutdownResourceSystem(); } From 4cac807ce2a68816068ac3922e064860c8d84aa3 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 16 May 2026 14:46:22 +0200 Subject: [PATCH 08/13] fix: tidy scenes (slides/secreta enums UPPER_CASE) i mapa membres _ --- source/game/mapa.cpp | 138 +++++++++++++-------------- source/game/mapa.hpp | 20 ++-- source/game/scenes/secreta_scene.cpp | 48 +++++----- source/game/scenes/secreta_scene.hpp | 26 ++--- source/game/scenes/slides_scene.cpp | 54 +++++------ source/game/scenes/slides_scene.hpp | 44 ++++----- 6 files changed, 165 insertions(+), 165 deletions(-) diff --git a/source/game/mapa.cpp b/source/game/mapa.cpp index 5b272f3..02d3519 100644 --- a/source/game/mapa.cpp +++ b/source/game/mapa.cpp @@ -7,102 +7,102 @@ #include "core/jail/jinput.hpp" Mapa::Mapa(Jd8::Surface gfx, Prota* sam) { - this->gfx = gfx; - this->sam = sam; + this->gfx_ = gfx; + this->sam_ = sam; this->preparaFondoEstatic(); this->preparaTombes(); - this->ultim_vertex.columna = 255; - this->frame_torxes = 0; + this->ultim_vertex_.columna = 255; + this->frame_torxes_ = 0; - this->farao = false; - this->clau = false; - this->porta_oberta = false; - this->nova_momia = false; + this->farao_ = false; + this->clau_ = false; + this->porta_oberta_ = false; + this->nova_momia_ = false; } Mapa::~Mapa() { - Jd8::freeSurface(this->fondo); + Jd8::freeSurface(this->fondo_); } void Mapa::draw() { if (info::ctx.num_piramide != 4) { - switch (sam->o) { + switch (sam_->o) { case 0: // Down - Jd8::blitCKToSurface(sam->x, sam->y, this->gfx, 15, 125 + sam->frame_pejades, 15, 1, this->fondo, 255); + Jd8::blitCKToSurface(sam_->x, sam_->y, this->gfx_, 15, 125 + sam_->frame_pejades, 15, 1, this->fondo_, 255); break; case 1: // Up - Jd8::blitCKToSurface(sam->x, sam->y + 15, this->gfx, 0, 125 + (14 - sam->frame_pejades), 15, 1, this->fondo, 255); + Jd8::blitCKToSurface(sam_->x, sam_->y + 15, this->gfx_, 0, 125 + (14 - sam_->frame_pejades), 15, 1, this->fondo_, 255); break; case 2: // Right - Jd8::blitCKToSurface(sam->x + 7, sam->y, this->gfx, 30 + sam->frame_pejades, 125, 1, 15, this->fondo, 255); + Jd8::blitCKToSurface(sam_->x + 7, sam_->y, this->gfx_, 30 + sam_->frame_pejades, 125, 1, 15, this->fondo_, 255); break; case 3: // Left - Jd8::blitCKToSurface(sam->x + 8, sam->y, this->gfx, 45 + (14 - sam->frame_pejades), 125, 1, 15, this->fondo, 255); + Jd8::blitCKToSurface(sam_->x + 8, sam_->y, this->gfx_, 45 + (14 - sam_->frame_pejades), 125, 1, 15, this->fondo_, 255); break; default: break; } } - Jd8::blit(this->fondo); + Jd8::blit(this->fondo_); // Pinta tombes for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { - Jd8::blitCK(35 + (x * 65), 45 + (y * 35), this->gfx, this->tombes[x + (y * 4)].x, this->tombes[x + (y * 4)].y, 50, 20, 255); + Jd8::blitCK(35 + (x * 65), 45 + (y * 35), this->gfx_, this->tombes[x + (y * 4)].x, this->tombes[x + (y * 4)].y, 50, 20, 255); } } - Jd8::blitCK(45, 15, this->gfx, 30 + (this->frame_torxes * 25), 80, 25, 15, 255); - Jd8::blitCK(95, 15, this->gfx, 30 + (this->frame_torxes * 25), 80, 25, 15, 255); - Jd8::blitCK(195, 15, this->gfx, 30 + (this->frame_torxes * 25), 80, 25, 15, 255); - Jd8::blitCK(245, 15, this->gfx, 30 + (this->frame_torxes * 25), 80, 25, 15, 255); + Jd8::blitCK(45, 15, this->gfx_, 30 + (this->frame_torxes_ * 25), 80, 25, 15, 255); + Jd8::blitCK(95, 15, this->gfx_, 30 + (this->frame_torxes_ * 25), 80, 25, 15, 255); + Jd8::blitCK(195, 15, this->gfx_, 30 + (this->frame_torxes_ * 25), 80, 25, 15, 255); + Jd8::blitCK(245, 15, this->gfx_, 30 + (this->frame_torxes_ * 25), 80, 25, 15, 255); }; void Mapa::update() { - if (((sam->x - 20) % 65 == 0) && ((sam->y - 30) % 35 == 0) && ((this->ultim_vertex.columna != (sam->x - 20) / 65) || (this->ultim_vertex.fila != (sam->y - 30) / 35))) { - this->vertex.columna = (sam->x - 20) / 65; - this->vertex.fila = (sam->y - 30) / 35; - if (this->ultim_vertex.columna != 255) { + if (((sam_->x - 20) % 65 == 0) && ((sam_->y - 30) % 35 == 0) && ((this->ultim_vertex_.columna != (sam_->x - 20) / 65) || (this->ultim_vertex_.fila != (sam_->y - 30) / 35))) { + this->vertex_.columna = (sam_->x - 20) / 65; + this->vertex_.fila = (sam_->y - 30) / 35; + if (this->ultim_vertex_.columna != 255) { this->comprovaUltimCami(); } - this->ultim_vertex = this->vertex; + this->ultim_vertex_ = this->vertex_; } - if (this->porta_oberta && sam->x == 150 && sam->y == 30) { + if (this->porta_oberta_ && sam_->x == 150 && sam_->y == 30) { if (Ji::keyPressed(SDL_SCANCODE_UP)) { - this->sam->o = 4; - this->sam->y -= 15; + this->sam_->o = 4; + this->sam_->y -= 15; } } if (Jg::getCycleCounter() % 8 == 0) { - this->frame_torxes++; - this->frame_torxes = this->frame_torxes % 4; + this->frame_torxes_++; + this->frame_torxes_ = this->frame_torxes_ % 4; } } auto Mapa::novaMomia() -> bool { - bool resultat = nova_momia; - nova_momia = false; + bool resultat = nova_momia_; + nova_momia_ = false; return resultat; } void Mapa::preparaFondoEstatic() { // Prepara el fondo est�tic de l'habitaci� - this->fondo = Jd8::newSurface(); + this->fondo_ = Jd8::newSurface(); if (info::ctx.num_piramide == 6) { - Jd8::blitToSurface(9, 2, this->gfx, 227, 185, 92, 7, this->fondo); // Text "SECRETA" + Jd8::blitToSurface(9, 2, this->gfx_, 227, 185, 92, 7, this->fondo_); // Text "SECRETA" } else { - Jd8::blitToSurface(9, 2, this->gfx, 60, 185, 39, 7, this->fondo); // Text "NIVELL" - Jd8::blitToSurface(72, 6, this->gfx, 153, 189, 3, 1, this->fondo); // Ralleta entre num piramide i num habitacio + Jd8::blitToSurface(9, 2, this->gfx_, 60, 185, 39, 7, this->fondo_); // Text "NIVELL" + Jd8::blitToSurface(72, 6, this->gfx_, 153, 189, 3, 1, this->fondo_); // Ralleta entre num piramide i num habitacio } - Jd8::blitToSurface(130, 2, this->gfx, 225, 192, 19, 8, this->fondo); // Montonet de monedes + signe '=' - Jd8::blitToSurface(220, 2, this->gfx, 160, 185, 48, 7, this->fondo); // Text "ENERGIA" + Jd8::blitToSurface(130, 2, this->gfx_, 225, 192, 19, 8, this->fondo_); // Montonet de monedes + signe '=' + Jd8::blitToSurface(220, 2, this->gfx_, 160, 185, 48, 7, this->fondo_); // Text "ENERGIA" if (info::ctx.diners >= 200) { - Jd8::blitToSurface(175, 3, this->gfx, 60, 193, 7, 6, this->fondo); + Jd8::blitToSurface(175, 3, this->gfx_, 60, 193, 7, 6, this->fondo_); } // Pinta taulells @@ -110,22 +110,22 @@ void Mapa::preparaFondoEstatic() { for (int x = 0; x < 19; x++) { switch (info::ctx.num_piramide) { case 1: - Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 0, 80, 15, 15, this->fondo); + Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx_, 0, 80, 15, 15, this->fondo_); break; case 2: - Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 25, 95, 15, 15, this->fondo); + Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx_, 25, 95, 15, 15, this->fondo_); break; case 3: - Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 40, 95, 15, 15, this->fondo); + Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx_, 40, 95, 15, 15, this->fondo_); break; case 4: - Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 175 + ((rand() % 3) * 15), 80, 15, 15, this->fondo); + Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx_, 175 + ((rand() % 3) * 15), 80, 15, 15, this->fondo_); break; case 5: - Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 130, 80, 15, 15, this->fondo); + Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx_, 130, 80, 15, 15, this->fondo_); break; case 6: - Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx, 145, 80, 15, 15, this->fondo); + Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx_, 145, 80, 15, 15, this->fondo_); break; default: break; @@ -134,28 +134,28 @@ void Mapa::preparaFondoEstatic() { } // Pinta vores de les parets - Jd8::blitCKToSurface(5, 15, this->gfx, 30, 110, 15, 15, this->fondo, 255); - Jd8::blitCKToSurface(295, 15, this->gfx, 45, 110, 15, 15, this->fondo, 255); - Jd8::blitCKToSurface(5, 180, this->gfx, 0, 155, 15, 20, this->fondo, 255); - Jd8::blitCKToSurface(295, 180, this->gfx, 15, 155, 15, 20, this->fondo, 255); + Jd8::blitCKToSurface(5, 15, this->gfx_, 30, 110, 15, 15, this->fondo_, 255); + Jd8::blitCKToSurface(295, 15, this->gfx_, 45, 110, 15, 15, this->fondo_, 255); + Jd8::blitCKToSurface(5, 180, this->gfx_, 0, 155, 15, 20, this->fondo_, 255); + Jd8::blitCKToSurface(295, 180, this->gfx_, 15, 155, 15, 20, this->fondo_, 255); // Pinta parets verticals for (int i = 0; i < 10; i++) { - Jd8::blitToSurface(5, 30 + (i * 15), this->gfx, 0, 110, 15, 15, this->fondo); - Jd8::blitToSurface(295, 30 + (i * 15), this->gfx, 15, 110, 15, 15, this->fondo); + Jd8::blitToSurface(5, 30 + (i * 15), this->gfx_, 0, 110, 15, 15, this->fondo_); + Jd8::blitToSurface(295, 30 + (i * 15), this->gfx_, 15, 110, 15, 15, this->fondo_); } // Pinta parets hortzintals for (int i = 0; i < 11; i++) { - Jd8::blitToSurface(20 + (i * 25), 185, this->gfx, 0, 95, 25, 15, this->fondo); - Jd8::blitToSurface(20 + (i * 25), 15, this->gfx, 0, 95, 25, 15, this->fondo); + Jd8::blitToSurface(20 + (i * 25), 185, this->gfx_, 0, 95, 25, 15, this->fondo_); + Jd8::blitToSurface(20 + (i * 25), 15, this->gfx_, 0, 95, 25, 15, this->fondo_); } // Pinta la porta - Jd8::blitCKToSurface(150, 18, this->gfx, 0, 143, 15, 12, this->fondo, 255); + Jd8::blitCKToSurface(150, 18, this->gfx_, 0, 143, 15, 12, this->fondo_, 255); if (info::ctx.num_piramide == 2) { - Jd8::blitToSurface(5, 100, this->gfx, 30, 140, 15, 15, this->fondo); + Jd8::blitToSurface(5, 100, this->gfx_, 30, 140, 15, 15, this->fondo_); } } @@ -204,12 +204,12 @@ auto minim(Uint8 a, Uint8 b) -> Uint8 { } void Mapa::comprovaUltimCami() { - Uint8 col_aux = abs(this->vertex.columna - this->ultim_vertex.columna); - Uint8 fil_aux = abs(this->vertex.fila - this->ultim_vertex.fila); + Uint8 col_aux = abs(this->vertex_.columna - this->ultim_vertex_.columna); + Uint8 fil_aux = abs(this->vertex_.fila - this->ultim_vertex_.fila); if (col_aux > fil_aux) { // Cam� horitzontal - Uint8 cami_fila = this->vertex.fila; - Uint8 cami_columna = minim(this->vertex.columna, this->ultim_vertex.columna); + Uint8 cami_fila = this->vertex_.fila; + Uint8 cami_columna = minim(this->vertex_.columna, this->ultim_vertex_.columna); Sint8 caixa_avall = (cami_fila << 2) + cami_columna; Sint8 caixa_amunt = caixa_avall - 4; @@ -223,8 +223,8 @@ void Mapa::comprovaUltimCami() { this->comprovaCaixa(caixa_amunt); } } else { // Cam� vertical - Uint8 cami_columna = this->vertex.columna; - Uint8 cami_fila = minim(this->vertex.fila, this->ultim_vertex.fila); + Uint8 cami_columna = this->vertex_.columna; + Uint8 cami_fila = minim(this->vertex_.fila, this->ultim_vertex_.fila); Sint8 caixa_dreta = (cami_fila << 2) + cami_columna; Sint8 caixa_esquerra = caixa_dreta - 1; @@ -265,26 +265,26 @@ void Mapa::comprovaCaixa(Uint8 num) { break; case CONTE_FARAO: this->tombes[num].x = 150; - this->farao = true; + this->farao_ = true; break; case CONTE_CLAU: this->tombes[num].x = 200; - this->clau = true; + this->clau_ = true; break; case CONTE_MOMIA: this->tombes[num].y = 175; - this->nova_momia = true; + this->nova_momia_ = true; break; case CONTE_PERGAMI: this->tombes[num].x = 250; - this->sam->pergami = true; + this->sam_->pergami = true; break; case CONTE_DIAMANT: this->tombes[num].y = 70; info::ctx.diamants++; info::ctx.diners += VALOR_DIAMANT; if (info::ctx.diamants == 16) { - this->farao = this->clau = true; + this->farao_ = this->clau_ = true; } break; default: @@ -295,8 +295,8 @@ void Mapa::comprovaCaixa(Uint8 num) { } void Mapa::comprovaPorta() { - if (this->clau && this->farao) { - Jd8::blitCKToSurface(150, 18, this->gfx, 15, 143, 15, 12, this->fondo, 255); - porta_oberta = true; + if (this->clau_ && this->farao_) { + Jd8::blitCKToSurface(150, 18, this->gfx_, 15, 143, 15, 12, this->fondo_, 255); + porta_oberta_ = true; } } diff --git a/source/game/mapa.hpp b/source/game/mapa.hpp index 7031e6a..118b043 100644 --- a/source/game/mapa.hpp +++ b/source/game/mapa.hpp @@ -53,16 +53,16 @@ class Mapa { void comprovaUltimCami(); void comprovaPorta(); - Jd8::Surface gfx; - Jd8::Surface fondo; - Vertex vertex; - Vertex ultim_vertex; - Uint8 frame_torxes; + Jd8::Surface gfx_; + Jd8::Surface fondo_; + Vertex vertex_; + Vertex ultim_vertex_; + Uint8 frame_torxes_; - Prota* sam; + Prota* sam_; - bool farao; - bool clau; - bool porta_oberta; - bool nova_momia; + bool farao_; + bool clau_; + bool porta_oberta_; + bool nova_momia_; }; diff --git a/source/game/scenes/secreta_scene.cpp b/source/game/scenes/secreta_scene.cpp index b95330a..1a2e732 100644 --- a/source/game/scenes/secreta_scene.cpp +++ b/source/game/scenes/secreta_scene.cpp @@ -54,7 +54,7 @@ namespace scenes { pal_active_ = new Color[256]; std::memcpy(pal_active_, pal_aux_, 768); - phase_ = Phase::InitialFadeOut; + phase_ = Phase::INITIAL_FADE_OUT; phase_acc_ms_ = 0; } @@ -78,20 +78,20 @@ namespace scenes { void SecretaScene::beginFinalFade() { Audio::get()->fadeOutMusic(250); fade_.startFadeOut(); - phase_ = Phase::FinalFadeOut; + phase_ = Phase::FINAL_FADE_OUT; } void SecretaScene::tick(int delta_ms) { // Skip per tecla (després del fade inicial, no mentre). Salta - // directament al FinalFadeOut. Mateix patró que el vell, on + // directament al FINAL_FADE_OUT. Mateix patró que el vell, on // qualsevol tecla sortia del loop. - if (!skip_triggered_ && phase_ != Phase::InitialFadeOut && Ji::anyKey()) { + if (!skip_triggered_ && phase_ != Phase::INITIAL_FADE_OUT && Ji::anyKey()) { skip_triggered_ = true; beginFinalFade(); } switch (phase_) { - case Phase::InitialFadeOut: + case Phase::INITIAL_FADE_OUT: fade_.tick(delta_ms); if (fade_.done()) { // Ara main_palette (la vella) té tots els canals a 0. @@ -100,12 +100,12 @@ namespace scenes { // futures escriptures a pal_active_ afecten la pantalla. Jd8::setScreenPalette(pal_active_); Jd8::clearScreen(255); - phase_ = Phase::Tomba1ScrollIn; + phase_ = Phase::TOMBA1_SCROLL_IN; phase_acc_ms_ = 0; } break; - case Phase::Tomba1ScrollIn: { + case Phase::TOMBA1_SCROLL_IN: { phase_acc_ms_ += delta_ms; const int contador = std::min(128, (phase_acc_ms_ / TICK_MS) + 1); // Dos blits solapats: el primer avança a velocitat completa, @@ -113,63 +113,63 @@ namespace scenes { Jd8::blit(70, 60, gfx_, 0, contador, 178, 70); Jd8::blitCK(70, 60, gfx_, 178, contador >> 1, 142, 70, 255); if (phase_acc_ms_ >= TOMBA1_SCROLL_MS) { - phase_ = Phase::Tomba1Hold; + phase_ = Phase::TOMBA1_HOLD; phase_acc_ms_ = 0; } break; } - case Phase::Tomba1Hold: + case Phase::TOMBA1_HOLD: phase_acc_ms_ += delta_ms; if (phase_acc_ms_ >= TOMBA1_HOLD_MS) { swapToTomba2(); - phase_ = Phase::Tomba2ScrollIn; + phase_ = Phase::TOMBA2_SCROLL_IN; phase_acc_ms_ = 0; } break; - case Phase::Tomba2ScrollIn: { + case Phase::TOMBA2_SCROLL_IN: { phase_acc_ms_ += delta_ms; const int contador = std::min(94, (phase_acc_ms_ / TICK_MS) + 1); Jd8::blit(55, 53, gfx_, 0, 158 - contador, 211, contador); if (phase_acc_ms_ >= TOMBA2_SCROLL_MS) { - phase_ = Phase::Tomba2Hold; + phase_ = Phase::TOMBA2_HOLD; phase_acc_ms_ = 0; } break; } - case Phase::Tomba2Hold: + case Phase::TOMBA2_HOLD: phase_acc_ms_ += delta_ms; if (phase_acc_ms_ >= TOMBA2_HOLD_MS) { beginRedPulseSetup(); - phase_ = Phase::Tomba2Reveal; + phase_ = Phase::TOMBA2_REVEAL; phase_acc_ms_ = 0; } break; - case Phase::Tomba2Reveal: { + case Phase::TOMBA2_REVEAL: { phase_acc_ms_ += delta_ms; const int contador = std::min(80, (phase_acc_ms_ / TICK_MS) + 1); // Revelat horitzontal simètric: l'amplada creix 2px per tick // i el src_x es desplaça a l'esquerra el mateix. Jd8::blit(80, 68, gfx_, 160 - (contador * 2), 0, contador * 2, 64); if (phase_acc_ms_ >= TOMBA2_REVEAL_MS) { - phase_ = Phase::Tomba2RevealHold; + phase_ = Phase::TOMBA2_REVEAL_HOLD; phase_acc_ms_ = 0; } break; } - case Phase::Tomba2RevealHold: + case Phase::TOMBA2_REVEAL_HOLD: phase_acc_ms_ += delta_ms; if (phase_acc_ms_ >= TOMBA2_REVEAL_HOLD_MS) { - phase_ = Phase::RedPulse; + phase_ = Phase::RED_PULSE; phase_acc_ms_ = 0; } break; - case Phase::RedPulse: { + case Phase::RED_PULSE: { phase_acc_ms_ += delta_ms; const int contador = std::min(51, phase_acc_ms_ / TICK_MS); // Anima el canal R dels índexs 254 i 253 (aquest a la meitat @@ -177,27 +177,27 @@ namespace scenes { Jd8::setPaletteColor(254, contador + 12, 11, 11); Jd8::setPaletteColor(253, (contador + 12) >> 1, 11, 11); if (phase_acc_ms_ >= RED_PULSE_MS) { - phase_ = Phase::RedPulseHold; + phase_ = Phase::RED_PULSE_HOLD; phase_acc_ms_ = 0; } break; } - case Phase::RedPulseHold: + case Phase::RED_PULSE_HOLD: phase_acc_ms_ += delta_ms; if (phase_acc_ms_ >= RED_PULSE_HOLD_MS) { beginFinalFade(); } break; - case Phase::FinalFadeOut: + case Phase::FINAL_FADE_OUT: fade_.tick(delta_ms); if (fade_.done()) { - phase_ = Phase::Done; + phase_ = Phase::DONE; } break; - case Phase::Done: + case Phase::DONE: break; } } diff --git a/source/game/scenes/secreta_scene.hpp b/source/game/scenes/secreta_scene.hpp index cd20ef2..4ea3dcd 100644 --- a/source/game/scenes/secreta_scene.hpp +++ b/source/game/scenes/secreta_scene.hpp @@ -33,22 +33,22 @@ namespace scenes { void onEnter() override; void tick(int delta_ms) override; - [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::Done; } + [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::DONE; } [[nodiscard]] auto nextState() const -> int override { return 0; } private: enum class Phase : std::uint8_t { - InitialFadeOut, - Tomba1ScrollIn, - Tomba1Hold, - Tomba2ScrollIn, - Tomba2Hold, - Tomba2Reveal, - Tomba2RevealHold, - RedPulse, - RedPulseHold, - FinalFadeOut, - Done, + INITIAL_FADE_OUT, + TOMBA1_SCROLL_IN, + TOMBA1_HOLD, + TOMBA2_SCROLL_IN, + TOMBA2_HOLD, + TOMBA2_REVEAL, + TOMBA2_REVEAL_HOLD, + RED_PULSE, + RED_PULSE_HOLD, + FINAL_FADE_OUT, + DONE, }; void swapToTomba2(); @@ -60,7 +60,7 @@ namespace scenes { Jd8::Palette pal_active_{nullptr}; // propietat transferida a main_palette PaletteFade fade_; - Phase phase_{Phase::InitialFadeOut}; + Phase phase_{Phase::INITIAL_FADE_OUT}; int phase_acc_ms_{0}; bool skip_triggered_{false}; }; diff --git a/source/game/scenes/slides_scene.cpp b/source/game/scenes/slides_scene.cpp index 3273d69..ed040ae 100644 --- a/source/game/scenes/slides_scene.cpp +++ b/source/game/scenes/slides_scene.cpp @@ -60,7 +60,7 @@ namespace scenes { Jd8::clearScreen(BG_COLOR_INDEX); - phase_ = Phase::Slide1Enter; + phase_ = Phase::SLIDE1_ENTER; phase_acc_ms_ = 0; next_state_ = 0; } @@ -96,7 +96,7 @@ namespace scenes { Audio::get()->fadeOutMusic(250); } fade_.startFadeOut(); - phase_ = Phase::FadeFinal; + phase_ = Phase::FADE_FINAL; } void SlidesScene::tick(int delta_ms) { @@ -109,18 +109,18 @@ namespace scenes { Audio::get()->fadeOutMusic(250); } fade_.startFadeOut(); - phase_ = Phase::FadeFinal; + phase_ = Phase::FADE_FINAL; } switch (phase_) { - case Phase::Slide1Enter: - case Phase::Slide2Enter: - case Phase::Slide3Enter: { + case Phase::SLIDE1_ENTER: + case Phase::SLIDE2_ENTER: + case Phase::SLIDE3_ENTER: { phase_acc_ms_ += delta_ms; int slide_idx = 2; - if (phase_ == Phase::Slide1Enter) { + if (phase_ == Phase::SLIDE1_ENTER) { slide_idx = 0; - } else if (phase_ == Phase::Slide2Enter) { + } else if (phase_ == Phase::SLIDE2_ENTER) { slide_idx = 1; } const float t = std::min(1.0F, static_cast(phase_acc_ms_) / static_cast(SCROLL_MS)); @@ -131,55 +131,55 @@ namespace scenes { if (phase_acc_ms_ >= SCROLL_MS) { // Garanteix posició final exacta (pos_x=0). drawSlide(slide_idx, 0); - if (phase_ == Phase::Slide1Enter) { - phase_ = Phase::Slide1Hold; - } else if (phase_ == Phase::Slide2Enter) { - phase_ = Phase::Slide2Hold; + if (phase_ == Phase::SLIDE1_ENTER) { + phase_ = Phase::SLIDE1_HOLD; + } else if (phase_ == Phase::SLIDE2_ENTER) { + phase_ = Phase::SLIDE2_HOLD; } else { - phase_ = Phase::Slide3Hold; + phase_ = Phase::SLIDE3_HOLD; } phase_acc_ms_ = 0; } break; } - case Phase::Slide1Hold: - case Phase::Slide2Hold: + case Phase::SLIDE1_HOLD: + case Phase::SLIDE2_HOLD: phase_acc_ms_ += delta_ms; if (phase_acc_ms_ >= HOLD_MS) { fade_.startFadeOut(); - if (phase_ == Phase::Slide1Hold) { - phase_ = Phase::FadeOut1; + if (phase_ == Phase::SLIDE1_HOLD) { + phase_ = Phase::FADE_OUT1; } else { - phase_ = Phase::FadeOut2; + phase_ = Phase::FADE_OUT2; } phase_acc_ms_ = 0; } break; - case Phase::Slide3Hold: + case Phase::SLIDE3_HOLD: phase_acc_ms_ += delta_ms; if (phase_acc_ms_ >= HOLD_MS) { beginFinalFade(); } break; - case Phase::FadeOut1: - case Phase::FadeOut2: + case Phase::FADE_OUT1: + case Phase::FADE_OUT2: fade_.tick(delta_ms); if (fade_.done()) { restorePalette(); Jd8::clearScreen(BG_COLOR_INDEX); - if (phase_ == Phase::FadeOut1) { - phase_ = Phase::Slide2Enter; + if (phase_ == Phase::FADE_OUT1) { + phase_ = Phase::SLIDE2_ENTER; } else { - phase_ = Phase::Slide3Enter; + phase_ = Phase::SLIDE3_ENTER; } phase_acc_ms_ = 0; } break; - case Phase::FadeFinal: + case Phase::FADE_FINAL: fade_.tick(delta_ms); if (fade_.done()) { if (num_piramide_at_start_ == 7) { @@ -188,11 +188,11 @@ namespace scenes { } else { next_state_ = 0; } - phase_ = Phase::Done; + phase_ = Phase::DONE; } break; - case Phase::Done: + case Phase::DONE: break; } } diff --git a/source/game/scenes/slides_scene.hpp b/source/game/scenes/slides_scene.hpp index 7644ca7..fb363a4 100644 --- a/source/game/scenes/slides_scene.hpp +++ b/source/game/scenes/slides_scene.hpp @@ -18,18 +18,18 @@ namespace scenes { // - altre cas (num_piramide == 1): gfx/intro.gif, sense música nova // // Flux: - // Slide1Enter (1600 ms scroll dreta→centre, easing outCubic) - // → Slide1Hold (4600 ms) - // → FadeOut1 + clear + reset paleta - // → Slide2Enter (1600 ms scroll esquerra→centre) - // → Slide2Hold (4600 ms) - // → FadeOut2 + clear + reset paleta - // → Slide3Enter (1600 ms scroll dreta→centre) - // → Slide3Hold (4600 ms) - // → FadeFinal (Ja::fadeOutMusic si num_piramide != 7 + fade paleta) + // SLIDE1_ENTER (1600 ms scroll dreta→centre, easing outCubic) + // → SLIDE1_HOLD (4600 ms) + // → FADE_OUT1 + clear + reset paleta + // → SLIDE2_ENTER (1600 ms scroll esquerra→centre) + // → SLIDE2_HOLD (4600 ms) + // → FADE_OUT2 + clear + reset paleta + // → SLIDE3_ENTER (1600 ms scroll dreta→centre) + // → SLIDE3_HOLD (4600 ms) + // → FADE_FINAL (Ja::fadeOutMusic si num_piramide != 7 + fade paleta) // → Done // - // Qualsevol tecla salta directament a FadeFinal (sense cortar la música + // Qualsevol tecla salta directament a FADE_FINAL (sense cortar la música // si hem entrat per num_piramide==7, per fidelitat al vell). // // NextState: @@ -42,21 +42,21 @@ namespace scenes { void onEnter() override; void tick(int delta_ms) override; - [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::Done; } + [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::DONE; } [[nodiscard]] auto nextState() const -> int override { return next_state_; } private: enum class Phase : std::uint8_t { - Slide1Enter, - Slide1Hold, - FadeOut1, - Slide2Enter, - Slide2Hold, - FadeOut2, - Slide3Enter, - Slide3Hold, - FadeFinal, - Done, + SLIDE1_ENTER, + SLIDE1_HOLD, + FADE_OUT1, + SLIDE2_ENTER, + SLIDE2_HOLD, + FADE_OUT2, + SLIDE3_ENTER, + SLIDE3_HOLD, + FADE_FINAL, + DONE, }; // Pinta un slide amb desplaçament horitzontal. `slide_idx` = 0..2 @@ -71,7 +71,7 @@ namespace scenes { Jd8::Palette pal_active_{nullptr}; // propietat transferida a main_palette PaletteFade fade_; - Phase phase_{Phase::Slide1Enter}; + Phase phase_{Phase::SLIDE1_ENTER}; int phase_acc_ms_{0}; int num_piramide_at_start_{1}; int next_state_{0}; From 35cdd88cbb7c5b371a8f2f79d2f60071281ab86e Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 16 May 2026 14:54:21 +0200 Subject: [PATCH 09/13] fix: tidy scenes enums Phase UPPER_CASE (intro/banner/mort/menu/credits) --- source/game/scenes/banner_scene.cpp | 16 +++---- source/game/scenes/banner_scene.hpp | 12 +++--- source/game/scenes/credits_scene.cpp | 12 +++--- source/game/scenes/credits_scene.hpp | 10 ++--- source/game/scenes/intro_new_logo_scene.cpp | 48 ++++++++++----------- source/game/scenes/intro_new_logo_scene.hpp | 18 ++++---- source/game/scenes/intro_scene.cpp | 42 +++++++++--------- source/game/scenes/intro_scene.hpp | 16 +++---- source/game/scenes/menu_scene.cpp | 18 ++++---- source/game/scenes/menu_scene.hpp | 12 +++--- source/game/scenes/mort_scene.cpp | 16 +++---- source/game/scenes/mort_scene.hpp | 12 +++--- 12 files changed, 116 insertions(+), 116 deletions(-) diff --git a/source/game/scenes/banner_scene.cpp b/source/game/scenes/banner_scene.cpp index 66b1a0b..352f7de 100644 --- a/source/game/scenes/banner_scene.cpp +++ b/source/game/scenes/banner_scene.cpp @@ -34,20 +34,20 @@ namespace scenes { fade_.startFadeTo(pal); delete[] pal; - phase_ = Phase::FadingIn; + phase_ = Phase::FADING_IN; remaining_ms_ = 5000; } void BannerScene::tick(int delta_ms) { switch (phase_) { - case Phase::FadingIn: + case Phase::FADING_IN: fade_.tick(delta_ms); if (fade_.done()) { - phase_ = Phase::Showing; + phase_ = Phase::SHOWING; } break; - case Phase::Showing: + case Phase::SHOWING: if (Ji::anyKey()) { remaining_ms_ = 0; } else { @@ -56,18 +56,18 @@ namespace scenes { if (remaining_ms_ <= 0) { Audio::get()->fadeOutMusic(250); fade_.startFadeOut(); - phase_ = Phase::FadingOut; + phase_ = Phase::FADING_OUT; } break; - case Phase::FadingOut: + case Phase::FADING_OUT: fade_.tick(delta_ms); if (fade_.done()) { - phase_ = Phase::Done; + phase_ = Phase::DONE; } break; - case Phase::Done: + case Phase::DONE: break; } } diff --git a/source/game/scenes/banner_scene.hpp b/source/game/scenes/banner_scene.hpp index 8940e3b..8a83da3 100644 --- a/source/game/scenes/banner_scene.hpp +++ b/source/game/scenes/banner_scene.hpp @@ -24,18 +24,18 @@ namespace scenes { public: void onEnter() override; void tick(int delta_ms) override; - [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::Done; } + [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::DONE; } [[nodiscard]] auto nextState() const -> int override { return 0; } private: - enum class Phase : std::uint8_t { FadingIn, - Showing, - FadingOut, - Done }; + enum class Phase : std::uint8_t { FADING_IN, + SHOWING, + FADING_OUT, + DONE }; SurfaceHandle gfx_; PaletteFade fade_; - Phase phase_{Phase::FadingIn}; + Phase phase_{Phase::FADING_IN}; int remaining_ms_{5000}; }; diff --git a/source/game/scenes/credits_scene.cpp b/source/game/scenes/credits_scene.cpp index 35ba37c..5d4d70f 100644 --- a/source/game/scenes/credits_scene.cpp +++ b/source/game/scenes/credits_scene.cpp @@ -56,7 +56,7 @@ namespace scenes { Jd8::setScreenPalette(pal); // `pal` passa a ser propietat de main_palette — no l'alliberem. - phase_ = Phase::Rolling; + phase_ = Phase::ROLLING; contador_ = 1; contador_acc_ms_ = 0; } @@ -109,7 +109,7 @@ namespace scenes { void CreditsScene::tick(int delta_ms) { switch (phase_) { - case Phase::Rolling: { + case Phase::ROLLING: { // Avancem el contador en passos discrets de 20 ms, igual // que feia Jg::shouldUpdate(20) al vell doCredits. contador_acc_ms_ += delta_ms; @@ -124,20 +124,20 @@ namespace scenes { if (Ji::anyKey() || contador_ >= CONTADOR_MAX) { writeTrickIni(); fade_.startFadeOut(); - phase_ = Phase::FadingOut; + phase_ = Phase::FADING_OUT; } break; } - case Phase::FadingOut: + case Phase::FADING_OUT: fade_.tick(delta_ms); if (fade_.done()) { info::ctx.num_piramide = 255; - phase_ = Phase::Done; + phase_ = Phase::DONE; } break; - case Phase::Done: + case Phase::DONE: break; } } diff --git a/source/game/scenes/credits_scene.hpp b/source/game/scenes/credits_scene.hpp index 2d4ef82..f2978b0 100644 --- a/source/game/scenes/credits_scene.hpp +++ b/source/game/scenes/credits_scene.hpp @@ -30,12 +30,12 @@ namespace scenes { void onEnter() override; void tick(int delta_ms) override; - [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::Done; } + [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::DONE; } private: - enum class Phase : std::uint8_t { Rolling, - FadingOut, - Done }; + enum class Phase : std::uint8_t { ROLLING, + FADING_OUT, + DONE }; void render(); static void writeTrickIni(); @@ -45,7 +45,7 @@ namespace scenes { PaletteFade fade_; FrameAnimator coche_{8, 60, true}; // 8 frames × 60 ms (~3 × 20 ms tick vell) - Phase phase_{Phase::Rolling}; + Phase phase_{Phase::ROLLING}; int contador_{1}; int contador_acc_ms_{0}; }; diff --git a/source/game/scenes/intro_new_logo_scene.cpp b/source/game/scenes/intro_new_logo_scene.cpp index 47d9807..1ca19f3 100644 --- a/source/game/scenes/intro_new_logo_scene.cpp +++ b/source/game/scenes/intro_new_logo_scene.cpp @@ -60,7 +60,7 @@ namespace scenes { Jd8::clearScreen(0); - phase_ = Phase::Initial; + phase_ = Phase::INITIAL; phase_acc_ms_ = 0; reveal_letter_ = 0; reveal_cursor_visible_ = true; @@ -69,11 +69,11 @@ namespace scenes { void IntroNewLogoScene::render() { switch (phase_) { - case Phase::Initial: + case Phase::INITIAL: Jd8::clearScreen(0); break; - case Phase::Revealing: { + case Phase::REVEALING: { Jd8::clearScreen(0); Jd8::blit(LOGO_DST_X, LOGO_DST_Y, gfx_, LOGO_SRC_X, LOGO_SRC_Y, LETTER_WIDTHS[reveal_letter_], LOGO_HEIGHT); if (reveal_cursor_visible_) { @@ -82,22 +82,22 @@ namespace scenes { break; } - case Phase::FullLogoFlash: + case Phase::FULL_LOGO_FLASH: Jd8::clearScreen(0); Jd8::blit(LOGO_DST_X, LOGO_DST_Y, gfx_, LOGO_SRC_X, LOGO_SRC_Y, LETTER_WIDTHS[8], LOGO_HEIGHT); Jd8::blit(CURSOR_X[8], CURSOR_Y, cursor_surf_, 0, 0, CURSOR_W, CURSOR_H); break; - case Phase::PaletteCycle: - case Phase::FinalWait: + case Phase::PALETTE_CYCLE: + case Phase::FINAL_WAIT: // Logo complet sense cursor — els pixels del cursor // ciclarien de color durant el cicle de paleta. Jd8::clearScreen(0); Jd8::blit(LOGO_DST_X, LOGO_DST_Y, gfx_, LOGO_SRC_X, LOGO_SRC_Y, LETTER_WIDTHS[8], LOGO_HEIGHT); break; - case Phase::Sprites: - case Phase::Done: + case Phase::SPRITES: + case Phase::DONE: break; } } @@ -134,26 +134,26 @@ namespace scenes { void IntroNewLogoScene::tick(int delta_ms) { // Qualsevol tecla durant el revelat o el ciclo de paleta salta - // TOTA la intro (inclou saltar la fase de sprites). Durant Sprites + // TOTA la intro (inclou saltar la fase de sprites). Durant SPRITES // deixem que la sub-escena gestione el seu propi skip (que a més // respecta la fase "final" no skippable de la variant 0). - if (phase_ != Phase::Sprites && phase_ != Phase::Done && Ji::anyKey()) { + if (phase_ != Phase::SPRITES && phase_ != Phase::DONE && Ji::anyKey()) { info::ctx.num_piramide = 0; - phase_ = Phase::Done; + phase_ = Phase::DONE; return; } switch (phase_) { - case Phase::Initial: + case Phase::INITIAL: phase_acc_ms_ += delta_ms; render(); if (phase_acc_ms_ >= INITIAL_MS) { - phase_ = Phase::Revealing; + phase_ = Phase::REVEALING; phase_acc_ms_ = 0; } break; - case Phase::Revealing: + case Phase::REVEALING: phase_acc_ms_ += delta_ms; render(); if (phase_acc_ms_ >= REVEAL_FRAME_MS) { @@ -164,23 +164,23 @@ namespace scenes { if (reveal_cursor_visible_) { ++reveal_letter_; if (reveal_letter_ >= 9) { - phase_ = Phase::FullLogoFlash; + phase_ = Phase::FULL_LOGO_FLASH; reveal_letter_ = 8; } } } break; - case Phase::FullLogoFlash: + case Phase::FULL_LOGO_FLASH: phase_acc_ms_ += delta_ms; render(); if (phase_acc_ms_ >= FULL_LOGO_MS) { - phase_ = Phase::PaletteCycle; + phase_ = Phase::PALETTE_CYCLE; phase_acc_ms_ = 0; } break; - case Phase::PaletteCycle: + case Phase::PALETTE_CYCLE: phase_acc_ms_ += delta_ms; // Avancem passos de paleta cada 20 ms. Si el delta és gran, // consumim múltiples passos en la mateixa crida. @@ -192,20 +192,20 @@ namespace scenes { } render(); if (palette_step_ >= PALETTE_CYCLE_STEPS) { - phase_ = Phase::FinalWait; + phase_ = Phase::FINAL_WAIT; phase_acc_ms_ = 0; } break; - case Phase::FinalWait: + case Phase::FINAL_WAIT: phase_acc_ms_ += delta_ms; render(); if (phase_acc_ms_ >= FINAL_WAIT_MS) { - phase_ = Phase::Sprites; + phase_ = Phase::SPRITES; } break; - case Phase::Sprites: + case Phase::SPRITES: // Sub-escena construïda al primer tick. Transferim el gfx_ // per move — la sub-escena se n'ocupa fins que es destruix. // Cada tick successiu delega l'animació dels sprites. @@ -219,11 +219,11 @@ namespace scenes { // per passar al menú. Sense açò el while del fiber // tornaria a crear IntroNewLogoScene infinitament. info::ctx.num_piramide = 0; - phase_ = Phase::Done; + phase_ = Phase::DONE; } break; - case Phase::Done: + case Phase::DONE: break; } } diff --git a/source/game/scenes/intro_new_logo_scene.hpp b/source/game/scenes/intro_new_logo_scene.hpp index e572025..40062c4 100644 --- a/source/game/scenes/intro_new_logo_scene.hpp +++ b/source/game/scenes/intro_new_logo_scene.hpp @@ -37,17 +37,17 @@ namespace scenes { void onEnter() override; void tick(int delta_ms) override; - [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::Done; } + [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::DONE; } private: enum class Phase : std::uint8_t { - Initial, // pantalla negra 1000 ms - Revealing, // 9 × 2 frames × 150 ms cada un - FullLogoFlash, // logo complet + cursor, 200 ms - PaletteCycle, // 256 passos × 20 ms modificant paleta - FinalWait, // 20 ms final - Sprites, // tick delegat a IntroSpritesScene fins que acaba - Done, + INITIAL, // pantalla negra 1000 ms + REVEALING, // 9 × 2 frames × 150 ms cada un + FULL_LOGO_FLASH, // logo complet + cursor, 200 ms + PALETTE_CYCLE, // 256 passos × 20 ms modificant paleta + FINAL_WAIT, // 20 ms final + SPRITES, // tick delegat a IntroSpritesScene fins que acaba + DONE, }; void render(); @@ -58,7 +58,7 @@ namespace scenes { Jd8::Palette pal_{nullptr}; // propietat transferida a main_palette via SetScreenPalette std::unique_ptr sprites_scene_; - Phase phase_{Phase::Initial}; + Phase phase_{Phase::INITIAL}; int phase_acc_ms_{0}; int reveal_letter_{0}; bool reveal_cursor_visible_{true}; diff --git a/source/game/scenes/intro_scene.cpp b/source/game/scenes/intro_scene.cpp index 978d3ff..51426a3 100644 --- a/source/game/scenes/intro_scene.cpp +++ b/source/game/scenes/intro_scene.cpp @@ -73,7 +73,7 @@ namespace scenes { Jd8::clearScreen(0); - phase_ = Phase::InitialWait; + phase_ = Phase::INITIAL_WAIT; phase_acc_ms_ = 0; reveal_index_ = 0; palette_step_ = 0; @@ -81,11 +81,11 @@ namespace scenes { void IntroScene::render() { switch (phase_) { - case Phase::InitialWait: + case Phase::INITIAL_WAIT: Jd8::clearScreen(0); break; - case Phase::Reveal: { + case Phase::REVEAL: { const RevealStep& s = REVEAL_STEPS[reveal_index_]; if (s.clear) { Jd8::clearScreen(0); @@ -101,8 +101,8 @@ namespace scenes { break; } - case Phase::PaletteCycle: - case Phase::FinalWait: + case Phase::PALETTE_CYCLE: + case Phase::FINAL_WAIT: // Wordmark complet fix mentre cicla la paleta — l'últim // pas del revelat (PAS 15) deixa la pantalla en aquest mateix // estat, i el vell doIntro no redibuixava durant el cicle. @@ -110,8 +110,8 @@ namespace scenes { drawWordmark(gfx_); break; - case Phase::Sprites: - case Phase::Done: + case Phase::SPRITES: + case Phase::DONE: break; } } @@ -149,39 +149,39 @@ namespace scenes { void IntroScene::tick(int delta_ms) { // Qualsevol tecla durant revelat/paleta salta TOTA la intro - // (inclou saltar la fase de sprites). Durant Sprites deixem que + // (inclou saltar la fase de sprites). Durant SPRITES deixem que // la sub-escena gestione el seu propi skip internament, que a més // respecta la fase "final" no skippable de la variant 0. - if (phase_ != Phase::Sprites && phase_ != Phase::Done && Ji::anyKey()) { + if (phase_ != Phase::SPRITES && phase_ != Phase::DONE && Ji::anyKey()) { info::ctx.num_piramide = 0; - phase_ = Phase::Done; + phase_ = Phase::DONE; return; } switch (phase_) { - case Phase::InitialWait: + case Phase::INITIAL_WAIT: phase_acc_ms_ += delta_ms; render(); if (phase_acc_ms_ >= INITIAL_MS) { - phase_ = Phase::Reveal; + phase_ = Phase::REVEAL; phase_acc_ms_ = 0; reveal_index_ = 0; } break; - case Phase::Reveal: + case Phase::REVEAL: phase_acc_ms_ += delta_ms; render(); if (phase_acc_ms_ >= REVEAL_STEPS[reveal_index_].duration_ms) { phase_acc_ms_ = 0; ++reveal_index_; if (reveal_index_ >= REVEAL_COUNT) { - phase_ = Phase::PaletteCycle; + phase_ = Phase::PALETTE_CYCLE; } } break; - case Phase::PaletteCycle: + case Phase::PALETTE_CYCLE: phase_acc_ms_ += delta_ms; // Avancem tants passos com permet el delta, per evitar // saltar-ne si el frame ha vingut lent. @@ -193,20 +193,20 @@ namespace scenes { } render(); if (palette_step_ >= PALETTE_CYCLE_STEPS) { - phase_ = Phase::FinalWait; + phase_ = Phase::FINAL_WAIT; phase_acc_ms_ = 0; } break; - case Phase::FinalWait: + case Phase::FINAL_WAIT: phase_acc_ms_ += delta_ms; render(); if (phase_acc_ms_ >= FINAL_WAIT_MS) { - phase_ = Phase::Sprites; + phase_ = Phase::SPRITES; } break; - case Phase::Sprites: + case Phase::SPRITES: // Sub-escena construïda al vol al primer tick d'aquesta fase. // Transferim el gfx_ per move — la sub-escena se n'ocupa // fins que es destruix. Una vegada feta, els ticks delegats @@ -221,11 +221,11 @@ namespace scenes { // Sense açò el while del fiber tornaria a crear IntroScene // infinitament amb num_piramide encara a 255. info::ctx.num_piramide = 0; - phase_ = Phase::Done; + phase_ = Phase::DONE; } break; - case Phase::Done: + case Phase::DONE: break; } } diff --git a/source/game/scenes/intro_scene.hpp b/source/game/scenes/intro_scene.hpp index a8813a6..e24c344 100644 --- a/source/game/scenes/intro_scene.hpp +++ b/source/game/scenes/intro_scene.hpp @@ -38,16 +38,16 @@ namespace scenes { void onEnter() override; void tick(int delta_ms) override; - [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::Done; } + [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::DONE; } private: enum class Phase : std::uint8_t { - InitialWait, // 1000 ms pantalla negra - Reveal, // 15 passos del wordmark - PaletteCycle, // 256 × 20 ms mutant pal[16..31] - FinalWait, // 200 ms abans de la sub-escena de sprites - Sprites, // tick delegat a IntroSpritesScene fins que acaba - Done, + INITIAL_WAIT, // 1000 ms pantalla negra + REVEAL, // 15 passos del wordmark + PALETTE_CYCLE, // 256 × 20 ms mutant pal[16..31] + FINAL_WAIT, // 200 ms abans de la sub-escena de sprites + SPRITES, // tick delegat a IntroSpritesScene fins que acaba + DONE, }; void render(); @@ -57,7 +57,7 @@ namespace scenes { Jd8::Palette pal_{nullptr}; // propietat transferida a main_palette via SetScreenPalette std::unique_ptr sprites_scene_; - Phase phase_{Phase::InitialWait}; + Phase phase_{Phase::INITIAL_WAIT}; int phase_acc_ms_{0}; int reveal_index_{0}; int palette_step_{0}; diff --git a/source/game/scenes/menu_scene.cpp b/source/game/scenes/menu_scene.cpp index 676be1a..09d0030 100644 --- a/source/game/scenes/menu_scene.cpp +++ b/source/game/scenes/menu_scene.cpp @@ -13,7 +13,7 @@ namespace scenes { gfx_ = SurfaceHandle("gfx/menu2.gif"); // Pintat inicial (congelat durant el fade-in de paleta). El loop - // d'animació repintarà tot des de zero en el primer tick de Showing. + // d'animació repintarà tot des de zero en el primer tick de SHOWING. Jd8::blit(fondo_); Jd8::blitCK(100, 25, gfx_, 0, 74, 124, 68, 255); // logo Jd8::blitCK(130, 100, gfx_, 0, 0, 80, 74, 255); // camell (frame 0) @@ -23,7 +23,7 @@ namespace scenes { fade_.startFadeTo(pal); delete[] pal; - phase_ = Phase::FadingIn; + phase_ = Phase::FADING_IN; } void MenuScene::render() { @@ -60,14 +60,14 @@ namespace scenes { void MenuScene::tick(int delta_ms) { switch (phase_) { - case Phase::FadingIn: + case Phase::FADING_IN: fade_.tick(delta_ms); if (fade_.done()) { - phase_ = Phase::Showing; + phase_ = Phase::SHOWING; } break; - case Phase::Showing: { + case Phase::SHOWING: { // Palmeres: 1 pixel cada 80 ms (= cada 4 ticks × 20 ms originals) palmeres_acc_ms_ += delta_ms; while (palmeres_acc_ms_ >= 80) { @@ -103,19 +103,19 @@ namespace scenes { Ji::disableKeyboard(60); info::ctx.num_piramide = 1; fade_.startFadeOut(); - phase_ = Phase::FadingOut; + phase_ = Phase::FADING_OUT; } break; } - case Phase::FadingOut: + case Phase::FADING_OUT: fade_.tick(delta_ms); if (fade_.done()) { - phase_ = Phase::Done; + phase_ = Phase::DONE; } break; - case Phase::Done: + case Phase::DONE: break; } } diff --git a/source/game/scenes/menu_scene.hpp b/source/game/scenes/menu_scene.hpp index b3699da..e992907 100644 --- a/source/game/scenes/menu_scene.hpp +++ b/source/game/scenes/menu_scene.hpp @@ -28,13 +28,13 @@ namespace scenes { public: void onEnter() override; void tick(int delta_ms) override; - [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::Done; } + [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::DONE; } private: - enum class Phase : std::uint8_t { FadingIn, - Showing, - FadingOut, - Done }; + enum class Phase : std::uint8_t { FADING_IN, + SHOWING, + FADING_OUT, + DONE }; void render(); @@ -43,7 +43,7 @@ namespace scenes { PaletteFade fade_; FrameAnimator camello_{4, 160, true}; - Phase phase_{Phase::FadingIn}; + Phase phase_{Phase::FADING_IN}; // Scrollers horizontals. Mouen 1 pixel per pas. int palmeres_{0}; diff --git a/source/game/scenes/mort_scene.cpp b/source/game/scenes/mort_scene.cpp index 9a323c4..279853a 100644 --- a/source/game/scenes/mort_scene.cpp +++ b/source/game/scenes/mort_scene.cpp @@ -24,20 +24,20 @@ namespace scenes { fade_.startFadeTo(pal); delete[] pal; - phase_ = Phase::FadingIn; + phase_ = Phase::FADING_IN; remaining_ms_ = 10000; } void MortScene::tick(int delta_ms) { switch (phase_) { - case Phase::FadingIn: + case Phase::FADING_IN: fade_.tick(delta_ms); if (fade_.done()) { - phase_ = Phase::Showing; + phase_ = Phase::SHOWING; } break; - case Phase::Showing: + case Phase::SHOWING: if (Ji::anyKey()) { remaining_ms_ = 0; } else { @@ -49,18 +49,18 @@ namespace scenes { playMusic("music/menu.ogg"); info::ctx.num_piramide = 0; fade_.startFadeOut(); - phase_ = Phase::FadingOut; + phase_ = Phase::FADING_OUT; } break; - case Phase::FadingOut: + case Phase::FADING_OUT: fade_.tick(delta_ms); if (fade_.done()) { - phase_ = Phase::Done; + phase_ = Phase::DONE; } break; - case Phase::Done: + case Phase::DONE: break; } } diff --git a/source/game/scenes/mort_scene.hpp b/source/game/scenes/mort_scene.hpp index b8bdfc4..fcc6be8 100644 --- a/source/game/scenes/mort_scene.hpp +++ b/source/game/scenes/mort_scene.hpp @@ -20,17 +20,17 @@ namespace scenes { public: void onEnter() override; void tick(int delta_ms) override; - [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::Done; } + [[nodiscard]] auto done() const -> bool override { return phase_ == Phase::DONE; } private: - enum class Phase : std::uint8_t { FadingIn, - Showing, - FadingOut, - Done }; + enum class Phase : std::uint8_t { FADING_IN, + SHOWING, + FADING_OUT, + DONE }; SurfaceHandle gfx_; PaletteFade fade_; - Phase phase_{Phase::FadingIn}; + Phase phase_{Phase::FADING_IN}; int remaining_ms_{10000}; // 1000 ticks × 10 ms/tick del doMort original }; From ae89b252e2b00f64e7202c31e02d362a5923f3e8 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 16 May 2026 14:57:07 +0200 Subject: [PATCH 10/13] =?UTF-8?q?fix:=20tidy=20director/jdraw8/jinput/jfil?= =?UTF-8?q?e=20(locals=20UPPER=5FCASE,=20file=5F*=E2=86=92Jf::)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/core/jail/jdraw8.cpp | 32 +++++++++++------------ source/core/jail/jfile.cpp | 12 ++++----- source/core/jail/jfile.hpp | 16 +++++++----- source/core/jail/jinput.cpp | 30 ++++++++++----------- source/core/resources/resource_helper.cpp | 2 +- source/core/resources/resource_helper.hpp | 2 +- source/core/system/director.cpp | 32 +++++++++++------------ source/main.cpp | 14 +++++----- 8 files changed, 72 insertions(+), 68 deletions(-) diff --git a/source/core/jail/jdraw8.cpp b/source/core/jail/jdraw8.cpp index 8f74420..b851349 100644 --- a/source/core/jail/jdraw8.cpp +++ b/source/core/jail/jdraw8.cpp @@ -117,9 +117,9 @@ void Jd8::setScreenPalette(Jd8::Palette palette) { } void Jd8::fillSquare(int ini, int height, Uint8 color) { - const int offset = ini * 320; - const int size = height * 320; - memset(&screen[offset], color, size); + const int OFFSET = ini * 320; + const int SIZE = height * 320; + memset(&screen[OFFSET], color, SIZE); } void Jd8::fillRect(int x, int y, int w, int h, Uint8 color) { @@ -265,25 +265,25 @@ void Jd8::setPaletteColor(Uint8 index, Uint8 r, Uint8 g, Uint8 b) { namespace { enum class FadeType : std::uint8_t { - None = 0, - Out, - ToPal, + NONE = 0, + OUT, + TO_PAL, }; constexpr int FADE_STEPS = 32; - FadeType fade_type = FadeType::None; + FadeType fade_type = FadeType::NONE; Color fade_target[256]; int fade_step = 0; - void apply_fade_step() { - if (fade_type == FadeType::Out) { + void applyFadeStep() { + if (fade_type == FadeType::OUT) { for (int i = 0; i < 256; i++) { main_palette[i].r = main_palette[i].r >= 8 ? main_palette[i].r - 8 : 0; main_palette[i].g = main_palette[i].g >= 8 ? main_palette[i].g - 8 : 0; main_palette[i].b = main_palette[i].b >= 8 ? main_palette[i].b - 8 : 0; } - } else if (fade_type == FadeType::ToPal) { + } else if (fade_type == FadeType::TO_PAL) { for (int i = 0; i < 256; i++) { main_palette[i].r = main_palette[i].r <= int(fade_target[i].r) - 8 ? main_palette[i].r + 8 @@ -301,30 +301,30 @@ namespace { } // namespace void Jd8::fadeStartOut() { - fade_type = FadeType::Out; + fade_type = FadeType::OUT; fade_step = 0; } void Jd8::fadeStartToPal(const Color* pal) { - fade_type = FadeType::ToPal; + fade_type = FadeType::TO_PAL; memcpy(fade_target, pal, sizeof(Color) * 256); fade_step = 0; } auto Jd8::fadeIsActive() -> bool { - return fade_type != FadeType::None; + return fade_type != FadeType::NONE; } auto Jd8::fadeTickStep() -> bool { - if (fade_type == FadeType::None) { + if (fade_type == FadeType::NONE) { return true; } - apply_fade_step(); + applyFadeStep(); fade_step++; if (fade_step >= FADE_STEPS) { - fade_type = FadeType::None; + fade_type = FadeType::NONE; return true; } return false; diff --git a/source/core/jail/jfile.cpp b/source/core/jail/jfile.cpp index 48ec485..e75ad28 100644 --- a/source/core/jail/jfile.cpp +++ b/source/core/jail/jfile.cpp @@ -55,17 +55,17 @@ namespace { } // namespace -void file_setresourcefolder(const char* str) { +void Jf::setResourceFolder(const char* str) { resource_folder = str; } -auto file_getresourcefolder() -> const char* { +auto Jf::getResourceFolder() -> const char* { return resource_folder.c_str(); } // Crea la carpeta del sistema on guardar les dades. // Accepta rutes amb subdirectoris (ex: "jailgames/aee") i crea tota la jerarquia. -void file_setconfigfolder(const char* foldername) { +void Jf::setConfigFolder(const char* foldername) { #ifdef _WIN32 const char* base = getenv("APPDATA"); if (!base) base = "C:/"; @@ -102,13 +102,13 @@ void file_setconfigfolder(const char* foldername) { // volàtil al navegador de totes formes: ignorem l'error i continuem. } -auto file_getconfigfolder() -> const char* { +auto Jf::getConfigFolder() -> const char* { thread_local std::string folder_; folder_ = config_folder + "/"; return folder_.c_str(); } -auto file_getconfigvalue(const char* key) -> const char* { +auto Jf::getConfigValue(const char* key) -> const char* { if (config.empty()) { loadConfigValues(); } @@ -121,7 +121,7 @@ auto file_getconfigvalue(const char* key) -> const char* { return nullptr; } -void file_setconfigvalue(const char* key, const char* value) { +void Jf::setConfigValue(const char* key, const char* value) { if (config.empty()) { loadConfigValues(); } diff --git a/source/core/jail/jfile.hpp b/source/core/jail/jfile.hpp index ac7c21c..3642810 100644 --- a/source/core/jail/jfile.hpp +++ b/source/core/jail/jfile.hpp @@ -1,10 +1,14 @@ #pragma once -void file_setconfigfolder(const char* foldername); -auto file_getconfigfolder() -> const char*; +namespace Jf { -void file_setresourcefolder(const char* str); -auto file_getresourcefolder() -> const char*; + void setConfigFolder(const char* foldername); + auto getConfigFolder() -> const char*; -auto file_getconfigvalue(const char* key) -> const char*; -void file_setconfigvalue(const char* key, const char* value); + void setResourceFolder(const char* str); + auto getResourceFolder() -> const char*; + + auto getConfigValue(const char* key) -> const char*; + void setConfigValue(const char* key, const char* value); + +} // namespace Jf diff --git a/source/core/jail/jinput.cpp b/source/core/jail/jinput.cpp index 98fecc5..de9532e 100644 --- a/source/core/jail/jinput.cpp +++ b/source/core/jail/jinput.cpp @@ -30,7 +30,7 @@ namespace { Uint8 virtual_keystates[static_cast(Ji::VirtualSource::COUNT)][SDL_SCANCODE_COUNT] = {{0}}; - auto scancode_to_ascii(Uint8 scancode) -> Uint8 { + auto scancodeToAscii(Uint8 scancode) -> Uint8 { if (scancode >= SDL_SCANCODE_A && scancode <= SDL_SCANCODE_Z) { return static_cast('a' + (scancode - SDL_SCANCODE_A)); } @@ -51,11 +51,11 @@ void Ji::setVirtualKey(int scancode, VirtualSource source, bool pressed) { if (scancode < 0 || scancode >= SDL_SCANCODE_COUNT) { return; } - const auto src_idx = static_cast(source); - if (src_idx >= static_cast(VirtualSource::COUNT)) { + const auto SRC_IDX = static_cast(source); + if (SRC_IDX >= static_cast(VirtualSource::COUNT)) { return; } - virtual_keystates[src_idx][scancode] = pressed ? 1 : 0; + virtual_keystates[SRC_IDX][scancode] = pressed ? 1 : 0; } void Ji::moveCheats(Uint8 scancode) { @@ -63,7 +63,7 @@ void Ji::moveCheats(Uint8 scancode) { cheat[1] = cheat[2]; cheat[2] = cheat[3]; cheat[3] = cheat[4]; - cheat[4] = scancode_to_ascii(scancode); + cheat[4] = scancodeToAscii(scancode); } void Ji::update() { @@ -73,15 +73,15 @@ void Ji::update() { keystates = SDL_GetKeyboardState(nullptr); } - const Uint64 now = SDL_GetTicks(); + const Uint64 NOW = SDL_GetTicks(); if (last_update_tick == 0) { - last_update_tick = now; + last_update_tick = NOW; } - const auto delta_ms = static_cast(now - last_update_tick); - last_update_tick = now; + const auto DELTA_MS = static_cast(NOW - last_update_tick); + last_update_tick = NOW; if (wait_ms > 0.0F) { - wait_ms -= delta_ms; + wait_ms -= DELTA_MS; wait_ms = std::max(wait_ms, 0.0F); } @@ -111,15 +111,15 @@ auto Ji::keyPressed(int key) -> bool { } auto Ji::cheatActivated(const char* cheat_code) -> bool { - const size_t len = std::strlen(cheat_code); - if (len > sizeof(cheat)) { + const size_t LEN = std::strlen(cheat_code); + if (LEN > sizeof(cheat)) { return false; } // Compara contra els últims `len` caràcters del buffer. El buffer té // mida fixa 5 i acumula sempre el darrer tecle a la posició 4. - const size_t offset = sizeof(cheat) - len; - for (size_t i = 0; i < len; i++) { - if (cheat[offset + i] != static_cast(cheat_code[i])) { + const size_t OFFSET = sizeof(cheat) - LEN; + for (size_t i = 0; i < LEN; i++) { + if (cheat[OFFSET + i] != static_cast(cheat_code[i])) { return false; } } diff --git a/source/core/resources/resource_helper.cpp b/source/core/resources/resource_helper.cpp index a9627f3..6fcea0a 100644 --- a/source/core/resources/resource_helper.cpp +++ b/source/core/resources/resource_helper.cpp @@ -14,7 +14,7 @@ namespace ResourceHelper { bool fallback_enabled_ = true; auto readFromDisk(const std::string& relative_path) -> std::vector { - const std::string full = std::string(file_getresourcefolder()) + relative_path; + const std::string full = std::string(Jf::getResourceFolder()) + relative_path; std::ifstream file(full, std::ios::binary | std::ios::ate); if (!file) { return {}; diff --git a/source/core/resources/resource_helper.hpp b/source/core/resources/resource_helper.hpp index a4df9b4..ea2b3ac 100644 --- a/source/core/resources/resource_helper.hpp +++ b/source/core/resources/resource_helper.hpp @@ -5,7 +5,7 @@ #include // API d'alt nivell per a llegir recursos. Prova primer el pack (si està -// carregat), després cau al fitxer solt dins `file_getresourcefolder()` +// carregat), després cau al fitxer solt dins `Jf::getResourceFolder()` // si el fallback està activat. namespace ResourceHelper { diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index c968064..bcb9b62 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -170,7 +170,7 @@ auto Director::iterate() -> bool { constexpr Uint32 FRAME_MS_VSYNC = 16; // ~60 FPS amb VSync constexpr Uint32 FRAME_MS_NO_VSYNC = 4; // ~250 FPS sense VSync (límit superior) - const Uint32 frame_start = SDL_GetTicks(); + const Uint32 FRAME_START = SDL_GetTicks(); Gamepad::update(); KeyRemap::update(); @@ -184,12 +184,12 @@ auto Director::iterate() -> bool { // Dispara els crèdits cinematogràfics la primera vegada que el joc // arriba al menú del títol (info::ctx.num_piramide == 0). - static bool credits_triggered = false; - if (!credits_triggered && info::ctx.num_piramide == 0) { + static bool credits_triggered_ = false; + if (!credits_triggered_ && info::ctx.num_piramide == 0) { if (Options::game.show_title_credits) { Overlay::startCredits(); } - credits_triggered = true; + credits_triggered_ = true; } // Si l'overlay ja no bloqueja ESC (timeout), desbloquegem @@ -225,12 +225,12 @@ auto Director::iterate() -> bool { } // Tick de l'escena. Ji::update refresca key_pressed/any_key; el - // delta_ms és el temps real transcorregut des de l'últim tick. + // DELTA_MS és el temps real transcorregut des de l'últim tick. Ji::update(); - const Uint32 now = SDL_GetTicks(); - const int delta_ms = static_cast(now - last_tick_ms_); - last_tick_ms_ = now; - current_scene_->tick(delta_ms); + const Uint32 NOW = SDL_GetTicks(); + const int DELTA_MS = static_cast(NOW - last_tick_ms_); + last_tick_ms_ = NOW; + current_scene_->tick(DELTA_MS); // Converteix `screen` indexat → `pixel_data` ARGB amb la paleta // actual. Jd8::flip ja no fa yield (Phase B.2 eliminà els fibers); @@ -250,10 +250,10 @@ auto Director::iterate() -> bool { // Nota: quan el runtime posseïx el main loop (SDL_AppIterate / // emscripten), aquest SDL_Delay no és ideal. Fase 7 afegirà un mode // que es basa en el timing intern de SDL en lloc del delay explícit. - const Uint32 target_ms = Options::video.vsync ? FRAME_MS_VSYNC : FRAME_MS_NO_VSYNC; - const Uint32 elapsed = SDL_GetTicks() - frame_start; - if (elapsed < target_ms) { - SDL_Delay(target_ms - elapsed); + const Uint32 TARGET_MS = Options::video.vsync ? FRAME_MS_VSYNC : FRAME_MS_NO_VSYNC; + const Uint32 ELAPSED = SDL_GetTicks() - FRAME_START; + if (ELAPSED < TARGET_MS) { + SDL_Delay(TARGET_MS - ELAPSED); } return true; @@ -386,10 +386,10 @@ void Director::handleEvent(const SDL_Event& event) { // KeyConfig::isGuiKey cobreix totes les tecles GUI a la vegada, // incloent pause_toggle i menu_toggle (defensa en profunditat: // aquestes ja s'haurien hagut de menjar al swallow d'amunt). - const auto sc = event.key.scancode; - if (!KeyConfig::isGuiKey(sc)) { + const auto SC = event.key.scancode; + if (!KeyConfig::isGuiKey(SC)) { key_pressed_ = true; - Ji::moveCheats(sc); + Ji::moveCheats(SC); } } Mouse::handleEvent(event); diff --git a/source/main.cpp b/source/main.cpp index d256b3d..a39ecf7 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -30,7 +30,7 @@ auto SDL_AppInit(void** /*appstate*/, int /*argc*/, char* /*argv*/[]) -> SDL_App srand(unsigned(time(nullptr))); // Crea la carpeta de configuració i carrega les opcions - file_setconfigfolder("jailgames/aee"); + Jf::setConfigFolder("jailgames/aee"); // Ruta absoluta a data/ basada en la ubicació de l'executable. // SDL_GetBasePath() detecta automàticament si estem dins d'un .app bundle @@ -39,7 +39,7 @@ auto SDL_AppInit(void** /*appstate*/, int /*argc*/, char* /*argv*/[]) -> SDL_App std::string resource_pack_path; if (base_path != nullptr) { const std::string data_path = std::string(base_path) + "data/"; - file_setresourcefolder(data_path.c_str()); + Jf::setResourceFolder(data_path.c_str()); resource_pack_path = std::string(base_path) + "resources.pack"; } else { resource_pack_path = "resources.pack"; @@ -57,17 +57,17 @@ auto SDL_AppInit(void** /*appstate*/, int /*argc*/, char* /*argv*/[]) -> SDL_App return SDL_APP_FAILURE; } - Options::setConfigFile(std::string(file_getconfigfolder()) + "config.yaml"); + Options::setConfigFile(std::string(Jf::getConfigFolder()) + "config.yaml"); Options::loadFromFile(); // KeyConfig: defaults des de data/input/keys.yaml + overrides de l'usuari KeyConfig::init("input/keys.yaml", - std::string(file_getconfigfolder()) + "keys.yaml"); + std::string(Jf::getConfigFolder()) + "keys.yaml"); #ifndef NDEBUG // debug.yaml: estat inicial de gameplay per a tests ràpids, // només en builds de debug. - Options::setDebugFile(std::string(file_getconfigfolder()) + "debug.yaml"); + Options::setDebugFile(std::string(Jf::getConfigFolder()) + "debug.yaml"); Options::loadDebugFromFile(); #endif @@ -84,9 +84,9 @@ auto SDL_AppInit(void** /*appstate*/, int /*argc*/, char* /*argv*/[]) -> SDL_App Locale::load("locale/ca.yaml"); // Carrega presets de shaders - Options::setPostFXFile(std::string(file_getconfigfolder()) + "postfx.yaml"); + Options::setPostFXFile(std::string(Jf::getConfigFolder()) + "postfx.yaml"); Options::loadPostFXFromFile(); - Options::setCrtPiFile(std::string(file_getconfigfolder()) + "crtpi.yaml"); + Options::setCrtPiFile(std::string(Jf::getConfigFolder()) + "crtpi.yaml"); Options::loadCrtPiFromFile(); Jg::init(); From ae359f4a1e066697a0446b36411db26262214a45 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 16 May 2026 15:06:16 +0200 Subject: [PATCH 11/13] fix: tidy namespace Scenes::/Info:: PascalCase i locals UPPER_CASE --- source/core/jail/jdraw8.cpp | 2 +- source/core/jail/jdraw8.hpp | 2 +- source/core/jail/jgame.cpp | 14 ++-- source/core/rendering/screen.cpp | 42 ++++++------ .../core/rendering/sdl3gpu/sdl3gpu_shader.cpp | 30 ++++----- source/core/resources/resource_cache.cpp | 6 +- source/core/resources/resource_helper.cpp | 4 +- source/core/system/director.cpp | 66 +++++++++---------- source/core/system/director.hpp | 12 ++-- source/game/bola.cpp | 4 +- source/game/info.cpp | 2 +- source/game/info.hpp | 6 +- source/game/mapa.cpp | 28 ++++---- source/game/marcador.cpp | 18 ++--- source/game/modulegame.cpp | 56 ++++++++-------- source/game/modulegame.hpp | 8 +-- source/game/momia.cpp | 10 +-- source/game/prota.cpp | 8 +-- source/game/scenes/banner_scene.cpp | 16 ++--- source/game/scenes/banner_scene.hpp | 6 +- source/game/scenes/boot_loader_scene.cpp | 12 ++-- source/game/scenes/boot_loader_scene.hpp | 4 +- source/game/scenes/credits_scene.cpp | 10 +-- source/game/scenes/credits_scene.hpp | 8 +-- source/game/scenes/frame_animator.cpp | 4 +- source/game/scenes/frame_animator.hpp | 4 +- source/game/scenes/intro_new_logo_scene.cpp | 8 +-- source/game/scenes/intro_new_logo_scene.hpp | 4 +- source/game/scenes/intro_scene.cpp | 8 +-- source/game/scenes/intro_scene.hpp | 4 +- source/game/scenes/intro_sprites_scene.cpp | 4 +- source/game/scenes/intro_sprites_scene.hpp | 4 +- source/game/scenes/menu_scene.cpp | 16 ++--- source/game/scenes/menu_scene.hpp | 6 +- source/game/scenes/mort_scene.cpp | 8 +-- source/game/scenes/mort_scene.hpp | 4 +- source/game/scenes/palette_fade.cpp | 4 +- source/game/scenes/palette_fade.hpp | 4 +- source/game/scenes/scene.hpp | 6 +- source/game/scenes/scene_registry.cpp | 10 +-- source/game/scenes/scene_registry.hpp | 6 +- source/game/scenes/scene_utils.cpp | 4 +- source/game/scenes/scene_utils.hpp | 4 +- source/game/scenes/secreta_scene.cpp | 32 ++++----- source/game/scenes/secreta_scene.hpp | 4 +- source/game/scenes/slides_scene.cpp | 34 +++++----- source/game/scenes/slides_scene.hpp | 4 +- source/game/scenes/sprite_mover.cpp | 12 ++-- source/game/scenes/sprite_mover.hpp | 4 +- source/game/scenes/surface_handle.cpp | 4 +- source/game/scenes/surface_handle.hpp | 4 +- source/game/scenes/timeline.cpp | 4 +- source/game/scenes/timeline.hpp | 4 +- source/main.cpp | 10 +-- source/utils/easing.cpp | 4 +- 55 files changed, 303 insertions(+), 303 deletions(-) diff --git a/source/core/jail/jdraw8.cpp b/source/core/jail/jdraw8.cpp index b851349..edfd095 100644 --- a/source/core/jail/jdraw8.cpp +++ b/source/core/jail/jdraw8.cpp @@ -334,5 +334,5 @@ auto Jd8::fadeTickStep() -> bool { // eliminats a Phase B.2: feien un bucle de 32 iteracions amb `Jd8::flip` // entre cada una que només funcionava mentre l'entorn tenia fibers i // `Jd8::flip` cedia el control al Director. Ara tot fade es fa tick a -// tick via `scenes::PaletteFade` (que encapsula `Jd8::fadeStartOut` / +// tick via `Scenes::PaletteFade` (que encapsula `Jd8::fadeStartOut` / // `Jd8::fadeStartToPal` + `Jd8::fadeTickStep`). diff --git a/source/core/jail/jdraw8.hpp b/source/core/jail/jdraw8.hpp index 3e8d3b1..ae5fc15 100644 --- a/source/core/jail/jdraw8.hpp +++ b/source/core/jail/jdraw8.hpp @@ -69,7 +69,7 @@ namespace Jd8 { // (32 passos en total). El caller és responsable de fer el Flip entre // passos si el vol veure animat. `fadeIsActive` permet saber si hi ha // un fade en curs per a enllaçar-lo amb un altre subsistema. - // L'embolcall `scenes::PaletteFade` ho fa més idiomàtic per a escenes. + // L'embolcall `Scenes::PaletteFade` ho fa més idiomàtic per a escenes. void fadeStartOut(); void fadeStartToPal(const Color* pal); auto fadeTickStep() -> bool; diff --git a/source/core/jail/jgame.cpp b/source/core/jail/jgame.cpp index 28d1f49..5135c02 100644 --- a/source/core/jail/jgame.cpp +++ b/source/core/jail/jgame.cpp @@ -33,9 +33,9 @@ void Jg::setUpdateTicks(Uint32 milliseconds) { } auto Jg::shouldUpdate() -> bool { - const Uint32 now = SDL_GetTicks(); - if (now - update_time > update_ticks) { - update_time = now; + const Uint32 NOW = SDL_GetTicks(); + if (NOW - update_time > update_ticks) { + update_time = NOW; cycle_counter++; return true; } @@ -50,8 +50,8 @@ auto Jg::getCycleCounter() -> Uint32 { } auto Jg::getDeltaMs() -> Uint32 { - const Uint32 now = SDL_GetTicks(); - const Uint32 delta = now - last_delta_time; - last_delta_time = now; - return delta; + const Uint32 NOW = SDL_GetTicks(); + const Uint32 DELTA = NOW - last_delta_time; + last_delta_time = NOW; + return DELTA; } diff --git a/source/core/rendering/screen.cpp b/source/core/rendering/screen.cpp index b532bae..c7541f9 100644 --- a/source/core/rendering/screen.cpp +++ b/source/core/rendering/screen.cpp @@ -231,28 +231,28 @@ void Screen::present(Uint32* pixel_data) { // no trencar la selecció de l'usuari. Rendering::PostFXParams clean{}; shader_backend_->setPostFXParams(clean); - const auto prev_shader = shader_backend_->getActiveShader(); - if (prev_shader != Rendering::ShaderType::POSTFX) { + const auto PREV_SHADER = shader_backend_->getActiveShader(); + if (PREV_SHADER != Rendering::ShaderType::POSTFX) { shader_backend_->setActiveShader(Rendering::ShaderType::POSTFX); } shader_backend_->uploadPixels(pixel_data, GAME_WIDTH, GAME_HEIGHT); shader_backend_->render(); - if (prev_shader != Rendering::ShaderType::POSTFX) { - shader_backend_->setActiveShader(prev_shader); + if (PREV_SHADER != Rendering::ShaderType::POSTFX) { + shader_backend_->setActiveShader(PREV_SHADER); } } else { - // Fallback SDL_Renderer. A mult=1, flux directe original: logical + // Fallback SDL_Renderer. A MULT=1, flux directe original: logical // presentation (setada per applyFallbackPresentation) + scale mode de - // texture_ segons l'opció. A mult>1, la còpia intermèdia crea la + // texture_ segons l'opció. A MULT>1, la còpia intermèdia crea la // font ampliada (NN via GPU), i es presenta via logical presentation // a la mida de la font intermèdia. SDL_UpdateTexture(texture_, nullptr, pixel_data, GAME_WIDTH * sizeof(Uint32)); - const int mult = Options::video.internal_resolution; - if (mult > 1) { + const int MULT = Options::video.internal_resolution; + if (MULT > 1) { ensureFallbackInternalTexture(); if (internal_texture_sdl_ != nullptr) { - // Còpia NN a la textura intermèdia (mult·game). Sampler NN + // Còpia NN a la textura intermèdia (MULT·game). Sampler NN // per construcció: volem píxels grans i nets. SDL_SetTextureScaleMode(texture_, SDL_SCALEMODE_NEAREST); SDL_SetRenderTarget(renderer_, internal_texture_sdl_); @@ -261,7 +261,7 @@ void Screen::present(Uint32* pixel_data) { SDL_SetRenderTarget(renderer_, nullptr); // Filtre global al pas final → finestra (via logical presentation - // que applyFallbackPresentation ja configura amb mida game·mult). + // que applyFallbackPresentation ja configura amb mida game·MULT). SDL_ScaleMode final_scale = (Options::video.texture_filter == Options::TextureFilter::LINEAR) ? SDL_SCALEMODE_LINEAR : SDL_SCALEMODE_NEAREST; @@ -273,9 +273,9 @@ void Screen::present(Uint32* pixel_data) { } // Si la creació de la textura intermèdia ha fallat, caiem al path normal. } - // mult=1 (o fallback-del-fallback): texture_ directament. El scale mode + // MULT=1 (o fallback-del-fallback): texture_ directament. El scale mode // el manté applyFallbackPresentation — però el re-apliquem per si la - // ruta mult>1 el va sobreescriure anteriorment. + // ruta MULT>1 el va sobreescriure anteriorment. SDL_ScaleMode direct_scale = (Options::video.texture_filter == Options::TextureFilter::LINEAR) ? SDL_SCALEMODE_LINEAR : SDL_SCALEMODE_NEAREST; @@ -632,16 +632,16 @@ void Screen::applyFallbackPresentation() { } // Amb resolució interna N > 1, la mida lògica creix proporcionalment // perquè SDL scale des de 320·N × 200·N a la finestra — menys aggressive linear. - const int mult = Options::video.internal_resolution < 1 ? 1 : Options::video.internal_resolution; - SDL_SetRenderLogicalPresentation(renderer_, GAME_WIDTH * mult, GAME_HEIGHT * mult, mode); + const int MULT = Options::video.internal_resolution < 1 ? 1 : Options::video.internal_resolution; + SDL_SetRenderLogicalPresentation(renderer_, GAME_WIDTH * MULT, GAME_HEIGHT * MULT, mode); } void Screen::ensureFallbackInternalTexture() { if (renderer_ == nullptr) { return; } - const int mult = Options::video.internal_resolution; - if (mult <= 1) { + const int MULT = Options::video.internal_resolution; + if (MULT <= 1) { // No cal textura intermèdia — recicla si la teníem. if (internal_texture_sdl_ != nullptr) { SDL_DestroyTexture(internal_texture_sdl_); @@ -650,7 +650,7 @@ void Screen::ensureFallbackInternalTexture() { } return; } - if (internal_texture_sdl_ != nullptr && internal_texture_mult_ == mult) { + if (internal_texture_sdl_ != nullptr && internal_texture_mult_ == MULT) { return; } @@ -661,15 +661,15 @@ void Screen::ensureFallbackInternalTexture() { internal_texture_sdl_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_TARGET, - GAME_WIDTH * mult, - GAME_HEIGHT * mult); + GAME_WIDTH * MULT, + GAME_HEIGHT * MULT); if (internal_texture_sdl_ == nullptr) { - std::cerr << "Screen: failed to create fallback internal texture (×" << mult << "): " + std::cerr << "Screen: failed to create fallback internal texture (×" << MULT << "): " << SDL_GetError() << '\n'; internal_texture_mult_ = 0; return; } - internal_texture_mult_ = mult; + internal_texture_mult_ = MULT; } void Screen::adjustWindowSize() { diff --git a/source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp b/source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp index 9516943..9e92519 100644 --- a/source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp +++ b/source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp @@ -906,8 +906,8 @@ namespace Rendering { // ---- Calcular viewport (dimensions lògiques del canvas) ---- // Si 4:3 actiu, effective_height ja és 240 (la textura estirada) - const auto logical_w = static_cast(game_width_); - const auto logical_h = static_cast(effective_height); + const auto LOGICAL_W = static_cast(game_width_); + const auto LOGICAL_H = static_cast(effective_height); float vx = 0.0F; float vy = 0.0F; @@ -916,8 +916,8 @@ namespace Rendering { switch (scaling_mode_) { case Options::ScalingMode::DISABLED: // 1:1, sense escala (pot ser diminut en finestres grans) - vw = logical_w; - vh = logical_h; + vw = LOGICAL_W; + vh = LOGICAL_H; break; case Options::ScalingMode::STRETCH: // Omple tota la finestra, escala no uniforme @@ -925,23 +925,23 @@ namespace Rendering { vh = static_cast(sh); break; case Options::ScalingMode::LETTERBOX: { - const float SCALE = std::min(static_cast(sw) / logical_w, - static_cast(sh) / logical_h); - vw = logical_w * SCALE; - vh = logical_h * SCALE; + const float SCALE = std::min(static_cast(sw) / LOGICAL_W, + static_cast(sh) / LOGICAL_H); + vw = LOGICAL_W * SCALE; + vh = LOGICAL_H * SCALE; break; } case Options::ScalingMode::OVERSCAN: { - const float SCALE = std::max(static_cast(sw) / logical_w, - static_cast(sh) / logical_h); - vw = logical_w * SCALE; - vh = logical_h * SCALE; + const float SCALE = std::max(static_cast(sw) / LOGICAL_W, + static_cast(sh) / LOGICAL_H); + vw = LOGICAL_W * SCALE; + vh = LOGICAL_H * SCALE; break; } case Options::ScalingMode::INTEGER: { - const int SCALE = std::max(1, std::min(static_cast(sw) / static_cast(logical_w), static_cast(sh) / static_cast(logical_h))); - vw = logical_w * static_cast(SCALE); - vh = logical_h * static_cast(SCALE); + const int SCALE = std::max(1, std::min(static_cast(sw) / static_cast(LOGICAL_W), static_cast(sh) / static_cast(LOGICAL_H))); + vw = LOGICAL_W * static_cast(SCALE); + vh = LOGICAL_H * static_cast(SCALE); break; } } diff --git a/source/core/resources/resource_cache.cpp b/source/core/resources/resource_cache.cpp index 14a0be9..c1e9188 100644 --- a/source/core/resources/resource_cache.cpp +++ b/source/core/resources/resource_cache.cpp @@ -108,8 +108,8 @@ namespace Resource { return true; } - const Uint64 start_ns = SDL_GetTicksNS(); - const Uint64 budget_ns = static_cast(budget_ms) * 1'000'000ULL; + const Uint64 START_NS = SDL_GetTicksNS(); + const Uint64 BUDGET_NS = static_cast(budget_ms) * 1'000'000ULL; const auto* list = List::get(); while (stage_ != LoadStage::DONE) { @@ -173,7 +173,7 @@ namespace Resource { case LoadStage::DONE: break; } - if ((SDL_GetTicksNS() - start_ns) >= budget_ns) { + if ((SDL_GetTicksNS() - START_NS) >= BUDGET_NS) { break; } } diff --git a/source/core/resources/resource_helper.cpp b/source/core/resources/resource_helper.cpp index 6fcea0a..9ea6443 100644 --- a/source/core/resources/resource_helper.cpp +++ b/source/core/resources/resource_helper.cpp @@ -14,8 +14,8 @@ namespace ResourceHelper { bool fallback_enabled_ = true; auto readFromDisk(const std::string& relative_path) -> std::vector { - const std::string full = std::string(Jf::getResourceFolder()) + relative_path; - std::ifstream file(full, std::ios::binary | std::ios::ate); + const std::string FULL = std::string(Jf::getResourceFolder()) + relative_path; + std::ifstream file(FULL, std::ios::binary | std::ios::ate); if (!file) { return {}; } diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index bcb9b62..5703d53 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -37,42 +37,42 @@ std::unique_ptr Director::instance_; Director::~Director() = default; void Director::initGameContext() { - info::ctx.num_habitacio = Options::game.habitacio_inicial; - info::ctx.num_piramide = Options::game.piramide_inicial; - info::ctx.diners = Options::game.diners_inicial; - info::ctx.diamants = Options::game.diamants_inicial; - info::ctx.vida = Options::game.vides; - info::ctx.momies = 0; - info::ctx.nou_personatge = false; - info::ctx.pepe_activat = false; + Info::ctx.num_habitacio = Options::game.habitacio_inicial; + Info::ctx.num_piramide = Options::game.piramide_inicial; + Info::ctx.diners = Options::game.diners_inicial; + Info::ctx.diamants = Options::game.diamants_inicial; + Info::ctx.vida = Options::game.vides; + Info::ctx.momies = 0; + Info::ctx.nou_personatge = false; + Info::ctx.pepe_activat = false; FILE* ini = fopen("trick.ini", "rb"); if (ini != nullptr) { - info::ctx.nou_personatge = true; + Info::ctx.nou_personatge = true; fclose(ini); } } -auto Director::createNextScene() const -> std::unique_ptr { +auto Director::createNextScene() const -> std::unique_ptr { // Mentre el Resource::Cache no haja acabat de precarregar, executem // el BootLoaderScene — pinta una barra de progrés i avança la // càrrega per pressupost de temps. Quan acaba, retorna i tornem ací // amb el cache plenament disponible per a la resta d'escenes. if (Resource::Cache::get() != nullptr && !Resource::Cache::get()->isLoadDone()) { - return std::make_unique(); + return std::make_unique(); } if (game_state_ == 0) { - // Gameplay. ModuleGame és una scenes::Scene des de la Phase A. + // Gameplay. ModuleGame és una Scenes::Scene des de la Phase A. return std::make_unique(); } // game_state_ == 1: dispatch al registry per num_piramide. Replica // del redirect que el vell ModuleSequence::Go() feia: si el jugador // arriba a la Secreta (6) sense prou diners, salta als slides de // fracàs (7) abans de buscar l'escena al registry. - if (info::ctx.num_piramide == 6 && info::ctx.diners < 200) { - info::ctx.num_piramide = 7; + if (Info::ctx.num_piramide == 6 && Info::ctx.diners < 200) { + Info::ctx.num_piramide = 7; } - return scenes::SceneRegistry::instance().tryCreate(info::ctx.num_piramide); + return Scenes::SceneRegistry::instance().tryCreate(Info::ctx.num_piramide); } void Director::init() { @@ -80,34 +80,34 @@ void Director::init() { Gamepad::init(); // Registre d'escenes. Cada entrada = un state_key (`num_piramide`) - // amb una factory de `scenes::Scene`. iterate() consulta aquest + // amb una factory de `Scenes::Scene`. iterate() consulta aquest // registry per a tots els states de seqüència (game_state_ == 1); si // una clau no apareix ací, Director surt ordenadament. - auto& registry = scenes::SceneRegistry::instance(); - registry.registerScene(0, [] { return std::make_unique(); }); - registry.registerScene(100, [] { return std::make_unique(); }); + auto& registry = Scenes::SceneRegistry::instance(); + registry.registerScene(0, [] { return std::make_unique(); }); + registry.registerScene(100, [] { return std::make_unique(); }); // BannerScene cobreix les piràmides 2..5 (el vell doBanner decideix - // pel switch intern llegint info::ctx.num_piramide). + // pel switch intern llegint Info::ctx.num_piramide). for (int p = 2; p <= 5; ++p) { - registry.registerScene(p, [] { return std::make_unique(); }); + registry.registerScene(p, [] { return std::make_unique(); }); } // SlidesScene cobreix els dos states on el vell `doSlides` s'invocava: // - num_piramide == 1: slides narratius inicials (entrada al joc) // - num_piramide == 7: slides de fracàs (ve del redirect 6→7 quan // l'usuari no té prou diners per a la Secreta) - registry.registerScene(1, [] { return std::make_unique(); }); - registry.registerScene(7, [] { return std::make_unique(); }); - registry.registerScene(6, [] { return std::make_unique(); }); - registry.registerScene(8, [] { return std::make_unique(); }); + registry.registerScene(1, [] { return std::make_unique(); }); + registry.registerScene(7, [] { return std::make_unique(); }); + registry.registerScene(6, [] { return std::make_unique(); }); + registry.registerScene(8, [] { return std::make_unique(); }); // State 255 (intro): dues variants segons `Options::game.use_new_logo`. // La factory tria a runtime — així es pot togglar des del menú sense // re-registrar. Les dues escenes construeixen una IntroSpritesScene // com a sub-escena per a la part d'animacions de sprites. - registry.registerScene(255, []() -> std::unique_ptr { + registry.registerScene(255, []() -> std::unique_ptr { if (Options::game.use_new_logo) { - return std::make_unique(); + return std::make_unique(); } - return std::make_unique(); + return std::make_unique(); }); } @@ -149,12 +149,12 @@ auto Director::iterate() -> bool { restart_requested_ = false; Audio::get()->stopMusic(); Audio::get()->stopAllSounds(); - // Reinicialitza info::ctx des d'Options (vides, diners, diamants...) + // Reinicialitza Info::ctx des d'Options (vides, diners, diamants...) // en lloc de ctx.reset() pla que deixaria vida=0 → jugador mort. initGameContext(); // Força l'intro independentment de `piramide_inicial` (que pot estar // configurat a una piràmide intermèdia per a proves ràpides). - info::ctx.num_piramide = 255; + Info::ctx.num_piramide = 255; current_scene_.reset(); game_state_ = 1; // 1 = dispatch via SceneRegistry per num_piramide has_frame_ = false; @@ -183,9 +183,9 @@ auto Director::iterate() -> bool { Audio::update(); // Dispara els crèdits cinematogràfics la primera vegada que el joc - // arriba al menú del títol (info::ctx.num_piramide == 0). + // arriba al menú del títol (Info::ctx.num_piramide == 0). static bool credits_triggered_ = false; - if (!credits_triggered_ && info::ctx.num_piramide == 0) { + if (!credits_triggered_ && Info::ctx.num_piramide == 0) { if (Options::game.show_title_credits) { Overlay::startCredits(); } @@ -210,7 +210,7 @@ auto Director::iterate() -> bool { } // Si no hi ha escena activa, construeix la pròxima segons - // game_state_ i info::ctx. Si és impossible (game_state_ == -1, + // game_state_ i Info::ctx. Si és impossible (game_state_ == -1, // quit, o state no registrat), eixim del loop. if (!current_scene_) { if (game_state_ == -1 || Jg::quitting()) { diff --git a/source/core/system/director.hpp b/source/core/system/director.hpp index b37bd19..812a300 100644 --- a/source/core/system/director.hpp +++ b/source/core/system/director.hpp @@ -10,7 +10,7 @@ // El Director és l'únic thread del runtime. Cada iterate() fa input → // tick de l'escena actual → Jd8::flip → overlay → present → sleep al frame -// target. Totes les escenes (`scenes::Scene` i `ModuleGame`) són +// target. Totes les escenes (`Scenes::Scene` i `ModuleGame`) són // tick-based i no bloquegen — no hi ha fibers, mutex ni condition_variable. // Compatible amb SDL_AppIterate i amb el futur port a emscripten. class Director { @@ -36,7 +36,7 @@ class Director { void requestQuit(); [[nodiscard]] auto isQuitRequested() const -> bool { return quit_requested_; } - // Demana un reinici "suau": para música i sons, reseteja info::ctx i + // Demana un reinici "suau": para música i sons, reseteja Info::ctx i // torna a l'intro (state 255). Es processa al començament del pròxim // iterate() per evitar manipular l'escena des d'una lambda del menú. void requestRestart(); @@ -61,12 +61,12 @@ class Director { void pollAllEvents(); // drenatge amb SDL_PollEvent, només per al bucle natiu - // Inicialitza info::ctx a partir de Options::game.* i comprova trick.ini. + // Inicialitza Info::ctx a partir de Options::game.* i comprova trick.ini. // Es crida una sola vegada des d'iterate() a la primera invocació. static void initGameContext(); - // Construeix l'escena apropiada segons game_state_ i info::ctx. + // Construeix l'escena apropiada segons game_state_ i Info::ctx. // Retorna nullptr si l'state actual no té escena registrada (bug). - [[nodiscard]] auto createNextScene() const -> std::unique_ptr; + [[nodiscard]] auto createNextScene() const -> std::unique_ptr; // Buffers persistents entre iteracions. Abans eren locals a run(), // ara són membres perquè iterate() els pot reutilitzar sense tornar-los @@ -77,7 +77,7 @@ class Director { // Estat de l'escena actual. Abans vivia al stack del GameFiber; des // de la Phase B.2 de la migració viu directament al Director. - std::unique_ptr current_scene_; + std::unique_ptr current_scene_; int game_state_{1}; // 0 = gameplay (ModuleGame), 1 = via SceneRegistry, -1 = quit Uint32 last_tick_ms_{0}; bool context_initialized_{false}; diff --git a/source/game/bola.cpp b/source/game/bola.cpp index 3513c3f..70f5325 100644 --- a/source/game/bola.cpp +++ b/source/game/bola.cpp @@ -48,8 +48,8 @@ void Bola::update() { // Comprovem si ha tocat a Sam if (this->x > (this->sam->x - 7) && this->x < (this->sam->x + 7) && this->y > (this->sam->y - 7) && this->y < (this->sam->y + 7)) { this->contador = 200; - info::ctx.vida--; - if (info::ctx.vida == 0) { + Info::ctx.vida--; + if (Info::ctx.vida == 0) { this->sam->o = 5; } } diff --git a/source/game/info.cpp b/source/game/info.cpp index 745d74e..4cba057 100644 --- a/source/game/info.cpp +++ b/source/game/info.cpp @@ -1,4 +1,4 @@ #include "game/info.hpp" -// La instància `info::ctx` està definida com a `inline` al header; +// La instància `Info::ctx` està definida com a `inline` al header; // aquest fitxer es manté per a si cal afegir lògica addicional més endavant. diff --git a/source/game/info.hpp b/source/game/info.hpp index 7c8feaf..23c04a6 100644 --- a/source/game/info.hpp +++ b/source/game/info.hpp @@ -1,6 +1,6 @@ #pragma once -namespace info { +namespace Info { struct GameContext { int num_piramide = 0; @@ -17,8 +17,8 @@ namespace info { }; // Instància única de l'estat del joc. Reemplaça les variables soltes del - // namespace `info::` per una struct encapsulada. A Fase 5 (single-threaded) + // namespace `Info::` per una struct encapsulada. A Fase 5 (single-threaded) // es podrà passar per referència als mòduls en lloc d'accedir via singleton. inline GameContext ctx; -} // namespace info +} // namespace Info diff --git a/source/game/mapa.cpp b/source/game/mapa.cpp index 02d3519..c0ff215 100644 --- a/source/game/mapa.cpp +++ b/source/game/mapa.cpp @@ -27,7 +27,7 @@ Mapa::~Mapa() { } void Mapa::draw() { - if (info::ctx.num_piramide != 4) { + if (Info::ctx.num_piramide != 4) { switch (sam_->o) { case 0: // Down Jd8::blitCKToSurface(sam_->x, sam_->y, this->gfx_, 15, 125 + sam_->frame_pejades, 15, 1, this->fondo_, 255); @@ -93,7 +93,7 @@ auto Mapa::novaMomia() -> bool { void Mapa::preparaFondoEstatic() { // Prepara el fondo est�tic de l'habitaci� this->fondo_ = Jd8::newSurface(); - if (info::ctx.num_piramide == 6) { + if (Info::ctx.num_piramide == 6) { Jd8::blitToSurface(9, 2, this->gfx_, 227, 185, 92, 7, this->fondo_); // Text "SECRETA" } else { Jd8::blitToSurface(9, 2, this->gfx_, 60, 185, 39, 7, this->fondo_); // Text "NIVELL" @@ -101,14 +101,14 @@ void Mapa::preparaFondoEstatic() { } Jd8::blitToSurface(130, 2, this->gfx_, 225, 192, 19, 8, this->fondo_); // Montonet de monedes + signe '=' Jd8::blitToSurface(220, 2, this->gfx_, 160, 185, 48, 7, this->fondo_); // Text "ENERGIA" - if (info::ctx.diners >= 200) { + if (Info::ctx.diners >= 200) { Jd8::blitToSurface(175, 3, this->gfx_, 60, 193, 7, 6, this->fondo_); } // Pinta taulells for (int y = 0; y < 11; y++) { for (int x = 0; x < 19; x++) { - switch (info::ctx.num_piramide) { + switch (Info::ctx.num_piramide) { case 1: Jd8::blitToSurface(20 + (x * 15), 30 + (y * 15), this->gfx_, 0, 80, 15, 15, this->fondo_); break; @@ -154,7 +154,7 @@ void Mapa::preparaFondoEstatic() { // Pinta la porta Jd8::blitCKToSurface(150, 18, this->gfx_, 0, 143, 15, 12, this->fondo_, 255); - if (info::ctx.num_piramide == 2) { + if (Info::ctx.num_piramide == 2) { Jd8::blitToSurface(5, 100, this->gfx_, 30, 140, 15, 15, this->fondo_); } } @@ -166,12 +166,12 @@ void swap(Uint8& a, Uint8& b) noexcept { } void Mapa::preparaTombes() { - const Uint8 contingut = info::ctx.num_piramide == 6 ? CONTE_DIAMANT : CONTE_RES; - int cx = info::ctx.num_piramide == 6 ? 270 : 0; - int cy = info::ctx.num_piramide == 6 ? 50 : 0; + const Uint8 CONTINGUT = Info::ctx.num_piramide == 6 ? CONTE_DIAMANT : CONTE_RES; + int cx = Info::ctx.num_piramide == 6 ? 270 : 0; + int cy = Info::ctx.num_piramide == 6 ? 50 : 0; for (auto& tombe : this->tombes) { - tombe.contingut = contingut; + tombe.contingut = CONTINGUT; tombe.oberta = false; tombe.costat[0] = false; tombe.costat[1] = false; @@ -180,7 +180,7 @@ void Mapa::preparaTombes() { tombe.x = cx; tombe.y = cy; } - if (info::ctx.num_piramide == 6) { + if (Info::ctx.num_piramide == 6) { return; } this->tombes[0].contingut = CONTE_FARAO; @@ -261,7 +261,7 @@ void Mapa::comprovaCaixa(Uint8 num) { break; case CONTE_TRESOR: this->tombes[num].x = 100; - info::ctx.diners++; + Info::ctx.diners++; break; case CONTE_FARAO: this->tombes[num].x = 150; @@ -281,9 +281,9 @@ void Mapa::comprovaCaixa(Uint8 num) { break; case CONTE_DIAMANT: this->tombes[num].y = 70; - info::ctx.diamants++; - info::ctx.diners += VALOR_DIAMANT; - if (info::ctx.diamants == 16) { + Info::ctx.diamants++; + Info::ctx.diners += VALOR_DIAMANT; + if (Info::ctx.diamants == 16) { this->farao_ = this->clau_ = true; } break; diff --git a/source/game/marcador.cpp b/source/game/marcador.cpp index 624d6fe..09495ba 100644 --- a/source/game/marcador.cpp +++ b/source/game/marcador.cpp @@ -6,22 +6,22 @@ Marcador::Marcador(Jd8::Surface gfx, Prota* sam) { } void Marcador::draw() { - if (info::ctx.num_piramide < 6) { - this->pintaNumero(55, 2, info::ctx.num_piramide); - this->pintaNumero(80, 2, info::ctx.num_habitacio); + if (Info::ctx.num_piramide < 6) { + this->pintaNumero(55, 2, Info::ctx.num_piramide); + this->pintaNumero(80, 2, Info::ctx.num_habitacio); } - this->pintaNumero(149, 2, info::ctx.diners / 100); - this->pintaNumero(156, 2, (info::ctx.diners % 100) / 10); - this->pintaNumero(163, 2, info::ctx.diners % 10); + this->pintaNumero(149, 2, Info::ctx.diners / 100); + this->pintaNumero(156, 2, (Info::ctx.diners % 100) / 10); + this->pintaNumero(163, 2, Info::ctx.diners % 10); if (this->sam->pergami) { Jd8::blitCK(190, 1, this->gfx, 209, 185, 15, 14, 255); } - Jd8::blitCK(271, 1, this->gfx, 0, 20, 15, info::ctx.vida * 3, 255); - if (info::ctx.vida < 5) { - Jd8::blitCK(271, 1 + (info::ctx.vida * 3), this->gfx, 75, 20, 15, 15 - (info::ctx.vida * 3), 255); + Jd8::blitCK(271, 1, this->gfx, 0, 20, 15, Info::ctx.vida * 3, 255); + if (Info::ctx.vida < 5) { + Jd8::blitCK(271, 1 + (Info::ctx.vida * 3), this->gfx, 75, 20, 15, 15 - (Info::ctx.vida * 3), 255); } } diff --git a/source/game/modulegame.cpp b/source/game/modulegame.cpp index a404ee7..238e855 100644 --- a/source/game/modulegame.cpp +++ b/source/game/modulegame.cpp @@ -8,13 +8,13 @@ #include "core/jail/jinput.hpp" ModuleGame::ModuleGame() { - this->gfx_ = Jd8::loadSurface(info::ctx.pepe_activat ? "gfx/frames2.gif" : "gfx/frames.gif"); + this->gfx_ = Jd8::loadSurface(Info::ctx.pepe_activat ? "gfx/frames2.gif" : "gfx/frames.gif"); Jg::setUpdateTicks(10); this->sam_ = std::make_unique(this->gfx_); this->mapa_ = std::make_unique(this->gfx_, this->sam_.get()); this->marcador_ = std::make_unique(this->gfx_, this->sam_.get()); - if (info::ctx.num_piramide == 2) { + if (Info::ctx.num_piramide == 2) { this->bola_ = std::make_unique(this->gfx_, this->sam_.get()); } @@ -35,11 +35,11 @@ void ModuleGame::onEnter() { // demanada, no fa res. Per això podem cridar-lo cada onEnter sense // desencadenar restarts indesitjats. const char* music_name = "piramide_1_4_5.ogg"; - if (info::ctx.num_piramide == 3) { + if (Info::ctx.num_piramide == 3) { music_name = "piramide_3.ogg"; - } else if (info::ctx.num_piramide == 2) { + } else if (Info::ctx.num_piramide == 2) { music_name = "piramide_2.ogg"; - } else if (info::ctx.num_piramide == 6) { + } else if (Info::ctx.num_piramide == 6) { music_name = "secreta.ogg"; } Audio::get()->playMusic(music_name); @@ -47,7 +47,7 @@ void ModuleGame::onEnter() { // Arranca el fade-in tick-based. El `PaletteFade` avança un pas (de // 32) per cada tick; durant aquesta fase el gameplay no corre, // només Draw+fade. Substituïx la crida bloquejant `JD8_FadeToPal`. - fade_.startFadeTo(Jd8::loadPalette(info::ctx.pepe_activat ? "gfx/frames2.gif" : "gfx/frames.gif")); + fade_.startFadeTo(Jd8::loadPalette(Info::ctx.pepe_activat ? "gfx/frames2.gif" : "gfx/frames.gif")); phase_ = Phase::FADING_IN; } @@ -95,9 +95,9 @@ auto ModuleGame::nextState() const -> int { if (Jg::quitting()) { return -1; } - if (info::ctx.num_habitacio == 1 || - info::ctx.num_piramide == 100 || - info::ctx.num_piramide == 7) { + if (Info::ctx.num_habitacio == 1 || + Info::ctx.num_piramide == 100 || + Info::ctx.num_piramide == 7) { return 1; } return 0; @@ -105,16 +105,16 @@ auto ModuleGame::nextState() const -> int { void ModuleGame::applyFinalTransitions() const { if (this->final_ == 1) { - info::ctx.num_habitacio++; - if (info::ctx.num_habitacio == 6) { - info::ctx.num_habitacio = 1; - info::ctx.num_piramide++; + Info::ctx.num_habitacio++; + if (Info::ctx.num_habitacio == 6) { + Info::ctx.num_habitacio = 1; + Info::ctx.num_piramide++; } - if (info::ctx.num_piramide == 6 && info::ctx.num_habitacio == 2) { - info::ctx.num_piramide++; + if (Info::ctx.num_piramide == 6 && Info::ctx.num_habitacio == 2) { + Info::ctx.num_piramide++; } } else if (this->final_ == 2) { - info::ctx.num_piramide = 100; + Info::ctx.num_piramide = 100; } } @@ -137,23 +137,23 @@ void ModuleGame::update() { Ji::update(); this->final_ = this->sam_->update(); - const auto erased = std::erase_if(this->momies_, [](auto& m) { return m->update(); }); - info::ctx.momies -= static_cast(erased); + const auto ERASED = std::erase_if(this->momies_, [](auto& m) { return m->update(); }); + Info::ctx.momies -= static_cast(ERASED); if (this->bola_) { this->bola_->update(); } this->mapa_->update(); if (this->mapa_->novaMomia()) { this->momies_.emplace_back(std::make_unique(this->gfx_, true, 0, 0, this->sam_.get())); - info::ctx.momies++; + Info::ctx.momies++; } if (Ji::cheatActivated("reviu")) { - info::ctx.vida = 5; + Info::ctx.vida = 5; } if (Ji::cheatActivated("alone")) { this->momies_.clear(); - info::ctx.momies = 0; + Info::ctx.momies = 0; } if (Ji::cheatActivated("obert")) { for (int i = 0; i < 16; i++) { @@ -172,19 +172,19 @@ void ModuleGame::update() { } void ModuleGame::iniciarMomies() { - if (info::ctx.num_habitacio == 1) { - info::ctx.momies = 1; + if (Info::ctx.num_habitacio == 1) { + Info::ctx.momies = 1; } else { - info::ctx.momies++; + Info::ctx.momies++; } - if (info::ctx.num_piramide == 6) { - info::ctx.momies = 8; + if (Info::ctx.num_piramide == 6) { + Info::ctx.momies = 8; } int x = 20; int y = 170; - bool dimonis = info::ctx.num_piramide == 6; - for (int i = 0; i < info::ctx.momies; i++) { + bool dimonis = Info::ctx.num_piramide == 6; + for (int i = 0; i < Info::ctx.momies; i++) { this->momies_.emplace_back(std::make_unique(this->gfx_, dimonis, x, y, this->sam_.get())); x += 65; if (x == 345) { diff --git a/source/game/modulegame.hpp b/source/game/modulegame.hpp index 5abea50..705e896 100644 --- a/source/game/modulegame.hpp +++ b/source/game/modulegame.hpp @@ -14,7 +14,7 @@ #include "game/scenes/scene.hpp" // Escena de gameplay pur. Reemplaça el vell `Go()` bloquejant amb -// l'interfície `scenes::Scene` tick-based: `onEnter()` arranca la +// l'interfície `Scenes::Scene` tick-based: `onEnter()` arranca la // música i un fade-in, el `tick()` avança un frame (Draw + Update // gated per Jg::shouldUpdate), i quan la partida acaba fa un fade-out // abans de retornar el next state. @@ -27,7 +27,7 @@ // 3. FADING_OUT — fade-out 32 passos mantenint l'últim frame visible // (substituïx el `JD8_FadeOut` bloquejant que feia el // destructor legacy). -class ModuleGame : public scenes::Scene { +class ModuleGame : public Scenes::Scene { public: ModuleGame(); ~ModuleGame() override; @@ -54,10 +54,10 @@ class ModuleGame : public scenes::Scene { void update(); // gated per Jg::shouldUpdate void iniciarMomies(); - void applyFinalTransitions() const; // muta info::ctx quan final_ passa a !=0 + void applyFinalTransitions() const; // muta Info::ctx quan final_ passa a !=0 Phase phase_{Phase::FADING_IN}; - scenes::PaletteFade fade_; + Scenes::PaletteFade fade_; Uint8 final_{0}; Jd8::Surface gfx_{nullptr}; diff --git a/source/game/momia.cpp b/source/game/momia.cpp index 4e34466..4033fc2 100644 --- a/source/game/momia.cpp +++ b/source/game/momia.cpp @@ -15,7 +15,7 @@ Momia::Momia(Jd8::Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam) Frame f; f.w = 15; f.h = 15; - if (info::ctx.num_piramide == 4) { + if (Info::ctx.num_piramide == 4) { f.h -= 5; } f.x = (col * 15) + 75; @@ -73,7 +73,7 @@ void Momia::draw() { } else { Sprite::draw(); - if (info::ctx.num_piramide == 4) { + if (Info::ctx.num_piramide == 4) { if ((Jg::getCycleCounter() % 40) < 20) { Jd8::blitCK(this->x, this->y, this->gfx, 220, 80, 15, 15, 255); } else { @@ -93,7 +93,7 @@ auto Momia::update() -> bool { return morta; } - if (this->sam->o < 4 && (this->dimoni || info::ctx.num_piramide == 5 || Jg::getCycleCounter() % 2 == 0)) { + if (this->sam->o < 4 && (this->dimoni || Info::ctx.num_piramide == 5 || Jg::getCycleCounter() % 2 == 0)) { if ((this->x - 20) % 65 == 0 && (this->y - 30) % 35 == 0) { if (this->dimoni) { if (rand() % 2 == 0) { @@ -159,8 +159,8 @@ auto Momia::update() -> bool { if (this->sam->pergami) { this->sam->pergami = false; } else { - info::ctx.vida--; - if (info::ctx.vida == 0) { + Info::ctx.vida--; + if (Info::ctx.vida == 0) { this->sam->o = 5; } } diff --git a/source/game/prota.cpp b/source/game/prota.cpp index 95e81e8..96ccbdd 100644 --- a/source/game/prota.cpp +++ b/source/game/prota.cpp @@ -14,7 +14,7 @@ Prota::Prota(Jd8::Surface gfx) Frame f; f.w = 15; f.h = 15; - if (info::ctx.num_piramide == 4) { + if (Info::ctx.num_piramide == 4) { f.h -= 5; } f.x = x * 15; @@ -28,7 +28,7 @@ Prota::Prota(Jd8::Surface gfx) Frame f; f.w = 15; f.h = 30; - if (info::ctx.num_piramide == 4) { + if (Info::ctx.num_piramide == 4) { f.h -= 5; } f.x = x; @@ -42,7 +42,7 @@ Prota::Prota(Jd8::Surface gfx) Frame f; f.w = 15; f.h = 15; - if (info::ctx.num_piramide == 4) { + if (Info::ctx.num_piramide == 4) { f.h -= 5; } f.x = x; @@ -90,7 +90,7 @@ Prota::Prota(Jd8::Surface gfx) void Prota::draw() { Sprite::draw(); - if (info::ctx.num_piramide == 4 && this->o != 4) { + if (Info::ctx.num_piramide == 4 && this->o != 4) { if ((Jg::getCycleCounter() % 40) < 20) { Jd8::blitCK(this->x, this->y, this->gfx, 220, 80, 15, 15, 255); } else { diff --git a/source/game/scenes/banner_scene.cpp b/source/game/scenes/banner_scene.cpp index 352f7de..28a890e 100644 --- a/source/game/scenes/banner_scene.cpp +++ b/source/game/scenes/banner_scene.cpp @@ -8,7 +8,7 @@ #include "game/info.hpp" #include "game/scenes/scene_utils.hpp" -namespace scenes { +namespace Scenes { void BannerScene::onEnter() { playMusic("music/banner.ogg"); @@ -21,12 +21,12 @@ namespace scenes { Jd8::blit(39, 150, gfx_, 39, 175, 248, 20); // Número de piràmide: les 4 variants del vell `doBanner` es reduïxen - // a coordenades (sx,sy) calculades a partir de l'índex 0..3. - const int idx = info::ctx.num_piramide - 2; // 2..5 → 0..3 - if (idx >= 0 && idx <= 3) { - const int sx = (idx % 2) * 160; - const int sy = (idx / 2) * 75; - Jd8::blit(82, 60, gfx_, sx, sy, 160, 75); + // a coordenades (SX,SY) calculades a partir de l'índex 0..3. + const int IDX = Info::ctx.num_piramide - 2; // 2..5 → 0..3 + if (IDX >= 0 && IDX <= 3) { + const int SX = (IDX % 2) * 160; + const int SY = (IDX / 2) * 75; + Jd8::blit(82, 60, gfx_, SX, SY, 160, 75); } // PaletteFade copia internament amb memcpy; alliberem la paleta temporal. @@ -72,4 +72,4 @@ namespace scenes { } } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/banner_scene.hpp b/source/game/scenes/banner_scene.hpp index 8a83da3..e8c0378 100644 --- a/source/game/scenes/banner_scene.hpp +++ b/source/game/scenes/banner_scene.hpp @@ -6,13 +6,13 @@ #include "game/scenes/scene.hpp" #include "game/scenes/surface_handle.hpp" -namespace scenes { +namespace Scenes { // Banner pre-piràmide ("PIRÀMIDE X"). Reemplaça `ModuleSequence::doBanner()`. // // Flux: // 1. Arranca música "music/banner.ogg" i carrega gfx/ffase.gif. - // 2. Pinta títol, subtítol i número de piràmide segons info::ctx.num_piramide. + // 2. Pinta títol, subtítol i número de piràmide segons Info::ctx.num_piramide. // 3. Fade-in de paleta. // 4. Mostra ~5s o fins que es polse una tecla. // 5. Ja::fadeOutMusic(250) + fade-out de paleta. @@ -39,4 +39,4 @@ namespace scenes { int remaining_ms_{5000}; }; -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/boot_loader_scene.cpp b/source/game/scenes/boot_loader_scene.cpp index 7d55756..954e7ed 100644 --- a/source/game/scenes/boot_loader_scene.cpp +++ b/source/game/scenes/boot_loader_scene.cpp @@ -4,7 +4,7 @@ #include "core/resources/resource_cache.hpp" #include "game/options.hpp" -namespace scenes { +namespace Scenes { namespace { constexpr int SCREEN_W = 320; @@ -42,8 +42,8 @@ namespace scenes { return; } - const float pct = Resource::Cache::get()->getProgress(); - const int filled = static_cast(static_cast(BAR_W) * pct); + const float PCT = Resource::Cache::get()->getProgress(); + const int FILLED = static_cast(static_cast(BAR_W) * PCT); // Vora de la barra (línia 1 píxel a dalt i a baix). Jd8::fillRect(BAR_X - 1, BAR_Y - 1, BAR_W + 2, 1, BAR_COLOR); @@ -52,9 +52,9 @@ namespace scenes { Jd8::fillRect(BAR_X + BAR_W, BAR_Y, 1, BAR_H, BAR_COLOR); // Ompliment proporcional al progrés. - if (filled > 0) { - Jd8::fillRect(BAR_X, BAR_Y, filled, BAR_H, BAR_COLOR); + if (FILLED > 0) { + Jd8::fillRect(BAR_X, BAR_Y, FILLED, BAR_H, BAR_COLOR); } } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/boot_loader_scene.hpp b/source/game/scenes/boot_loader_scene.hpp index 34baa5f..69f7701 100644 --- a/source/game/scenes/boot_loader_scene.hpp +++ b/source/game/scenes/boot_loader_scene.hpp @@ -2,7 +2,7 @@ #include "game/scenes/scene.hpp" -namespace scenes { +namespace Scenes { // Escena de boot que conduix la càrrega incremental del Resource::Cache. // tick() crida loadStep amb un pressupost de ~8ms i pinta una barra @@ -23,4 +23,4 @@ namespace scenes { bool done_{false}; }; -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/credits_scene.cpp b/source/game/scenes/credits_scene.cpp index 5d4d70f..a05f00c 100644 --- a/source/game/scenes/credits_scene.cpp +++ b/source/game/scenes/credits_scene.cpp @@ -34,7 +34,7 @@ namespace { } // namespace -namespace scenes { +namespace Scenes { // No toquem la paleta activa: SetScreenPalette n'ha pres ownership. CreditsScene::~CreditsScene() = default; @@ -80,7 +80,7 @@ namespace scenes { // Fons: 4 capes parallax + cotxe només si l'usuari ha aconseguit // tots els diamants (final "bo"). Altrament fons estàtic. - if (info::ctx.diamants == 16) { + if (Info::ctx.diamants == 16) { Jd8::blitCKScroll(50, vaddr3_, ((contador_ >> 3) % 320) + 1, 0, 50, 255); Jd8::blitCKScroll(50, vaddr3_, ((contador_ >> 2) % 320) + 1, 50, 50, 255); Jd8::blitCKScroll(50, vaddr3_, ((contador_ >> 1) % 320) + 1, 100, 50, 255); @@ -104,7 +104,7 @@ namespace scenes { std::fwrite("1", 1, 1, ini); std::fclose(ini); } - info::ctx.nou_personatge = true; + Info::ctx.nou_personatge = true; } void CreditsScene::tick(int delta_ms) { @@ -132,7 +132,7 @@ namespace scenes { case Phase::FADING_OUT: fade_.tick(delta_ms); if (fade_.done()) { - info::ctx.num_piramide = 255; + Info::ctx.num_piramide = 255; phase_ = Phase::DONE; } break; @@ -142,4 +142,4 @@ namespace scenes { } } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/credits_scene.hpp b/source/game/scenes/credits_scene.hpp index f2978b0..1dd813b 100644 --- a/source/game/scenes/credits_scene.hpp +++ b/source/game/scenes/credits_scene.hpp @@ -8,7 +8,7 @@ #include "game/scenes/scene.hpp" #include "game/scenes/surface_handle.hpp" -namespace scenes { +namespace Scenes { // Crèdits finals del joc. Reemplaça `ModuleSequence::doCredits()`. // @@ -16,10 +16,10 @@ namespace scenes { // 1. Carrega gfx/final.gif (sprites de crèdits) i gfx/finals.gif (fons). // 2. Mostra els crèdits amb scroll vertical de 2 columnes durant // ~62 segons (contador 0..3100 × 20 ms). - // 3. Si `info::ctx.diamants == 16`, pinta addicionalment un parallax + // 3. Si `Info::ctx.diamants == 16`, pinta addicionalment un parallax // de 4 capes amb cotxe animat (8 frames). Si no, 2 blits fixos. // 4. Al acabar (per tecla o per contador), crea el fitxer `trick.ini` - // i activa `info::ctx.nou_personatge`. + // i activa `Info::ctx.nou_personatge`. // 5. Fade-out de paleta. Torna a la intro (num_piramide = 255). // // Registrada al SceneRegistry amb state_key = 8. @@ -50,4 +50,4 @@ namespace scenes { int contador_acc_ms_{0}; }; -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/frame_animator.cpp b/source/game/scenes/frame_animator.cpp index 4c9cad5..de5a3ec 100644 --- a/source/game/scenes/frame_animator.cpp +++ b/source/game/scenes/frame_animator.cpp @@ -2,7 +2,7 @@ #include -namespace scenes { +namespace Scenes { FrameAnimator::FrameAnimator(int num_frames, int frame_ms, bool loop) : num_frames_(std::max(1, num_frames)), @@ -35,4 +35,4 @@ namespace scenes { finished_ = false; } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/frame_animator.hpp b/source/game/scenes/frame_animator.hpp index 790b4dc..25802a2 100644 --- a/source/game/scenes/frame_animator.hpp +++ b/source/game/scenes/frame_animator.hpp @@ -1,6 +1,6 @@ #pragma once -namespace scenes { +namespace Scenes { // Cicla per un conjunt de frames numerats (0..num_frames-1) avançant un // frame cada `frame_ms` mil·lisegons. No carrega ni dibuixa cap sprite — @@ -31,4 +31,4 @@ namespace scenes { bool finished_{false}; }; -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/intro_new_logo_scene.cpp b/source/game/scenes/intro_new_logo_scene.cpp index 1ca19f3..a089219 100644 --- a/source/game/scenes/intro_new_logo_scene.cpp +++ b/source/game/scenes/intro_new_logo_scene.cpp @@ -37,7 +37,7 @@ namespace { } // namespace -namespace scenes { +namespace Scenes { IntroNewLogoScene::IntroNewLogoScene() = default; @@ -138,7 +138,7 @@ namespace scenes { // deixem que la sub-escena gestione el seu propi skip (que a més // respecta la fase "final" no skippable de la variant 0). if (phase_ != Phase::SPRITES && phase_ != Phase::DONE && Ji::anyKey()) { - info::ctx.num_piramide = 0; + Info::ctx.num_piramide = 0; phase_ = Phase::DONE; return; } @@ -218,7 +218,7 @@ namespace scenes { // El vell `Go()` post-switch feia `num_piramide = 0` // per passar al menú. Sense açò el while del fiber // tornaria a crear IntroNewLogoScene infinitament. - info::ctx.num_piramide = 0; + Info::ctx.num_piramide = 0; phase_ = Phase::DONE; } break; @@ -228,4 +228,4 @@ namespace scenes { } } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/intro_new_logo_scene.hpp b/source/game/scenes/intro_new_logo_scene.hpp index 40062c4..a4b05c4 100644 --- a/source/game/scenes/intro_new_logo_scene.hpp +++ b/source/game/scenes/intro_new_logo_scene.hpp @@ -8,7 +8,7 @@ #include "game/scenes/scene.hpp" #include "game/scenes/surface_handle.hpp" -namespace scenes { +namespace Scenes { // Intro "moderna" del logo Jailgames amb revelat lletra-a-lletra + // ciclo de paleta final. Reemplaça `ModuleSequence::doIntroNewLogo()`. @@ -65,4 +65,4 @@ namespace scenes { int palette_step_{0}; }; -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/intro_scene.cpp b/source/game/scenes/intro_scene.cpp index 51426a3..1a40fe7 100644 --- a/source/game/scenes/intro_scene.cpp +++ b/source/game/scenes/intro_scene.cpp @@ -55,7 +55,7 @@ namespace { } // namespace -namespace scenes { +namespace Scenes { IntroScene::IntroScene() = default; @@ -153,7 +153,7 @@ namespace scenes { // la sub-escena gestione el seu propi skip internament, que a més // respecta la fase "final" no skippable de la variant 0. if (phase_ != Phase::SPRITES && phase_ != Phase::DONE && Ji::anyKey()) { - info::ctx.num_piramide = 0; + Info::ctx.num_piramide = 0; phase_ = Phase::DONE; return; } @@ -220,7 +220,7 @@ namespace scenes { // Equivalent al vell `Go()` post-switch: passem al menú. // Sense açò el while del fiber tornaria a crear IntroScene // infinitament amb num_piramide encara a 255. - info::ctx.num_piramide = 0; + Info::ctx.num_piramide = 0; phase_ = Phase::DONE; } break; @@ -230,4 +230,4 @@ namespace scenes { } } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/intro_scene.hpp b/source/game/scenes/intro_scene.hpp index e24c344..1250421 100644 --- a/source/game/scenes/intro_scene.hpp +++ b/source/game/scenes/intro_scene.hpp @@ -8,7 +8,7 @@ #include "game/scenes/scene.hpp" #include "game/scenes/surface_handle.hpp" -namespace scenes { +namespace Scenes { // Intro "legacy" del wordmark JAILGAMES lletra a lletra + cicle de paleta. // Reemplaça `ModuleSequence::doIntro()`. S'activa quan @@ -63,4 +63,4 @@ namespace scenes { int palette_step_{0}; }; -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/intro_sprites_scene.cpp b/source/game/scenes/intro_sprites_scene.cpp index 367c1f1..baf6004 100644 --- a/source/game/scenes/intro_sprites_scene.cpp +++ b/source/game/scenes/intro_sprites_scene.cpp @@ -314,7 +314,7 @@ namespace { } // namespace -namespace scenes { +namespace Scenes { IntroSpritesScene::IntroSpritesScene(SurfaceHandle&& gfx) : gfx_(std::move(gfx)) {} @@ -367,4 +367,4 @@ namespace scenes { phases[phase_].render(gfx_.get(), phaseCurrentI(phases[phase_], phase_step_)); } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/intro_sprites_scene.hpp b/source/game/scenes/intro_sprites_scene.hpp index 3c4cf46..afc8e45 100644 --- a/source/game/scenes/intro_sprites_scene.hpp +++ b/source/game/scenes/intro_sprites_scene.hpp @@ -3,7 +3,7 @@ #include "game/scenes/scene.hpp" #include "game/scenes/surface_handle.hpp" -namespace scenes { +namespace Scenes { // Sub-escena de sprites de la intro (prota + momia + mapa + etc). // Reemplaça `ModuleSequence::doIntroSprites()`. No es registra al @@ -39,4 +39,4 @@ namespace scenes { bool done_{false}; }; -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/menu_scene.cpp b/source/game/scenes/menu_scene.cpp index 09d0030..a285ccd 100644 --- a/source/game/scenes/menu_scene.cpp +++ b/source/game/scenes/menu_scene.cpp @@ -6,7 +6,7 @@ #include "core/jail/jinput.hpp" #include "game/info.hpp" -namespace scenes { +namespace Scenes { void MenuScene::onEnter() { fondo_ = SurfaceHandle("gfx/menu.gif"); @@ -49,10 +49,10 @@ namespace scenes { // "Polsa tecla" parpallejant. Al vell `contador % 100 > 30` amb // updateTicks=20 ms, el cicle són 2000 ms amb un llindar de 600 ms: // amagat els primers 600 ms, visible els següents 1400 ms. - const bool blink_on = (blink_ms_ % 2000) > 600; - if (blink_on) { + const bool BLINK_ON = (blink_ms_ % 2000) > 600; + if (BLINK_ON) { Jd8::blitCK(98, 130, gfx_, 161, 92, 127, 9, 255); - if (info::ctx.nou_personatge) { + if (Info::ctx.nou_personatge) { Jd8::blitCK(68, 141, gfx_, 128, 105, 189, 9, 255); } } @@ -96,12 +96,12 @@ namespace scenes { render(); // Qualsevol tecla tanca el menú. Llegim 'P' explícitament abans - // de reiniciar el flag de input perquè `info::ctx.pepe_activat` + // de reiniciar el flag de input perquè `Info::ctx.pepe_activat` // reflecteixca si l'usuari estava polsant P al moment d'eixir. if (Ji::anyKey() || Ji::keyPressed(SDL_SCANCODE_P)) { - info::ctx.pepe_activat = Ji::keyPressed(SDL_SCANCODE_P); + Info::ctx.pepe_activat = Ji::keyPressed(SDL_SCANCODE_P); Ji::disableKeyboard(60); - info::ctx.num_piramide = 1; + Info::ctx.num_piramide = 1; fade_.startFadeOut(); phase_ = Phase::FADING_OUT; } @@ -120,4 +120,4 @@ namespace scenes { } } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/menu_scene.hpp b/source/game/scenes/menu_scene.hpp index e992907..33f4b3f 100644 --- a/source/game/scenes/menu_scene.hpp +++ b/source/game/scenes/menu_scene.hpp @@ -7,7 +7,7 @@ #include "game/scenes/scene.hpp" #include "game/scenes/surface_handle.hpp" -namespace scenes { +namespace Scenes { // Menú del títol. Reemplaça `ModuleSequence::doMenu()`. // @@ -20,7 +20,7 @@ namespace scenes { // i el text "polsa tecla" parpallejant cada 2 s (visible 1.4 s, // amagat 0.6 s, igual que el `contador % 100 > 30` original). // 4. Quan l'usuari polsa qualsevol tecla — o 'P' per a activar Pepe — - // llegim `info::ctx.pepe_activat`, disparem fade-out i marquem + // llegim `Info::ctx.pepe_activat`, disparem fade-out i marquem // num_piramide=1 (vas a doSlides). // // Registrat al SceneRegistry amb state_key = 0. @@ -55,4 +55,4 @@ namespace scenes { int blink_ms_{0}; }; -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/mort_scene.cpp b/source/game/scenes/mort_scene.cpp index 279853a..a195dc2 100644 --- a/source/game/scenes/mort_scene.cpp +++ b/source/game/scenes/mort_scene.cpp @@ -7,12 +7,12 @@ #include "game/info.hpp" #include "game/scenes/scene_utils.hpp" -namespace scenes { +namespace Scenes { void MortScene::onEnter() { playMusic("music/mort.ogg"); Ji::disableKeyboard(60); - info::ctx.vida = 5; + Info::ctx.vida = 5; gfx_ = SurfaceHandle("gfx/gameover.gif"); Jd8::clearScreen(0); @@ -47,7 +47,7 @@ namespace scenes { // Arrenca música del següent mòdul abans del fade out, // igual que la versió vella feia al final de doMort(). playMusic("music/menu.ogg"); - info::ctx.num_piramide = 0; + Info::ctx.num_piramide = 0; fade_.startFadeOut(); phase_ = Phase::FADING_OUT; } @@ -65,4 +65,4 @@ namespace scenes { } } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/mort_scene.hpp b/source/game/scenes/mort_scene.hpp index fcc6be8..50a0a4c 100644 --- a/source/game/scenes/mort_scene.hpp +++ b/source/game/scenes/mort_scene.hpp @@ -6,7 +6,7 @@ #include "game/scenes/scene.hpp" #include "game/scenes/surface_handle.hpp" -namespace scenes { +namespace Scenes { // Pantalla de "game over". Reemplaça `ModuleSequence::doMort()`. // @@ -34,4 +34,4 @@ namespace scenes { int remaining_ms_{10000}; // 1000 ticks × 10 ms/tick del doMort original }; -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/palette_fade.cpp b/source/game/scenes/palette_fade.cpp index 9ab981d..4d1d589 100644 --- a/source/game/scenes/palette_fade.cpp +++ b/source/game/scenes/palette_fade.cpp @@ -1,6 +1,6 @@ #include "game/scenes/palette_fade.hpp" -namespace scenes { +namespace Scenes { void PaletteFade::startFadeOut() { Jd8::fadeStartOut(); @@ -27,4 +27,4 @@ namespace scenes { } } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/palette_fade.hpp b/source/game/scenes/palette_fade.hpp index ed12a86..76e53ce 100644 --- a/source/game/scenes/palette_fade.hpp +++ b/source/game/scenes/palette_fade.hpp @@ -2,7 +2,7 @@ #include "core/jail/jdraw8.hpp" -namespace scenes { +namespace Scenes { // Embolcall fi damunt de la màquina d'estats de fade de jdraw8 // (`JD8_FadeStart*` / `Jd8::fadeTickStep`). Exposa una API time-based @@ -27,4 +27,4 @@ namespace scenes { bool active_{false}; }; -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/scene.hpp b/source/game/scenes/scene.hpp index 50605c5..8767734 100644 --- a/source/game/scenes/scene.hpp +++ b/source/game/scenes/scene.hpp @@ -14,7 +14,7 @@ // - `onEnter()` es crida una vegada just abans del primer tick. És el // moment bo per a arrancar música, disparar un fade-in, etc. -namespace scenes { +namespace Scenes { class Scene { public: @@ -28,10 +28,10 @@ namespace scenes { // Valor retornat al caller quan l'escena acaba — equivalent al int // que retornaven les velles funcions `Go()` de ModuleSequence: - // 1 = continuar amb la següent escena segons info::ctx + // 1 = continuar amb la següent escena segons Info::ctx // 0 = entrar al gameplay (ModuleGame) // -1 = eixir del joc [[nodiscard]] virtual auto nextState() const -> int { return 1; } }; -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/scene_registry.cpp b/source/game/scenes/scene_registry.cpp index dfa434f..d245169 100644 --- a/source/game/scenes/scene_registry.cpp +++ b/source/game/scenes/scene_registry.cpp @@ -1,6 +1,6 @@ #include "game/scenes/scene_registry.hpp" -namespace scenes { +namespace Scenes { auto SceneRegistry::instance() -> SceneRegistry& { static SceneRegistry inst; @@ -12,11 +12,11 @@ namespace scenes { } auto SceneRegistry::tryCreate(int state_key) const -> std::unique_ptr { - const auto it = factories_.find(state_key); - if (it == factories_.end()) { + const auto IT = factories_.find(state_key); + if (IT == factories_.end()) { return nullptr; } - return it->second(); + return IT->second(); } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/scene_registry.hpp b/source/game/scenes/scene_registry.hpp index a2cc7e8..4e04a6b 100644 --- a/source/game/scenes/scene_registry.hpp +++ b/source/game/scenes/scene_registry.hpp @@ -6,9 +6,9 @@ #include "game/scenes/scene.hpp" -namespace scenes { +namespace Scenes { - // Mapa de `state_key` (actualment = `info::ctx.num_piramide`) a factory + // Mapa de `state_key` (actualment = `Info::ctx.num_piramide`) a factory // d'escena. Permet que el dispatch de `gameFiberEntry` provi primer una // Scene nova i caiga al vell `ModuleSequence::Go()` si encara no està // migrada. @@ -34,4 +34,4 @@ namespace scenes { std::unordered_map factories_; }; -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/scene_utils.cpp b/source/game/scenes/scene_utils.cpp index f737994..d7ba3fb 100644 --- a/source/game/scenes/scene_utils.cpp +++ b/source/game/scenes/scene_utils.cpp @@ -4,7 +4,7 @@ #include "core/audio/audio.hpp" -namespace scenes { +namespace Scenes { namespace { auto basename(const char* path) -> std::string { @@ -21,4 +21,4 @@ namespace scenes { Audio::get()->playMusic(basename(filename), loop); } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/scene_utils.hpp b/source/game/scenes/scene_utils.hpp index e419872..0e2d26d 100644 --- a/source/game/scenes/scene_utils.hpp +++ b/source/game/scenes/scene_utils.hpp @@ -3,11 +3,11 @@ // Helpers compartits per les escenes. Aquest header és petit i creix // quan una abstracció comú apareix en dos o més escenes. -namespace scenes { +namespace Scenes { // Carrega un OGG de `data/` i arranca'l com a música de fons. Substituïx // el `play_music()` repetit en tots els doX() del vell modulesequence. // `loop`: -1 = infinit (per defecte), 0 = una sola vegada, N = N+1 passades. void playMusic(const char* filename, int loop = -1); -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/secreta_scene.cpp b/source/game/scenes/secreta_scene.cpp index 1a2e732..8ddc664 100644 --- a/source/game/scenes/secreta_scene.cpp +++ b/source/game/scenes/secreta_scene.cpp @@ -14,9 +14,9 @@ namespace { constexpr int TICK_MS = 20; // Jg::setUpdateTicks(20) del vell doSecreta - // Durades per fase, derivades dels contador-thresholds del vell: - // tomba1 scroll: 127 passos (contador 1→128) × 20ms - // tomba1 hold: 128 passos (contador 128→0) × 20ms + // Durades per fase, derivades dels CONTADOR-thresholds del vell: + // tomba1 scroll: 127 passos (CONTADOR 1→128) × 20ms + // tomba1 hold: 128 passos (CONTADOR 128→0) × 20ms // tomba2 scroll: 94 passos × 20ms // tomba2 hold: 94 passos × 20ms // reveal horit: 80 passos × 20ms @@ -34,7 +34,7 @@ namespace { } // namespace -namespace scenes { +namespace Scenes { SecretaScene::~SecretaScene() { delete[] pal_aux_; @@ -107,11 +107,11 @@ namespace scenes { case Phase::TOMBA1_SCROLL_IN: { phase_acc_ms_ += delta_ms; - const int contador = std::min(128, (phase_acc_ms_ / TICK_MS) + 1); + const int CONTADOR = std::min(128, (phase_acc_ms_ / TICK_MS) + 1); // Dos blits solapats: el primer avança a velocitat completa, - // el segon (contingut de la dreta del src) a meitat (contador>>1). - Jd8::blit(70, 60, gfx_, 0, contador, 178, 70); - Jd8::blitCK(70, 60, gfx_, 178, contador >> 1, 142, 70, 255); + // el segon (contingut de la dreta del src) a meitat (CONTADOR>>1). + Jd8::blit(70, 60, gfx_, 0, CONTADOR, 178, 70); + Jd8::blitCK(70, 60, gfx_, 178, CONTADOR >> 1, 142, 70, 255); if (phase_acc_ms_ >= TOMBA1_SCROLL_MS) { phase_ = Phase::TOMBA1_HOLD; phase_acc_ms_ = 0; @@ -130,8 +130,8 @@ namespace scenes { case Phase::TOMBA2_SCROLL_IN: { phase_acc_ms_ += delta_ms; - const int contador = std::min(94, (phase_acc_ms_ / TICK_MS) + 1); - Jd8::blit(55, 53, gfx_, 0, 158 - contador, 211, contador); + const int CONTADOR = std::min(94, (phase_acc_ms_ / TICK_MS) + 1); + Jd8::blit(55, 53, gfx_, 0, 158 - CONTADOR, 211, CONTADOR); if (phase_acc_ms_ >= TOMBA2_SCROLL_MS) { phase_ = Phase::TOMBA2_HOLD; phase_acc_ms_ = 0; @@ -150,10 +150,10 @@ namespace scenes { case Phase::TOMBA2_REVEAL: { phase_acc_ms_ += delta_ms; - const int contador = std::min(80, (phase_acc_ms_ / TICK_MS) + 1); + const int CONTADOR = std::min(80, (phase_acc_ms_ / TICK_MS) + 1); // Revelat horitzontal simètric: l'amplada creix 2px per tick // i el src_x es desplaça a l'esquerra el mateix. - Jd8::blit(80, 68, gfx_, 160 - (contador * 2), 0, contador * 2, 64); + Jd8::blit(80, 68, gfx_, 160 - (CONTADOR * 2), 0, CONTADOR * 2, 64); if (phase_acc_ms_ >= TOMBA2_REVEAL_MS) { phase_ = Phase::TOMBA2_REVEAL_HOLD; phase_acc_ms_ = 0; @@ -171,11 +171,11 @@ namespace scenes { case Phase::RED_PULSE: { phase_acc_ms_ += delta_ms; - const int contador = std::min(51, phase_acc_ms_ / TICK_MS); + const int CONTADOR = std::min(51, phase_acc_ms_ / TICK_MS); // Anima el canal R dels índexs 254 i 253 (aquest a la meitat // de brillantor). Va de (12,11,11) fins a (63,11,11) / (31,11,11). - Jd8::setPaletteColor(254, contador + 12, 11, 11); - Jd8::setPaletteColor(253, (contador + 12) >> 1, 11, 11); + Jd8::setPaletteColor(254, CONTADOR + 12, 11, 11); + Jd8::setPaletteColor(253, (CONTADOR + 12) >> 1, 11, 11); if (phase_acc_ms_ >= RED_PULSE_MS) { phase_ = Phase::RED_PULSE_HOLD; phase_acc_ms_ = 0; @@ -202,4 +202,4 @@ namespace scenes { } } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/secreta_scene.hpp b/source/game/scenes/secreta_scene.hpp index 4ea3dcd..f0f6b05 100644 --- a/source/game/scenes/secreta_scene.hpp +++ b/source/game/scenes/secreta_scene.hpp @@ -7,7 +7,7 @@ #include "game/scenes/scene.hpp" #include "game/scenes/surface_handle.hpp" -namespace scenes { +namespace Scenes { // Pre-Secreta. Reemplaça `ModuleSequence::doSecreta()`. // @@ -65,4 +65,4 @@ namespace scenes { bool skip_triggered_{false}; }; -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/slides_scene.cpp b/source/game/scenes/slides_scene.cpp index ed040ae..e9ea5da 100644 --- a/source/game/scenes/slides_scene.cpp +++ b/source/game/scenes/slides_scene.cpp @@ -20,15 +20,15 @@ namespace { constexpr int BG_COLOR_INDEX = 255; // Desplaçament inicial del slide segons direcció del wipe. - // Slide 1 i 3: "scroll in from right" (pos_x va de 320 → 0). - // Slide 2: "wipe reverse" (pos_x va de -320 → 0), el mateix efecte + // Slide 1 i 3: "scroll in from right" (POS_X va de 320 → 0). + // Slide 2: "wipe reverse" (POS_X va de -320 → 0), el mateix efecte // estrany del doSlides vell on la imatge es desplaça des de l'esquerra // però revela primer el lateral dret del src. constexpr int SLIDE_START_X[3] = {320, -320, 320}; } // namespace -namespace scenes { +namespace Scenes { SlidesScene::~SlidesScene() { delete[] pal_aux_; @@ -36,13 +36,13 @@ namespace scenes { } void SlidesScene::onEnter() { - num_piramide_at_start_ = info::ctx.num_piramide; + num_piramide_at_start_ = Info::ctx.num_piramide; const char* arxiu = nullptr; if (num_piramide_at_start_ == 7) { // loop=1 per replicar el vell `play_music("final.ogg", 1)`. playMusic("music/final.ogg", 1); - arxiu = (info::ctx.diners < 200) ? "gfx/intro2.gif" : "gfx/intro3.gif"; + arxiu = (Info::ctx.diners < 200) ? "gfx/intro2.gif" : "gfx/intro3.gif"; } else { arxiu = "gfx/intro.gif"; } @@ -65,12 +65,12 @@ namespace scenes { next_state_ = 0; } - void SlidesScene::drawSlide(int slide_idx, int pos_x) { - const int src_y = slide_idx * SLIDE_H; + void SlidesScene::drawSlide(int slide_idx, int POS_X) { + const int SRC_Y = slide_idx * SLIDE_H; - // Clipping manual: translada un rect de 320×65 des de (pos_x, SLIDE_Y) + // Clipping manual: translada un rect de 320×65 des de (POS_X, SLIDE_Y) // a l'àrea visible (0..319, SLIDE_Y..SLIDE_Y+64). - int dst_x = pos_x; + int dst_x = POS_X; int src_x = 0; int w = 320; @@ -83,7 +83,7 @@ namespace scenes { } if (w > 0) { - Jd8::blit(dst_x, SLIDE_Y, gfx_, src_x, src_y, w, SLIDE_H); + Jd8::blit(dst_x, SLIDE_Y, gfx_, src_x, SRC_Y, w, SLIDE_H); } } @@ -123,13 +123,13 @@ namespace scenes { } else if (phase_ == Phase::SLIDE2_ENTER) { slide_idx = 1; } - const float t = std::min(1.0F, static_cast(phase_acc_ms_) / static_cast(SCROLL_MS)); - const float eased = Easing::outCubic(t); - const int pos_x = Easing::lerpInt(SLIDE_START_X[slide_idx], 0, eased); - drawSlide(slide_idx, pos_x); + const float T = std::min(1.0F, static_cast(phase_acc_ms_) / static_cast(SCROLL_MS)); + const float EASED = Easing::outCubic(T); + const int POS_X = Easing::lerpInt(SLIDE_START_X[slide_idx], 0, EASED); + drawSlide(slide_idx, POS_X); if (phase_acc_ms_ >= SCROLL_MS) { - // Garanteix posició final exacta (pos_x=0). + // Garanteix posició final exacta (POS_X=0). drawSlide(slide_idx, 0); if (phase_ == Phase::SLIDE1_ENTER) { phase_ = Phase::SLIDE1_HOLD; @@ -183,7 +183,7 @@ namespace scenes { fade_.tick(delta_ms); if (fade_.done()) { if (num_piramide_at_start_ == 7) { - info::ctx.num_piramide = 8; + Info::ctx.num_piramide = 8; next_state_ = 1; } else { next_state_ = 0; @@ -197,4 +197,4 @@ namespace scenes { } } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/slides_scene.hpp b/source/game/scenes/slides_scene.hpp index fb363a4..cbecc55 100644 --- a/source/game/scenes/slides_scene.hpp +++ b/source/game/scenes/slides_scene.hpp @@ -7,7 +7,7 @@ #include "game/scenes/scene.hpp" #include "game/scenes/surface_handle.hpp" -namespace scenes { +namespace Scenes { // 3 slides narratius amb scroll d'entrada + espera + transició amb // fade-out. Reemplaça `ModuleSequence::doSlides()`. @@ -78,4 +78,4 @@ namespace scenes { bool skip_triggered_{false}; }; -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/sprite_mover.cpp b/source/game/scenes/sprite_mover.cpp index 6b5b5c4..805e188 100644 --- a/source/game/scenes/sprite_mover.cpp +++ b/source/game/scenes/sprite_mover.cpp @@ -2,7 +2,7 @@ #include -namespace scenes { +namespace Scenes { void SpriteMover::moveTo(int x0, int y0, int x1, int y1, int duration_ms, EaseFn ease) { x0_ = x0; @@ -32,10 +32,10 @@ namespace scenes { return; } elapsed_ms_ = std::min(elapsed_ms_ + delta_ms, duration_ms_); - const float t = static_cast(elapsed_ms_) / static_cast(duration_ms_); - const float eased = ease_(t); - cur_x_ = Easing::lerpInt(x0_, x1_, eased); - cur_y_ = Easing::lerpInt(y0_, y1_, eased); + const float T = static_cast(elapsed_ms_) / static_cast(duration_ms_); + const float EASED = ease_(T); + cur_x_ = Easing::lerpInt(x0_, x1_, EASED); + cur_y_ = Easing::lerpInt(y0_, y1_, EASED); } auto SpriteMover::progress() const -> float { @@ -45,4 +45,4 @@ namespace scenes { return static_cast(elapsed_ms_) / static_cast(duration_ms_); } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/sprite_mover.hpp b/source/game/scenes/sprite_mover.hpp index 6196b2f..f1acfea 100644 --- a/source/game/scenes/sprite_mover.hpp +++ b/source/game/scenes/sprite_mover.hpp @@ -2,7 +2,7 @@ #include "utils/easing.hpp" -namespace scenes { +namespace Scenes { // Interpola una posició 2D entre dos punts durant un temps donat amb // una funció d'easing. No toca cap surface — el caller llegix x()/y() @@ -35,4 +35,4 @@ namespace scenes { EaseFn ease_{Easing::linear}; }; -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/surface_handle.cpp b/source/game/scenes/surface_handle.cpp index b8cd0df..8bffa2e 100644 --- a/source/game/scenes/surface_handle.cpp +++ b/source/game/scenes/surface_handle.cpp @@ -1,6 +1,6 @@ #include "game/scenes/surface_handle.hpp" -namespace scenes { +namespace Scenes { SurfaceHandle::SurfaceHandle(const char* file) : surface_(Jd8::loadSurface(file)) {} @@ -47,4 +47,4 @@ namespace scenes { return r; } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/surface_handle.hpp b/source/game/scenes/surface_handle.hpp index 4d71f50..d0f860a 100644 --- a/source/game/scenes/surface_handle.hpp +++ b/source/game/scenes/surface_handle.hpp @@ -2,7 +2,7 @@ #include "core/jail/jdraw8.hpp" -namespace scenes { +namespace Scenes { // Wrapper RAII damunt de `Jd8::Surface`. Allibera automàticament amb // `Jd8::freeSurface` al destructor. Move-only per evitar dobles alliberaments. @@ -46,4 +46,4 @@ namespace scenes { Jd8::Surface surface_{nullptr}; }; -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/timeline.cpp b/source/game/scenes/timeline.cpp index 1ee2c8a..27650e1 100644 --- a/source/game/scenes/timeline.cpp +++ b/source/game/scenes/timeline.cpp @@ -2,7 +2,7 @@ #include -namespace scenes { +namespace Scenes { auto Timeline::step(int duration_ms, StepFn fn) -> Timeline& { Step s; @@ -98,4 +98,4 @@ namespace scenes { return static_cast(elapsed_in_step_) / static_cast(s.duration_ms); } -} // namespace scenes +} // namespace Scenes diff --git a/source/game/scenes/timeline.hpp b/source/game/scenes/timeline.hpp index d23b279..70b2bbb 100644 --- a/source/game/scenes/timeline.hpp +++ b/source/game/scenes/timeline.hpp @@ -3,7 +3,7 @@ #include #include -namespace scenes { +namespace Scenes { // Timeline declaratiu de passos seqüencials. Cada pas té una duració en // ms i un callback. Exemple d'ús: @@ -54,4 +54,4 @@ namespace scenes { bool skipped_{false}; }; -} // namespace scenes +} // namespace Scenes diff --git a/source/main.cpp b/source/main.cpp index a39ecf7..706370d 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -38,8 +38,8 @@ auto SDL_AppInit(void** /*appstate*/, int /*argc*/, char* /*argv*/[]) -> SDL_App const char* base_path = SDL_GetBasePath(); std::string resource_pack_path; if (base_path != nullptr) { - const std::string data_path = std::string(base_path) + "data/"; - Jf::setResourceFolder(data_path.c_str()); + const std::string DATA_PATH = std::string(base_path) + "data/"; + Jf::setResourceFolder(DATA_PATH.c_str()); resource_pack_path = std::string(base_path) + "resources.pack"; } else { resource_pack_path = "resources.pack"; @@ -49,11 +49,11 @@ auto SDL_AppInit(void** /*appstate*/, int /*argc*/, char* /*argv*/[]) -> SDL_App // Release natiu exigix el pack (sense fallback); Debug i WASM mantenen // el fallback actiu per a desenvolupament i per al build amb MEMFS. #if defined(NDEBUG) && !defined(__EMSCRIPTEN__) - const bool enable_fallback = false; + const bool ENABLE_FALLBACK = false; #else - const bool enable_fallback = true; + const bool ENABLE_FALLBACK = true; #endif - if (!ResourceHelper::initializeResourceSystem(resource_pack_path, enable_fallback)) { + if (!ResourceHelper::initializeResourceSystem(resource_pack_path, ENABLE_FALLBACK)) { return SDL_APP_FAILURE; } diff --git a/source/utils/easing.cpp b/source/utils/easing.cpp index 9610f39..3c0d191 100644 --- a/source/utils/easing.cpp +++ b/source/utils/easing.cpp @@ -11,8 +11,8 @@ namespace Easing { } auto outCubic(float t) -> float { - const float inv = 1.0F - t; - return 1.0F - (inv * inv * inv); + const float INV = 1.0F - t; + return 1.0F - (INV * INV * INV); } auto inCubic(float t) -> float { return t * t * t; } From b984e6041e39c1ff63c4fbd967415a35bf7c30ef Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 16 May 2026 15:17:38 +0200 Subject: [PATCH 12/13] fix: tidy statics, instance, stretch43, fill/find_if ranges, NOLINT externs --- source/core/audio/audio.cpp | 8 +-- source/core/audio/jail_audio.hpp | 4 +- source/core/input/key_config.cpp | 56 +++++++++---------- source/core/jail/jfile.cpp | 4 +- source/core/locale/locale.cpp | 12 ++-- source/core/rendering/screen.cpp | 16 +++--- source/core/rendering/screen.hpp | 2 +- .../core/rendering/sdl3gpu/sdl3gpu_shader.cpp | 2 +- .../core/rendering/sdl3gpu/sdl3gpu_shader.hpp | 4 +- source/core/rendering/shader_backend.hpp | 4 +- source/core/rendering/text.cpp | 1 + source/core/resources/resource_cache.cpp | 2 + source/core/resources/resource_helper.cpp | 26 ++++----- source/core/system/director.cpp | 8 +-- source/core/system/director.hpp | 2 +- 15 files changed, 77 insertions(+), 74 deletions(-) diff --git a/source/core/audio/audio.cpp b/source/core/audio/audio.cpp index 2efd9ff..fdd4cf9 100644 --- a/source/core/audio/audio.cpp +++ b/source/core/audio/audio.cpp @@ -176,16 +176,16 @@ auto Audio::getRealMusicState() -> MusicState { // Establece el volumen de los sonidos (float 0.0..1.0) void Audio::setSoundVolume(float sound_volume, Group group) const { sound_volume = std::clamp(sound_volume, MIN_VOLUME, MAX_VOLUME); - const bool active = enabled_ && sound_enabled_; - const float CONVERTED_VOLUME = active ? sound_volume * Options::audio.volume : 0.0F; + const bool ACTIVE = enabled_ && sound_enabled_; + const float CONVERTED_VOLUME = ACTIVE ? sound_volume * Options::audio.volume : 0.0F; Ja::setSoundVolume(CONVERTED_VOLUME, static_cast(group)); } // Establece el volumen de la música (float 0.0..1.0) void Audio::setMusicVolume(float music_volume) const { music_volume = std::clamp(music_volume, MIN_VOLUME, MAX_VOLUME); - const bool active = enabled_ && music_enabled_; - const float CONVERTED_VOLUME = active ? music_volume * Options::audio.volume : 0.0F; + const bool ACTIVE = enabled_ && music_enabled_; + const float CONVERTED_VOLUME = ACTIVE ? music_volume * Options::audio.volume : 0.0F; Ja::setMusicVolume(CONVERTED_VOLUME); } diff --git a/source/core/audio/jail_audio.hpp b/source/core/audio/jail_audio.hpp index 276841f..a7d9e50 100644 --- a/source/core/audio/jail_audio.hpp +++ b/source/core/audio/jail_audio.hpp @@ -259,7 +259,7 @@ namespace Ja { sdl_audio_device = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audio_spec); if (sdl_audio_device == 0) { std::cout << "Failed to initialize SDL audio!" << '\n'; } for (auto& ch : channels) { ch.state = ChannelState::FREE; } - std::fill(std::begin(sound_volume), std::end(sound_volume), 0.5F); + std::ranges::fill(sound_volume, 0.5F); } inline void quit() { @@ -663,7 +663,7 @@ namespace Ja { const float V = SDL_clamp(volume, 0.0F, 1.0F); if (group == -1) { - std::fill(std::begin(sound_volume), std::end(sound_volume), V); + std::ranges::fill(sound_volume, V); } else if (group >= 0 && group < MAX_GROUPS) { sound_volume[group] = V; } else { diff --git a/source/core/input/key_config.cpp b/source/core/input/key_config.cpp index 71997cf..75ba75d 100644 --- a/source/core/input/key_config.cpp +++ b/source/core/input/key_config.cpp @@ -11,13 +11,13 @@ namespace KeyConfig { namespace { - std::vector entries_; - std::unordered_map index_; - std::string overrides_path_; + std::vector key_entries; + std::unordered_map index_table; + std::string overrides_path; auto findIndex(const std::string& id) -> size_t { - auto it = index_.find(id); - if (it == index_.end()) { + auto it = index_table.find(id); + if (it == index_table.end()) { return SIZE_MAX; } return it->second; @@ -52,10 +52,10 @@ namespace KeyConfig { entry.scancode = sc; entry.default_scancode = sc; - index_[entry.id] = entries_.size(); - entries_.push_back(std::move(entry)); + index_table[entry.id] = key_entries.size(); + key_entries.push_back(std::move(entry)); } - std::cout << "KeyConfig: " << entries_.size() << " tecles carregades de " + std::cout << "KeyConfig: " << key_entries.size() << " tecles carregades de " << defaults_resource_path << '\n'; } catch (const fkyaml::exception& e) { std::cerr << "KeyConfig: error parsejant YAML: " << e.what() << '\n'; @@ -93,8 +93,8 @@ namespace KeyConfig { << "' per '" << id << "'\n"; continue; } - entries_[idx].scancode = sc; - entries_[idx].code = code; + key_entries[idx].scancode = sc; + key_entries[idx].code = code; applied++; } if (applied > 0) { @@ -109,20 +109,20 @@ namespace KeyConfig { void init(const std::string& defaults_resource_path, const std::string& user_overrides_disk_path) { - entries_.clear(); - index_.clear(); - overrides_path_ = user_overrides_disk_path; + key_entries.clear(); + index_table.clear(); + overrides_path = user_overrides_disk_path; loadDefaults(defaults_resource_path); - if (!overrides_path_.empty()) { - applyOverrides(overrides_path_); + if (!overrides_path.empty()) { + applyOverrides(overrides_path); } } void destroy() { - entries_.clear(); - index_.clear(); - overrides_path_.clear(); + key_entries.clear(); + index_table.clear(); + overrides_path.clear(); } auto scancode(const std::string& id) -> SDL_Scancode { @@ -130,7 +130,7 @@ namespace KeyConfig { if (idx == SIZE_MAX) { return SDL_SCANCODE_UNKNOWN; } - return entries_[idx].scancode; + return key_entries[idx].scancode; } auto scancodePtr(const std::string& id) -> SDL_Scancode* { @@ -138,7 +138,7 @@ namespace KeyConfig { if (idx == SIZE_MAX) { return nullptr; } - return &entries_[idx].scancode; + return &key_entries[idx].scancode; } void setScancode(const std::string& id, SDL_Scancode sc) { @@ -146,38 +146,38 @@ namespace KeyConfig { if (idx == SIZE_MAX) { return; } - entries_[idx].scancode = sc; + key_entries[idx].scancode = sc; const char* name = SDL_GetScancodeName(sc); - entries_[idx].code = (name != nullptr) ? name : ""; + key_entries[idx].code = (name != nullptr) ? name : ""; } auto isGuiKey(SDL_Scancode sc) -> bool { if (sc == SDL_SCANCODE_UNKNOWN) { return false; } - return std::ranges::any_of(entries_, [sc](const auto& e) { return e.scancode == sc; }); + return std::ranges::any_of(key_entries, [sc](const auto& e) { return e.scancode == sc; }); } auto entries() -> const std::vector& { - return entries_; + return key_entries; } auto saveOverrides() -> bool { - if (overrides_path_.empty()) { + if (overrides_path.empty()) { return false; } // Recull només les entrades remapeades. std::vector changed; - for (const auto& e : entries_) { + for (const auto& e : key_entries) { if (e.scancode != e.default_scancode) { changed.push_back(&e); } } - std::ofstream file(overrides_path_); + std::ofstream file(overrides_path); if (!file.is_open()) { - std::cerr << "KeyConfig: no es pot escriure " << overrides_path_ << '\n'; + std::cerr << "KeyConfig: no es pot escriure " << overrides_path << '\n'; return false; } diff --git a/source/core/jail/jfile.cpp b/source/core/jail/jfile.cpp index e75ad28..fc742e0 100644 --- a/source/core/jail/jfile.cpp +++ b/source/core/jail/jfile.cpp @@ -112,7 +112,7 @@ auto Jf::getConfigValue(const char* key) -> const char* { if (config.empty()) { loadConfigValues(); } - const auto IT = std::find_if(config.begin(), config.end(), [key](const Keyvalue& pair) { return pair.key == key; }); + const auto IT = std::ranges::find_if(config, [key](const Keyvalue& pair) { return pair.key == key; }); if (IT != config.end()) { thread_local std::string value_cache_; value_cache_ = IT->value; @@ -125,7 +125,7 @@ void Jf::setConfigValue(const char* key, const char* value) { if (config.empty()) { loadConfigValues(); } - const auto IT = std::find_if(config.begin(), config.end(), [key](const Keyvalue& pair) { return pair.key == key; }); + const auto IT = std::ranges::find_if(config, [key](const Keyvalue& pair) { return pair.key == key; }); if (IT != config.end()) { IT->value = value; saveConfigValues(); diff --git a/source/core/locale/locale.cpp b/source/core/locale/locale.cpp index 547d4a8..d2eb811 100644 --- a/source/core/locale/locale.cpp +++ b/source/core/locale/locale.cpp @@ -9,7 +9,7 @@ namespace Locale { - static std::unordered_map strings_; + static std::unordered_map strings_table; // Aplana un node YAML en claus amb notació punt static void traverse(const fkyaml::node& node, const std::string& prefix) { @@ -25,7 +25,7 @@ namespace Locale { } } else if (node.is_scalar()) { try { - strings_[prefix] = node.get_value(); + strings_table[prefix] = node.get_value(); } catch (...) { // @INTENTIONAL: si el valor no és string vàlid, l'ignorem i continuem. } @@ -42,9 +42,9 @@ namespace Locale { try { auto yaml = fkyaml::node::deserialize(content); - strings_.clear(); + strings_table.clear(); traverse(yaml, ""); - std::cout << "Locale loaded: " << strings_.size() << " string(s) from " << filename << '\n'; + std::cout << "Locale loaded: " << strings_table.size() << " string(s) from " << filename << '\n'; return true; } catch (const fkyaml::exception& e) { std::cerr << "Locale: error parsing " << filename << ": " << e.what() << '\n'; @@ -53,8 +53,8 @@ namespace Locale { } auto get(const char* key) -> const char* { - auto it = strings_.find(key); - if (it != strings_.end()) { + auto it = strings_table.find(key); + if (it != strings_table.end()) { return it->second.c_str(); } return key; // fallback: retorna la clau mateixa diff --git a/source/core/rendering/screen.cpp b/source/core/rendering/screen.cpp index c7541f9..91ab710 100644 --- a/source/core/rendering/screen.cpp +++ b/source/core/rendering/screen.cpp @@ -56,18 +56,18 @@ namespace { } // namespace #endif // __EMSCRIPTEN__ -std::unique_ptr Screen::instance_; +std::unique_ptr Screen::instance; void Screen::init() { - instance_ = std::unique_ptr(new Screen()); + instance = std::unique_ptr(new Screen()); } void Screen::destroy() { - instance_.reset(); + instance.reset(); } auto Screen::get() -> Screen* { - return instance_.get(); + return instance.get(); } Screen::Screen() { @@ -178,7 +178,7 @@ void Screen::initShaders() { shader_backend_->setScalingMode(Options::video.scaling_mode); shader_backend_->setVSync(Options::video.vsync); shader_backend_->setTextureFilter(Options::video.texture_filter); - shader_backend_->setStretch4_3(Options::video.aspect_ratio_4_3); + shader_backend_->setStretch43(Options::video.aspect_ratio_4_3); shader_backend_->setDownscaleAlgo(Options::video.downscale_algo); if (Options::video.supersampling) { @@ -346,7 +346,7 @@ auto Screen::toggleSupersampling() -> bool { void Screen::toggleAspectRatio() { Options::video.aspect_ratio_4_3 = !Options::video.aspect_ratio_4_3; if (shader_backend_) { - shader_backend_->setStretch4_3(Options::video.aspect_ratio_4_3); + shader_backend_->setStretch43(Options::video.aspect_ratio_4_3); } else { applyFallbackPresentation(); } @@ -560,7 +560,7 @@ auto Screen::getActiveShaderName() const -> const char* { } void Screen::updateRenderInfo() { - static const Uint32 start_ticks = SDL_GetTicks(); + static const Uint32 START_TICKS = SDL_GetTicks(); std::string driver = gpu_driver_.empty() ? "sdl" : toLower(gpu_driver_); // Segment 0: FPS + driver (sempre visible) @@ -578,7 +578,7 @@ void Screen::updateRenderInfo() { // Segment 3: hora (només si show_time) char time_buf[32] = {0}; if (Options::render_info.show_time) { - Uint32 elapsed = SDL_GetTicks() - start_ticks; + Uint32 elapsed = SDL_GetTicks() - START_TICKS; int minutes = elapsed / 60000; int seconds = (elapsed / 1000) % 60; int centis = (elapsed / 10) % 100; diff --git a/source/core/rendering/screen.hpp b/source/core/rendering/screen.hpp index 3818df6..b9d36b7 100644 --- a/source/core/rendering/screen.hpp +++ b/source/core/rendering/screen.hpp @@ -71,7 +71,7 @@ class Screen { void applyFallbackPresentation(); // Logical presentation + scale mode per al path SDL_Renderer void ensureFallbackInternalTexture(); // Recrea internal_texture_sdl_ si cal (fallback path) - static std::unique_ptr instance_; + static std::unique_ptr instance; SDL_Window* window_{nullptr}; SDL_Renderer* renderer_{nullptr}; diff --git a/source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp b/source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp index 9e92519..a8d3422 100644 --- a/source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp +++ b/source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp @@ -1286,7 +1286,7 @@ namespace Rendering { } } - void SDL3GPUShader::setStretch4_3(bool enabled) { + void SDL3GPUShader::setStretch43(bool enabled) { stretch_4_3_ = enabled; if (!is_initialized_ || device_ == nullptr) { return; diff --git a/source/core/rendering/sdl3gpu/sdl3gpu_shader.hpp b/source/core/rendering/sdl3gpu/sdl3gpu_shader.hpp index 13bcf5b..61d6796 100644 --- a/source/core/rendering/sdl3gpu/sdl3gpu_shader.hpp +++ b/source/core/rendering/sdl3gpu/sdl3gpu_shader.hpp @@ -118,8 +118,8 @@ namespace Rendering { [[nodiscard]] auto getActiveShader() const -> ShaderType override { return active_shader_; } // Estirament vertical 4:3 (fusionat amb l'upscale pass) - void setStretch4_3(bool enabled) override; - [[nodiscard]] auto isStretch4_3() const -> bool override { return stretch_4_3_; } + void setStretch43(bool enabled) override; + [[nodiscard]] auto isStretch43() const -> bool override { return stretch_4_3_; } // Filtre de textura global (sempre aplicat, independent de 4:3) void setTextureFilter(Options::TextureFilter filter) override { diff --git a/source/core/rendering/shader_backend.hpp b/source/core/rendering/shader_backend.hpp index aa5acfc..7c3cb52 100644 --- a/source/core/rendering/shader_backend.hpp +++ b/source/core/rendering/shader_backend.hpp @@ -171,8 +171,8 @@ namespace Rendering { * @brief Activa/desactiva estirament vertical 4:3 (200→240 línies efectives). * Només afecta el viewport, no les textures ni els shaders. */ - virtual void setStretch4_3(bool /*enabled*/) {} - [[nodiscard]] virtual auto isStretch4_3() const -> bool { return false; } + virtual void setStretch43(bool /*enabled*/) {} + [[nodiscard]] virtual auto isStretch43() const -> bool { return false; } /** * @brief Filtre de textura global per a l'upscale final (sempre aplicat). diff --git a/source/core/rendering/text.cpp b/source/core/rendering/text.cpp index 1033b20..686714c 100644 --- a/source/core/rendering/text.cpp +++ b/source/core/rendering/text.cpp @@ -12,6 +12,7 @@ // Forward declarations de gif.h (inclòs des de jdraw8.cpp, no es pot incloure dos vegades) struct rgb; +// NOLINTNEXTLINE(readability-identifier-naming) — exportat per external/gif.h, no controlem el nom. extern auto LoadGif(unsigned char* data, unsigned short* w, unsigned short* h) -> unsigned char*; Text::Text(const char* fnt_file, const char* gif_file) { diff --git a/source/core/resources/resource_cache.cpp b/source/core/resources/resource_cache.cpp index c1e9188..d058808 100644 --- a/source/core/resources/resource_cache.cpp +++ b/source/core/resources/resource_cache.cpp @@ -15,8 +15,10 @@ // ni inline, així que no podem tornar-lo a incloure aquí. Ens fiem de les // declaracions extern dels símbols que ens calen (linkatge C++ normal, // igual que fa text.cpp). +// NOLINTBEGIN(readability-identifier-naming) — símbols externs de gif.h. extern auto LoadGif(unsigned char* data, unsigned short* w, unsigned short* h) -> unsigned char*; extern auto LoadPalette(unsigned char* data) -> unsigned char*; +// NOLINTEND(readability-identifier-naming) namespace Resource { diff --git a/source/core/resources/resource_helper.cpp b/source/core/resources/resource_helper.cpp index 9ea6443..d2b0a34 100644 --- a/source/core/resources/resource_helper.cpp +++ b/source/core/resources/resource_helper.cpp @@ -9,9 +9,9 @@ namespace ResourceHelper { namespace { - ResourcePack pack_; - bool pack_loaded_ = false; - bool fallback_enabled_ = true; + ResourcePack pack_obj; + bool pack_loaded = false; + bool fallback_enabled = true; auto readFromDisk(const std::string& relative_path) -> std::vector { const std::string FULL = std::string(Jf::getResourceFolder()) + relative_path; @@ -32,11 +32,11 @@ namespace ResourceHelper { } // namespace auto initializeResourceSystem(const std::string& pack_file, bool enable_fallback) -> bool { - fallback_enabled_ = enable_fallback; - pack_loaded_ = pack_.loadPack(pack_file); + fallback_enabled = enable_fallback; + pack_loaded = pack_obj.loadPack(pack_file); - if (pack_loaded_) { - std::cout << "ResourceHelper: pack loaded (" << pack_.getResourceCount() + if (pack_loaded) { + std::cout << "ResourceHelper: pack loaded (" << pack_obj.getResourceCount() << " entries) from " << pack_file << '\n'; } else if (enable_fallback) { std::cout << "ResourceHelper: no pack at " << pack_file @@ -50,22 +50,22 @@ namespace ResourceHelper { } void shutdownResourceSystem() { - pack_.clear(); - pack_loaded_ = false; + pack_obj.clear(); + pack_loaded = false; } auto loadFile(const std::string& relative_path) -> std::vector { - if (pack_loaded_ && pack_.hasResource(relative_path)) { - return pack_.getResource(relative_path); + if (pack_loaded && pack_obj.hasResource(relative_path)) { + return pack_obj.getResource(relative_path); } - if (fallback_enabled_) { + if (fallback_enabled) { return readFromDisk(relative_path); } return {}; } auto hasPack() -> bool { - return pack_loaded_; + return pack_loaded; } } // namespace ResourceHelper diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 5703d53..fda83ee 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -32,7 +32,7 @@ #include "game/scenes/secreta_scene.hpp" #include "game/scenes/slides_scene.hpp" -std::unique_ptr Director::instance_; +std::unique_ptr Director::instance; Director::~Director() = default; @@ -76,7 +76,7 @@ auto Director::createNextScene() const -> std::unique_ptr { } void Director::init() { - instance_ = std::unique_ptr(new Director()); + instance = std::unique_ptr(new Director()); Gamepad::init(); // Registre d'escenes. Cada entrada = un state_key (`num_piramide`) @@ -113,11 +113,11 @@ void Director::init() { void Director::destroy() { Gamepad::destroy(); - instance_.reset(); + instance.reset(); } auto Director::get() -> Director* { - return instance_.get(); + return instance.get(); } void Director::togglePause() { diff --git a/source/core/system/director.hpp b/source/core/system/director.hpp index 812a300..870566b 100644 --- a/source/core/system/director.hpp +++ b/source/core/system/director.hpp @@ -57,7 +57,7 @@ class Director { private: Director() = default; - static std::unique_ptr instance_; + static std::unique_ptr instance; void pollAllEvents(); // drenatge amb SDL_PollEvent, només per al bucle natiu From e1bc1b597f7d754bc83b5e63699c04e3739be3d9 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 16 May 2026 16:13:57 +0200 Subject: [PATCH 13/13] refactor: extreure helpers per reduir complexitat cognitiva (tidy net) --- source/core/input/gamepad.cpp | 157 ++++--- source/core/input/global_inputs.cpp | 123 ++---- source/core/rendering/menu.cpp | 226 +++++----- source/core/rendering/overlay.cpp | 453 ++++++++++---------- source/core/rendering/text.cpp | 242 +++-------- source/core/rendering/text.hpp | 7 + source/core/resources/resource_cache.cpp | 91 ++-- source/core/resources/resource_cache.hpp | 4 + source/core/system/director.cpp | 244 +++++------ source/core/system/director.hpp | 8 + source/external/gif.h | 2 + source/game/bola.cpp | 24 +- source/game/bola.hpp | 4 +- source/game/engendro.cpp | 10 +- source/game/engendro.hpp | 2 +- source/game/mapa.cpp | 2 +- source/game/marcador.cpp | 32 +- source/game/marcador.hpp | 4 +- source/game/momia.cpp | 189 ++++---- source/game/momia.hpp | 11 +- source/game/options.cpp | 64 ++- source/game/prota.cpp | 280 ++++++------ source/game/prota.hpp | 4 + source/game/scenes/intro_new_logo_scene.cpp | 101 +++-- source/game/scenes/intro_new_logo_scene.hpp | 14 +- source/game/scenes/scene_registry.cpp | 4 +- source/game/scenes/slides_scene.cpp | 157 +++---- source/game/scenes/slides_scene.hpp | 6 + source/game/scenes/timeline.cpp | 4 +- source/game/sprite.cpp | 4 +- source/game/sprite.hpp | 4 +- 31 files changed, 1145 insertions(+), 1332 deletions(-) diff --git a/source/core/input/gamepad.cpp b/source/core/input/gamepad.cpp index 6e5af71..e7b1677 100644 --- a/source/core/input/gamepad.cpp +++ b/source/core/input/gamepad.cpp @@ -195,97 +195,86 @@ namespace Gamepad { SDL_PushEvent(&e); } + // Estat agregat d'un frame: D-pad i stick combinats, més botons frontals. + struct PadState { + bool up; + bool down; + bool left; + bool right; + bool south; + bool east; + bool west; + bool north; + bool start; + bool back; + }; + + static auto readPadState() -> PadState { + const Sint16 LX = SDL_GetGamepadAxis(pad, SDL_GAMEPAD_AXIS_LEFTX); + const Sint16 LY = SDL_GetGamepadAxis(pad, SDL_GAMEPAD_AXIS_LEFTY); + return PadState{ + .up = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_DPAD_UP) || LY < -STICK_DEADZONE, + .down = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_DPAD_DOWN) || LY > STICK_DEADZONE, + .left = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_DPAD_LEFT) || LX < -STICK_DEADZONE, + .right = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_DPAD_RIGHT) || LX > STICK_DEADZONE, + .south = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_SOUTH), + .east = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_EAST), + .west = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_WEST), + .north = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_NORTH), + .start = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_START), + .back = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_BACK), + }; + } + + static void handleMenuNavigation(const PadState& s) { + if (s.up && !prev_up) { pushKey(SDL_SCANCODE_UP); } + if (s.down && !prev_down) { pushKey(SDL_SCANCODE_DOWN); } + if (s.left && !prev_left) { pushKey(SDL_SCANCODE_LEFT); } + if (s.right && !prev_right) { pushKey(SDL_SCANCODE_RIGHT); } + if (s.east && !prev_east) { pushKey(SDL_SCANCODE_RETURN); } + if (s.south && !prev_south) { pushKey(SDL_SCANCODE_BACKSPACE); } + // Mentre el menú està obert, el joc no ha de rebre moviment. + Ji::setVirtualKey(SDL_SCANCODE_UP, Ji::VirtualSource::GAMEPAD, false); + Ji::setVirtualKey(SDL_SCANCODE_DOWN, Ji::VirtualSource::GAMEPAD, false); + Ji::setVirtualKey(SDL_SCANCODE_LEFT, Ji::VirtualSource::GAMEPAD, false); + Ji::setVirtualKey(SDL_SCANCODE_RIGHT, Ji::VirtualSource::GAMEPAD, false); + } + + static void handleGameInput(const PadState& s) { + Ji::setVirtualKey(SDL_SCANCODE_UP, Ji::VirtualSource::GAMEPAD, s.up); + Ji::setVirtualKey(SDL_SCANCODE_DOWN, Ji::VirtualSource::GAMEPAD, s.down); + Ji::setVirtualKey(SDL_SCANCODE_LEFT, Ji::VirtualSource::GAMEPAD, s.left); + Ji::setVirtualKey(SDL_SCANCODE_RIGHT, Ji::VirtualSource::GAMEPAD, s.right); + const bool ANY_FRONT_EDGE = (s.south && !prev_south) || (s.east && !prev_east) || + (s.west && !prev_west) || (s.north && !prev_north); + if (ANY_FRONT_EDGE) { + pushKey(SDL_SCANCODE_RETURN); + } + } + void update() { if (pad == nullptr) { return; } - - // D-pad - bool dup = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_DPAD_UP); - bool ddn = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_DPAD_DOWN); - bool dlt = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_DPAD_LEFT); - bool drt = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_DPAD_RIGHT); - - // Stick esquerre amb dead-zone - Sint16 lx = SDL_GetGamepadAxis(pad, SDL_GAMEPAD_AXIS_LEFTX); - Sint16 ly = SDL_GetGamepadAxis(pad, SDL_GAMEPAD_AXIS_LEFTY); - bool sup = ly < -STICK_DEADZONE; - bool sdn = ly > STICK_DEADZONE; - bool slt = lx < -STICK_DEADZONE; - bool srt = lx > STICK_DEADZONE; - - bool up = dup || sup; - bool dn = ddn || sdn; - bool lt = dlt || slt; - bool rt = drt || srt; - - // Botons frontals (layout SDL: SOUTH=A/Cross, EAST=B/Circle, WEST=X/Square, NORTH=Y/Triangle) - bool south = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_SOUTH); - bool east = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_EAST); - bool west = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_WEST); - bool north = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_NORTH); - bool start = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_START); - bool back = SDL_GetGamepadButton(pad, SDL_GAMEPAD_BUTTON_BACK); - - // Select (Back) → obre/tanca menú de servei (flanc) - if (back && !prev_back) { - pushKey(KeyConfig::scancode("menu_toggle")); - } - // Start → pausa (flanc) - if (start && !prev_start) { - pushKey(KeyConfig::scancode("pause_toggle")); - } - + const PadState S = readPadState(); + // Flancs globals: Select i Start sempre operen. + if (S.back && !prev_back) { pushKey(KeyConfig::scancode("menu_toggle")); } + if (S.start && !prev_start) { pushKey(KeyConfig::scancode("pause_toggle")); } if (Menu::isOpen()) { - // Navegació del menú per flanc - if (up && !prev_up) { - pushKey(SDL_SCANCODE_UP); - } - if (dn && !prev_down) { - pushKey(SDL_SCANCODE_DOWN); - } - if (lt && !prev_left) { - pushKey(SDL_SCANCODE_LEFT); - } - if (rt && !prev_right) { - pushKey(SDL_SCANCODE_RIGHT); - } - // EAST accepta, SOUTH cancela / endarrere - if (east && !prev_east) { - pushKey(SDL_SCANCODE_RETURN); - } - if (south && !prev_south) { - pushKey(SDL_SCANCODE_BACKSPACE); - } - - // Assegura que el joc no rep tecles de moviment mentre el menú està obert - Ji::setVirtualKey(SDL_SCANCODE_UP, Ji::VirtualSource::GAMEPAD, false); - Ji::setVirtualKey(SDL_SCANCODE_DOWN, Ji::VirtualSource::GAMEPAD, false); - Ji::setVirtualKey(SDL_SCANCODE_LEFT, Ji::VirtualSource::GAMEPAD, false); - Ji::setVirtualKey(SDL_SCANCODE_RIGHT, Ji::VirtualSource::GAMEPAD, false); + handleMenuNavigation(S); } else { - // Moviment al joc — level-triggered (polling) - Ji::setVirtualKey(SDL_SCANCODE_UP, Ji::VirtualSource::GAMEPAD, up); - Ji::setVirtualKey(SDL_SCANCODE_DOWN, Ji::VirtualSource::GAMEPAD, dn); - Ji::setVirtualKey(SDL_SCANCODE_LEFT, Ji::VirtualSource::GAMEPAD, lt); - Ji::setVirtualKey(SDL_SCANCODE_RIGHT, Ji::VirtualSource::GAMEPAD, rt); - // Qualsevol dels 4 botons frontals avança escenes (Ji::anyKey via Enter sintètic) - if ((south && !prev_south) || (east && !prev_east) || - (west && !prev_west) || (north && !prev_north)) { - pushKey(SDL_SCANCODE_RETURN); - } + handleGameInput(S); } - - prev_up = up; - prev_down = dn; - prev_left = lt; - prev_right = rt; - prev_south = south; - prev_east = east; - prev_west = west; - prev_north = north; - prev_start = start; - prev_back = back; + prev_up = S.up; + prev_down = S.down; + prev_left = S.left; + prev_right = S.right; + prev_south = S.south; + prev_east = S.east; + prev_west = S.west; + prev_north = S.north; + prev_start = S.start; + prev_back = S.back; } } // namespace Gamepad diff --git a/source/core/input/global_inputs.cpp b/source/core/input/global_inputs.cpp index c004848..bec764a 100644 --- a/source/core/input/global_inputs.cpp +++ b/source/core/input/global_inputs.cpp @@ -1,6 +1,7 @@ #include "core/input/global_inputs.hpp" #include +#include #include #include "core/input/key_config.hpp" @@ -23,131 +24,71 @@ namespace GlobalInputs { static bool texture_filter_prev = false; static bool render_info_prev = false; + // Patró comú: lectura amb detecció de flanc + acumulació al flag "consumed". + // `on_press` només s'executa al flanc puja; `prev` es manté actualitzat. + static auto edgeTrigger(const char* key_id, bool& prev, const std::function& on_press) -> bool { + const bool PRESSED = Ji::keyPressed(KeyConfig::scancode(key_id)); + if (PRESSED && !prev) { + on_press(); + } + prev = PRESSED; + return PRESSED; + } + auto handle() -> bool { bool consumed = false; - - // F1 — Reduir zoom - bool dec_zoom = Ji::keyPressed(KeyConfig::scancode("dec_zoom")); - if (dec_zoom && !dec_zoom_prev) { + consumed |= edgeTrigger("dec_zoom", dec_zoom_prev, [] { Screen::get()->decZoom(); char msg[32]; snprintf(msg, sizeof(msg), Locale::get("notifications.zoom_fmt"), Screen::get()->getZoom()); Overlay::showNotification(msg); - } - if (dec_zoom) { - consumed = true; - } - dec_zoom_prev = dec_zoom; - - // F2 — Augmentar zoom - bool inc_zoom = Ji::keyPressed(KeyConfig::scancode("inc_zoom")); - if (inc_zoom && !inc_zoom_prev) { + }); + consumed |= edgeTrigger("inc_zoom", inc_zoom_prev, [] { Screen::get()->incZoom(); char msg[32]; snprintf(msg, sizeof(msg), Locale::get("notifications.zoom_fmt"), Screen::get()->getZoom()); Overlay::showNotification(msg); - } - if (inc_zoom) { - consumed = true; - } - inc_zoom_prev = inc_zoom; - - // F3 — Toggle pantalla completa - bool fullscreen = Ji::keyPressed(KeyConfig::scancode("fullscreen")); - if (fullscreen && !fullscreen_prev) { + }); + consumed |= edgeTrigger("fullscreen", fullscreen_prev, [] { Screen::get()->toggleFullscreen(); Overlay::showNotification(Screen::get()->isFullscreen() ? Locale::get("notifications.fullscreen") : Locale::get("notifications.windowed")); - } - if (fullscreen) { - consumed = true; - } - fullscreen_prev = fullscreen; - - // F4 — Toggle shaders - bool shader = Ji::keyPressed(KeyConfig::scancode("toggle_shader")); - if (shader && !shader_prev) { + }); + consumed |= edgeTrigger("toggle_shader", shader_prev, [] { Screen::get()->toggleShaders(); Overlay::showNotification(Options::video.shader_enabled ? Locale::get("notifications.shader_on") : Locale::get("notifications.shader_off")); - } - if (shader) { - consumed = true; - } - shader_prev = shader; - - // F5 — Toggle aspect ratio 4:3 - bool aspect = Ji::keyPressed(KeyConfig::scancode("toggle_aspect_ratio")); - if (aspect && !aspect_prev) { + }); + consumed |= edgeTrigger("toggle_aspect_ratio", aspect_prev, [] { Screen::get()->toggleAspectRatio(); Overlay::showNotification(Options::video.aspect_ratio_4_3 ? Locale::get("notifications.aspect_43") : Locale::get("notifications.aspect_square")); - } - if (aspect) { - consumed = true; - } - aspect_prev = aspect; - - // F6 — Toggle supersampling - bool ss = Ji::keyPressed(KeyConfig::scancode("toggle_supersampling")); - if (ss && !ss_prev) { + }); + consumed |= edgeTrigger("toggle_supersampling", ss_prev, [] { if (Screen::get()->toggleSupersampling()) { Overlay::showNotification(Options::video.supersampling ? Locale::get("notifications.ss_on") : Locale::get("notifications.ss_off")); } - } - if (ss) { - consumed = true; - } - ss_prev = ss; - - // F7 — Canviar tipus de shader (PostFX ↔ CrtPi) - bool next_shader = Ji::keyPressed(KeyConfig::scancode("next_shader")); - if (next_shader && !next_shader_prev) { + }); + consumed |= edgeTrigger("next_shader", next_shader_prev, [] { if (Screen::get()->nextShaderType()) { char msg[64]; snprintf(msg, sizeof(msg), "%s: %s", Screen::get()->getActiveShaderName(), Screen::get()->getCurrentPresetName()); Overlay::showNotification(msg); } - } - if (next_shader) { - consumed = true; - } - next_shader_prev = next_shader; - - // F8 — Pròxim preset del shader actiu - bool next_preset = Ji::keyPressed(KeyConfig::scancode("next_shader_preset")); - if (next_preset && !next_preset_prev) { + }); + consumed |= edgeTrigger("next_shader_preset", next_preset_prev, [] { if (Screen::get()->nextPreset()) { char msg[64]; snprintf(msg, sizeof(msg), Locale::get("notifications.preset_fmt"), Screen::get()->getCurrentPresetName()); Overlay::showNotification(msg); } - } - if (next_preset) { - consumed = true; - } - next_preset_prev = next_preset; - - // F9 — Cicla filtre de textura (NEAREST ↔ LINEAR), sempre aplicat - bool texture_filter = Ji::keyPressed(KeyConfig::scancode("cycle_texture_filter")); - if (texture_filter && !texture_filter_prev) { + }); + consumed |= edgeTrigger("cycle_texture_filter", texture_filter_prev, [] { Screen::get()->cycleTextureFilter(+1); Overlay::showNotification(Options::video.texture_filter == Options::TextureFilter::LINEAR ? Locale::get("notifications.filter_linear") : Locale::get("notifications.filter_nearest")); - } - if (texture_filter) { - consumed = true; - } - texture_filter_prev = texture_filter; - - // F10 — Toggle render info (FPS, driver, shader) - bool render_info = Ji::keyPressed(KeyConfig::scancode("toggle_render_info")); - if (render_info && !render_info_prev) { + }); + consumed |= edgeTrigger("toggle_render_info", render_info_prev, [] { Overlay::toggleRenderInfo(); - } - if (render_info) { - consumed = true; - } - render_info_prev = render_info; - + }); return consumed; } diff --git a/source/core/rendering/menu.cpp b/source/core/rendering/menu.cpp index ebddb33..006def4 100644 --- a/source/core/rendering/menu.cpp +++ b/source/core/rendering/menu.cpp @@ -60,10 +60,10 @@ namespace Menu { const char* label; ItemKind kind; std::function get_value; // opcional - std::function change; // per TOGGLE/CYCLE/INT_RANGE - std::function enter; // per SUBMENU i ACTION - SDL_Scancode* scancode{nullptr}; // per KEY_BIND - std::function visible; // nullptr ⇒ sempre visible + std::function change; // per TOGGLE/CYCLE/INT_RANGE + std::function enter; // per SUBMENU i ACTION + SDL_Scancode* scancode{nullptr}; // per KEY_BIND + std::function visible; // nullptr ⇒ sempre visible }; struct Page { @@ -448,27 +448,30 @@ namespace Menu { capturing = nullptr; } - void handleKey(SDL_Scancode sc) { - if (!isOpen()) { - return; + static void backOrClose() { + if (stack.size() > 1) { + popPage(); + } else { + close(); } - Page& page = stack.back(); - if (page.items.empty()) { - // Pàgina buida — només backspace surt - if (sc == SDL_SCANCODE_BACKSPACE) { - if (stack.size() > 1) { - popPage(); - } else { - close(); - } + } + + // Activació d'un ítem (RETURN/KP_ENTER): SUBMENU/ACTION criden enter, + // KEY_BIND inicia captura, la resta avança change(+1). + static void activateItem(Item& item) { + if (item.kind == ItemKind::SUBMENU || item.kind == ItemKind::ACTION) { + if (item.enter) { + item.enter(); } - return; - } - // Si el cursor està sobre un ítem ocultat (p. ex. una acció anterior el va ocultar), - // reubica'l al pròxim visible abans de processar l'entrada. - if (!isVisible(page.items[page.cursor])) { - page.cursor = nextVisibleCursor(page, page.cursor, +1); + } else if (item.kind == ItemKind::KEY_BIND) { + capturing = item.scancode; + } else if (item.change) { + item.change(+1); } + } + + static void applyKeyToItem(Page& page, SDL_Scancode sc) { + Item& item = page.items[page.cursor]; switch (sc) { case SDL_SCANCODE_UP: page.cursor = nextVisibleCursor(page, page.cursor, -1); @@ -477,43 +480,44 @@ namespace Menu { page.cursor = nextVisibleCursor(page, page.cursor, +1); break; case SDL_SCANCODE_LEFT: - if (page.items[page.cursor].kind != ItemKind::SUBMENU && - page.items[page.cursor].change) { - page.items[page.cursor].change(-1); + if (item.kind != ItemKind::SUBMENU && item.change) { + item.change(-1); } break; case SDL_SCANCODE_RIGHT: - if (page.items[page.cursor].kind != ItemKind::SUBMENU && - page.items[page.cursor].change) { - page.items[page.cursor].change(+1); + if (item.kind != ItemKind::SUBMENU && item.change) { + item.change(+1); } break; case SDL_SCANCODE_RETURN: case SDL_SCANCODE_KP_ENTER: - if (page.items[page.cursor].kind == ItemKind::SUBMENU || - page.items[page.cursor].kind == ItemKind::ACTION) { - if (page.items[page.cursor].enter) { - page.items[page.cursor].enter(); - } - } else if (page.items[page.cursor].kind == ItemKind::KEY_BIND) { - capturing = page.items[page.cursor].scancode; - } else if (page.items[page.cursor].change) { - page.items[page.cursor].change(+1); - } + activateItem(item); break; case SDL_SCANCODE_BACKSPACE: - if (stack.size() > 1) { - popPage(); - } else { - close(); - } + backOrClose(); break; default: break; } - // Després de qualsevol acció, si el cursor quedara sobre un ítem ocult - // (possible si una acció ha canviat la visibilitat pròpia de l'ítem actual, - // edge case defensiu), salta al següent visible. + } + + void handleKey(SDL_Scancode sc) { + if (!isOpen()) { + return; + } + Page& page = stack.back(); + if (page.items.empty()) { + if (sc == SDL_SCANCODE_BACKSPACE) { + backOrClose(); + } + return; + } + if (!isVisible(page.items[page.cursor])) { + page.cursor = nextVisibleCursor(page, page.cursor, +1); + } + applyKeyToItem(page, sc); + // Defensa: si una acció ha amagat l'ítem que tenim sota el cursor, + // saltem al pròxim visible. if (!stack.empty()) { Page& top = stack.back(); if (!top.items.empty() && !isVisible(top.items[top.cursor])) { @@ -522,6 +526,9 @@ namespace Menu { } } + // Forward decl: renderOneItem viu sota renderPageContent però aquest l'ha de cridar. + static void renderOneItem(Uint32* pixel_data, const Item& item, bool selected, int box_x, int y, int x_offset, int clip_x_min, int clip_x_max, int clip_y_min, int clip_y_max); + // Dibuixa el contingut d'una pàgina amb un offset horitzontal i un rang de clip. // box_x/box_y són les coordenades de la caixa (per calcular posicions relatives); // clip_x_min/clip_x_max limiten on es dibuixa text i la línia separadora. @@ -560,69 +567,88 @@ namespace Menu { return; } - int y_slot = 0; // índex de fila visible (independent de l'índex real de l'ítem) + int y_slot = 0; for (size_t i = 0; i < page.items.size(); i++) { const Item& item = page.items[i]; if (!isVisible(item)) { continue; } - int y = items_y + (y_slot * ITEM_SPACING); + const int Y = items_y + (y_slot * ITEM_SPACING); ++y_slot; - bool selected = (static_cast(i) == page.cursor); - Uint32 label_color = selected ? CURSOR_COLOR : LABEL_COLOR; - - // ACTION: sense valor a la dreta — centrem el label amb el cursor just a l'esquerra. - if (item.kind == ItemKind::ACTION) { - int lw = font->width(item.label); - int lx = box_x + ((BOX_W - lw) / 2) + x_offset; - if (selected) { - font->drawClipped(pixel_data, lx - font->width("> "), y, ">", CURSOR_COLOR, clip_x_min, clip_x_max, clip_y_min, clip_y_max); - } - font->drawClipped(pixel_data, lx, y, item.label, label_color, clip_x_min, clip_x_max, clip_y_min, clip_y_max); - continue; - } - - if (selected) { - font->drawClipped(pixel_data, box_x + 4 + x_offset, y, ">", CURSOR_COLOR, clip_x_min, clip_x_max, clip_y_min, clip_y_max); - } - - font->drawClipped(pixel_data, box_x + ITEM_PAD_X + x_offset, y, item.label, label_color, clip_x_min, clip_x_max, clip_y_min, clip_y_max); - - if (item.kind == ItemKind::SUBMENU) { - const char* arrow = ">>"; - int aw = font->width(arrow); - Uint32 ac = selected ? CURSOR_COLOR : VALUE_COLOR; - font->drawClipped(pixel_data, box_x + BOX_W - ITEM_PAD_X - aw + x_offset, y, arrow, ac, clip_x_min, clip_x_max, clip_y_min, clip_y_max); - } else if (item.kind == ItemKind::KEY_BIND) { - bool this_capturing = (capturing == item.scancode); - const char* text = nullptr; - if (this_capturing) { - text = Locale::get("menu.values.press_key"); - } else if (item.scancode != nullptr) { - text = SDL_GetScancodeName(*item.scancode); - } else { - text = ""; - } - if ((text == nullptr) || (*text == 0)) { - text = Locale::get("menu.values.unknown"); - } - int tw = font->width(text); - Uint32 tc = 0; - if (this_capturing) { - tc = 0xFF00FFFF; - } else { - tc = selected ? CURSOR_COLOR : VALUE_COLOR; - } - font->drawClipped(pixel_data, box_x + BOX_W - ITEM_PAD_X - tw + x_offset, y, text, tc, clip_x_min, clip_x_max, clip_y_min, clip_y_max); - } else if (item.get_value) { - std::string value = item.get_value(); - int value_w = font->width(value.c_str()); - Uint32 value_color = selected ? CURSOR_COLOR : VALUE_COLOR; - font->drawClipped(pixel_data, box_x + BOX_W - ITEM_PAD_X - value_w + x_offset, y, value.c_str(), value_color, clip_x_min, clip_x_max, clip_y_min, clip_y_max); - } + const bool SELECTED = (static_cast(i) == page.cursor); + renderOneItem(pixel_data, item, SELECTED, box_x, Y, x_offset, clip_x_min, clip_x_max, clip_y_min, clip_y_max); } } + static auto keybindText(const Item& item, bool this_capturing) -> const char* { + const char* text = nullptr; + if (this_capturing) { + text = Locale::get("menu.values.press_key"); + } else if (item.scancode != nullptr) { + text = SDL_GetScancodeName(*item.scancode); + } else { + text = ""; + } + if ((text == nullptr) || (*text == 0)) { + text = Locale::get("menu.values.unknown"); + } + return text; + } + + static void renderActionItem(Uint32* pixel_data, const Item& item, bool selected, int box_x, int y, int x_offset, int clip_x_min, int clip_x_max, int clip_y_min, int clip_y_max) { + const Uint32 LABEL_COLOR_LOCAL = selected ? CURSOR_COLOR : LABEL_COLOR; + const int LW = font->width(item.label); + const int LX = box_x + ((BOX_W - LW) / 2) + x_offset; + if (selected) { + font->drawClipped(pixel_data, LX - font->width("> "), y, ">", CURSOR_COLOR, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + } + font->drawClipped(pixel_data, LX, y, item.label, LABEL_COLOR_LOCAL, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + } + + static auto keybindColor(bool this_capturing, bool selected) -> Uint32 { + if (this_capturing) { + return 0xFF00FFFF; + } + return selected ? CURSOR_COLOR : VALUE_COLOR; + } + + static void renderItemValue(Uint32* pixel_data, const Item& item, bool selected, int box_x, int y, int x_offset, int clip_x_min, int clip_x_max, int clip_y_min, int clip_y_max) { + if (item.kind == ItemKind::SUBMENU) { + const char* arrow = ">>"; + const int AW = font->width(arrow); + const Uint32 AC = selected ? CURSOR_COLOR : VALUE_COLOR; + font->drawClipped(pixel_data, box_x + BOX_W - ITEM_PAD_X - AW + x_offset, y, arrow, AC, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + return; + } + if (item.kind == ItemKind::KEY_BIND) { + const bool THIS_CAPTURING = (capturing == item.scancode); + const char* text = keybindText(item, THIS_CAPTURING); + const int TW = font->width(text); + const Uint32 TC = keybindColor(THIS_CAPTURING, selected); + font->drawClipped(pixel_data, box_x + BOX_W - ITEM_PAD_X - TW + x_offset, y, text, TC, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + return; + } + if (item.get_value) { + const std::string VALUE = item.get_value(); + const int VALUE_W = font->width(VALUE.c_str()); + const Uint32 VALUE_COLOR_LOCAL = selected ? CURSOR_COLOR : VALUE_COLOR; + font->drawClipped(pixel_data, box_x + BOX_W - ITEM_PAD_X - VALUE_W + x_offset, y, VALUE.c_str(), VALUE_COLOR_LOCAL, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + } + } + + static void renderOneItem(Uint32* pixel_data, const Item& item, bool selected, int box_x, int y, int x_offset, int clip_x_min, int clip_x_max, int clip_y_min, int clip_y_max) { + if (item.kind == ItemKind::ACTION) { + renderActionItem(pixel_data, item, selected, box_x, y, x_offset, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + return; + } + const Uint32 LABEL_COLOR_LOCAL = selected ? CURSOR_COLOR : LABEL_COLOR; + if (selected) { + font->drawClipped(pixel_data, box_x + 4 + x_offset, y, ">", CURSOR_COLOR, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + } + font->drawClipped(pixel_data, box_x + ITEM_PAD_X + x_offset, y, item.label, LABEL_COLOR_LOCAL, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + renderItemValue(pixel_data, item, selected, box_x, y, x_offset, clip_x_min, clip_x_max, clip_y_min, clip_y_max); + } + void render(Uint32* pixel_data) { if (!isVisible() || !font || (pixel_data == nullptr)) { return; diff --git a/source/core/rendering/overlay.cpp b/source/core/rendering/overlay.cpp index 498f9e2..ab52091 100644 --- a/source/core/rendering/overlay.cpp +++ b/source/core/rendering/overlay.cpp @@ -114,258 +114,241 @@ namespace Overlay { } } + static void updateNotifFsm(Notification& notif, float dt) { + switch (notif.status) { + case Status::RISING: + notif.anim += SLIDE_SPEED * dt; + if (notif.anim >= 1.0F) { + notif.anim = 1.0F; + notif.status = Status::STAY; + notif.timer = 0.0F; + } + break; + case Status::STAY: + notif.timer += dt; + if (notif.timer >= notif.duration) { + notif.status = Status::VANISHING; + } + break; + case Status::VANISHING: + notif.anim -= SLIDE_SPEED * dt; + if (notif.anim <= 0.0F) { + notif.status = Status::FINISHED; + } + break; + case Status::FINISHED: + break; + } + } + + static void computeNotifBoxPos(const Notification& notif, int& box_x, int& box_y) { + switch (notif.pos) { + case NotifPosition::TOP_LEFT_SLIDE: + box_x = NOTIF_MARGIN_X - static_cast((1.0F - notif.anim) * (notif.box_w + NOTIF_MARGIN_X)); + box_y = NOTIF_MARGIN_Y; + break; + case NotifPosition::TOP_CENTER_DROP: + box_x = (SCREEN_W - notif.box_w) / 2; + box_y = NOTIF_MARGIN_Y - static_cast((1.0F - notif.anim) * (notif.box_h + NOTIF_MARGIN_Y)); + break; + } + } + + static void drawNotifTextLine(Uint32* pixel_data, const std::string& line, int line_x, int line_y, const Notification& notif) { + if (notif.style == NotifStyle::SHADOW) { + font->draw(pixel_data, line_x + 1, line_y + 1, line.c_str(), notif.accent_color); + } else if (notif.style == NotifStyle::OUTLINE) { + font->draw(pixel_data, line_x, line_y - 1, line.c_str(), notif.accent_color); + font->draw(pixel_data, line_x, line_y + 1, line.c_str(), notif.accent_color); + font->draw(pixel_data, line_x - 1, line_y, line.c_str(), notif.accent_color); + font->draw(pixel_data, line_x + 1, line_y, line.c_str(), notif.accent_color); + } + font->draw(pixel_data, line_x, line_y, line.c_str(), notif.text_color); + } + + static void renderOneNotification(Uint32* pixel_data, const Notification& notif) { + int box_x = 0; + int box_y = 0; + computeNotifBoxPos(notif, box_x, box_y); + if (notif.style == NotifStyle::BOX) { + drawRect(pixel_data, box_x, box_y, notif.box_w, notif.box_h, notif.accent_color); + } + const int LINE_H = font->charHeight(); + int line_y = box_y + NOTIF_PADDING_V; + for (const auto& line : notif.lines) { + const int LINE_W = font->width(line.c_str()); + const int LINE_X = box_x + ((notif.box_w - LINE_W) / 2); + drawNotifTextLine(pixel_data, line, LINE_X, line_y, notif); + line_y += LINE_H + 1; + } + } + + static void updateRenderInfoFsm(float dt) { + const auto DESIRED = Options::render_info.position; + if (DESIRED == info_visible_pos) { + if (info_anim < 1.0F) { + info_anim = std::min(info_anim + (INFO_SLIDE_SPEED * dt), 1.0F); + } + } else if (info_visible_pos == Options::RenderInfoPosition::OFF) { + info_visible_pos = DESIRED; + info_anim = 0.0F; + } else { + info_anim -= INFO_SLIDE_SPEED * dt; + if (info_anim <= 0.0F) { + info_anim = 0.0F; + info_visible_pos = DESIRED; + } + } + for (auto& seg : info_segments) { + const float TARGET = seg.visible ? 1.0F : 0.0F; + if (seg.anim < TARGET) { + seg.anim = std::min(seg.anim + (SEG_SPEED * dt), TARGET); + } else if (seg.anim > TARGET) { + seg.anim = std::max(seg.anim - (SEG_SPEED * dt), TARGET); + } + } + } + + static auto computeInfoTotalWidth(int digit_cell) -> float { + float total_w = 0.0F; + for (const auto& seg : info_segments) { + if (seg.anim > 0.0F && !seg.text.empty()) { + const int W = seg.mono_digits + ? font->widthMonoDigits(seg.text.c_str(), digit_cell) + : font->width(seg.text.c_str()); + total_w += static_cast(W) * Easing::outQuad(seg.anim); + } + } + return total_w; + } + + static void drawInfoSegment(Uint32* pixel_data, const InfoSegment& seg, int xi, int info_y, int digit_cell) { + if (seg.mono_digits) { + font->drawMonoDigits(pixel_data, xi + 1, info_y + 1, seg.text.c_str(), Options::render_info.shadow_color, digit_cell); + font->drawMonoDigits(pixel_data, xi, info_y, seg.text.c_str(), Options::render_info.text_color, digit_cell); + } else { + font->draw(pixel_data, xi + 1, info_y + 1, seg.text.c_str(), Options::render_info.shadow_color); + font->draw(pixel_data, xi, info_y, seg.text.c_str(), Options::render_info.text_color); + } + } + + static void renderRenderInfo(Uint32* pixel_data) { + if (info_visible_pos == Options::RenderInfoPosition::OFF || info_anim <= 0.0F) { + return; + } + const int DIGIT_CELL = font->charBoxWidth() - 1; + const float TOTAL_W = computeInfoTotalWidth(DIGIT_CELL); + if (TOTAL_W <= 0.0F) { + return; + } + const float EASED_Y = Easing::outQuad(info_anim); + const int CH = font->charHeight(); + const int FINAL_Y = (info_visible_pos == Options::RenderInfoPosition::TOP) ? 1 : SCREEN_H - CH - 1; + const int START_Y = (info_visible_pos == Options::RenderInfoPosition::TOP) ? -CH - 1 : SCREEN_H; + const int INFO_Y = START_Y + static_cast(static_cast(FINAL_Y - START_Y) * EASED_Y); + float cur_x = (SCREEN_W - TOTAL_W) / 2.0F; + for (const auto& seg : info_segments) { + if (seg.anim <= 0.01F || seg.text.empty()) { + continue; + } + const int XI = static_cast(cur_x); + const int SEG_W = seg.mono_digits + ? font->widthMonoDigits(seg.text.c_str(), DIGIT_CELL) + : font->width(seg.text.c_str()); + drawInfoSegment(pixel_data, seg, XI, INFO_Y, DIGIT_CELL); + cur_x += static_cast(SEG_W) * Easing::outQuad(seg.anim); + } + } + + static void renderPauseIndicator(Uint32* pixel_data) { + if ((Director::get() == nullptr) || !Director::get()->isPaused()) { + return; + } + const char* pause_text = Locale::get("notifications.pause"); + const int W = font->width(pause_text); + const int X = SCREEN_W - W - 4; + const int Y = 4; + font->draw(pixel_data, X, Y - 1, pause_text, 0xFFFFFFFF); + font->draw(pixel_data, X, Y + 1, pause_text, 0xFFFFFFFF); + font->draw(pixel_data, X - 1, Y, pause_text, 0xFFFFFFFF); + font->draw(pixel_data, X + 1, Y, pause_text, 0xFFFFFFFF); + font->draw(pixel_data, X, Y, pause_text, 0xFF0000FF); + } + + static void emitCreditsLines(const char* role_key, const char* name_key) { + showNotification( + {std::string(Locale::get(role_key)), std::string(Locale::get(name_key))}, + CREDITS_HOLD, + NotifPosition::TOP_CENTER_DROP, + NotifStyle::OUTLINE, + CREDITS_BG, + CREDITS_FG); + } + + static void advanceCredits(float dt) { + if (credits_phase == CreditsPhase::IDLE) { + return; + } + credits_timer += dt; + switch (credits_phase) { + case CreditsPhase::DELAY: + if (credits_timer >= CREDITS_DELAY) { + emitCreditsLines("credits.port_role", "credits.port_name"); + credits_phase = CreditsPhase::PLAYING_1; + credits_timer = 0.0F; + } + break; + case CreditsPhase::PLAYING_1: + if (notifications.empty()) { + credits_phase = CreditsPhase::GAP; + credits_timer = 0.0F; + } + break; + case CreditsPhase::GAP: + if (credits_timer >= CREDITS_GAP) { + emitCreditsLines("credits.modern_role", "credits.modern_name"); + credits_phase = CreditsPhase::PLAYING_2; + credits_timer = 0.0F; + } + break; + case CreditsPhase::PLAYING_2: + if (notifications.empty()) { + credits_phase = CreditsPhase::IDLE; + credits_timer = 0.0F; + } + break; + case CreditsPhase::IDLE: + break; + } + } + void render(Uint32* pixel_data) { if (!font || (pixel_data == nullptr)) { return; } + const Uint32 NOW = SDL_GetTicks(); + const float DT = static_cast(NOW - last_ticks) / 1000.0F; + last_ticks = NOW; - // Calcula delta time - Uint32 now = SDL_GetTicks(); - float dt = static_cast(now - last_ticks) / 1000.0F; - last_ticks = now; - - // Actualitza i pinta cada notificació for (auto& notif : notifications) { - switch (notif.status) { - case Status::RISING: - notif.anim += SLIDE_SPEED * dt; - if (notif.anim >= 1.0F) { - notif.anim = 1.0F; - notif.status = Status::STAY; - notif.timer = 0.0F; - } - break; - - case Status::STAY: - notif.timer += dt; - if (notif.timer >= notif.duration) { - notif.status = Status::VANISHING; - } - break; - - case Status::VANISHING: - notif.anim -= SLIDE_SPEED * dt; - if (notif.anim <= 0.0F) { - notif.status = Status::FINISHED; - } - break; - - case Status::FINISHED: - break; - } - - if (notif.status == Status::FINISHED) { - continue; - } - - // Posició segons el tipus - int box_x = 0; - int box_y = 0; - switch (notif.pos) { - case NotifPosition::TOP_LEFT_SLIDE: { - int target_x = NOTIF_MARGIN_X; - int target_y = NOTIF_MARGIN_Y; - box_x = target_x - static_cast((1.0F - notif.anim) * (notif.box_w + NOTIF_MARGIN_X)); - box_y = target_y; - break; - } - case NotifPosition::TOP_CENTER_DROP: { - int target_y = NOTIF_MARGIN_Y; - box_x = (SCREEN_W - notif.box_w) / 2; - // Baixa des de sobre de la pantalla fins a target_y - box_y = target_y - static_cast((1.0F - notif.anim) * (notif.box_h + NOTIF_MARGIN_Y)); - break; - } - } - - // Pinta fons (si BOX) - if (notif.style == NotifStyle::BOX) { - drawRect(pixel_data, box_x, box_y, notif.box_w, notif.box_h, notif.accent_color); - } - - // Pinta el text línia a línia (amb ombra o contorn segons style) - int line_h = font->charHeight(); - int line_y = box_y + NOTIF_PADDING_V; - for (const auto& line : notif.lines) { - int line_w = font->width(line.c_str()); - int line_x = box_x + ((notif.box_w - line_w) / 2); // centrat dins la caixa - if (notif.style == NotifStyle::SHADOW) { - font->draw(pixel_data, line_x + 1, line_y + 1, line.c_str(), notif.accent_color); - } else if (notif.style == NotifStyle::OUTLINE) { - // Contorn 4-direccional (N, S, E, W) - font->draw(pixel_data, line_x, line_y - 1, line.c_str(), notif.accent_color); - font->draw(pixel_data, line_x, line_y + 1, line.c_str(), notif.accent_color); - font->draw(pixel_data, line_x - 1, line_y, line.c_str(), notif.accent_color); - font->draw(pixel_data, line_x + 1, line_y, line.c_str(), notif.accent_color); - } - font->draw(pixel_data, line_x, line_y, line.c_str(), notif.text_color); - line_y += line_h + 1; + updateNotifFsm(notif, DT); + if (notif.status != Status::FINISHED) { + renderOneNotification(pixel_data, notif); } } - // Render info (FPS, driver, shader) — animat amb slide vertical - // State machine: visible_pos s'actualitza cap a DESIRED quan anim arriba a 0 - { - const auto DESIRED = Options::render_info.position; - if (DESIRED == info_visible_pos) { - // Mateix lloc: entra fins a 1 - if (info_anim < 1.0F) { - info_anim += INFO_SLIDE_SPEED * dt; - info_anim = std::min(info_anim, 1.0F); - } - } else { - // Canvi: si visible_pos està OFF, commuta directament - if (info_visible_pos == Options::RenderInfoPosition::OFF) { - info_visible_pos = DESIRED; - info_anim = 0.0F; - } else { - // Ix del lloc actual - info_anim -= INFO_SLIDE_SPEED * dt; - if (info_anim <= 0.0F) { - info_anim = 0.0F; - info_visible_pos = DESIRED; - } - } - } + updateRenderInfoFsm(DT); + renderRenderInfo(pixel_data); - // Actualitza animacions individuals dels segments - for (auto& seg : info_segments) { - float target = seg.visible ? 1.0F : 0.0F; - if (seg.anim < target) { - seg.anim += SEG_SPEED * dt; - seg.anim = std::min(seg.anim, target); - } else if (seg.anim > target) { - seg.anim -= SEG_SPEED * dt; - seg.anim = std::max(seg.anim, target); - } - } - - // Render si hi ha alguna cosa visible - if (info_visible_pos != Options::RenderInfoPosition::OFF && info_anim > 0.0F) { - const int DIGIT_CELL = font->charBoxWidth() - 1; // amplada uniforme per dígit - - // Calcula amplada total interpolant cada segment per la seva anim - float total_w = 0.0F; - for (const auto& seg : info_segments) { - if (seg.anim > 0.0F && !seg.text.empty()) { - int w = seg.mono_digits - ? font->widthMonoDigits(seg.text.c_str(), DIGIT_CELL) - : font->width(seg.text.c_str()); - total_w += w * Easing::outQuad(seg.anim); - } - } - if (total_w > 0.0F) { - float eased_y = Easing::outQuad(info_anim); - int ch = font->charHeight(); - int final_y; - int start_y; - if (info_visible_pos == Options::RenderInfoPosition::TOP) { - final_y = 1; - start_y = -ch - 1; - } else { - final_y = SCREEN_H - ch - 1; - start_y = SCREEN_H; - } - int info_y = start_y + static_cast((final_y - start_y) * eased_y); - - // Dibuixa cada segment en la seva posició x acumulada - float cur_x = (SCREEN_W - total_w) / 2.0F; - for (const auto& seg : info_segments) { - if (seg.anim > 0.01F && !seg.text.empty()) { - int xi = static_cast(cur_x); - int seg_w = seg.mono_digits - ? font->widthMonoDigits(seg.text.c_str(), DIGIT_CELL) - : font->width(seg.text.c_str()); - if (seg.mono_digits) { - font->drawMonoDigits(pixel_data, xi + 1, info_y + 1, seg.text.c_str(), Options::render_info.shadow_color, DIGIT_CELL); - font->drawMonoDigits(pixel_data, xi, info_y, seg.text.c_str(), Options::render_info.text_color, DIGIT_CELL); - } else { - font->draw(pixel_data, xi + 1, info_y + 1, seg.text.c_str(), Options::render_info.shadow_color); - font->draw(pixel_data, xi, info_y, seg.text.c_str(), Options::render_info.text_color); - } - cur_x += seg_w * Easing::outQuad(seg.anim); - } - } - } - } - } - - // Elimina les acabades std::erase_if(notifications, [](const Notification& n) { return n.status == Status::FINISHED; }); - - // Si la notificació d'ESC ha desaparegut, reseteja l'estat if (esc_waiting && notifications.empty()) { esc_waiting = false; } - // Indicador de pausa persistent (cantó superior dret) - if ((Director::get() != nullptr) && Director::get()->isPaused()) { - const char* pause_text = Locale::get("notifications.pause"); - int w = font->width(pause_text); - int x = SCREEN_W - w - 4; - int y = 4; - // Contorn blanc 4-direccional - font->draw(pixel_data, x, y - 1, pause_text, 0xFFFFFFFF); - font->draw(pixel_data, x, y + 1, pause_text, 0xFFFFFFFF); - font->draw(pixel_data, x - 1, y, pause_text, 0xFFFFFFFF); - font->draw(pixel_data, x + 1, y, pause_text, 0xFFFFFFFF); - // Text en roig - font->draw(pixel_data, x, y, pause_text, 0xFF0000FF); - } + renderPauseIndicator(pixel_data); + advanceCredits(DT); - // Crèdits seqüencials — dispara notificacions TOP_CENTER_DROP una darrere l'altra. - if (credits_phase != CreditsPhase::IDLE) { - credits_timer += dt; - switch (credits_phase) { - case CreditsPhase::DELAY: - if (credits_timer >= CREDITS_DELAY) { - showNotification( - {std::string(Locale::get("credits.port_role")), - std::string(Locale::get("credits.port_name"))}, - CREDITS_HOLD, - NotifPosition::TOP_CENTER_DROP, - NotifStyle::OUTLINE, - CREDITS_BG, - CREDITS_FG); - credits_phase = CreditsPhase::PLAYING_1; - credits_timer = 0.0F; - } - break; - case CreditsPhase::PLAYING_1: - if (notifications.empty()) { - credits_phase = CreditsPhase::GAP; - credits_timer = 0.0F; - } - break; - case CreditsPhase::GAP: - if (credits_timer >= CREDITS_GAP) { - showNotification( - {std::string(Locale::get("credits.modern_role")), - std::string(Locale::get("credits.modern_name"))}, - CREDITS_HOLD, - NotifPosition::TOP_CENTER_DROP, - NotifStyle::OUTLINE, - CREDITS_BG, - CREDITS_FG); - credits_phase = CreditsPhase::PLAYING_2; - credits_timer = 0.0F; - } - break; - case CreditsPhase::PLAYING_2: - if (notifications.empty()) { - credits_phase = CreditsPhase::IDLE; - credits_timer = 0.0F; - } - break; - case CreditsPhase::IDLE: - break; - } - } - - // Neteja notificacions finalitzades std::erase_if(notifications, [](const Notification& n) { return n.status == Status::FINISHED; }); - - // Menú flotant per damunt de tot (isVisible inclou l'animació de tancament) if (Menu::isVisible()) { Menu::render(pixel_data); } diff --git a/source/core/rendering/text.cpp b/source/core/rendering/text.cpp index 686714c..1de8968 100644 --- a/source/core/rendering/text.cpp +++ b/source/core/rendering/text.cpp @@ -1,5 +1,6 @@ #include "core/rendering/text.hpp" +#include #include #include #include @@ -158,60 +159,57 @@ void Text::loadBitmap(const char* gif_file) { // --- Renderitzat --- +auto Text::resolveGlyph(uint32_t cp) const -> const GlyphInfo* { + auto it = glyphs_.find(cp); + if (it != glyphs_.end()) { + return &it->second; + } + it = glyphs_.find('?'); + return (it != glyphs_.end()) ? &it->second : nullptr; +} + +void Text::blitGlyph(Uint32* pixel_data, int dst_x, int dst_y, const GlyphInfo& glyph, Uint32 color, int clip_x_min, int clip_x_max, int clip_y_min, int clip_y_max) const { + const int GY_START = std::max(0, clip_y_min - dst_y); + const int GY_END = std::min(box_height_, clip_y_max - dst_y); + const int GX_START = std::max(0, clip_x_min - dst_x); + const int GX_END = std::min(glyph.w, clip_x_max - dst_x); + for (int gy = GY_START; gy < GY_END; gy++) { + const int SRC_Y = glyph.y + gy; + if (SRC_Y >= bitmap_height_) { + continue; + } + const int DST_ROW = dst_y + gy; + for (int gx = GX_START; gx < GX_END; gx++) { + const int SRC_X = glyph.x + gx; + if (SRC_X >= bitmap_width_) { + continue; + } + const Uint8 PIXEL = bitmap_[SRC_X + (SRC_Y * bitmap_width_)]; + if (PIXEL != 0) { + pixel_data[(dst_x + gx) + (DST_ROW * SCREEN_WIDTH)] = color; + } + } + } +} + void Text::draw(Uint32* pixel_data, int x, int y, const char* text, Uint32 color) const { if (bitmap_.empty() || (pixel_data == nullptr)) { return; } - const char* ptr = text; int cursor_x = x; - while (*ptr != 0) { uint32_t cp = nextCodepoint(ptr); if (cp == 0) { break; } - - auto it = glyphs_.find(cp); - if (it == glyphs_.end()) { - it = glyphs_.find('?'); - if (it == glyphs_.end()) { - cursor_x += box_width_; - continue; - } + const GlyphInfo* glyph = resolveGlyph(cp); + if (glyph == nullptr) { + cursor_x += box_width_; + continue; } - - const auto& glyph = it->second; - - // Pinta glifo pixel a pixel - for (int gy = 0; gy < box_height_; gy++) { - int dst_y = y + gy; - if (dst_y < 0 || dst_y >= SCREEN_HEIGHT) { - continue; - } - - for (int gx = 0; gx < glyph.w; gx++) { - int dst_x = cursor_x + gx; - if (dst_x < 0 || dst_x >= SCREEN_WIDTH) { - continue; - } - - int src_x = glyph.x + gx; - int src_y = glyph.y + gy; - - if (src_x >= bitmap_width_ || src_y >= bitmap_height_) { - continue; - } - - Uint8 pixel = bitmap_[src_x + (src_y * bitmap_width_)]; - // Píxel no transparent (índex 0 és fons típicament) - if (pixel != 0) { - pixel_data[dst_x + (dst_y * SCREEN_WIDTH)] = color; - } - } - } - - cursor_x += glyph.w + 1; // +1 kerning + blitGlyph(pixel_data, cursor_x, y, *glyph, color, 0, SCREEN_WIDTH, 0, SCREEN_HEIGHT); + cursor_x += glyph->w + 1; } } @@ -225,70 +223,29 @@ void Text::drawClipped(Uint32* pixel_data, int x, int y, const char* text, Uint3 if (bitmap_.empty() || (pixel_data == nullptr)) { return; } - - // Descart ràpid si el glifo sencer cau fora verticalment if (y + box_height_ <= clip_y_min || y >= clip_y_max) { return; } - + const int X_MIN = std::max(0, clip_x_min); + const int X_MAX = std::min(SCREEN_WIDTH, clip_x_max); + const int Y_MIN = std::max(0, clip_y_min); + const int Y_MAX = std::min(SCREEN_HEIGHT, clip_y_max); const char* ptr = text; int cursor_x = x; - while (*ptr != 0) { uint32_t cp = nextCodepoint(ptr); if (cp == 0) { break; } - - auto it = glyphs_.find(cp); - if (it == glyphs_.end()) { - it = glyphs_.find('?'); - if (it == glyphs_.end()) { - cursor_x += box_width_; - continue; - } - } - - const auto& glyph = it->second; - - // Si el glifo està completament fora del clip horitzontal, salta - if (cursor_x + glyph.w <= clip_x_min || cursor_x >= clip_x_max) { - cursor_x += glyph.w + 1; + const GlyphInfo* glyph = resolveGlyph(cp); + if (glyph == nullptr) { + cursor_x += box_width_; continue; } - - for (int gy = 0; gy < box_height_; gy++) { - int dst_y = y + gy; - if (dst_y < 0 || dst_y >= SCREEN_HEIGHT) { - continue; - } - if (dst_y < clip_y_min || dst_y >= clip_y_max) { - continue; - } - - for (int gx = 0; gx < glyph.w; gx++) { - int dst_x = cursor_x + gx; - if (dst_x < 0 || dst_x >= SCREEN_WIDTH) { - continue; - } - if (dst_x < clip_x_min || dst_x >= clip_x_max) { - continue; - } - - int src_x = glyph.x + gx; - int src_y = glyph.y + gy; - if (src_x >= bitmap_width_ || src_y >= bitmap_height_) { - continue; - } - - Uint8 pixel = bitmap_[src_x + (src_y * bitmap_width_)]; - if (pixel != 0) { - pixel_data[dst_x + (dst_y * SCREEN_WIDTH)] = color; - } - } + if (cursor_x + glyph->w > X_MIN && cursor_x < X_MAX) { + blitGlyph(pixel_data, cursor_x, y, *glyph, color, X_MIN, X_MAX, Y_MIN, Y_MAX); } - - cursor_x += glyph.w + 1; + cursor_x += glyph->w + 1; } } @@ -296,54 +253,20 @@ void Text::drawMono(Uint32* pixel_data, int x, int y, const char* text, Uint32 c if (bitmap_.empty() || (pixel_data == nullptr)) { return; } - const char* ptr = text; int cursor_x = x; - while (*ptr != 0) { uint32_t cp = nextCodepoint(ptr); if (cp == 0) { break; } - - auto it = glyphs_.find(cp); - if (it == glyphs_.end()) { - it = glyphs_.find('?'); - if (it == glyphs_.end()) { - cursor_x += cell_w; - continue; - } + const GlyphInfo* glyph = resolveGlyph(cp); + if (glyph == nullptr) { + cursor_x += cell_w; + continue; } - - const auto& glyph = it->second; - // Centra el glif dins la cel·la - int glyph_x = cursor_x + ((cell_w - glyph.w) / 2); - - for (int gy = 0; gy < box_height_; gy++) { - int dst_y = y + gy; - if (dst_y < 0 || dst_y >= SCREEN_HEIGHT) { - continue; - } - - for (int gx = 0; gx < glyph.w; gx++) { - int dst_x = glyph_x + gx; - if (dst_x < 0 || dst_x >= SCREEN_WIDTH) { - continue; - } - - int src_x = glyph.x + gx; - int src_y = glyph.y + gy; - if (src_x >= bitmap_width_ || src_y >= bitmap_height_) { - continue; - } - - Uint8 pixel = bitmap_[src_x + (src_y * bitmap_width_)]; - if (pixel != 0) { - pixel_data[dst_x + (dst_y * SCREEN_WIDTH)] = color; - } - } - } - + const int GLYPH_X = cursor_x + ((cell_w - glyph->w) / 2); + blitGlyph(pixel_data, GLYPH_X, y, *glyph, color, 0, SCREEN_WIDTH, 0, SCREEN_HEIGHT); cursor_x += cell_w; } } @@ -352,62 +275,27 @@ void Text::drawMonoDigits(Uint32* pixel_data, int x, int y, const char* text, Ui if (bitmap_.empty() || (pixel_data == nullptr)) { return; } - const char* ptr = text; int cursor_x = x; bool first = true; - while (*ptr != 0) { uint32_t cp = nextCodepoint(ptr); if (cp == 0) { break; } - - auto it = glyphs_.find(cp); - if (it == glyphs_.end()) { - it = glyphs_.find('?'); - if (it == glyphs_.end()) { - if (!first) { - cursor_x += 1; - } - cursor_x += box_width_; - first = false; - continue; - } - } - - const auto& glyph = it->second; - bool is_digit = (cp >= '0' && cp <= '9'); - if (!first) { cursor_x += 1; // kerning } - - int glyph_x = is_digit ? cursor_x + ((digit_cell_w - glyph.w) / 2) : cursor_x; - - for (int gy = 0; gy < box_height_; gy++) { - int dst_y = y + gy; - if (dst_y < 0 || dst_y >= SCREEN_HEIGHT) { - continue; - } - for (int gx = 0; gx < glyph.w; gx++) { - int dst_x = glyph_x + gx; - if (dst_x < 0 || dst_x >= SCREEN_WIDTH) { - continue; - } - int src_x = glyph.x + gx; - int src_y = glyph.y + gy; - if (src_x >= bitmap_width_ || src_y >= bitmap_height_) { - continue; - } - Uint8 pixel = bitmap_[src_x + (src_y * bitmap_width_)]; - if (pixel != 0) { - pixel_data[dst_x + (dst_y * SCREEN_WIDTH)] = color; - } - } + const GlyphInfo* glyph = resolveGlyph(cp); + if (glyph == nullptr) { + cursor_x += box_width_; + first = false; + continue; } - - cursor_x += is_digit ? digit_cell_w : glyph.w; + const bool IS_DIGIT = (cp >= '0' && cp <= '9'); + const int GLYPH_X = IS_DIGIT ? cursor_x + ((digit_cell_w - glyph->w) / 2) : cursor_x; + blitGlyph(pixel_data, GLYPH_X, y, *glyph, color, 0, SCREEN_WIDTH, 0, SCREEN_HEIGHT); + cursor_x += IS_DIGIT ? digit_cell_w : glyph->w; first = false; } } diff --git a/source/core/rendering/text.hpp b/source/core/rendering/text.hpp index 1c9c653..3d52f79 100644 --- a/source/core/rendering/text.hpp +++ b/source/core/rendering/text.hpp @@ -57,6 +57,13 @@ class Text { void loadFont(const char* fnt_file); void loadBitmap(const char* gif_file); + // Resolt un codepoint al GlyphInfo corresponent o al fallback '?'. + // Retorna nullptr si ni el codepoint ni el fallback existeixen. + [[nodiscard]] auto resolveGlyph(uint32_t cp) const -> const GlyphInfo*; + // Pinta un glif a (dst_x, dst_y) amb clipping per finestra. + // Si la finestra és tota la pantalla, passar clip_x_min=0, clip_x_max=SCREEN_WIDTH, idem y. + void blitGlyph(Uint32* pixel_data, int dst_x, int dst_y, const GlyphInfo& glyph, Uint32 color, int clip_x_min, int clip_x_max, int clip_y_min, int clip_y_max) const; + static constexpr int SCREEN_WIDTH = 320; static constexpr int SCREEN_HEIGHT = 200; }; diff --git a/source/core/resources/resource_cache.cpp b/source/core/resources/resource_cache.cpp index d058808..48b05ac 100644 --- a/source/core/resources/resource_cache.cpp +++ b/source/core/resources/resource_cache.cpp @@ -105,6 +105,36 @@ namespace Resource { std::cout << "Resource::Cache: precarregant " << total_count_ << " assets\n"; } + void Cache::stepEachInList(List::Type type, const std::function& clear_fn, LoadStage next, const std::function& load_fn) { + auto items = List::get()->getListByType(type); + if (stage_index_ == 0) { + clear_fn(); + } + if (stage_index_ >= items.size()) { + stage_ = next; + stage_index_ = 0; + return; + } + load_fn(stage_index_++); + } + + void Cache::stepTextFiles() { + auto data_items = List::get()->getListByType(List::Type::DATA); + auto font_items = List::get()->getListByType(List::Type::FONT); + auto items = data_items; + items.insert(items.end(), font_items.begin(), font_items.end()); + if (stage_index_ == 0) { + text_files_.clear(); + } + if (stage_index_ >= items.size()) { + stage_ = LoadStage::DONE; + stage_index_ = 0; + std::cout << "Resource::Cache: precarrega completada (" << loaded_count_ << "/" << total_count_ << ")\n"; + return; + } + loadOneTextFile(stage_index_++); + } + auto Cache::loadStep(int budget_ms) -> bool { if (stage_ == LoadStage::DONE) { return true; @@ -112,66 +142,21 @@ namespace Resource { const Uint64 START_NS = SDL_GetTicksNS(); const Uint64 BUDGET_NS = static_cast(budget_ms) * 1'000'000ULL; - const auto* list = List::get(); while (stage_ != LoadStage::DONE) { switch (stage_) { - case LoadStage::MUSICS: { - auto items = list->getListByType(List::Type::MUSIC); - if (stage_index_ == 0) { - musics_.clear(); - } - if (stage_index_ >= items.size()) { - stage_ = LoadStage::SOUNDS; - stage_index_ = 0; - break; - } - loadOneMusic(stage_index_++); + case LoadStage::MUSICS: + stepEachInList(List::Type::MUSIC, [this] { musics_.clear(); }, LoadStage::SOUNDS, [this](size_t i) { loadOneMusic(i); }); break; - } - case LoadStage::SOUNDS: { - auto items = list->getListByType(List::Type::SOUND); - if (stage_index_ == 0) { - sounds_.clear(); - } - if (stage_index_ >= items.size()) { - stage_ = LoadStage::BITMAPS; - stage_index_ = 0; - break; - } - loadOneSound(stage_index_++); + case LoadStage::SOUNDS: + stepEachInList(List::Type::SOUND, [this] { sounds_.clear(); }, LoadStage::BITMAPS, [this](size_t i) { loadOneSound(i); }); break; - } - case LoadStage::BITMAPS: { - auto items = list->getListByType(List::Type::BITMAP); - if (stage_index_ == 0) { - surfaces_.clear(); - } - if (stage_index_ >= items.size()) { - stage_ = LoadStage::TEXT_FILES; - stage_index_ = 0; - break; - } - loadOneBitmap(stage_index_++); + case LoadStage::BITMAPS: + stepEachInList(List::Type::BITMAP, [this] { surfaces_.clear(); }, LoadStage::TEXT_FILES, [this](size_t i) { loadOneBitmap(i); }); break; - } - case LoadStage::TEXT_FILES: { - auto data_items = list->getListByType(List::Type::DATA); - auto font_items = list->getListByType(List::Type::FONT); - auto items = data_items; - items.insert(items.end(), font_items.begin(), font_items.end()); - if (stage_index_ == 0) { - text_files_.clear(); - } - if (stage_index_ >= items.size()) { - stage_ = LoadStage::DONE; - stage_index_ = 0; - std::cout << "Resource::Cache: precarrega completada (" << loaded_count_ << "/" << total_count_ << ")\n"; - break; - } - loadOneTextFile(stage_index_++); + case LoadStage::TEXT_FILES: + stepTextFiles(); break; - } case LoadStage::DONE: break; } diff --git a/source/core/resources/resource_cache.hpp b/source/core/resources/resource_cache.hpp index 28f1a80..78d90a7 100644 --- a/source/core/resources/resource_cache.hpp +++ b/source/core/resources/resource_cache.hpp @@ -4,10 +4,12 @@ #include #include +#include #include #include #include +#include "core/resources/resource_list.hpp" #include "core/resources/resource_types.hpp" namespace Resource { @@ -56,6 +58,8 @@ namespace Resource { void loadOneSound(size_t index); void loadOneBitmap(size_t index); void loadOneTextFile(size_t index); + void stepEachInList(List::Type type, const std::function& clear_fn, LoadStage next, const std::function& load_fn); + void stepTextFiles(); std::vector musics_; std::vector sounds_; diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index fda83ee..5b021b6 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -136,120 +136,100 @@ void Director::setup() { has_frame_ = false; } +void Director::applyRestart() { + restart_requested_ = false; + Audio::get()->stopMusic(); + Audio::get()->stopAllSounds(); + initGameContext(); + Info::ctx.num_piramide = 255; + current_scene_.reset(); + game_state_ = 1; + has_frame_ = false; + Menu::close(); + Ji::setInputBlocked(false); +} + +void Director::maybeStartTitleCredits() { + static bool credits_triggered_ = false; + if (credits_triggered_ || Info::ctx.num_piramide != 0) { + return; + } + if (Options::game.show_title_credits) { + Overlay::startCredits(); + } + credits_triggered_ = true; +} + +auto Director::tickActiveScene() -> bool { + if (current_scene_ && (current_scene_->done() || Jg::quitting())) { + game_state_ = current_scene_->nextState(); + current_scene_.reset(); + } + if (!current_scene_) { + if (game_state_ == -1 || Jg::quitting()) { + return false; + } + current_scene_ = createNextScene(); + if (!current_scene_) { + return false; + } + current_scene_->onEnter(); + last_tick_ms_ = SDL_GetTicks(); + } + + Ji::update(); + const Uint32 NOW = SDL_GetTicks(); + const int DELTA_MS = static_cast(NOW - last_tick_ms_); + last_tick_ms_ = NOW; + current_scene_->tick(DELTA_MS); + + Jd8::flip(); + std::memcpy(game_frame_, Jd8::getFramebuffer(), sizeof(game_frame_)); + has_frame_ = true; + return true; +} + auto Director::iterate() -> bool { if (quit_requested_) { Jg::quitSignal(); - current_scene_.reset(); // destrueix l'escena actual ordenadament + current_scene_.reset(); return false; } - - // Reinici "suau": processat al començament del frame per no manipular - // l'escena des d'una lambda del menú mentre encara s'està executant. if (restart_requested_) { - restart_requested_ = false; - Audio::get()->stopMusic(); - Audio::get()->stopAllSounds(); - // Reinicialitza Info::ctx des d'Options (vides, diners, diamants...) - // en lloc de ctx.reset() pla que deixaria vida=0 → jugador mort. - initGameContext(); - // Força l'intro independentment de `piramide_inicial` (que pot estar - // configurat a una piràmide intermèdia per a proves ràpides). - Info::ctx.num_piramide = 255; - current_scene_.reset(); - game_state_ = 1; // 1 = dispatch via SceneRegistry per num_piramide - has_frame_ = false; - Menu::close(); - Ji::setInputBlocked(false); // el menú ho havia bloquejat — cal desfer-ho + applyRestart(); } - if (!context_initialized_) { initGameContext(); context_initialized_ = true; } - constexpr Uint32 FRAME_MS_VSYNC = 16; // ~60 FPS amb VSync - constexpr Uint32 FRAME_MS_NO_VSYNC = 4; // ~250 FPS sense VSync (límit superior) - + constexpr Uint32 FRAME_MS_VSYNC = 16; + constexpr Uint32 FRAME_MS_NO_VSYNC = 4; const Uint32 FRAME_START = SDL_GetTicks(); Gamepad::update(); KeyRemap::update(); GlobalInputs::handle(); Mouse::updateCursorVisibility(); - - // Bombeig de l'àudio: reomple l'stream de música i para els canals - // drenats. Substituïx el callback de SDL_AddTimer de la versió - // antiga — imprescindible per al port a emscripten. Audio::update(); - // Dispara els crèdits cinematogràfics la primera vegada que el joc - // arriba al menú del títol (Info::ctx.num_piramide == 0). - static bool credits_triggered_ = false; - if (!credits_triggered_ && Info::ctx.num_piramide == 0) { - if (Options::game.show_title_credits) { - Overlay::startCredits(); - } - credits_triggered_ = true; - } + maybeStartTitleCredits(); - // Si l'overlay ja no bloqueja ESC (timeout), desbloquegem if (esc_blocked_ && !Overlay::isEscConsumed()) { esc_blocked_ = false; } - // Avança l'escena (si no estem pausats). En pausa, es manté l'escena - // congelada i re-presentem l'últim frame amb l'overlay fresc per - // damunt. if (!paused_) { - // Transicions: si l'escena actual ha acabat (o s'ha senyalat - // quit), llegim el seu next state i la destruïm per crear la - // següent a continuació. - if (current_scene_ && (current_scene_->done() || Jg::quitting())) { - game_state_ = current_scene_->nextState(); - current_scene_.reset(); + if (!tickActiveScene()) { + return false; } - - // Si no hi ha escena activa, construeix la pròxima segons - // game_state_ i Info::ctx. Si és impossible (game_state_ == -1, - // quit, o state no registrat), eixim del loop. - if (!current_scene_) { - if (game_state_ == -1 || Jg::quitting()) { - return false; - } - current_scene_ = createNextScene(); - if (!current_scene_) { - return false; - } - current_scene_->onEnter(); - last_tick_ms_ = SDL_GetTicks(); - } - - // Tick de l'escena. Ji::update refresca key_pressed/any_key; el - // DELTA_MS és el temps real transcorregut des de l'últim tick. - Ji::update(); - const Uint32 NOW = SDL_GetTicks(); - const int DELTA_MS = static_cast(NOW - last_tick_ms_); - last_tick_ms_ = NOW; - current_scene_->tick(DELTA_MS); - - // Converteix `screen` indexat → `pixel_data` ARGB amb la paleta - // actual. Jd8::flip ja no fa yield (Phase B.2 eliminà els fibers); - // ara només omple el framebuffer perquè el Director l'aprofite. - Jd8::flip(); - std::memcpy(game_frame_, Jd8::getFramebuffer(), sizeof(game_frame_)); - has_frame_ = true; } - // Presenta sempre: parteix del frame net del joc, afegeix overlay i envia if (has_frame_) { std::memcpy(presentation_buffer_, game_frame_, sizeof(presentation_buffer_)); Screen::get()->present(presentation_buffer_); } - // Límit de framerate segons VSync. - // Nota: quan el runtime posseïx el main loop (SDL_AppIterate / - // emscripten), aquest SDL_Delay no és ideal. Fase 7 afegirà un mode - // que es basa en el timing intern de SDL en lloc del delay explícit. const Uint32 TARGET_MS = Options::video.vsync ? FRAME_MS_VSYNC : FRAME_MS_NO_VSYNC; const Uint32 ELAPSED = SDL_GetTicks() - FRAME_START; if (ELAPSED < TARGET_MS) { @@ -285,107 +265,97 @@ void Director::pollAllEvents() { } } -void Director::handleEvent(const SDL_Event& event) { - if (event.type == SDL_EVENT_QUIT) { - Jg::quitSignal(); - requestQuit(); - } - // Hot-plug de gamepad (a Emscripten els dispositius web entren com - // JOYSTICK_ADDED/REMOVED perquè SDL no reconeix el GUID) - if (event.type == SDL_EVENT_GAMEPAD_ADDED || event.type == SDL_EVENT_GAMEPAD_REMOVED || - event.type == SDL_EVENT_JOYSTICK_ADDED || event.type == SDL_EVENT_JOYSTICK_REMOVED) { - Gamepad::handleEvent(event); - return; - } - // Empassar-se el KEY_UP de qualsevol tecla que el menú va consumir en KEY_DOWN +auto Director::handleMenuEvent(const SDL_Event& event) -> bool { + // Empassar-se el KEY_UP d'una tecla que el menú va consumir en KEY_DOWN. if (event.type == SDL_EVENT_KEY_UP && event.key.scancode >= 0 && event.key.scancode < SDL_SCANCODE_COUNT && menu_keys_held_[event.key.scancode]) { menu_keys_held_[event.key.scancode] = false; - return; + return true; } - // Captura de tecla (remapeig al menú): intercepta KEY_DOWN abans de tot - if (Menu::isCapturing() && event.type == SDL_EVENT_KEY_DOWN && !event.key.repeat) { + const bool KEY_DOWN = event.type == SDL_EVENT_KEY_DOWN && !event.key.repeat; + // Captura de tecla (remapeig al menú): intercepta KEY_DOWN abans de tot. + if (Menu::isCapturing() && KEY_DOWN) { Menu::captureKey(event.key.scancode); menu_keys_held_[event.key.scancode] = true; - return; + return true; } - // Pausa: F11 (o tecla configurada) pausa/reprén la simulació. - // No mostrem notificació — l'indicador persistent "Pausa" a la cantonada - // superior dreta (pintat per Overlay) ja comunica l'estat. - if (event.type == SDL_EVENT_KEY_DOWN && !event.key.repeat && - event.key.scancode == KeyConfig::scancode("pause_toggle")) { + // Pausa / menú toggle. + if (KEY_DOWN && event.key.scancode == KeyConfig::scancode("pause_toggle")) { togglePause(); menu_keys_held_[event.key.scancode] = true; - return; + return true; } - // Menú: F12 (o tecla configurada) obre/tanca el menú flotant - if (event.type == SDL_EVENT_KEY_DOWN && !event.key.repeat && - event.key.scancode == KeyConfig::scancode("menu_toggle")) { + if (KEY_DOWN && event.key.scancode == KeyConfig::scancode("menu_toggle")) { Menu::toggle(); Ji::setInputBlocked(Menu::isOpen()); menu_keys_held_[event.key.scancode] = true; - return; + return true; } - // Si el menú està obert, consumeix tot l'input de teclat - if (Menu::isOpen() && event.type == SDL_EVENT_KEY_DOWN && !event.key.repeat) { + // Si el menú està obert, consumeix tot l'input de teclat. + if (Menu::isOpen() && KEY_DOWN) { if (event.key.scancode == SDL_SCANCODE_ESCAPE) { Menu::close(); Ji::setInputBlocked(false); - // Empassa l'ESC fins al release perquè el joc no la veja per polling esc_swallow_until_release_ = true; } else { Menu::handleKey(event.key.scancode); - // El menú pot haver-se tancat (p.ex. Backspace al nivell arrel) if (!Menu::isOpen()) { Ji::setInputBlocked(false); } } menu_keys_held_[event.key.scancode] = true; - return; + return true; } if (Menu::isOpen() && event.type == SDL_EVENT_KEY_UP) { - return; // no deixem passar KEY_UP al joc tampoc + return true; } - // Salta els crèdits amb qualsevol tecla que arribe al joc. Es fa DESPRÉS - // del toggle del menú/pausa i del handling del menú obert — així F12 i - // SELECT (gamepad) obrin el menú sense cancel·lar els crèdits, i la - // navegació per dins del menú tampoc els anul·la. + return false; +} + +auto Director::handleEscapeEvent(const SDL_Event& event) -> bool { + // Salta els crèdits amb qualsevol tecla que arribe al joc. if (event.type == SDL_EVENT_KEY_DOWN && !event.key.repeat && Overlay::creditsActive()) { Overlay::cancelCredits(); - return; + return true; } - // Allibera el bloqueig d'ESC quan l'usuari la deixa anar + // Allibera el bloqueig d'ESC quan l'usuari la deixa anar. if (event.type == SDL_EVENT_KEY_UP && event.key.scancode == SDL_SCANCODE_ESCAPE && esc_swallow_until_release_) { esc_swallow_until_release_ = false; - return; + return true; } - // ESC: interceptem KEY_DOWN per bloquejar-la ABANS que el joc la veja per polling + // ESC KEY_DOWN: bloqueja per polling i decideix notificació vs eixida. if (event.type == SDL_EVENT_KEY_DOWN && event.key.scancode == SDL_SCANCODE_ESCAPE && !event.key.repeat) { - esc_blocked_ = true; // Bloqueja ESC per polling immediatament + esc_blocked_ = true; if (!Overlay::isEscConsumed()) { - // Primera pulsació: mostra notificació Overlay::handleEscape(); } else { - // Segona pulsació: senyal d'eixida al joc esc_blocked_ = false; key_pressed_ = true; Jg::quitSignal(); - // Si estem en pausa, la desactivem: el fiber del joc està - // congelat i necessita ser reprès per veure la senyal de - // quit i poder tornar de forma natural. paused_ = false; } - return; // no processa més aquest event + return true; } - if (event.type == SDL_EVENT_KEY_UP) { - if (event.key.scancode == SDL_SCANCODE_ESCAPE) { - // Ja processat a KEY_DOWN, només deixem netejar el bloqueig - // quan l'overlay faça timeout - return; - } // Comprova si és una tecla d'UI registrada (no passa al joc). - // KeyConfig::isGuiKey cobreix totes les tecles GUI a la vegada, - // incloent pause_toggle i menu_toggle (defensa en profunditat: - // aquestes ja s'haurien hagut de menjar al swallow d'amunt). + return false; +} + +void Director::handleEvent(const SDL_Event& event) { + if (event.type == SDL_EVENT_QUIT) { + Jg::quitSignal(); + requestQuit(); + } + if (event.type == SDL_EVENT_GAMEPAD_ADDED || event.type == SDL_EVENT_GAMEPAD_REMOVED || + event.type == SDL_EVENT_JOYSTICK_ADDED || event.type == SDL_EVENT_JOYSTICK_REMOVED) { + Gamepad::handleEvent(event); + return; + } + if (handleMenuEvent(event)) { + return; + } + if (handleEscapeEvent(event)) { + return; + } + if (event.type == SDL_EVENT_KEY_UP && event.key.scancode != SDL_SCANCODE_ESCAPE) { const auto SC = event.key.scancode; if (!KeyConfig::isGuiKey(SC)) { key_pressed_ = true; diff --git a/source/core/system/director.hpp b/source/core/system/director.hpp index 870566b..3bb462a 100644 --- a/source/core/system/director.hpp +++ b/source/core/system/director.hpp @@ -67,6 +67,14 @@ class Director { // Construeix l'escena apropiada segons game_state_ i Info::ctx. // Retorna nullptr si l'state actual no té escena registrada (bug). [[nodiscard]] auto createNextScene() const -> std::unique_ptr; + // Helpers d'iterate() — extrets per reduir complexitat cognitiva. + void applyRestart(); + static void maybeStartTitleCredits(); + auto tickActiveScene() -> bool; // true = continuar; false = sortir del loop + + // Helpers d'handleEvent() — cada un retorna true si l'event s'ha consumit. + auto handleMenuEvent(const SDL_Event& event) -> bool; + auto handleEscapeEvent(const SDL_Event& event) -> bool; // Buffers persistents entre iteracions. Abans eren locals a run(), // ara són membres perquè iterate() els pot reutilitzar sense tornar-los diff --git a/source/external/gif.h b/source/external/gif.h index 0f147d2..ca42ea2 100644 --- a/source/external/gif.h +++ b/source/external/gif.h @@ -1,3 +1,4 @@ +// NOLINTBEGIN(clang-analyzer-unix.Malloc) — codi extern de tercers, no l'auditem #include #include #include @@ -510,3 +511,4 @@ unsigned char* LoadGif(unsigned char *buffer, unsigned short* w, unsigned short* fclose( gif_file ); }*/ +// NOLINTEND(clang-analyzer-unix.Malloc) diff --git a/source/game/bola.cpp b/source/game/bola.cpp index 70f5325..d745f5c 100644 --- a/source/game/bola.cpp +++ b/source/game/bola.cpp @@ -6,7 +6,7 @@ Bola::Bola(Jd8::Surface gfx, Prota* sam) : Sprite(gfx) { - this->sam = sam; + this->sam_ = sam; entitat.frames.reserve(2); entitat.frames.push_back({30, 155, 15, 15}); @@ -17,28 +17,28 @@ Bola::Bola(Jd8::Surface gfx, Prota* sam) this->cur_frame = 0; this->o = 0; - this->cycles_per_frame = 4; + this->cycles_per_frame_ = 4; this->x = 20; this->y = 100; - this->contador = 0; + this->contador_ = 0; } void Bola::draw() { - if (this->contador == 0) { + if (this->contador_ == 0) { Sprite::draw(); } } void Bola::update() { - if (this->contador == 0) { + if (this->contador_ == 0) { // Augmentem la x this->x++; if (this->x == 280) { - this->contador = 200; + this->contador_ = 200; } // Augmentem el frame - if (Jg::getCycleCounter() % this->cycles_per_frame == 0) { + if (Jg::getCycleCounter() % this->cycles_per_frame_ == 0) { this->cur_frame++; if (this->cur_frame == entitat.animacions[this->o].frames.size()) { this->cur_frame = 0; @@ -46,16 +46,16 @@ void Bola::update() { } // Comprovem si ha tocat a Sam - if (this->x > (this->sam->x - 7) && this->x < (this->sam->x + 7) && this->y > (this->sam->y - 7) && this->y < (this->sam->y + 7)) { - this->contador = 200; + if (this->x > (this->sam_->x - 7) && this->x < (this->sam_->x + 7) && this->y > (this->sam_->y - 7) && this->y < (this->sam_->y + 7)) { + this->contador_ = 200; Info::ctx.vida--; if (Info::ctx.vida == 0) { - this->sam->o = 5; + this->sam_->o = 5; } } } else { - this->contador--; - if (this->contador == 0) { + this->contador_--; + if (this->contador_ == 0) { this->x = 20; } } diff --git a/source/game/bola.hpp b/source/game/bola.hpp index 2f80ca2..bd11599 100644 --- a/source/game/bola.hpp +++ b/source/game/bola.hpp @@ -12,6 +12,6 @@ class Bola : public Sprite { void update(); protected: - Uint8 contador; - Prota* sam; + Uint8 contador_; + Prota* sam_; }; diff --git a/source/game/engendro.cpp b/source/game/engendro.cpp index 74dd5da..a566406 100644 --- a/source/game/engendro.cpp +++ b/source/game/engendro.cpp @@ -22,25 +22,25 @@ Engendro::Engendro(Jd8::Surface gfx, Uint16 x, Uint16 y) entitat.animacions[0].frames = {0, 1, 2, 3, 2, 1}; this->cur_frame = 0; - this->vida = 18; + this->vida_ = 18; this->x = x; this->y = y; this->o = 0; - this->cycles_per_frame = 30; + this->cycles_per_frame_ = 30; } auto Engendro::update() -> bool { bool mort = false; - if (Jg::getCycleCounter() % this->cycles_per_frame == 0) { + if (Jg::getCycleCounter() % this->cycles_per_frame_ == 0) { this->cur_frame++; if (this->cur_frame == entitat.animacions[this->o].frames.size()) { this->cur_frame = 0; } - this->vida--; + this->vida_--; } - if (vida == 0) { + if (vida_ == 0) { mort = true; } diff --git a/source/game/engendro.hpp b/source/game/engendro.hpp index 2319956..a2ae1f8 100644 --- a/source/game/engendro.hpp +++ b/source/game/engendro.hpp @@ -9,5 +9,5 @@ class Engendro : public Sprite { auto update() -> bool; protected: - Uint8 vida; + Uint8 vida_; }; diff --git a/source/game/mapa.cpp b/source/game/mapa.cpp index c0ff215..6e36e99 100644 --- a/source/game/mapa.cpp +++ b/source/game/mapa.cpp @@ -247,7 +247,7 @@ void Mapa::comprovaCaixa(Uint8 num) { } // Si algun costat encara no està passat, no hi ha res que fer - if (std::any_of(std::begin(this->tombes[num].costat), std::end(this->tombes[num].costat), [](bool c) { return !c; })) { + if (std::ranges::any_of(this->tombes[num].costat, [](bool c) { return !c; })) { return; } diff --git a/source/game/marcador.cpp b/source/game/marcador.cpp index 09495ba..d707ed8 100644 --- a/source/game/marcador.cpp +++ b/source/game/marcador.cpp @@ -1,8 +1,8 @@ #include "game/marcador.hpp" Marcador::Marcador(Jd8::Surface gfx, Prota* sam) { - this->gfx = gfx; - this->sam = sam; + this->gfx_ = gfx; + this->sam_ = sam; } void Marcador::draw() { @@ -15,47 +15,47 @@ void Marcador::draw() { this->pintaNumero(156, 2, (Info::ctx.diners % 100) / 10); this->pintaNumero(163, 2, Info::ctx.diners % 10); - if (this->sam->pergami) { - Jd8::blitCK(190, 1, this->gfx, 209, 185, 15, 14, 255); + if (this->sam_->pergami) { + Jd8::blitCK(190, 1, this->gfx_, 209, 185, 15, 14, 255); } - Jd8::blitCK(271, 1, this->gfx, 0, 20, 15, Info::ctx.vida * 3, 255); + Jd8::blitCK(271, 1, this->gfx_, 0, 20, 15, Info::ctx.vida * 3, 255); if (Info::ctx.vida < 5) { - Jd8::blitCK(271, 1 + (Info::ctx.vida * 3), this->gfx, 75, 20, 15, 15 - (Info::ctx.vida * 3), 255); + Jd8::blitCK(271, 1 + (Info::ctx.vida * 3), this->gfx_, 75, 20, 15, 15 - (Info::ctx.vida * 3), 255); } } void Marcador::pintaNumero(Uint16 x, Uint16 y, Uint8 num) { switch (num) { case 0: - Jd8::blitCK(x, y, this->gfx, 141, 193, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx_, 141, 193, 10, 7, 255); break; case 1: - Jd8::blitCK(x, y, this->gfx, 100, 185, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx_, 100, 185, 10, 7, 255); break; case 2: - Jd8::blitCK(x, y, this->gfx, 110, 185, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx_, 110, 185, 10, 7, 255); break; case 3: - Jd8::blitCK(x, y, this->gfx, 120, 185, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx_, 120, 185, 10, 7, 255); break; case 4: - Jd8::blitCK(x, y, this->gfx, 130, 185, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx_, 130, 185, 10, 7, 255); break; case 5: - Jd8::blitCK(x, y, this->gfx, 140, 185, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx_, 140, 185, 10, 7, 255); break; case 6: - Jd8::blitCK(x, y, this->gfx, 101, 193, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx_, 101, 193, 10, 7, 255); break; case 7: - Jd8::blitCK(x, y, this->gfx, 111, 193, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx_, 111, 193, 10, 7, 255); break; case 8: - Jd8::blitCK(x, y, this->gfx, 121, 193, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx_, 121, 193, 10, 7, 255); break; case 9: - Jd8::blitCK(x, y, this->gfx, 131, 193, 10, 7, 255); + Jd8::blitCK(x, y, this->gfx_, 131, 193, 10, 7, 255); break; default: break; diff --git a/source/game/marcador.hpp b/source/game/marcador.hpp index bbb45a1..8b1090a 100644 --- a/source/game/marcador.hpp +++ b/source/game/marcador.hpp @@ -14,6 +14,6 @@ class Marcador { protected: void pintaNumero(Uint16 x, Uint16 y, Uint8 num); - Jd8::Surface gfx; - Prota* sam; + Jd8::Surface gfx_; + Prota* sam_; }; diff --git a/source/game/momia.cpp b/source/game/momia.cpp index 4033fc2..e85e29a 100644 --- a/source/game/momia.cpp +++ b/source/game/momia.cpp @@ -7,7 +7,7 @@ Momia::Momia(Jd8::Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam) : Sprite(gfx) { this->dimoni = dimoni; - this->sam = sam; + this->sam_ = sam; entitat.frames.reserve(20); for (int row = 0; row < 4; row++) { @@ -43,7 +43,7 @@ Momia::Momia(Jd8::Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam) this->cur_frame = 0; this->o = rand() % 4; - this->cycles_per_frame = 4; + this->cycles_per_frame_ = 4; if (this->dimoni) { if (x == 0) { @@ -52,7 +52,7 @@ Momia::Momia(Jd8::Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam) this->x = x; } if (y == 0) { - if (this->sam->y > 100) { + if (this->sam_->y > 100) { this->y = 30; } else { this->y = 170; @@ -60,7 +60,7 @@ Momia::Momia(Jd8::Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam) } else { this->y = y; } - this->engendro = std::make_unique(gfx, this->x, this->y); + this->engendro_ = std::make_unique(gfx, this->x, this->y); } else { this->x = x; this->y = y; @@ -68,104 +68,117 @@ Momia::Momia(Jd8::Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam) } void Momia::draw() { - if (this->engendro) { - this->engendro->draw(); + if (this->engendro_) { + this->engendro_->draw(); } else { Sprite::draw(); if (Info::ctx.num_piramide == 4) { if ((Jg::getCycleCounter() % 40) < 20) { - Jd8::blitCK(this->x, this->y, this->gfx, 220, 80, 15, 15, 255); + Jd8::blitCK(this->x, this->y, this->gfx_, 220, 80, 15, 15, 255); } else { - Jd8::blitCK(this->x, this->y, this->gfx, 235, 80, 15, 15, 255); + Jd8::blitCK(this->x, this->y, this->gfx_, 235, 80, 15, 15, 255); } } } } +void Momia::pickHorizontalThenVertical() { + if (this->x > this->sam_->x) { + this->o = 3; + } else if (this->x < this->sam_->x) { + this->o = 2; + } else if (this->y < this->sam_->y) { + this->o = 0; + } else if (this->y > this->sam_->y) { + this->o = 1; + } +} + +void Momia::pickVerticalThenHorizontal() { + if (this->y < this->sam_->y) { + this->o = 0; + } else if (this->y > this->sam_->y) { + this->o = 1; + } else if (this->x > this->sam_->x) { + this->o = 3; + } else if (this->x < this->sam_->x) { + this->o = 2; + } +} + +void Momia::pickDirection() { + if (!this->dimoni) { + this->o = rand() % 4; + return; + } + if (rand() % 2 == 0) { + pickHorizontalThenVertical(); + } else { + pickVerticalThenHorizontal(); + } +} + +void Momia::stepInDirection() { + switch (this->o) { + case 0: + if (y < 170) { this->y++; } + break; + case 1: + if (y > 30) { this->y--; } + break; + case 2: + if (x < 280) { this->x++; } + break; + case 3: + if (x > 20) { this->x--; } + break; + default: + break; + } +} + +auto Momia::collidesWithSam() const -> bool { + return this->x > (this->sam_->x - 7) && this->x < (this->sam_->x + 7) && + this->y > (this->sam_->y - 7) && this->y < (this->sam_->y + 7); +} + +void Momia::applyCollisionWithSam() { + if (this->sam_->pergami) { + this->sam_->pergami = false; + return; + } + Info::ctx.vida--; + if (Info::ctx.vida == 0) { + this->sam_->o = 5; + } +} + auto Momia::update() -> bool { - bool morta = false; - - if (this->engendro) { - if (this->engendro->update()) { - this->engendro.reset(); + if (this->engendro_) { + if (this->engendro_->update()) { + this->engendro_.reset(); } - return morta; + return false; } - - if (this->sam->o < 4 && (this->dimoni || Info::ctx.num_piramide == 5 || Jg::getCycleCounter() % 2 == 0)) { - if ((this->x - 20) % 65 == 0 && (this->y - 30) % 35 == 0) { - if (this->dimoni) { - if (rand() % 2 == 0) { - if (this->x > this->sam->x) { - this->o = 3; - } else if (this->x < this->sam->x) { - this->o = 2; - } else if (this->y < this->sam->y) { - this->o = 0; - } else if (this->y > this->sam->y) { - this->o = 1; - } - } else { - if (this->y < this->sam->y) { - this->o = 0; - } else if (this->y > this->sam->y) { - this->o = 1; - } else if (this->x > this->sam->x) { - this->o = 3; - } else if (this->x < this->sam->x) { - this->o = 2; - } - } - } else { - this->o = rand() % 4; - } - } - - switch (this->o) { - case 0: - if (y < 170) { - this->y++; - } - break; - case 1: - if (y > 30) { - this->y--; - } - break; - case 2: - if (x < 280) { - this->x++; - } - break; - case 3: - if (x > 20) { - this->x--; - } - break; - default: - break; - } - - if (Jg::getCycleCounter() % this->cycles_per_frame == 0) { - this->cur_frame++; - if (this->cur_frame == entitat.animacions[this->o].frames.size()) { - this->cur_frame = 0; - } - } - - if (this->x > (this->sam->x - 7) && this->x < (this->sam->x + 7) && this->y > (this->sam->y - 7) && this->y < (this->sam->y + 7)) { - morta = true; - if (this->sam->pergami) { - this->sam->pergami = false; - } else { - Info::ctx.vida--; - if (Info::ctx.vida == 0) { - this->sam->o = 5; - } - } + const bool SAM_ALIVE = this->sam_->o < 4; + const bool MAY_STEP = this->dimoni || Info::ctx.num_piramide == 5 || Jg::getCycleCounter() % 2 == 0; + if (!SAM_ALIVE || !MAY_STEP) { + return false; + } + if ((this->x - 20) % 65 == 0 && (this->y - 30) % 35 == 0) { + pickDirection(); + } + stepInDirection(); + if (Jg::getCycleCounter() % this->cycles_per_frame_ == 0) { + this->cur_frame++; + if (this->cur_frame == entitat.animacions[this->o].frames.size()) { + this->cur_frame = 0; } } - - return morta; + if (collidesWithSam()) { + applyCollisionWithSam(); + return true; + } + return false; } diff --git a/source/game/momia.hpp b/source/game/momia.hpp index 9c91954..a039fb8 100644 --- a/source/game/momia.hpp +++ b/source/game/momia.hpp @@ -17,6 +17,13 @@ class Momia : public Sprite { bool dimoni; protected: - Prota* sam; - std::unique_ptr engendro; + Prota* sam_; + std::unique_ptr engendro_; + + void pickDirection(); + void pickHorizontalThenVertical(); + void pickVerticalThenHorizontal(); + void stepInDirection(); + [[nodiscard]] auto collidesWithSam() const -> bool; + void applyCollisionWithSam(); }; diff --git a/source/game/options.cpp b/source/game/options.cpp index 0bfa3b9..4923451 100644 --- a/source/game/options.cpp +++ b/source/game/options.cpp @@ -437,7 +437,7 @@ namespace Options { return true; } - // --- Helper per a parsejar floats de YAML --- + // --- Helpers per a parsejar camps de YAML --- static void parseFloatField(const fkyaml::node& node, const std::string& key, float& target) { if (node.contains(key)) { try { @@ -448,6 +448,26 @@ namespace Options { } } + static void parseIntField(const fkyaml::node& node, const std::string& key, int& target) { + if (node.contains(key)) { + try { + target = node[key].get_value(); + } catch (...) { + // @INTENTIONAL: camp YAML no és int vàlid, mantenim valor per defecte. + } + } + } + + static void parseBoolField(const fkyaml::node& node, const std::string& key, bool& target) { + if (node.contains(key)) { + try { + target = node[key].get_value(); + } catch (...) { + // @INTENTIONAL: camp YAML no és bool vàlid, mantenim valor per defecte. + } + } + } + // --- Presets PostFX --- void setPostFXFile(const std::string& path) { postfx_file_path = path; } @@ -561,42 +581,12 @@ namespace Options { parseFloatField(p, "mask_brightness", preset.mask_brightness); parseFloatField(p, "curvature_x", preset.curvature_x); parseFloatField(p, "curvature_y", preset.curvature_y); - if (p.contains("mask_type")) { - try { - preset.mask_type = p["mask_type"].get_value(); - } catch (...) { /* @INTENTIONAL: camp YAML invàlid, mantenim el valor per defecte. */ - } - } - if (p.contains("enable_scanlines")) { - try { - preset.enable_scanlines = p["enable_scanlines"].get_value(); - } catch (...) { /* @INTENTIONAL: camp YAML invàlid, mantenim el valor per defecte. */ - } - } - if (p.contains("enable_multisample")) { - try { - preset.enable_multisample = p["enable_multisample"].get_value(); - } catch (...) { /* @INTENTIONAL: camp YAML invàlid, mantenim el valor per defecte. */ - } - } - if (p.contains("enable_gamma")) { - try { - preset.enable_gamma = p["enable_gamma"].get_value(); - } catch (...) { /* @INTENTIONAL: camp YAML invàlid, mantenim el valor per defecte. */ - } - } - if (p.contains("enable_curvature")) { - try { - preset.enable_curvature = p["enable_curvature"].get_value(); - } catch (...) { /* @INTENTIONAL: camp YAML invàlid, mantenim el valor per defecte. */ - } - } - if (p.contains("enable_sharper")) { - try { - preset.enable_sharper = p["enable_sharper"].get_value(); - } catch (...) { /* @INTENTIONAL: camp YAML invàlid, mantenim el valor per defecte. */ - } - } + parseIntField(p, "mask_type", preset.mask_type); + parseBoolField(p, "enable_scanlines", preset.enable_scanlines); + parseBoolField(p, "enable_multisample", preset.enable_multisample); + parseBoolField(p, "enable_gamma", preset.enable_gamma); + parseBoolField(p, "enable_curvature", preset.enable_curvature); + parseBoolField(p, "enable_sharper", preset.enable_sharper); crtpi_presets.push_back(preset); } } diff --git a/source/game/prota.cpp b/source/game/prota.cpp index 96ccbdd..612a303 100644 --- a/source/game/prota.cpp +++ b/source/game/prota.cpp @@ -5,84 +5,75 @@ #include "core/jail/jgame.hpp" #include "core/jail/jinput.hpp" -Prota::Prota(Jd8::Surface gfx) - : Sprite(gfx) { - entitat.frames.reserve(82); - - for (int y = 0; y < 4; y++) { - for (int x = 0; x < 5; x++) { - Frame f; - f.w = 15; - f.h = 15; - if (Info::ctx.num_piramide == 4) { - f.h -= 5; - } - f.x = x * 15; - f.y = 20 + (y * 15); - entitat.frames.push_back(f); - } +namespace { + // Atura el frame.h a 10 quan piràmide 4 (sprite "petit" amb pijama de presoner). + auto adjustedHeight(int base_h) -> int { + return (Info::ctx.num_piramide == 4) ? base_h - 5 : base_h; } - for (int y = 95; y < 185; y += 30) { - for (int x = 60; x < 315; x += 15) { - if (x != 300 || y != 155) { - Frame f; - f.w = 15; - f.h = 30; - if (Info::ctx.num_piramide == 4) { - f.h -= 5; + + void addFrameGrid(Entitat& entitat, int x0, int x1, int x_step, int y0, int y1, int y_step, int w, int h, int skip_x = -1, int skip_y = -1) { + for (int yy = y0; yy < y1; yy += y_step) { + for (int xx = x0; xx < x1; xx += x_step) { + if (xx == skip_x && yy == skip_y) { + continue; } - f.x = x; - f.y = y; + Frame f; + f.w = w; + f.h = adjustedHeight(h); + f.x = xx; + f.y = yy; entitat.frames.push_back(f); } } } - for (int y = 20; y < 50; y += 15) { - for (int x = 225; x < 315; x += 15) { - Frame f; - f.w = 15; - f.h = 15; - if (Info::ctx.num_piramide == 4) { - f.h -= 5; - } - f.x = x; - f.y = y; - entitat.frames.push_back(f); + + void buildProtaFrames(Entitat& entitat) { + entitat.frames.reserve(82); + // Cara/quatre direccions (4×5 sprites de 15×15 a y=20..) + addFrameGrid(entitat, 0, 75, 15, 20, 80, 15, 15, 15); + // Animació de mort (15×30 a y=95..; salta x=300/y=155) + addFrameGrid(entitat, 60, 315, 15, 95, 185, 30, 15, 30, 300, 155); + // Animació de victòria (15×15 a y=20.., x=225..) + addFrameGrid(entitat, 225, 315, 15, 20, 50, 15, 15, 15); + } + + void buildProtaAnimations(Entitat& entitat) { + entitat.animacions.resize(6); + for (int i = 0; i < 4; i++) { + entitat.animacions[i].frames = { + static_cast(0 + (i * 5)), + static_cast(1 + (i * 5)), + static_cast(2 + (i * 5)), + static_cast(1 + (i * 5)), + static_cast(0 + (i * 5)), + static_cast(3 + (i * 5)), + static_cast(4 + (i * 5)), + static_cast(3 + (i * 5)), + }; + } + entitat.animacions[4].frames.resize(50); + for (int i = 0; i < 50; i++) { + entitat.animacions[4].frames[i] = i + 20; + } + entitat.animacions[5].frames.resize(48); + for (int i = 0; i < 12; i++) { + entitat.animacions[5].frames[i] = i + 70; + } + for (int i = 12; i < 48; i++) { + entitat.animacions[5].frames[i] = 81; } } +} // namespace - entitat.animacions.resize(6); - for (int i = 0; i < 4; i++) { - entitat.animacions[i].frames = { - static_cast(0 + (i * 5)), - static_cast(1 + (i * 5)), - static_cast(2 + (i * 5)), - static_cast(1 + (i * 5)), - static_cast(0 + (i * 5)), - static_cast(3 + (i * 5)), - static_cast(4 + (i * 5)), - static_cast(3 + (i * 5)), - }; - } - - entitat.animacions[4].frames.resize(50); - for (int i = 0; i < 50; i++) { - entitat.animacions[4].frames[i] = i + 20; - } - - entitat.animacions[5].frames.resize(48); - for (int i = 0; i < 12; i++) { - entitat.animacions[5].frames[i] = i + 70; - } - for (int i = 12; i < 48; i++) { - entitat.animacions[5].frames[i] = 81; - } - +Prota::Prota(Jd8::Surface gfx) + : Sprite(gfx) { + buildProtaFrames(entitat); + buildProtaAnimations(entitat); cur_frame = 0; x = 150; y = 30; o = 0; - cycles_per_frame = 4; + cycles_per_frame_ = 4; pergami = false; frame_pejades = 0; } @@ -92,94 +83,87 @@ void Prota::draw() { if (Info::ctx.num_piramide == 4 && this->o != 4) { if ((Jg::getCycleCounter() % 40) < 20) { - Jd8::blitCK(this->x, this->y, this->gfx, 220, 80, 15, 15, 255); + Jd8::blitCK(this->x, this->y, this->gfx_, 220, 80, 15, 15, 255); } else { - Jd8::blitCK(this->x, this->y, this->gfx, 235, 80, 15, 15, 255); + Jd8::blitCK(this->x, this->y, this->gfx_, 235, 80, 15, 15, 255); } } } +auto Prota::readDirection() -> Uint8 { + Uint8 dir = 4; + if (Ji::keyPressed(SDL_SCANCODE_DOWN)) { + if ((this->x - 20) % 65 == 0) { this->o = 0; } + dir = this->o; + } + if (Ji::keyPressed(SDL_SCANCODE_UP)) { + if ((this->x - 20) % 65 == 0) { this->o = 1; } + dir = this->o; + } + if (Ji::keyPressed(SDL_SCANCODE_RIGHT)) { + if ((this->y - 30) % 35 == 0) { this->o = 2; } + dir = this->o; + } + if (Ji::keyPressed(SDL_SCANCODE_LEFT)) { + if ((this->y - 30) % 35 == 0) { this->o = 3; } + dir = this->o; + } + return dir; +} + +void Prota::stepInDirection(Uint8 dir) { + switch (dir) { + case 0: + if (this->y < 170) { this->y++; } + break; + case 1: + if (this->y > 30) { this->y--; } + break; + case 2: + if (this->x < 280) { this->x++; } + break; + case 3: + if (this->x > 20) { this->x--; } + break; + default: + break; + } +} + +void Prota::advanceWalkingFrame(Uint8 dir) { + if (dir == 4) { + this->cur_frame = 0; + return; + } + this->frame_pejades++; + if (this->frame_pejades == 15) { + this->frame_pejades = 0; + } + if (Jg::getCycleCounter() % this->cycles_per_frame_ == 0) { + this->cur_frame++; + if (this->cur_frame == entitat.animacions[this->o].frames.size()) { + this->cur_frame = 0; + } + } +} + +auto Prota::advanceFinalAnimation() -> Uint8 { + if (Jg::getCycleCounter() % this->cycles_per_frame_ != 0) { + return 0; + } + this->cur_frame++; + if (this->cur_frame != entitat.animacions[this->o].frames.size()) { + return 0; + } + return (this->o == 4) ? 1 : 2; +} + auto Prota::update() -> Uint8 { - Uint8 eixir = 0; - - if (this->o < 4) { - Uint8 dir = 4; - if (Ji::keyPressed(SDL_SCANCODE_DOWN)) { - if ((this->x - 20) % 65 == 0) { - this->o = 0; - } - dir = this->o; - } - if (Ji::keyPressed(SDL_SCANCODE_UP)) { - if ((this->x - 20) % 65 == 0) { - this->o = 1; - } - dir = this->o; - } - if (Ji::keyPressed(SDL_SCANCODE_RIGHT)) { - if ((this->y - 30) % 35 == 0) { - this->o = 2; - } - dir = this->o; - } - if (Ji::keyPressed(SDL_SCANCODE_LEFT)) { - if ((this->y - 30) % 35 == 0) { - this->o = 3; - } - dir = this->o; - } - - switch (dir) { - case 0: - if (this->y < 170) { - this->y++; - } - break; - case 1: - if (this->y > 30) { - this->y--; - } - break; - case 2: - if (this->x < 280) { - this->x++; - } - break; - case 3: - if (this->x > 20) { - this->x--; - } - break; - default: - break; - } - - if (dir == 4) { - this->cur_frame = 0; - } else { - this->frame_pejades++; - if (this->frame_pejades == 15) { - this->frame_pejades = 0; - } - if (Jg::getCycleCounter() % this->cycles_per_frame == 0) { - this->cur_frame++; - if (this->cur_frame == entitat.animacions[this->o].frames.size()) { - this->cur_frame = 0; - } - } - } - eixir = 0U; - } else { - if (Jg::getCycleCounter() % this->cycles_per_frame == 0) { - this->cur_frame++; - if (this->cur_frame == entitat.animacions[this->o].frames.size()) { - if (this->o == 4) { - eixir = 1; - } else { - eixir = 2; - } - } - } + if (this->o >= 4) { + return advanceFinalAnimation(); } - return eixir; + const Uint8 DIR = readDirection(); + stepInDirection(DIR); + advanceWalkingFrame(DIR); + return 0; } diff --git a/source/game/prota.hpp b/source/game/prota.hpp index 8358c85..e8b49bc 100644 --- a/source/game/prota.hpp +++ b/source/game/prota.hpp @@ -14,4 +14,8 @@ class Prota : public Sprite { bool pergami; protected: + auto readDirection() -> Uint8; + void stepInDirection(Uint8 dir); + void advanceWalkingFrame(Uint8 dir); + auto advanceFinalAnimation() -> Uint8; }; diff --git a/source/game/scenes/intro_new_logo_scene.cpp b/source/game/scenes/intro_new_logo_scene.cpp index a089219..3c85dd6 100644 --- a/source/game/scenes/intro_new_logo_scene.cpp +++ b/source/game/scenes/intro_new_logo_scene.cpp @@ -132,17 +132,59 @@ namespace Scenes { } } + void IntroNewLogoScene::advanceRevealing(int delta_ms) { + phase_acc_ms_ += delta_ms; + render(); + if (phase_acc_ms_ < REVEAL_FRAME_MS) { + return; + } + phase_acc_ms_ = 0; + reveal_cursor_visible_ = !reveal_cursor_visible_; + if (!reveal_cursor_visible_) { + return; + } + ++reveal_letter_; + if (reveal_letter_ >= 9) { + phase_ = Phase::FULL_LOGO_FLASH; + reveal_letter_ = 8; + } + } + + void IntroNewLogoScene::advancePaletteStep(int delta_ms) { + phase_acc_ms_ += delta_ms; + while (phase_acc_ms_ >= PALETTE_CYCLE_STEP_MS && palette_step_ < PALETTE_CYCLE_STEPS) { + phase_acc_ms_ -= PALETTE_CYCLE_STEP_MS; + advancePaletteCycle(); + ++palette_step_; + } + render(); + if (palette_step_ >= PALETTE_CYCLE_STEPS) { + phase_ = Phase::FINAL_WAIT; + phase_acc_ms_ = 0; + } + } + + void IntroNewLogoScene::advanceSpritesPhase(int delta_ms) { + if (!sprites_scene_) { + sprites_scene_ = std::make_unique(std::move(gfx_)); + sprites_scene_->onEnter(); + } + sprites_scene_->tick(delta_ms); + if (sprites_scene_->done()) { + Info::ctx.num_piramide = 0; + phase_ = Phase::DONE; + } + } + void IntroNewLogoScene::tick(int delta_ms) { // Qualsevol tecla durant el revelat o el ciclo de paleta salta // TOTA la intro (inclou saltar la fase de sprites). Durant SPRITES - // deixem que la sub-escena gestione el seu propi skip (que a més - // respecta la fase "final" no skippable de la variant 0). + // deixem que la sub-escena gestione el seu propi skip. if (phase_ != Phase::SPRITES && phase_ != Phase::DONE && Ji::anyKey()) { Info::ctx.num_piramide = 0; phase_ = Phase::DONE; return; } - switch (phase_) { case Phase::INITIAL: phase_acc_ms_ += delta_ms; @@ -152,25 +194,9 @@ namespace Scenes { phase_acc_ms_ = 0; } break; - case Phase::REVEALING: - phase_acc_ms_ += delta_ms; - render(); - if (phase_acc_ms_ >= REVEAL_FRAME_MS) { - phase_acc_ms_ = 0; - reveal_cursor_visible_ = !reveal_cursor_visible_; - // Quan acabem els dos frames d'una lletra (cursor on → off), - // passem a la següent lletra. - if (reveal_cursor_visible_) { - ++reveal_letter_; - if (reveal_letter_ >= 9) { - phase_ = Phase::FULL_LOGO_FLASH; - reveal_letter_ = 8; - } - } - } + advanceRevealing(delta_ms); break; - case Phase::FULL_LOGO_FLASH: phase_acc_ms_ += delta_ms; render(); @@ -179,24 +205,9 @@ namespace Scenes { phase_acc_ms_ = 0; } break; - case Phase::PALETTE_CYCLE: - phase_acc_ms_ += delta_ms; - // Avancem passos de paleta cada 20 ms. Si el delta és gran, - // consumim múltiples passos en la mateixa crida. - while (phase_acc_ms_ >= PALETTE_CYCLE_STEP_MS && - palette_step_ < PALETTE_CYCLE_STEPS) { - phase_acc_ms_ -= PALETTE_CYCLE_STEP_MS; - advancePaletteCycle(); - ++palette_step_; - } - render(); - if (palette_step_ >= PALETTE_CYCLE_STEPS) { - phase_ = Phase::FINAL_WAIT; - phase_acc_ms_ = 0; - } + advancePaletteStep(delta_ms); break; - case Phase::FINAL_WAIT: phase_acc_ms_ += delta_ms; render(); @@ -204,25 +215,9 @@ namespace Scenes { phase_ = Phase::SPRITES; } break; - case Phase::SPRITES: - // Sub-escena construïda al primer tick. Transferim el gfx_ - // per move — la sub-escena se n'ocupa fins que es destruix. - // Cada tick successiu delega l'animació dels sprites. - if (!sprites_scene_) { - sprites_scene_ = std::make_unique(std::move(gfx_)); - sprites_scene_->onEnter(); - } - sprites_scene_->tick(delta_ms); - if (sprites_scene_->done()) { - // El vell `Go()` post-switch feia `num_piramide = 0` - // per passar al menú. Sense açò el while del fiber - // tornaria a crear IntroNewLogoScene infinitament. - Info::ctx.num_piramide = 0; - phase_ = Phase::DONE; - } + advanceSpritesPhase(delta_ms); break; - case Phase::DONE: break; } diff --git a/source/game/scenes/intro_new_logo_scene.hpp b/source/game/scenes/intro_new_logo_scene.hpp index a4b05c4..bf9a929 100644 --- a/source/game/scenes/intro_new_logo_scene.hpp +++ b/source/game/scenes/intro_new_logo_scene.hpp @@ -41,17 +41,21 @@ namespace Scenes { private: enum class Phase : std::uint8_t { - INITIAL, // pantalla negra 1000 ms - REVEALING, // 9 × 2 frames × 150 ms cada un + INITIAL, // pantalla negra 1000 ms + REVEALING, // 9 × 2 frames × 150 ms cada un FULL_LOGO_FLASH, // logo complet + cursor, 200 ms - PALETTE_CYCLE, // 256 passos × 20 ms modificant paleta - FINAL_WAIT, // 20 ms final - SPRITES, // tick delegat a IntroSpritesScene fins que acaba + PALETTE_CYCLE, // 256 passos × 20 ms modificant paleta + FINAL_WAIT, // 20 ms final + SPRITES, // tick delegat a IntroSpritesScene fins que acaba DONE, }; void render(); void advancePaletteCycle(); + // Helpers per a `tick()` — extrets per reduir complexitat cognitiva. + void advanceRevealing(int delta_ms); + void advancePaletteStep(int delta_ms); + void advanceSpritesPhase(int delta_ms); SurfaceHandle gfx_; SurfaceHandle cursor_surf_; diff --git a/source/game/scenes/scene_registry.cpp b/source/game/scenes/scene_registry.cpp index d245169..6a4770a 100644 --- a/source/game/scenes/scene_registry.cpp +++ b/source/game/scenes/scene_registry.cpp @@ -3,8 +3,8 @@ namespace Scenes { auto SceneRegistry::instance() -> SceneRegistry& { - static SceneRegistry inst; - return inst; + static SceneRegistry instance_; + return instance_; } void SceneRegistry::registerScene(int state_key, Factory factory) { diff --git a/source/game/scenes/slides_scene.cpp b/source/game/scenes/slides_scene.cpp index e9ea5da..165da52 100644 --- a/source/game/scenes/slides_scene.cpp +++ b/source/game/scenes/slides_scene.cpp @@ -65,12 +65,12 @@ namespace Scenes { next_state_ = 0; } - void SlidesScene::drawSlide(int slide_idx, int POS_X) { + void SlidesScene::drawSlide(int slide_idx, int pos_x) { const int SRC_Y = slide_idx * SLIDE_H; // Clipping manual: translada un rect de 320×65 des de (POS_X, SLIDE_Y) // a l'àrea visible (0..319, SLIDE_Y..SLIDE_Y+64). - int dst_x = POS_X; + int dst_x = pos_x; int src_x = 0; int w = 320; @@ -99,99 +99,106 @@ namespace Scenes { phase_ = Phase::FADE_FINAL; } - void SlidesScene::tick(int delta_ms) { - // Skip: qualsevol tecla salta directament al fade final. Per fidelitat - // al vell doSlides, el skip NO atura la música explícitament — només - // el final natural crida Ja::fadeOutMusic (beginFinalFade() distingeix). - if (!skip_triggered_ && Ji::anyKey()) { - skip_triggered_ = true; - if (num_piramide_at_start_ != 7) { - Audio::get()->fadeOutMusic(250); - } - fade_.startFadeOut(); - phase_ = Phase::FADE_FINAL; + void SlidesScene::triggerSkip() { + skip_triggered_ = true; + if (num_piramide_at_start_ != 7) { + Audio::get()->fadeOutMusic(250); } + fade_.startFadeOut(); + phase_ = Phase::FADE_FINAL; + } + void SlidesScene::tickSlideEnter(int delta_ms) { + phase_acc_ms_ += delta_ms; + int slide_idx = 2; + if (phase_ == Phase::SLIDE1_ENTER) { + slide_idx = 0; + } else if (phase_ == Phase::SLIDE2_ENTER) { + slide_idx = 1; + } + const float T = std::min(1.0F, static_cast(phase_acc_ms_) / static_cast(SCROLL_MS)); + const float EASED = Easing::outCubic(T); + drawSlide(slide_idx, Easing::lerpInt(SLIDE_START_X[slide_idx], 0, EASED)); + if (phase_acc_ms_ < SCROLL_MS) { + return; + } + drawSlide(slide_idx, 0); + switch (phase_) { + case Phase::SLIDE1_ENTER: + phase_ = Phase::SLIDE1_HOLD; + break; + case Phase::SLIDE2_ENTER: + phase_ = Phase::SLIDE2_HOLD; + break; + default: + phase_ = Phase::SLIDE3_HOLD; + break; + } + phase_acc_ms_ = 0; + } + + void SlidesScene::tickHoldIntermediate(int delta_ms) { + phase_acc_ms_ += delta_ms; + if (phase_acc_ms_ < HOLD_MS) { + return; + } + fade_.startFadeOut(); + phase_ = (phase_ == Phase::SLIDE1_HOLD) ? Phase::FADE_OUT1 : Phase::FADE_OUT2; + phase_acc_ms_ = 0; + } + + void SlidesScene::tickFadeOutIntermediate(int delta_ms) { + fade_.tick(delta_ms); + if (!fade_.done()) { + return; + } + restorePalette(); + Jd8::clearScreen(BG_COLOR_INDEX); + phase_ = (phase_ == Phase::FADE_OUT1) ? Phase::SLIDE2_ENTER : Phase::SLIDE3_ENTER; + phase_acc_ms_ = 0; + } + + void SlidesScene::tickFinalFade(int delta_ms) { + fade_.tick(delta_ms); + if (!fade_.done()) { + return; + } + if (num_piramide_at_start_ == 7) { + Info::ctx.num_piramide = 8; + next_state_ = 1; + } else { + next_state_ = 0; + } + phase_ = Phase::DONE; + } + + void SlidesScene::tick(int delta_ms) { + if (!skip_triggered_ && Ji::anyKey()) { + triggerSkip(); + } switch (phase_) { case Phase::SLIDE1_ENTER: case Phase::SLIDE2_ENTER: - case Phase::SLIDE3_ENTER: { - phase_acc_ms_ += delta_ms; - int slide_idx = 2; - if (phase_ == Phase::SLIDE1_ENTER) { - slide_idx = 0; - } else if (phase_ == Phase::SLIDE2_ENTER) { - slide_idx = 1; - } - const float T = std::min(1.0F, static_cast(phase_acc_ms_) / static_cast(SCROLL_MS)); - const float EASED = Easing::outCubic(T); - const int POS_X = Easing::lerpInt(SLIDE_START_X[slide_idx], 0, EASED); - drawSlide(slide_idx, POS_X); - - if (phase_acc_ms_ >= SCROLL_MS) { - // Garanteix posició final exacta (POS_X=0). - drawSlide(slide_idx, 0); - if (phase_ == Phase::SLIDE1_ENTER) { - phase_ = Phase::SLIDE1_HOLD; - } else if (phase_ == Phase::SLIDE2_ENTER) { - phase_ = Phase::SLIDE2_HOLD; - } else { - phase_ = Phase::SLIDE3_HOLD; - } - phase_acc_ms_ = 0; - } + case Phase::SLIDE3_ENTER: + tickSlideEnter(delta_ms); break; - } - case Phase::SLIDE1_HOLD: case Phase::SLIDE2_HOLD: - phase_acc_ms_ += delta_ms; - if (phase_acc_ms_ >= HOLD_MS) { - fade_.startFadeOut(); - if (phase_ == Phase::SLIDE1_HOLD) { - phase_ = Phase::FADE_OUT1; - } else { - phase_ = Phase::FADE_OUT2; - } - phase_acc_ms_ = 0; - } + tickHoldIntermediate(delta_ms); break; - case Phase::SLIDE3_HOLD: phase_acc_ms_ += delta_ms; if (phase_acc_ms_ >= HOLD_MS) { beginFinalFade(); } break; - case Phase::FADE_OUT1: case Phase::FADE_OUT2: - fade_.tick(delta_ms); - if (fade_.done()) { - restorePalette(); - Jd8::clearScreen(BG_COLOR_INDEX); - if (phase_ == Phase::FADE_OUT1) { - phase_ = Phase::SLIDE2_ENTER; - } else { - phase_ = Phase::SLIDE3_ENTER; - } - phase_acc_ms_ = 0; - } + tickFadeOutIntermediate(delta_ms); break; - case Phase::FADE_FINAL: - fade_.tick(delta_ms); - if (fade_.done()) { - if (num_piramide_at_start_ == 7) { - Info::ctx.num_piramide = 8; - next_state_ = 1; - } else { - next_state_ = 0; - } - phase_ = Phase::DONE; - } + tickFinalFade(delta_ms); break; - case Phase::DONE: break; } diff --git a/source/game/scenes/slides_scene.hpp b/source/game/scenes/slides_scene.hpp index cbecc55..8ab13f9 100644 --- a/source/game/scenes/slides_scene.hpp +++ b/source/game/scenes/slides_scene.hpp @@ -65,6 +65,12 @@ namespace Scenes { void drawSlide(int slide_idx, int pos_x); void restorePalette(); void beginFinalFade(); + // Helpers per a `tick()` — extrets per reduir complexitat cognitiva. + void triggerSkip(); + void tickSlideEnter(int delta_ms); + void tickHoldIntermediate(int delta_ms); + void tickFadeOutIntermediate(int delta_ms); + void tickFinalFade(int delta_ms); SurfaceHandle gfx_; Jd8::Palette pal_aux_{nullptr}; // còpia "neta" que preservem diff --git a/source/game/scenes/timeline.cpp b/source/game/scenes/timeline.cpp index 27650e1..60dc084 100644 --- a/source/game/scenes/timeline.cpp +++ b/source/game/scenes/timeline.cpp @@ -63,9 +63,9 @@ namespace Scenes { // Pot ser que el següent pas siga una cadena de one-shots. flushOneShots(); } else if (s.continuous) { - const float p = static_cast(elapsed_in_step_) / + const float P = static_cast(elapsed_in_step_) / static_cast(std::max(1, s.duration_ms)); - s.continuous(p); + s.continuous(P); } } diff --git a/source/game/sprite.cpp b/source/game/sprite.cpp index f3a83c4..59ce756 100644 --- a/source/game/sprite.cpp +++ b/source/game/sprite.cpp @@ -1,9 +1,9 @@ #include "game/sprite.hpp" Sprite::Sprite(Jd8::Surface gfx) - : gfx(gfx) {} + : gfx_(gfx) {} void Sprite::draw() { const Frame& f = entitat.frames[entitat.animacions[o].frames[cur_frame]]; - Jd8::blitCK(x, y, gfx, f.x, f.y, f.w, f.h, 255); + Jd8::blitCK(x, y, gfx_, f.x, f.y, f.w, f.h, 255); } diff --git a/source/game/sprite.hpp b/source/game/sprite.hpp index fa49365..913f8f8 100644 --- a/source/game/sprite.hpp +++ b/source/game/sprite.hpp @@ -34,6 +34,6 @@ class Sprite { Uint16 o = 0; protected: - Jd8::Surface gfx; - Uint8 cycles_per_frame = 1; + Jd8::Surface gfx_; + Uint8 cycles_per_frame_ = 1; };