merge: neteja tidy JDD
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
// Implementación de stb_vorbis (debe estar ANTES de incluir jail_audio.hpp).
|
// Implementación de stb_vorbis (debe estar ANTES de incluir jail_audio.hpp).
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#undef STB_VORBIS_HEADER_ONLY
|
#undef STB_VORBIS_HEADER_ONLY
|
||||||
|
// NOLINTNEXTLINE(bugprone-suspicious-include) — stb_vorbis és single-file: el TU principal inclou el .c per portar la implementació.
|
||||||
#include "external/stb_vorbis.c"
|
#include "external/stb_vorbis.c"
|
||||||
// stb_vorbis.c filtra les macros L, C i R (i PLAYBACK_*) al TU. Les netegem
|
// stb_vorbis.c filtra les macros L, C i R (i PLAYBACK_*) al TU. Les netegem
|
||||||
// perquè xocarien amb noms de paràmetres de plantilla en altres headers.
|
// perquè xocarien amb noms de paràmetres de plantilla en altres headers.
|
||||||
@@ -43,15 +44,15 @@ Audio::Audio() { initSDLAudio(); }
|
|||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
Audio::~Audio() {
|
Audio::~Audio() {
|
||||||
JA_Quit();
|
Ja::quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Método principal
|
// Método principal
|
||||||
void Audio::update() {
|
void Audio::update() {
|
||||||
JA_Update();
|
Ja::update();
|
||||||
|
|
||||||
// Sincronizar estado: detectar cuando la música se para (ej. fade-out completado)
|
// 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 != nullptr && instance->music_.state == MusicState::PLAYING && Ja::getMusicState() != Ja::MusicState::PLAYING) {
|
||||||
instance->music_.state = MusicState::STOPPED;
|
instance->music_.state = MusicState::STOPPED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,18 +66,18 @@ void Audio::playMusic(const std::string& name, const int loop, const int crossfa
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!music_enabled_) return;
|
if (!music_enabled_) { return; }
|
||||||
|
|
||||||
auto* resource = AudioResource::getMusic(name);
|
auto* resource = AudioResource::getMusic(name);
|
||||||
if (resource == nullptr) return;
|
if (resource == nullptr) { return; }
|
||||||
|
|
||||||
if (crossfade_ms > 0 && music_.state == MusicState::PLAYING) {
|
if (crossfade_ms > 0 && music_.state == MusicState::PLAYING) {
|
||||||
JA_CrossfadeMusic(resource, crossfade_ms, loop);
|
Ja::crossfadeMusic(resource, crossfade_ms, loop);
|
||||||
} else {
|
} else {
|
||||||
if (music_.state == MusicState::PLAYING) {
|
if (music_.state == MusicState::PLAYING) {
|
||||||
JA_StopMusic();
|
Ja::stopMusic();
|
||||||
}
|
}
|
||||||
JA_PlayMusic(resource, loop);
|
Ja::playMusic(resource, loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
music_.name = name;
|
music_.name = name;
|
||||||
@@ -85,16 +86,16 @@ void Audio::playMusic(const std::string& name, const int loop, const int crossfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reproduce la música por puntero (con crossfade opcional)
|
// 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 (!music_enabled_ || music == nullptr) { return; }
|
||||||
|
|
||||||
if (crossfade_ms > 0 && music_.state == MusicState::PLAYING) {
|
if (crossfade_ms > 0 && music_.state == MusicState::PLAYING) {
|
||||||
JA_CrossfadeMusic(music, crossfade_ms, loop);
|
Ja::crossfadeMusic(music, crossfade_ms, loop);
|
||||||
} else {
|
} else {
|
||||||
if (music_.state == MusicState::PLAYING) {
|
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
|
music_.name.clear(); // nom desconegut quan es passa per punter
|
||||||
@@ -105,7 +106,7 @@ void Audio::playMusic(JA_Music_t* music, const int loop, const int crossfade_ms)
|
|||||||
// Pausa la música
|
// Pausa la música
|
||||||
void Audio::pauseMusic() {
|
void Audio::pauseMusic() {
|
||||||
if (music_enabled_ && music_.state == MusicState::PLAYING) {
|
if (music_enabled_ && music_.state == MusicState::PLAYING) {
|
||||||
JA_PauseMusic();
|
Ja::pauseMusic();
|
||||||
music_.state = MusicState::PAUSED;
|
music_.state = MusicState::PAUSED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,7 +114,7 @@ void Audio::pauseMusic() {
|
|||||||
// Continua la música pausada
|
// Continua la música pausada
|
||||||
void Audio::resumeMusic() {
|
void Audio::resumeMusic() {
|
||||||
if (music_enabled_ && music_.state == MusicState::PAUSED) {
|
if (music_enabled_ && music_.state == MusicState::PAUSED) {
|
||||||
JA_ResumeMusic();
|
Ja::resumeMusic();
|
||||||
music_.state = MusicState::PLAYING;
|
music_.state = MusicState::PLAYING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,7 +122,7 @@ void Audio::resumeMusic() {
|
|||||||
// Detiene la música
|
// Detiene la música
|
||||||
void Audio::stopMusic() {
|
void Audio::stopMusic() {
|
||||||
if (music_enabled_) {
|
if (music_enabled_) {
|
||||||
JA_StopMusic();
|
Ja::stopMusic();
|
||||||
music_.state = MusicState::STOPPED;
|
music_.state = MusicState::STOPPED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,42 +130,42 @@ void Audio::stopMusic() {
|
|||||||
// Reproduce un sonido por nombre
|
// Reproduce un sonido por nombre
|
||||||
void Audio::playSound(const std::string& name, Group group) const {
|
void Audio::playSound(const std::string& name, Group group) const {
|
||||||
if (sound_enabled_) {
|
if (sound_enabled_) {
|
||||||
JA_PlaySound(AudioResource::getSound(name), 0, static_cast<int>(group));
|
Ja::playSound(AudioResource::getSound(name), 0, static_cast<int>(group));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reproduce un sonido por puntero directo
|
// 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) {
|
if (sound_enabled_ && sound != nullptr) {
|
||||||
JA_PlaySound(sound, 0, static_cast<int>(group));
|
Ja::playSound(sound, 0, static_cast<int>(group));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detiene todos los sonidos
|
// Detiene todos los sonidos
|
||||||
void Audio::stopAllSounds() const {
|
void Audio::stopAllSounds() const {
|
||||||
if (sound_enabled_) {
|
if (sound_enabled_) {
|
||||||
JA_StopChannel(-1);
|
Ja::stopChannel(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Realiza un fundido de salida de la música
|
// Realiza un fundido de salida de la música
|
||||||
void Audio::fadeOutMusic(int milliseconds) const {
|
void Audio::fadeOutMusic(int milliseconds) const {
|
||||||
if (music_enabled_ && getRealMusicState() == MusicState::PLAYING) {
|
if (music_enabled_ && getRealMusicState() == MusicState::PLAYING) {
|
||||||
JA_FadeOutMusic(milliseconds);
|
Ja::fadeOutMusic(milliseconds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consulta directamente el estado real de la música en jailaudio
|
// Consulta directamente el estado real de la música en jailaudio
|
||||||
auto Audio::getRealMusicState() -> MusicState {
|
auto Audio::getRealMusicState() -> MusicState {
|
||||||
JA_Music_state ja_state = JA_GetMusicState();
|
Ja::MusicState ja_state = Ja::getMusicState();
|
||||||
switch (ja_state) {
|
switch (ja_state) {
|
||||||
case JA_MUSIC_PLAYING:
|
case Ja::MusicState::PLAYING:
|
||||||
return MusicState::PLAYING;
|
return MusicState::PLAYING;
|
||||||
case JA_MUSIC_PAUSED:
|
case Ja::MusicState::PAUSED:
|
||||||
return MusicState::PAUSED;
|
return MusicState::PAUSED;
|
||||||
case JA_MUSIC_STOPPED:
|
case Ja::MusicState::STOPPED:
|
||||||
case JA_MUSIC_INVALID:
|
case Ja::MusicState::INVALID:
|
||||||
case JA_MUSIC_DISABLED:
|
case Ja::MusicState::DISABLED:
|
||||||
default:
|
default:
|
||||||
return MusicState::STOPPED;
|
return MusicState::STOPPED;
|
||||||
}
|
}
|
||||||
@@ -175,7 +176,7 @@ void Audio::setSoundVolume(float sound_volume, Group group) const {
|
|||||||
if (sound_enabled_) {
|
if (sound_enabled_) {
|
||||||
sound_volume = std::clamp(sound_volume, MIN_VOLUME, MAX_VOLUME);
|
sound_volume = std::clamp(sound_volume, MIN_VOLUME, MAX_VOLUME);
|
||||||
const float CONVERTED_VOLUME = sound_volume * Options::audio.volume;
|
const float CONVERTED_VOLUME = sound_volume * Options::audio.volume;
|
||||||
JA_SetSoundVolume(CONVERTED_VOLUME, static_cast<int>(group));
|
Ja::setSoundVolume(CONVERTED_VOLUME, static_cast<int>(group));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +185,7 @@ void Audio::setMusicVolume(float music_volume) const {
|
|||||||
if (music_enabled_) {
|
if (music_enabled_) {
|
||||||
music_volume = std::clamp(music_volume, MIN_VOLUME, MAX_VOLUME);
|
music_volume = std::clamp(music_volume, MIN_VOLUME, MAX_VOLUME);
|
||||||
const float CONVERTED_VOLUME = music_volume * Options::audio.volume;
|
const float CONVERTED_VOLUME = music_volume * Options::audio.volume;
|
||||||
JA_SetMusicVolume(CONVERTED_VOLUME);
|
Ja::setMusicVolume(CONVERTED_VOLUME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +207,7 @@ void Audio::initSDLAudio() {
|
|||||||
if (!SDL_Init(SDL_INIT_AUDIO)) {
|
if (!SDL_Init(SDL_INIT_AUDIO)) {
|
||||||
std::cout << "SDL_AUDIO could not initialize! SDL Error: " << SDL_GetError() << '\n';
|
std::cout << "SDL_AUDIO could not initialize! SDL Error: " << SDL_GetError() << '\n';
|
||||||
} else {
|
} else {
|
||||||
JA_Init(FREQUENCY, SDL_AUDIO_S16LE, 2);
|
Ja::init(FREQUENCY, SDL_AUDIO_S16LE, 2);
|
||||||
enable(Options::audio.enabled);
|
enable(Options::audio.enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cmath> // Para std::lround
|
||||||
#include <cstdint> // Para int8_t, uint8_t
|
#include <cstdint> // Para int8_t, uint8_t
|
||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
#include <utility> // Para move
|
#include <utility> // Para move
|
||||||
|
|
||||||
|
namespace Ja {
|
||||||
|
struct Music;
|
||||||
|
struct Sound;
|
||||||
|
} // namespace Ja
|
||||||
|
|
||||||
// --- Clase Audio: gestor de audio (singleton) ---
|
// --- Clase Audio: gestor de audio (singleton) ---
|
||||||
// Implementació canònica, byte-idèntica entre projectes.
|
// Implementació canònica, byte-idèntica entre projectes.
|
||||||
// Els volums es manegen internament com a float 0.0–1.0; la capa de
|
// Els volums es manegen internament com a float 0.0–1.0; la capa de
|
||||||
@@ -41,17 +47,17 @@ class Audio {
|
|||||||
static void update(); // Actualización del sistema de audio
|
static void update(); // Actualización del sistema de audio
|
||||||
|
|
||||||
// --- Control de música ---
|
// --- 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(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 pauseMusic(); // Pausar reproducción de música
|
||||||
void resumeMusic(); // Continua la música pausada
|
void resumeMusic(); // Continua la música pausada
|
||||||
void stopMusic(); // Detener completamente la música
|
void stopMusic(); // Detener completamente la música
|
||||||
void fadeOutMusic(int milliseconds) const; // Fundido de salida de la música
|
void fadeOutMusic(int milliseconds) const; // Fundido de salida de la música
|
||||||
|
|
||||||
// --- Control de sonidos ---
|
// --- Control de sonidos ---
|
||||||
void playSound(const std::string& name, Group group = Group::GAME) const; // Reproducir sonido puntual por nombre
|
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
|
void stopAllSounds() const; // Detener todos los sonidos
|
||||||
|
|
||||||
// --- Control de volumen (API interna: float 0.0..1.0) ---
|
// --- Control de volumen (API interna: float 0.0..1.0) ---
|
||||||
void setSoundVolume(float volume, Group group = Group::ALL) const; // Ajustar volumen de efectos
|
void setSoundVolume(float volume, Group group = Group::ALL) const; // Ajustar volumen de efectos
|
||||||
@@ -59,8 +65,8 @@ class Audio {
|
|||||||
|
|
||||||
// --- Helpers de conversió per a la capa de presentació ---
|
// --- Helpers de conversió per a la capa de presentació ---
|
||||||
// UI (menús, notificacions) manega enters 0..100; internament viu float 0..1.
|
// UI (menús, notificacions) manega enters 0..100; internament viu float 0..1.
|
||||||
static constexpr auto toPercent(float volume) -> int {
|
static auto toPercent(float volume) -> int {
|
||||||
return static_cast<int>(volume * 100.0F + 0.5F);
|
return static_cast<int>(std::lround(volume * 100.0F));
|
||||||
}
|
}
|
||||||
static constexpr auto fromPercent(int percent) -> float {
|
static constexpr auto fromPercent(int percent) -> float {
|
||||||
return static_cast<float>(percent) / 100.0F;
|
return static_cast<float>(percent) / 100.0F;
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
#include "core/resources/resource_cache.hpp"
|
#include "core/resources/resource_cache.hpp"
|
||||||
|
|
||||||
namespace AudioResource {
|
namespace AudioResource {
|
||||||
JA_Music_t* getMusic(const std::string& name) {
|
auto getMusic(const std::string& name) -> Ja::Music* {
|
||||||
return Resource::Cache::get()->getMusic(name);
|
return Resource::Cache::get()->getMusic(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
JA_Sound_t* getSound(const std::string& name) {
|
auto getSound(const std::string& name) -> Ja::Sound* {
|
||||||
return Resource::Cache::get()->getSound(name);
|
return Resource::Cache::get()->getSound(name);
|
||||||
}
|
}
|
||||||
} // namespace AudioResource
|
} // namespace AudioResource
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// --- Audio Resource Adapter ---
|
// --- Audio Resource Adapter ---
|
||||||
// Aquest fitxer exposa una interfície comuna a Audio per obtenir JA_Music_t* /
|
// Aquest fitxer exposa una interfície comuna a Audio per obtenir Ja::Music* /
|
||||||
// JA_Sound_t* per nom. Cada projecte la implementa en audio_adapter.cpp
|
// Ja::Sound* per nom. Cada projecte la implementa en audio_adapter.cpp
|
||||||
// delegant al seu singleton de recursos (Resource::get(), Resource::Cache::get(),
|
// delegant al seu singleton de recursos (Resource::get(), Resource::Cache::get(),
|
||||||
// etc.). Això permet que audio.hpp/audio.cpp siguin idèntics entre projectes.
|
// etc.). Això permet que audio.hpp/audio.cpp siguin idèntics entre projectes.
|
||||||
|
|
||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
|
|
||||||
struct JA_Music_t;
|
namespace Ja {
|
||||||
struct JA_Sound_t;
|
struct Music;
|
||||||
|
struct Sound;
|
||||||
|
} // namespace Ja
|
||||||
|
|
||||||
namespace AudioResource {
|
namespace AudioResource {
|
||||||
JA_Music_t* getMusic(const std::string& name);
|
auto getMusic(const std::string& name) -> Ja::Music*;
|
||||||
JA_Sound_t* getSound(const std::string& name);
|
auto getSound(const std::string& name) -> Ja::Sound*;
|
||||||
} // namespace AudioResource
|
} // namespace AudioResource
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_GetGamepadAxis, SDL_GamepadAxis, SDL_GamepadButton, SDL_GetError, SDL_JoystickID, SDL_AddGamepadMappingsFromFile, SDL_Event, SDL_EventType, SDL_GetGamepadButton, SDL_GetKeyboardState, SDL_INIT_GAMEPAD, SDL_InitSubSystem, SDL_LogError, SDL_OpenGamepad, SDL_PollEvent, SDL_WasInit, Sint16, SDL_Gamepad, SDL_LogCategory, SDL_Scancode
|
#include <SDL3/SDL.h> // Para SDL_GetGamepadAxis, SDL_GamepadAxis, SDL_GamepadButton, SDL_GetError, SDL_JoystickID, SDL_AddGamepadMappingsFromFile, SDL_Event, SDL_EventType, SDL_GetGamepadButton, SDL_GetKeyboardState, SDL_INIT_GAMEPAD, SDL_InitSubSystem, SDL_LogError, SDL_OpenGamepad, SDL_PollEvent, SDL_WasInit, Sint16, SDL_Gamepad, SDL_LogCategory, SDL_Scancode
|
||||||
|
|
||||||
|
#include <algorithm> // Para ranges::any_of
|
||||||
#include <iostream> // Para basic_ostream, operator<<, cout, cerr
|
#include <iostream> // Para basic_ostream, operator<<, cout, cerr
|
||||||
#include <memory> // Para shared_ptr, __shared_ptr_access, allocator, operator==, make_shared
|
#include <memory> // Para shared_ptr, __shared_ptr_access, allocator, operator==, make_shared
|
||||||
#include <algorithm> // Para ranges::any_of
|
|
||||||
#include <ranges> // Para __find_if_fn, find_if
|
#include <ranges> // Para __find_if_fn, find_if
|
||||||
#include <unordered_map> // Para unordered_map, _Node_iterator, operator==, _Node_iterator_base, _Node_const_iterator
|
#include <unordered_map> // Para unordered_map, _Node_iterator, operator==, _Node_iterator_base, _Node_const_iterator
|
||||||
#include <utility> // Para pair, move
|
#include <utility> // Para pair, move
|
||||||
@@ -184,8 +184,7 @@ auto Input::checkAnyInput(bool check_keyboard, const std::shared_ptr<Gamepad>& g
|
|||||||
|
|
||||||
// --- Comprobación del Teclado ---
|
// --- Comprobación del Teclado ---
|
||||||
// Llegim l'estat pre-calculat per Input::update() (sense tornar a cridar SDL_GetKeyboardState).
|
// Llegim l'estat pre-calculat per Input::update() (sense tornar a cridar SDL_GetKeyboardState).
|
||||||
if (check_keyboard && std::ranges::any_of(keyboard_.bindings,
|
if (check_keyboard && std::ranges::any_of(keyboard_.bindings, [](const auto& pair) { return pair.second.just_pressed; })) {
|
||||||
[](const auto& pair) { return pair.second.just_pressed; })) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,8 +196,7 @@ auto Input::checkAnyInput(bool check_keyboard, const std::shared_ptr<Gamepad>& g
|
|||||||
|
|
||||||
// --- Comprobación del Mando ---
|
// --- Comprobación del Mando ---
|
||||||
// Iterem sobre totes les accions del mandos pre-calculades per Input::update().
|
// Iterem sobre totes les accions del mandos pre-calculades per Input::update().
|
||||||
if (active_gamepad != nullptr && std::ranges::any_of(active_gamepad->bindings,
|
if (active_gamepad != nullptr && std::ranges::any_of(active_gamepad->bindings, [](const auto& pair) { return pair.second.just_pressed; })) {
|
||||||
[](const auto& pair) { return pair.second.just_pressed; })) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,8 +228,7 @@ auto Input::getControllerName(const std::shared_ptr<Gamepad>& gamepad) -> std::s
|
|||||||
auto Input::getControllerNames() const -> std::vector<std::string> {
|
auto Input::getControllerNames() const -> std::vector<std::string> {
|
||||||
std::vector<std::string> names;
|
std::vector<std::string> names;
|
||||||
names.reserve(gamepads_.size());
|
names.reserve(gamepads_.size());
|
||||||
std::ranges::transform(gamepads_, std::back_inserter(names),
|
std::ranges::transform(gamepads_, std::back_inserter(names), [](const auto& gamepad) { return gamepad->name; });
|
||||||
[](const auto& gamepad) { return gamepad->name; });
|
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,10 +406,10 @@ void Input::update() { // NOLINT(readability-convert-member-functions-to-static
|
|||||||
// JUMP accepta qualsevol dels 4 botons frontals (South/East/North/West)
|
// JUMP accepta qualsevol dels 4 botons frontals (South/East/North/West)
|
||||||
if (action == Action::JUMP) {
|
if (action == Action::JUMP) {
|
||||||
is_down_now = is_down_now ||
|
is_down_now = is_down_now ||
|
||||||
(SDL_GetGamepadButton(gamepad->pad, SDL_GAMEPAD_BUTTON_SOUTH) != 0) ||
|
SDL_GetGamepadButton(gamepad->pad, SDL_GAMEPAD_BUTTON_SOUTH) ||
|
||||||
(SDL_GetGamepadButton(gamepad->pad, SDL_GAMEPAD_BUTTON_EAST) != 0) ||
|
SDL_GetGamepadButton(gamepad->pad, SDL_GAMEPAD_BUTTON_EAST) ||
|
||||||
(SDL_GetGamepadButton(gamepad->pad, SDL_GAMEPAD_BUTTON_NORTH) != 0) ||
|
SDL_GetGamepadButton(gamepad->pad, SDL_GAMEPAD_BUTTON_NORTH) ||
|
||||||
(SDL_GetGamepadButton(gamepad->pad, SDL_GAMEPAD_BUTTON_WEST) != 0);
|
SDL_GetGamepadButton(gamepad->pad, SDL_GAMEPAD_BUTTON_WEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
// El estado .is_held del fotograma anterior nos sirve para saber si es un pulso nuevo
|
// El estado .is_held del fotograma anterior nos sirve para saber si es un pulso nuevo
|
||||||
@@ -428,8 +425,9 @@ auto Input::handleEvent(const SDL_Event& event) -> std::string { // NOLINT(read
|
|||||||
return addGamepad(event.gdevice.which);
|
return addGamepad(event.gdevice.which);
|
||||||
case SDL_EVENT_GAMEPAD_REMOVED:
|
case SDL_EVENT_GAMEPAD_REMOVED:
|
||||||
return removeGamepad(event.gdevice.which);
|
return removeGamepad(event.gdevice.which);
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Input::addGamepad(int device_index) -> std::string { // NOLINT(readability-convert-member-functions-to-static)
|
auto Input::addGamepad(int device_index) -> std::string { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ class Input {
|
|||||||
// Evita nombres como "Retroid Controller (vendor: 1001) ..." en las notificaciones.
|
// Evita nombres como "Retroid Controller (vendor: 1001) ..." en las notificaciones.
|
||||||
static auto trimName(const char* raw) -> std::string {
|
static auto trimName(const char* raw) -> std::string {
|
||||||
std::string s(raw != nullptr ? raw : "");
|
std::string s(raw != nullptr ? raw : "");
|
||||||
const auto pos = s.find_first_of("([");
|
const auto POS = s.find_first_of("([");
|
||||||
if (pos != std::string::npos) { s.erase(pos); }
|
if (POS != std::string::npos) { s.erase(POS); }
|
||||||
while (!s.empty() && s.back() == ' ') { s.pop_back(); }
|
while (!s.empty() && s.back() == ' ') { s.pop_back(); }
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,12 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
// --- Enums ---
|
// --- Enums ---
|
||||||
enum class InputAction : int { // Acciones de entrada posibles en el juego
|
enum class InputAction : std::uint8_t { // Acciones de entrada posibles en el juego
|
||||||
// Inputs de movimiento
|
// Inputs de movimiento
|
||||||
LEFT,
|
LEFT,
|
||||||
RIGHT,
|
RIGHT,
|
||||||
|
|||||||
@@ -224,8 +224,8 @@ namespace GIF {
|
|||||||
if ((screen_descriptor.fields & 0x80) != 0) {
|
if ((screen_descriptor.fields & 0x80) != 0) {
|
||||||
int global_color_table_size = 1 << ((screen_descriptor.fields & 0x07) + 1);
|
int global_color_table_size = 1 << ((screen_descriptor.fields & 0x07) + 1);
|
||||||
global_color_table.resize(global_color_table_size);
|
global_color_table.resize(global_color_table_size);
|
||||||
std::memcpy(global_color_table.data(), buffer, 3 * global_color_table_size);
|
std::memcpy(global_color_table.data(), buffer, static_cast<size_t>(3) * global_color_table_size);
|
||||||
buffer += 3 * global_color_table_size;
|
buffer += static_cast<ptrdiff_t>(3) * global_color_table_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Supongamos que 'buffer' es el puntero actual y TRAILER es 0x3B
|
// Supongamos que 'buffer' es el puntero actual y TRAILER es 0x3B
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -14,7 +15,7 @@ using Palette = std::array<Uint32, 256>;
|
|||||||
class Surface;
|
class Surface;
|
||||||
|
|
||||||
// Modo de ordenación de paletas
|
// Modo de ordenación de paletas
|
||||||
enum class PaletteSortMode : int {
|
enum class PaletteSortMode : std::uint8_t {
|
||||||
ORIGINAL = 0, // Paleta tal cual viene del fichero
|
ORIGINAL = 0, // Paleta tal cual viene del fichero
|
||||||
LUMINANCE = 1, // Ordenada por luminancia percibida
|
LUMINANCE = 1, // Ordenada por luminancia percibida
|
||||||
SPECTRUM = 2, // Reordenada para imitar la paleta ZX Spectrum
|
SPECTRUM = 2, // Reordenada para imitar la paleta ZX Spectrum
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory> // Para shared_ptr
|
#include <cstdint> // Para uint8_t
|
||||||
#include <vector> // Para vector
|
#include <memory> // Para shared_ptr
|
||||||
|
#include <vector> // Para vector
|
||||||
|
|
||||||
class Surface;
|
class Surface;
|
||||||
|
|
||||||
@@ -10,7 +11,7 @@ class Surface;
|
|||||||
class PixelReveal {
|
class PixelReveal {
|
||||||
public:
|
public:
|
||||||
// Modo de revelado: aleatorio por fila o en orden de bisección (dithering ordenado 1D)
|
// Modo de revelado: aleatorio por fila o en orden de bisección (dithering ordenado 1D)
|
||||||
enum class RevealMode { RANDOM,
|
enum class RevealMode : std::uint8_t { RANDOM,
|
||||||
ORDERED };
|
ORDERED };
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint> // Para uint8_t
|
||||||
|
|
||||||
class RenderInfo {
|
class RenderInfo {
|
||||||
public:
|
public:
|
||||||
// Singleton
|
// Singleton
|
||||||
@@ -20,7 +22,7 @@ class RenderInfo {
|
|||||||
static constexpr float SLIDE_SPEED = 120.0F;
|
static constexpr float SLIDE_SPEED = 120.0F;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class Status { HIDDEN,
|
enum class Status : std::uint8_t { HIDDEN,
|
||||||
RISING,
|
RISING,
|
||||||
ACTIVE,
|
ACTIVE,
|
||||||
VANISHING };
|
VANISHING };
|
||||||
|
|||||||
@@ -475,13 +475,13 @@ void Screen::textureToRenderer() {
|
|||||||
|
|
||||||
// Franjas superior e inferior (ancho completo)
|
// Franjas superior e inferior (ancho completo)
|
||||||
std::fill_n(border_pixel_buffer_.data(), OFF_Y * BORDER_W, border_argb_color_);
|
std::fill_n(border_pixel_buffer_.data(), OFF_Y * BORDER_W, border_argb_color_);
|
||||||
std::fill_n(&border_pixel_buffer_[(OFF_Y + GAME_H) * BORDER_W],
|
std::fill_n(&border_pixel_buffer_[static_cast<size_t>(OFF_Y + GAME_H) * BORDER_W],
|
||||||
(BORDER_H - OFF_Y - GAME_H) * BORDER_W,
|
(BORDER_H - OFF_Y - GAME_H) * BORDER_W,
|
||||||
border_argb_color_);
|
border_argb_color_);
|
||||||
// Columnas laterales en las filas del área de juego
|
// Columnas laterales en las filas del área de juego
|
||||||
for (int y = OFF_Y; y < OFF_Y + GAME_H; ++y) {
|
for (int y = OFF_Y; y < OFF_Y + GAME_H; ++y) {
|
||||||
std::fill_n(&border_pixel_buffer_[y * BORDER_W], OFF_X, border_argb_color_);
|
std::fill_n(&border_pixel_buffer_[static_cast<size_t>(y) * BORDER_W], OFF_X, border_argb_color_);
|
||||||
std::fill_n(&border_pixel_buffer_[(y * BORDER_W) + OFF_X + GAME_W],
|
std::fill_n(&border_pixel_buffer_[(static_cast<size_t>(y) * BORDER_W) + OFF_X + GAME_W],
|
||||||
BORDER_W - OFF_X - GAME_W,
|
BORDER_W - OFF_X - GAME_W,
|
||||||
border_argb_color_);
|
border_argb_color_);
|
||||||
}
|
}
|
||||||
@@ -494,7 +494,7 @@ void Screen::textureToRenderer() {
|
|||||||
// Overlay del juego sobre el centro del buffer (ambos paths)
|
// Overlay del juego sobre el centro del buffer (ambos paths)
|
||||||
game_surface_->toARGBBuffer(game_pixel_buffer_.data());
|
game_surface_->toARGBBuffer(game_pixel_buffer_.data());
|
||||||
for (int y = 0; y < GAME_H; ++y) {
|
for (int y = 0; y < GAME_H; ++y) {
|
||||||
const Uint32* src = &game_pixel_buffer_[y * GAME_W];
|
const Uint32* src = &game_pixel_buffer_[static_cast<size_t>(y) * GAME_W];
|
||||||
Uint32* dst = &border_pixel_buffer_[((OFF_Y + y) * BORDER_W) + OFF_X];
|
Uint32* dst = &border_pixel_buffer_[((OFF_Y + y) * BORDER_W) + OFF_X];
|
||||||
std::memcpy(dst, src, GAME_W * sizeof(Uint32));
|
std::memcpy(dst, src, GAME_W * sizeof(Uint32));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <SDL3/SDL_pixels.h> // Para Uint32
|
#include <SDL3/SDL_pixels.h> // Para Uint32
|
||||||
|
|
||||||
#include <cstddef> // Para size_t
|
#include <cstddef> // Para size_t
|
||||||
|
#include <cstdint> // Para uint8_t
|
||||||
#include <memory> // Para shared_ptr, __shared_ptr_access
|
#include <memory> // Para shared_ptr, __shared_ptr_access
|
||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
#include <utility> // Para std::pair
|
#include <utility> // Para std::pair
|
||||||
@@ -18,7 +19,7 @@ class Text;
|
|||||||
class Screen {
|
class Screen {
|
||||||
public:
|
public:
|
||||||
// Tipos de filtro
|
// Tipos de filtro
|
||||||
enum class Filter : Uint32 {
|
enum class Filter : std::uint8_t {
|
||||||
NEAREST = 0,
|
NEAREST = 0,
|
||||||
LINEAR = 1,
|
LINEAR = 1,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -762,7 +762,7 @@ namespace Rendering {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copia directa — el upscale lo hace la GPU en el primer render pass
|
// Copia directa — el upscale lo hace la GPU en el primer render pass
|
||||||
std::memcpy(mapped, pixels, static_cast<size_t>(width * height * 4));
|
std::memcpy(mapped, pixels, static_cast<size_t>(width) * static_cast<size_t>(height) * 4);
|
||||||
|
|
||||||
SDL_UnmapGPUTransferBuffer(device_, upload_buffer_);
|
SDL_UnmapGPUTransferBuffer(device_, upload_buffer_);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,14 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace Rendering {
|
namespace Rendering {
|
||||||
|
|
||||||
/** @brief Identificador del shader de post-procesado activo */
|
/** @brief Identificador del shader de post-procesado activo */
|
||||||
enum class ShaderType { POSTFX,
|
enum class ShaderType : std::uint8_t { POSTFX,
|
||||||
CRTPI };
|
CRTPI };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,14 +2,15 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <memory> // Para shared_ptr
|
#include <cstdint> // Para uint8_t
|
||||||
|
#include <memory> // Para shared_ptr
|
||||||
|
|
||||||
#include "core/rendering/sprite/animated_sprite.hpp" // Para SurfaceAnimatedSprite
|
#include "core/rendering/sprite/animated_sprite.hpp" // Para SurfaceAnimatedSprite
|
||||||
|
|
||||||
class Surface;
|
class Surface;
|
||||||
|
|
||||||
// Direcció de la dissolució
|
// Direcció de la dissolució
|
||||||
enum class DissolveDirection { NONE,
|
enum class DissolveDirection : std::uint8_t { NONE,
|
||||||
DOWN,
|
DOWN,
|
||||||
UP };
|
UP };
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ class DissolveSprite : public AnimatedSprite {
|
|||||||
void setColorReplace(Uint8 source, Uint8 target);
|
void setColorReplace(Uint8 source, Uint8 target);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class TransitionMode { NONE,
|
enum class TransitionMode : std::uint8_t { NONE,
|
||||||
DISSOLVING,
|
DISSOLVING,
|
||||||
GENERATING };
|
GENERATING };
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ class Surface; // lines 5-5
|
|||||||
class Sprite {
|
class Sprite {
|
||||||
public:
|
public:
|
||||||
// Constructores
|
// Constructores
|
||||||
Sprite(std::shared_ptr<Surface>, float x, float y, float w, float h);
|
Sprite(std::shared_ptr<Surface> surface, float x, float y, float w, float h);
|
||||||
Sprite(std::shared_ptr<Surface>, SDL_FRect rect);
|
Sprite(std::shared_ptr<Surface> surface, SDL_FRect rect);
|
||||||
Sprite();
|
Sprite();
|
||||||
explicit Sprite(std::shared_ptr<Surface>);
|
explicit Sprite(std::shared_ptr<Surface> surface);
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
virtual ~Sprite() = default;
|
virtual ~Sprite() = default;
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ void Surface::fillRect(const SDL_FRect* rect, Uint8 color) { // NOLINT(readabil
|
|||||||
const int SURF_WIDTH = surface_data_->width;
|
const int SURF_WIDTH = surface_data_->width;
|
||||||
const int ROW_WIDTH = static_cast<int>(x_end) - static_cast<int>(x_start);
|
const int ROW_WIDTH = static_cast<int>(x_end) - static_cast<int>(x_start);
|
||||||
for (int y = static_cast<int>(y_start); y < static_cast<int>(y_end); ++y) {
|
for (int y = static_cast<int>(y_start); y < static_cast<int>(y_end); ++y) {
|
||||||
std::memset(data_ptr + (y * SURF_WIDTH) + static_cast<int>(x_start), color, ROW_WIDTH);
|
std::memset(data_ptr + (static_cast<ptrdiff_t>(y) * SURF_WIDTH) + static_cast<int>(x_start), color, ROW_WIDTH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,8 +196,8 @@ void Surface::drawRectBorder(const SDL_FRect* rect, Uint8 color) { // NOLINT(re
|
|||||||
Uint8* data_ptr = surface_data_->data.get();
|
Uint8* data_ptr = surface_data_->data.get();
|
||||||
const int SURF_WIDTH = surface_data_->width;
|
const int SURF_WIDTH = surface_data_->width;
|
||||||
const int ROW_WIDTH = static_cast<int>(x_end) - static_cast<int>(x_start);
|
const int ROW_WIDTH = static_cast<int>(x_end) - static_cast<int>(x_start);
|
||||||
std::memset(data_ptr + (static_cast<int>(y_start) * SURF_WIDTH) + static_cast<int>(x_start), color, ROW_WIDTH);
|
std::memset(data_ptr + (static_cast<ptrdiff_t>(y_start) * SURF_WIDTH) + static_cast<int>(x_start), color, ROW_WIDTH);
|
||||||
std::memset(data_ptr + ((static_cast<int>(y_end) - 1) * SURF_WIDTH) + static_cast<int>(x_start), color, ROW_WIDTH);
|
std::memset(data_ptr + ((static_cast<ptrdiff_t>(y_end) - 1) * SURF_WIDTH) + static_cast<int>(x_start), color, ROW_WIDTH);
|
||||||
|
|
||||||
// Dibujar bordes verticales
|
// Dibujar bordes verticales
|
||||||
for (int y = y_start; y < y_end; ++y) {
|
for (int y = y_start; y < y_end; ++y) {
|
||||||
@@ -539,8 +539,8 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture) { //
|
|||||||
const int WIDTH = surface_data_->width;
|
const int WIDTH = surface_data_->width;
|
||||||
const int HEIGHT = surface_data_->height;
|
const int HEIGHT = surface_data_->height;
|
||||||
for (int y = 0; y < HEIGHT; ++y) {
|
for (int y = 0; y < HEIGHT; ++y) {
|
||||||
const Uint8* src_row = src + (y * WIDTH);
|
const Uint8* src_row = src + (static_cast<ptrdiff_t>(y) * WIDTH);
|
||||||
Uint32* dst_row = pixels + (y * row_stride);
|
Uint32* dst_row = pixels + (static_cast<ptrdiff_t>(y) * row_stride);
|
||||||
for (int x = 0; x < WIDTH; ++x) {
|
for (int x = 0; x < WIDTH; ++x) {
|
||||||
dst_row[x] = pal[src_row[x]];
|
dst_row[x] = pal[src_row[x]];
|
||||||
}
|
}
|
||||||
@@ -588,8 +588,8 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_FR
|
|||||||
const int WIDTH = surface_data_->width;
|
const int WIDTH = surface_data_->width;
|
||||||
const int HEIGHT = surface_data_->height;
|
const int HEIGHT = surface_data_->height;
|
||||||
for (int y = 0; y < HEIGHT; ++y) {
|
for (int y = 0; y < HEIGHT; ++y) {
|
||||||
const Uint8* src_row = src + (y * WIDTH);
|
const Uint8* src_row = src + (static_cast<ptrdiff_t>(y) * WIDTH);
|
||||||
Uint32* dst_row = pixels + (y * row_stride);
|
Uint32* dst_row = pixels + (static_cast<ptrdiff_t>(y) * row_stride);
|
||||||
for (int x = 0; x < WIDTH; ++x) {
|
for (int x = 0; x < WIDTH; ++x) {
|
||||||
dst_row[x] = pal[src_row[x]];
|
dst_row[x] = pal[src_row[x]];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ auto Text::nextCodepoint(const std::string& s, size_t& pos) -> uint32_t { // NO
|
|||||||
if (c < 0x80) {
|
if (c < 0x80) {
|
||||||
cp = c;
|
cp = c;
|
||||||
extra = 0;
|
extra = 0;
|
||||||
} else if (c < 0xC0) {
|
} else if (c < 0xE0) {
|
||||||
pos++;
|
if (c < 0xC0) {
|
||||||
return 0xFFFD;
|
pos++;
|
||||||
} // byte de continuación suelto
|
return 0xFFFD; // byte de continuación suelto
|
||||||
else if (c < 0xE0) {
|
}
|
||||||
cp = c & 0x1F;
|
cp = c & 0x1F;
|
||||||
extra = 1;
|
extra = 1;
|
||||||
} else if (c < 0xF0) {
|
} else if (c < 0xF0) {
|
||||||
@@ -260,7 +260,7 @@ void Text::writeDX(Uint8 flags, int x, int y, const std::string& text, int kerni
|
|||||||
if (COLORED) {
|
if (COLORED) {
|
||||||
writeColored(x, y, text, text_color, kerning, lenght);
|
writeColored(x, y, text, text_color, kerning, lenght);
|
||||||
} else {
|
} else {
|
||||||
writeColored(x, y, text, text_color, kerning, lenght);
|
write(x, y, text, kerning, lenght);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include <stdexcept> // Para runtime_error
|
#include <stdexcept> // Para runtime_error
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "core/audio/jail_audio.hpp" // Para JA_DeleteMusic, JA_DeleteSound, JA_Loa...
|
#include "core/audio/jail_audio.hpp" // Para Ja::deleteMusic, Ja::deleteSound, JA_Loa...
|
||||||
#include "core/rendering/screen.hpp" // Para Screen
|
#include "core/rendering/screen.hpp" // Para Screen
|
||||||
#include "core/rendering/text.hpp" // Para Text, loadTextFile
|
#include "core/rendering/text.hpp" // Para Text, loadTextFile
|
||||||
#include "core/resources/resource_helper.hpp" // Para Helper
|
#include "core/resources/resource_helper.hpp" // Para Helper
|
||||||
@@ -21,8 +21,10 @@
|
|||||||
#include "utils/defines.hpp" // Para WINDOW_CAPTION
|
#include "utils/defines.hpp" // Para WINDOW_CAPTION
|
||||||
#include "utils/utils.hpp" // Para getFileName, printWithDots, PaletteColor
|
#include "utils/utils.hpp" // Para getFileName, printWithDots, PaletteColor
|
||||||
#include "version.h" // Para Version::GIT_HASH
|
#include "version.h" // Para Version::GIT_HASH
|
||||||
struct JA_Music_t; // lines 17-17
|
namespace Ja {
|
||||||
struct JA_Sound_t; // lines 18-18
|
struct Music;
|
||||||
|
struct Sound;
|
||||||
|
} // namespace Ja
|
||||||
|
|
||||||
namespace Resource {
|
namespace Resource {
|
||||||
|
|
||||||
@@ -85,148 +87,88 @@ namespace Resource {
|
|||||||
return stage_ == LoadStage::DONE;
|
return stage_ == LoadStage::DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper per a una etapa que itera una llista de recursos.
|
||||||
|
// Imprimeix la capçalera i neteja el vector al primer cop; després carrega
|
||||||
|
// un element per crida fins exhaurir la llista, moment en què passa a `next`.
|
||||||
|
void Cache::stepEachInList(List::Type type, const char* header, const std::function<void()>& clear_fn, LoadStage next, const std::function<void(size_t)>& load_fn) {
|
||||||
|
auto list = List::get()->getListByType(type);
|
||||||
|
if (stage_index_ == 0) {
|
||||||
|
std::cout << "\n>> " << header << '\n';
|
||||||
|
clear_fn();
|
||||||
|
}
|
||||||
|
if (stage_index_ >= list.size()) {
|
||||||
|
stage_ = next;
|
||||||
|
stage_index_ = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
load_fn(stage_index_++);
|
||||||
|
}
|
||||||
|
|
||||||
// Carga assets hasta agotar el presupuesto de tiempo o completar todas las etapas.
|
// Carga assets hasta agotar el presupuesto de tiempo o completar todas las etapas.
|
||||||
// Devuelve true cuando ya no queda nada por cargar.
|
// Devuelve true cuando ya no queda nada por cargar.
|
||||||
auto Cache::loadStep(int budget_ms) -> bool {
|
auto Cache::loadStep(int budget_ms) -> bool {
|
||||||
if (stage_ == LoadStage::DONE) return true;
|
if (stage_ == LoadStage::DONE) { return true; }
|
||||||
|
|
||||||
const Uint64 start_ns = SDL_GetTicksNS();
|
const Uint64 START_NS = SDL_GetTicksNS();
|
||||||
const Uint64 budget_ns = static_cast<Uint64>(budget_ms) * 1'000'000ULL;
|
const Uint64 BUDGET_NS = static_cast<Uint64>(budget_ms) * 1'000'000ULL;
|
||||||
|
|
||||||
auto listOf = [](List::Type t) { return List::get()->getListByType(t); };
|
|
||||||
|
|
||||||
while (stage_ != LoadStage::DONE) {
|
while (stage_ != LoadStage::DONE) {
|
||||||
switch (stage_) {
|
switch (stage_) {
|
||||||
case LoadStage::SOUNDS: {
|
case LoadStage::SOUNDS:
|
||||||
auto list = listOf(List::Type::SOUND);
|
stepEachInList(List::Type::SOUND, "SOUND FILES", [this] { sounds_.clear(); }, LoadStage::MUSICS, [this](size_t i) { loadOneSound(i); });
|
||||||
if (stage_index_ == 0) {
|
|
||||||
std::cout << "\n>> SOUND FILES" << '\n';
|
|
||||||
sounds_.clear();
|
|
||||||
}
|
|
||||||
if (stage_index_ >= list.size()) {
|
|
||||||
stage_ = LoadStage::MUSICS;
|
|
||||||
stage_index_ = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
loadOneSound(stage_index_++);
|
|
||||||
break;
|
break;
|
||||||
}
|
case LoadStage::MUSICS:
|
||||||
case LoadStage::MUSICS: {
|
stepEachInList(List::Type::MUSIC, "MUSIC FILES", [this] { musics_.clear(); }, LoadStage::SURFACES, [this](size_t i) { loadOneMusic(i); });
|
||||||
auto list = listOf(List::Type::MUSIC);
|
|
||||||
if (stage_index_ == 0) {
|
|
||||||
std::cout << "\n>> MUSIC FILES" << '\n';
|
|
||||||
musics_.clear();
|
|
||||||
}
|
|
||||||
if (stage_index_ >= list.size()) {
|
|
||||||
stage_ = LoadStage::SURFACES;
|
|
||||||
stage_index_ = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
loadOneMusic(stage_index_++);
|
|
||||||
break;
|
break;
|
||||||
}
|
case LoadStage::SURFACES:
|
||||||
case LoadStage::SURFACES: {
|
stepEachInList(List::Type::BITMAP, "SURFACES", [this] { surfaces_.clear(); }, LoadStage::SURFACES_POST, [this](size_t i) { loadOneSurface(i); });
|
||||||
auto list = listOf(List::Type::BITMAP);
|
|
||||||
if (stage_index_ == 0) {
|
|
||||||
std::cout << "\n>> SURFACES" << '\n';
|
|
||||||
surfaces_.clear();
|
|
||||||
}
|
|
||||||
if (stage_index_ >= list.size()) {
|
|
||||||
stage_ = LoadStage::SURFACES_POST;
|
|
||||||
stage_index_ = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
loadOneSurface(stage_index_++);
|
|
||||||
break;
|
break;
|
||||||
}
|
case LoadStage::SURFACES_POST:
|
||||||
case LoadStage::SURFACES_POST: {
|
|
||||||
finalizeSurfaces();
|
finalizeSurfaces();
|
||||||
stage_ = LoadStage::PALETTES;
|
stage_ = LoadStage::PALETTES;
|
||||||
stage_index_ = 0;
|
stage_index_ = 0;
|
||||||
break;
|
break;
|
||||||
}
|
case LoadStage::PALETTES:
|
||||||
case LoadStage::PALETTES: {
|
stepEachInList(List::Type::PALETTE, "PALETTES", [this] { palettes_.clear(); }, LoadStage::TEXT_FILES, [this](size_t i) { loadOnePalette(i); });
|
||||||
auto list = listOf(List::Type::PALETTE);
|
|
||||||
if (stage_index_ == 0) {
|
|
||||||
std::cout << "\n>> PALETTES" << '\n';
|
|
||||||
palettes_.clear();
|
|
||||||
}
|
|
||||||
if (stage_index_ >= list.size()) {
|
|
||||||
stage_ = LoadStage::TEXT_FILES;
|
|
||||||
stage_index_ = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
loadOnePalette(stage_index_++);
|
|
||||||
break;
|
break;
|
||||||
}
|
case LoadStage::TEXT_FILES:
|
||||||
case LoadStage::TEXT_FILES: {
|
stepEachInList(List::Type::FONT, "TEXT FILES", [this] { text_files_.clear(); }, LoadStage::ANIMATIONS, [this](size_t i) { loadOneTextFile(i); });
|
||||||
auto list = listOf(List::Type::FONT);
|
|
||||||
if (stage_index_ == 0) {
|
|
||||||
std::cout << "\n>> TEXT FILES" << '\n';
|
|
||||||
text_files_.clear();
|
|
||||||
}
|
|
||||||
if (stage_index_ >= list.size()) {
|
|
||||||
stage_ = LoadStage::ANIMATIONS;
|
|
||||||
stage_index_ = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
loadOneTextFile(stage_index_++);
|
|
||||||
break;
|
break;
|
||||||
}
|
case LoadStage::ANIMATIONS:
|
||||||
case LoadStage::ANIMATIONS: {
|
stepEachInList(List::Type::ANIMATION, "ANIMATIONS", [this] { animations_.clear(); }, LoadStage::ROOMS, [this](size_t i) { loadOneAnimation(i); });
|
||||||
auto list = listOf(List::Type::ANIMATION);
|
|
||||||
if (stage_index_ == 0) {
|
|
||||||
std::cout << "\n>> ANIMATIONS" << '\n';
|
|
||||||
animations_.clear();
|
|
||||||
}
|
|
||||||
if (stage_index_ >= list.size()) {
|
|
||||||
stage_ = LoadStage::ROOMS;
|
|
||||||
stage_index_ = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
loadOneAnimation(stage_index_++);
|
|
||||||
break;
|
break;
|
||||||
}
|
case LoadStage::ROOMS:
|
||||||
case LoadStage::ROOMS: {
|
stepEachInList(List::Type::ROOM, "ROOMS", [this] { rooms_.clear(); }, LoadStage::TEXTS, [this](size_t i) { loadOneRoom(i); });
|
||||||
auto list = listOf(List::Type::ROOM);
|
|
||||||
if (stage_index_ == 0) {
|
|
||||||
std::cout << "\n>> ROOMS" << '\n';
|
|
||||||
rooms_.clear();
|
|
||||||
}
|
|
||||||
if (stage_index_ >= list.size()) {
|
|
||||||
stage_ = LoadStage::TEXTS;
|
|
||||||
stage_index_ = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
loadOneRoom(stage_index_++);
|
|
||||||
break;
|
break;
|
||||||
}
|
case LoadStage::TEXTS:
|
||||||
case LoadStage::TEXTS: {
|
stepTexts();
|
||||||
// createText itera sobre una lista fija de 5 fuentes
|
|
||||||
constexpr size_t TEXT_COUNT = 5;
|
|
||||||
if (stage_index_ == 0) {
|
|
||||||
std::cout << "\n>> CREATING TEXT_OBJECTS" << '\n';
|
|
||||||
texts_.clear();
|
|
||||||
}
|
|
||||||
if (stage_index_ >= TEXT_COUNT) {
|
|
||||||
stage_ = LoadStage::DONE;
|
|
||||||
stage_index_ = 0;
|
|
||||||
std::cout << "\n** RESOURCES LOADED" << '\n';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
createOneText(stage_index_++);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case LoadStage::DONE:
|
case LoadStage::DONE:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((SDL_GetTicksNS() - start_ns) >= budget_ns) break;
|
if ((SDL_GetTicksNS() - START_NS) >= BUDGET_NS) { break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
return stage_ == LoadStage::DONE;
|
return stage_ == LoadStage::DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Cache::stepTexts() {
|
||||||
|
// createText itera sobre una lista fija de 5 fuentes
|
||||||
|
constexpr size_t TEXT_COUNT = 5;
|
||||||
|
if (stage_index_ == 0) {
|
||||||
|
std::cout << "\n>> CREATING TEXT_OBJECTS" << '\n';
|
||||||
|
texts_.clear();
|
||||||
|
}
|
||||||
|
if (stage_index_ >= TEXT_COUNT) {
|
||||||
|
stage_ = LoadStage::DONE;
|
||||||
|
stage_index_ = 0;
|
||||||
|
std::cout << "\n** RESOURCES LOADED" << '\n';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
createOneText(stage_index_++);
|
||||||
|
}
|
||||||
|
|
||||||
// Recarga todos los recursos (síncrono, solo para hot-reload de debug)
|
// Recarga todos los recursos (síncrono, solo para hot-reload de debug)
|
||||||
void Cache::reload() {
|
void Cache::reload() {
|
||||||
clear();
|
clear();
|
||||||
@@ -234,7 +176,7 @@ namespace Resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene el sonido a partir de un nombre
|
// Obtiene el sonido a partir de un nombre
|
||||||
auto Cache::getSound(const std::string& name) -> JA_Sound_t* { // NOLINT(readability-convert-member-functions-to-static)
|
auto Cache::getSound(const std::string& name) -> Ja::Sound* { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
auto it = std::ranges::find_if(sounds_, [&name](const auto& s) -> bool { return s.name == name; });
|
auto it = std::ranges::find_if(sounds_, [&name](const auto& s) -> bool { return s.name == name; });
|
||||||
|
|
||||||
if (it != sounds_.end()) {
|
if (it != sounds_.end()) {
|
||||||
@@ -246,7 +188,7 @@ namespace Resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene la música a partir de un nombre
|
// Obtiene la música a partir de un nombre
|
||||||
auto Cache::getMusic(const std::string& name) -> JA_Music_t* { // NOLINT(readability-convert-member-functions-to-static)
|
auto Cache::getMusic(const std::string& name) -> Ja::Music* { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
auto it = std::ranges::find_if(musics_, [&name](const auto& m) -> bool { return m.name == name; });
|
auto it = std::ranges::find_if(musics_, [&name](const auto& m) -> bool { return m.name == name; });
|
||||||
|
|
||||||
if (it != musics_.end()) {
|
if (it != musics_.end()) {
|
||||||
@@ -379,14 +321,14 @@ namespace Resource {
|
|||||||
std::string text_file; // Nombre del archivo de texto
|
std::string text_file; // Nombre del archivo de texto
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<TextObjectInfo>& getTextObjectInfos() {
|
auto getTextObjectInfos() -> const std::vector<TextObjectInfo>& {
|
||||||
static const std::vector<TextObjectInfo> info = {
|
static const std::vector<TextObjectInfo> INFO = {
|
||||||
{.key = "aseprite", .texture_file = "aseprite.gif", .text_file = "aseprite.fnt"},
|
{.key = "aseprite", .texture_file = "aseprite.gif", .text_file = "aseprite.fnt"},
|
||||||
{.key = "gauntlet", .texture_file = "gauntlet.gif", .text_file = "gauntlet.fnt"},
|
{.key = "gauntlet", .texture_file = "gauntlet.gif", .text_file = "gauntlet.fnt"},
|
||||||
{.key = "smb2", .texture_file = "smb2.gif", .text_file = "smb2.fnt"},
|
{.key = "smb2", .texture_file = "smb2.gif", .text_file = "smb2.fnt"},
|
||||||
{.key = "subatomic", .texture_file = "subatomic.gif", .text_file = "subatomic.fnt"},
|
{.key = "subatomic", .texture_file = "subatomic.gif", .text_file = "subatomic.fnt"},
|
||||||
{.key = "8bithud", .texture_file = "8bithud.gif", .text_file = "8bithud.fnt"}};
|
{.key = "8bithud", .texture_file = "8bithud.gif", .text_file = "8bithud.fnt"}};
|
||||||
return info;
|
return INFO;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@@ -398,14 +340,14 @@ namespace Resource {
|
|||||||
try {
|
try {
|
||||||
auto name = getFileName(l);
|
auto name = getFileName(l);
|
||||||
setCurrentLoading(name);
|
setCurrentLoading(name);
|
||||||
JA_Sound_t* sound = nullptr;
|
Ja::Sound* sound = nullptr;
|
||||||
|
|
||||||
auto audio_data = Helper::loadFile(l);
|
auto audio_data = Helper::loadFile(l);
|
||||||
if (!audio_data.empty()) {
|
if (!audio_data.empty()) {
|
||||||
sound = JA_LoadSound(audio_data.data(), static_cast<Uint32>(audio_data.size()));
|
sound = Ja::loadSound(audio_data.data(), static_cast<Uint32>(audio_data.size()));
|
||||||
}
|
}
|
||||||
if (sound == nullptr) {
|
if (sound == nullptr) {
|
||||||
sound = JA_LoadSound(l.c_str());
|
sound = Ja::loadSound(l.c_str());
|
||||||
}
|
}
|
||||||
if (sound == nullptr) {
|
if (sound == nullptr) {
|
||||||
throw std::runtime_error("Failed to decode audio file");
|
throw std::runtime_error("Failed to decode audio file");
|
||||||
@@ -426,14 +368,14 @@ namespace Resource {
|
|||||||
try {
|
try {
|
||||||
auto name = getFileName(l);
|
auto name = getFileName(l);
|
||||||
setCurrentLoading(name);
|
setCurrentLoading(name);
|
||||||
JA_Music_t* music = nullptr;
|
Ja::Music* music = nullptr;
|
||||||
|
|
||||||
auto audio_data = Helper::loadFile(l);
|
auto audio_data = Helper::loadFile(l);
|
||||||
if (!audio_data.empty()) {
|
if (!audio_data.empty()) {
|
||||||
music = JA_LoadMusic(audio_data.data(), static_cast<Uint32>(audio_data.size()));
|
music = Ja::loadMusic(audio_data.data(), static_cast<Uint32>(audio_data.size()));
|
||||||
}
|
}
|
||||||
if (music == nullptr) {
|
if (music == nullptr) {
|
||||||
music = JA_LoadMusic(l.c_str());
|
music = Ja::loadMusic(l.c_str());
|
||||||
}
|
}
|
||||||
if (music == nullptr) {
|
if (music == nullptr) {
|
||||||
throw std::runtime_error("Failed to decode music file");
|
throw std::runtime_error("Failed to decode music file");
|
||||||
@@ -553,21 +495,21 @@ namespace Resource {
|
|||||||
std::cout << "\n>> SOUND FILES" << '\n';
|
std::cout << "\n>> SOUND FILES" << '\n';
|
||||||
auto list = List::get()->getListByType(List::Type::SOUND);
|
auto list = List::get()->getListByType(List::Type::SOUND);
|
||||||
sounds_.clear();
|
sounds_.clear();
|
||||||
for (size_t i = 0; i < list.size(); ++i) loadOneSound(i);
|
for (size_t i = 0; i < list.size(); ++i) { loadOneSound(i); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cache::loadMusics() {
|
void Cache::loadMusics() {
|
||||||
std::cout << "\n>> MUSIC FILES" << '\n';
|
std::cout << "\n>> MUSIC FILES" << '\n';
|
||||||
auto list = List::get()->getListByType(List::Type::MUSIC);
|
auto list = List::get()->getListByType(List::Type::MUSIC);
|
||||||
musics_.clear();
|
musics_.clear();
|
||||||
for (size_t i = 0; i < list.size(); ++i) loadOneMusic(i);
|
for (size_t i = 0; i < list.size(); ++i) { loadOneMusic(i); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cache::loadSurfaces() {
|
void Cache::loadSurfaces() {
|
||||||
std::cout << "\n>> SURFACES" << '\n';
|
std::cout << "\n>> SURFACES" << '\n';
|
||||||
auto list = List::get()->getListByType(List::Type::BITMAP);
|
auto list = List::get()->getListByType(List::Type::BITMAP);
|
||||||
surfaces_.clear();
|
surfaces_.clear();
|
||||||
for (size_t i = 0; i < list.size(); ++i) loadOneSurface(i);
|
for (size_t i = 0; i < list.size(); ++i) { loadOneSurface(i); }
|
||||||
finalizeSurfaces();
|
finalizeSurfaces();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -575,43 +517,43 @@ namespace Resource {
|
|||||||
std::cout << "\n>> PALETTES" << '\n';
|
std::cout << "\n>> PALETTES" << '\n';
|
||||||
auto list = List::get()->getListByType(List::Type::PALETTE);
|
auto list = List::get()->getListByType(List::Type::PALETTE);
|
||||||
palettes_.clear();
|
palettes_.clear();
|
||||||
for (size_t i = 0; i < list.size(); ++i) loadOnePalette(i);
|
for (size_t i = 0; i < list.size(); ++i) { loadOnePalette(i); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cache::loadTextFiles() {
|
void Cache::loadTextFiles() {
|
||||||
std::cout << "\n>> TEXT FILES" << '\n';
|
std::cout << "\n>> TEXT FILES" << '\n';
|
||||||
auto list = List::get()->getListByType(List::Type::FONT);
|
auto list = List::get()->getListByType(List::Type::FONT);
|
||||||
text_files_.clear();
|
text_files_.clear();
|
||||||
for (size_t i = 0; i < list.size(); ++i) loadOneTextFile(i);
|
for (size_t i = 0; i < list.size(); ++i) { loadOneTextFile(i); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cache::loadAnimations() {
|
void Cache::loadAnimations() {
|
||||||
std::cout << "\n>> ANIMATIONS" << '\n';
|
std::cout << "\n>> ANIMATIONS" << '\n';
|
||||||
auto list = List::get()->getListByType(List::Type::ANIMATION);
|
auto list = List::get()->getListByType(List::Type::ANIMATION);
|
||||||
animations_.clear();
|
animations_.clear();
|
||||||
for (size_t i = 0; i < list.size(); ++i) loadOneAnimation(i);
|
for (size_t i = 0; i < list.size(); ++i) { loadOneAnimation(i); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cache::loadRooms() {
|
void Cache::loadRooms() {
|
||||||
std::cout << "\n>> ROOMS" << '\n';
|
std::cout << "\n>> ROOMS" << '\n';
|
||||||
auto list = List::get()->getListByType(List::Type::ROOM);
|
auto list = List::get()->getListByType(List::Type::ROOM);
|
||||||
rooms_.clear();
|
rooms_.clear();
|
||||||
for (size_t i = 0; i < list.size(); ++i) loadOneRoom(i);
|
for (size_t i = 0; i < list.size(); ++i) { loadOneRoom(i); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cache::createText() {
|
void Cache::createText() {
|
||||||
std::cout << "\n>> CREATING TEXT_OBJECTS" << '\n';
|
std::cout << "\n>> CREATING TEXT_OBJECTS" << '\n';
|
||||||
texts_.clear();
|
texts_.clear();
|
||||||
const auto& infos = getTextObjectInfos();
|
const auto& infos = getTextObjectInfos();
|
||||||
for (size_t i = 0; i < infos.size(); ++i) createOneText(i);
|
for (size_t i = 0; i < infos.size(); ++i) { createOneText(i); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vacía el vector de sonidos
|
// Vacía el vector de sonidos
|
||||||
void Cache::clearSounds() {
|
void Cache::clearSounds() {
|
||||||
// Itera sobre el vector y libera los recursos asociados a cada JA_Sound_t
|
// Itera sobre el vector y libera los recursos asociados a cada Ja::Sound
|
||||||
for (auto& sound : sounds_) {
|
for (auto& sound : sounds_) {
|
||||||
if (sound.sound != nullptr) {
|
if (sound.sound != nullptr) {
|
||||||
JA_DeleteSound(sound.sound);
|
Ja::deleteSound(sound.sound);
|
||||||
sound.sound = nullptr;
|
sound.sound = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -620,10 +562,10 @@ namespace Resource {
|
|||||||
|
|
||||||
// Vacía el vector de musicas
|
// Vacía el vector de musicas
|
||||||
void Cache::clearMusics() {
|
void Cache::clearMusics() {
|
||||||
// Itera sobre el vector y libera los recursos asociados a cada JA_Music_t
|
// Itera sobre el vector y libera los recursos asociados a cada Ja::Music
|
||||||
for (auto& music : musics_) {
|
for (auto& music : musics_) {
|
||||||
if (music.music != nullptr) {
|
if (music.music != nullptr) {
|
||||||
JA_DeleteMusic(music.music);
|
Ja::deleteMusic(music.music);
|
||||||
music.music = nullptr;
|
music.music = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory> // Para shared_ptr
|
#include <cstdint> // Para uint8_t
|
||||||
#include <string> // Para string
|
#include <functional> // Para std::function
|
||||||
|
#include <memory> // Para shared_ptr
|
||||||
|
#include <string> // Para string
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
|
#include "core/resources/resource_list.hpp" // Para List::Type
|
||||||
#include "core/resources/resource_types.hpp" // Para structs de recursos
|
#include "core/resources/resource_types.hpp" // Para structs de recursos
|
||||||
|
|
||||||
namespace Resource {
|
namespace Resource {
|
||||||
@@ -15,8 +18,8 @@ namespace Resource {
|
|||||||
static void destroy(); // Destrucción singleton
|
static void destroy(); // Destrucción singleton
|
||||||
static auto get() -> Cache*; // Acceso al singleton
|
static auto get() -> Cache*; // Acceso al singleton
|
||||||
|
|
||||||
auto getSound(const std::string& name) -> JA_Sound_t*; // Getters de recursos
|
auto getSound(const std::string& name) -> Ja::Sound*; // Getters de recursos
|
||||||
auto getMusic(const std::string& name) -> JA_Music_t*;
|
auto getMusic(const std::string& name) -> Ja::Music*;
|
||||||
auto getSurface(const std::string& name) -> std::shared_ptr<Surface>;
|
auto getSurface(const std::string& name) -> std::shared_ptr<Surface>;
|
||||||
auto getPalette(const std::string& name) -> Palette;
|
auto getPalette(const std::string& name) -> Palette;
|
||||||
auto getTextFile(const std::string& name) -> std::shared_ptr<Text::File>;
|
auto getTextFile(const std::string& name) -> std::shared_ptr<Text::File>;
|
||||||
@@ -54,7 +57,7 @@ namespace Resource {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Etapas del loader incremental
|
// Etapas del loader incremental
|
||||||
enum class LoadStage {
|
enum class LoadStage : std::uint8_t {
|
||||||
SOUNDS,
|
SOUNDS,
|
||||||
MUSICS,
|
MUSICS,
|
||||||
SURFACES,
|
SURFACES,
|
||||||
@@ -102,6 +105,11 @@ namespace Resource {
|
|||||||
// Helper para mensajes de error de carga
|
// Helper para mensajes de error de carga
|
||||||
static void logLoadError(const std::string& asset_type, const std::string& file_path, const std::exception& e);
|
static void logLoadError(const std::string& asset_type, const std::string& file_path, const std::exception& e);
|
||||||
|
|
||||||
|
// Helper d'iteració per a una etapa que recorre una llista de recursos.
|
||||||
|
// Crida `load_fn(i)` per a cada element i, en exhaurir-se, transiciona a `next`.
|
||||||
|
void stepEachInList(List::Type type, const char* header, const std::function<void()>& clear_fn, LoadStage next, const std::function<void(size_t)>& load_fn);
|
||||||
|
void stepTexts(); // Etapa especial: no usa List, itera sobre TEXT_COUNT fonts fixes.
|
||||||
|
|
||||||
// Constructor y destructor
|
// Constructor y destructor
|
||||||
Cache();
|
Cache();
|
||||||
~Cache() = default;
|
~Cache() = default;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace Resource {
|
|||||||
class List {
|
class List {
|
||||||
public:
|
public:
|
||||||
// --- Enums ---
|
// --- Enums ---
|
||||||
enum class Type : int {
|
enum class Type : std::uint8_t {
|
||||||
DATA, // Datos
|
DATA, // Datos
|
||||||
BITMAP, // Imágenes
|
BITMAP, // Imágenes
|
||||||
ANIMATION, // Animaciones
|
ANIMATION, // Animaciones
|
||||||
|
|||||||
@@ -6,19 +6,18 @@
|
|||||||
#include <SDL3/SDL_filesystem.h>
|
#include <SDL3/SDL_filesystem.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <numeric>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
namespace Resource {
|
namespace Resource {
|
||||||
|
|
||||||
// Calculate CRC32 checksum for data verification
|
// Calculate CRC32 checksum for data verification
|
||||||
auto Pack::calculateChecksum(const std::vector<uint8_t>& data) -> uint32_t { // NOLINT(readability-convert-member-functions-to-static)
|
auto Pack::calculateChecksum(const std::vector<uint8_t>& data) -> uint32_t { // NOLINT(readability-convert-member-functions-to-static)
|
||||||
return std::accumulate(data.begin(), data.end(), uint32_t{0x12345678},
|
return std::accumulate(data.begin(), data.end(), uint32_t{0x12345678}, [](uint32_t acc, unsigned char byte) -> uint32_t {
|
||||||
[](uint32_t acc, unsigned char byte) -> uint32_t {
|
return ((acc << 5) + acc) + byte;
|
||||||
return ((acc << 5) + acc) + byte;
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// XOR encryption (symmetric - same function for encrypt/decrypt)
|
// XOR encryption (symmetric - same function for encrypt/decrypt)
|
||||||
|
|||||||
@@ -10,19 +10,21 @@
|
|||||||
#include "game/gameplay/room.hpp" // Para Room::Data
|
#include "game/gameplay/room.hpp" // Para Room::Data
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
struct JA_Music_t;
|
namespace Ja {
|
||||||
struct JA_Sound_t;
|
struct Music;
|
||||||
|
struct Sound;
|
||||||
|
} // namespace Ja
|
||||||
|
|
||||||
// Estructura para almacenar ficheros de sonido y su nombre
|
// Estructura para almacenar ficheros de sonido y su nombre
|
||||||
struct SoundResource {
|
struct SoundResource {
|
||||||
std::string name; // Nombre del sonido
|
std::string name; // Nombre del sonido
|
||||||
JA_Sound_t* sound{nullptr}; // Objeto con el sonido
|
Ja::Sound* sound{nullptr}; // Objeto con el sonido
|
||||||
};
|
};
|
||||||
|
|
||||||
// Estructura para almacenar ficheros musicales y su nombre
|
// Estructura para almacenar ficheros musicales y su nombre
|
||||||
struct MusicResource {
|
struct MusicResource {
|
||||||
std::string name; // Nombre de la musica
|
std::string name; // Nombre de la musica
|
||||||
JA_Music_t* music{nullptr}; // Objeto con la música
|
Ja::Music* music{nullptr}; // Objeto con la música
|
||||||
};
|
};
|
||||||
|
|
||||||
// Estructura para almacenar objetos Surface y su nombre
|
// Estructura para almacenar objetos Surface y su nombre
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ namespace {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Director::Director() : executable_path_(getExecutablePath()) {
|
Director::Director()
|
||||||
|
: executable_path_(getExecutablePath()) {
|
||||||
std::cout << "Game start" << '\n';
|
std::cout << "Game start" << '\n';
|
||||||
|
|
||||||
// Crea la carpeta del sistema donde guardar datos
|
// Crea la carpeta del sistema donde guardar datos
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace GlobalEvents {
|
|||||||
namespace {
|
namespace {
|
||||||
// Flag per saber si en aquest frame s'ha rebut un button down del gamepad.
|
// Flag per saber si en aquest frame s'ha rebut un button down del gamepad.
|
||||||
// El consumeix GlobalInputs perquè un botó del comandament salti escenes.
|
// El consumeix GlobalInputs perquè un botó del comandament salti escenes.
|
||||||
bool gamepad_button_pressed_ = false;
|
bool gamepad_button_pressed = false;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// Comprueba los eventos que se pueden producir en cualquier sección del juego.
|
// Comprueba los eventos que se pueden producir en cualquier sección del juego.
|
||||||
@@ -56,7 +56,7 @@ namespace GlobalEvents {
|
|||||||
const bool RESERVE_BACK = IS_BACK;
|
const bool RESERVE_BACK = IS_BACK;
|
||||||
#endif
|
#endif
|
||||||
if (!RESERVE_BACK && !IS_SHOULDER) {
|
if (!RESERVE_BACK && !IS_SHOULDER) {
|
||||||
gamepad_button_pressed_ = true;
|
gamepad_button_pressed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,8 +72,8 @@ namespace GlobalEvents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto consumeGamepadButtonPressed() -> bool {
|
auto consumeGamepadButtonPressed() -> bool {
|
||||||
const bool RESULT = gamepad_button_pressed_;
|
const bool RESULT = gamepad_button_pressed;
|
||||||
gamepad_button_pressed_ = false;
|
gamepad_button_pressed = false;
|
||||||
return RESULT;
|
return RESULT;
|
||||||
}
|
}
|
||||||
} // namespace GlobalEvents
|
} // namespace GlobalEvents
|
||||||
@@ -836,8 +836,6 @@ void Player::updateVelocity() {
|
|||||||
sprite_->setFlip(Flip::RIGHT);
|
sprite_->setFlip(Flip::RIGHT);
|
||||||
break;
|
break;
|
||||||
case Direction::NONE:
|
case Direction::NONE:
|
||||||
vx_ = 0.0F;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
vx_ = 0.0F;
|
vx_ = 0.0F;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <array> // Para array
|
#include <array> // Para array
|
||||||
#include <limits> // Para numeric_limits
|
#include <cstdint> // Para uint8_t
|
||||||
#include <memory> // Para shared_ptr, __shared_ptr_access
|
#include <limits> // Para numeric_limits
|
||||||
#include <string> // Para string
|
#include <memory> // Para shared_ptr, __shared_ptr_access
|
||||||
|
#include <string> // Para string
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "core/rendering/sprite/animated_sprite.hpp" // Para SAnimatedSprite
|
#include "core/rendering/sprite/animated_sprite.hpp" // Para SAnimatedSprite
|
||||||
@@ -13,19 +14,21 @@
|
|||||||
#include "game/options.hpp" // Para Cheat, Options, options
|
#include "game/options.hpp" // Para Cheat, Options, options
|
||||||
#include "utils/defines.hpp" // Para BORDER_TOP, BLOCK
|
#include "utils/defines.hpp" // Para BORDER_TOP, BLOCK
|
||||||
#include "utils/utils.hpp" // Para Color
|
#include "utils/utils.hpp" // Para Color
|
||||||
struct JA_Sound_t; // lines 13-13
|
namespace Ja {
|
||||||
|
struct Sound;
|
||||||
|
}
|
||||||
|
|
||||||
class Player {
|
class Player {
|
||||||
public:
|
public:
|
||||||
// --- Enums y Structs ---
|
// --- Enums y Structs ---
|
||||||
enum class State {
|
enum class State : std::uint8_t {
|
||||||
ON_GROUND, // En suelo plano o conveyor belt
|
ON_GROUND, // En suelo plano o conveyor belt
|
||||||
ON_SLOPE, // En rampa/pendiente
|
ON_SLOPE, // En rampa/pendiente
|
||||||
JUMPING,
|
JUMPING,
|
||||||
FALLING,
|
FALLING,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Direction {
|
enum class Direction : std::uint8_t {
|
||||||
LEFT,
|
LEFT,
|
||||||
RIGHT,
|
RIGHT,
|
||||||
UP,
|
UP,
|
||||||
@@ -155,12 +158,12 @@ class Player {
|
|||||||
int last_grounded_position_ = 0; // Ultima posición en Y en la que se estaba en contacto con el suelo (hace doble función: tracking de caída + altura inicial del salto)
|
int last_grounded_position_ = 0; // Ultima posición en Y en la que se estaba en contacto con el suelo (hace doble función: tracking de caída + altura inicial del salto)
|
||||||
|
|
||||||
// --- Variables de renderizado y sonido ---
|
// --- Variables de renderizado y sonido ---
|
||||||
Uint8 color_ = 0; // Color del jugador
|
Uint8 color_ = 0; // Color del jugador
|
||||||
std::array<JA_Sound_t*, 24> jumping_sound_{}; // Array con todos los sonidos del salto
|
std::array<Ja::Sound*, 24> jumping_sound_{}; // Array con todos los sonidos del salto
|
||||||
std::array<JA_Sound_t*, 14> falling_sound_{}; // Array con todos los sonidos de la caída
|
std::array<Ja::Sound*, 14> falling_sound_{}; // Array con todos los sonidos de la caída
|
||||||
JumpSoundController jump_sound_ctrl_; // Controlador de sonidos de salto
|
JumpSoundController jump_sound_ctrl_; // Controlador de sonidos de salto
|
||||||
FallSoundController fall_sound_ctrl_; // Controlador de sonidos de caída
|
FallSoundController fall_sound_ctrl_; // Controlador de sonidos de caída
|
||||||
int fall_start_position_ = 0; // Posición Y al iniciar la caída
|
int fall_start_position_ = 0; // Posición Y al iniciar la caída
|
||||||
|
|
||||||
void handleConveyorBelts();
|
void handleConveyorBelts();
|
||||||
void handleShouldFall();
|
void handleShouldFall();
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <vector> // Para vector
|
#include <cstdint> // Para uint8_t
|
||||||
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "utils/utils.hpp" // Para LineHorizontal, LineDiagonal, LineVertical
|
#include "utils/utils.hpp" // Para LineHorizontal, LineDiagonal, LineVertical
|
||||||
|
|
||||||
@@ -18,7 +19,7 @@
|
|||||||
class CollisionMap {
|
class CollisionMap {
|
||||||
public:
|
public:
|
||||||
// Enumeración de tipos de tile (para colisiones)
|
// Enumeración de tipos de tile (para colisiones)
|
||||||
enum class Tile {
|
enum class Tile : std::uint8_t {
|
||||||
EMPTY,
|
EMPTY,
|
||||||
WALL,
|
WALL,
|
||||||
PASSABLE,
|
PASSABLE,
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <memory> // Para shared_ptr
|
#include <cstdint> // Para uint8_t
|
||||||
#include <string> // Para string
|
#include <memory> // Para shared_ptr
|
||||||
#include <vector> // Para vector
|
#include <string> // Para string
|
||||||
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "game/entities/enemy.hpp" // Para EnemyData
|
#include "game/entities/enemy.hpp" // Para EnemyData
|
||||||
#include "game/entities/item.hpp" // Para ItemData
|
#include "game/entities/item.hpp" // Para ItemData
|
||||||
@@ -20,7 +21,7 @@ class TilemapRenderer;
|
|||||||
class Room {
|
class Room {
|
||||||
public:
|
public:
|
||||||
// -- Enumeraciones y estructuras ---
|
// -- Enumeraciones y estructuras ---
|
||||||
enum class Border : int {
|
enum class Border : std::uint8_t {
|
||||||
TOP = 0,
|
TOP = 0,
|
||||||
RIGHT = 1,
|
RIGHT = 1,
|
||||||
BOTTOM = 2,
|
BOTTOM = 2,
|
||||||
@@ -28,7 +29,7 @@ class Room {
|
|||||||
NONE = 4
|
NONE = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Tile {
|
enum class Tile : std::uint8_t {
|
||||||
EMPTY,
|
EMPTY,
|
||||||
WALL,
|
WALL,
|
||||||
PASSABLE,
|
PASSABLE,
|
||||||
|
|||||||
@@ -133,8 +133,7 @@ void RoomLoader::parseTilemap(const fkyaml::node& yaml, Room::Data& room, const
|
|||||||
for (const auto& row_node : tilemap_node) {
|
for (const auto& row_node : tilemap_node) {
|
||||||
std::vector<int> row;
|
std::vector<int> row;
|
||||||
row.reserve(32);
|
row.reserve(32);
|
||||||
std::ranges::transform(row_node, std::back_inserter(row),
|
std::ranges::transform(row_node, std::back_inserter(row), [](const auto& tile_node) { return tile_node.template get_value<int>(); });
|
||||||
[](const auto& tile_node) { return tile_node.template get_value<int>(); });
|
|
||||||
tilemap_2d.push_back(std::move(row));
|
tilemap_2d.push_back(std::move(row));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,8 +37,7 @@ Scoreboard::Scoreboard(std::shared_ptr<Data> data)
|
|||||||
// Inicializa el vector de colores
|
// Inicializa el vector de colores
|
||||||
const std::vector<std::string> COLORS = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"};
|
const std::vector<std::string> COLORS = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"};
|
||||||
color_.reserve(COLORS.size());
|
color_.reserve(COLORS.size());
|
||||||
std::ranges::transform(COLORS, std::back_inserter(color_),
|
std::ranges::transform(COLORS, std::back_inserter(color_), [](const auto& color) { return stringToColor(color); });
|
||||||
[](const auto& color) { return stringToColor(color); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pinta el objeto en pantalla
|
// Pinta el objeto en pantalla
|
||||||
|
|||||||
@@ -368,12 +368,14 @@ namespace Options {
|
|||||||
if (sh_node.contains("current_postfx_preset")) {
|
if (sh_node.contains("current_postfx_preset")) {
|
||||||
try {
|
try {
|
||||||
video.shader.current_postfx_preset_name = sh_node["current_postfx_preset"].get_value<std::string>();
|
video.shader.current_postfx_preset_name = sh_node["current_postfx_preset"].get_value<std::string>();
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (sh_node.contains("current_crtpi_preset")) {
|
if (sh_node.contains("current_crtpi_preset")) {
|
||||||
try {
|
try {
|
||||||
video.shader.current_crtpi_preset_name = sh_node["current_crtpi_preset"].get_value<std::string>();
|
video.shader.current_crtpi_preset_name = sh_node["current_crtpi_preset"].get_value<std::string>();
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -573,24 +575,28 @@ namespace Options {
|
|||||||
if (a.contains("enabled")) {
|
if (a.contains("enabled")) {
|
||||||
try {
|
try {
|
||||||
audio.enabled = a["enabled"].get_value<bool>();
|
audio.enabled = a["enabled"].get_value<bool>();
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (a.contains("volume")) {
|
if (a.contains("volume")) {
|
||||||
try {
|
try {
|
||||||
audio.volume = std::clamp(a["volume"].get_value<float>(), 0.0F, 1.0F);
|
audio.volume = std::clamp(a["volume"].get_value<float>(), 0.0F, 1.0F);
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (a.contains("music")) {
|
if (a.contains("music")) {
|
||||||
const auto& m = a["music"];
|
const auto& m = a["music"];
|
||||||
if (m.contains("enabled")) {
|
if (m.contains("enabled")) {
|
||||||
try {
|
try {
|
||||||
audio.music.enabled = m["enabled"].get_value<bool>();
|
audio.music.enabled = m["enabled"].get_value<bool>();
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (m.contains("volume")) {
|
if (m.contains("volume")) {
|
||||||
try {
|
try {
|
||||||
audio.music.volume = std::clamp(m["volume"].get_value<float>(), 0.0F, 1.0F);
|
audio.music.volume = std::clamp(m["volume"].get_value<float>(), 0.0F, 1.0F);
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (a.contains("sound")) {
|
if (a.contains("sound")) {
|
||||||
@@ -598,12 +604,14 @@ namespace Options {
|
|||||||
if (s.contains("enabled")) {
|
if (s.contains("enabled")) {
|
||||||
try {
|
try {
|
||||||
audio.sound.enabled = s["enabled"].get_value<bool>();
|
audio.sound.enabled = s["enabled"].get_value<bool>();
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (s.contains("volume")) {
|
if (s.contains("volume")) {
|
||||||
try {
|
try {
|
||||||
audio.sound.volume = std::clamp(s["volume"].get_value<float>(), 0.0F, 1.0F);
|
audio.sound.volume = std::clamp(s["volume"].get_value<float>(), 0.0F, 1.0F);
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -891,7 +899,8 @@ namespace Options {
|
|||||||
if (node.contains(key)) {
|
if (node.contains(key)) {
|
||||||
try {
|
try {
|
||||||
target = node[key].get_value<float>();
|
target = node[key].get_value<float>();
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1181,32 +1190,38 @@ namespace Options {
|
|||||||
if (p.contains("mask_type")) {
|
if (p.contains("mask_type")) {
|
||||||
try {
|
try {
|
||||||
preset.mask_type = p["mask_type"].get_value<int>();
|
preset.mask_type = p["mask_type"].get_value<int>();
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (p.contains("enable_scanlines")) {
|
if (p.contains("enable_scanlines")) {
|
||||||
try {
|
try {
|
||||||
preset.enable_scanlines = p["enable_scanlines"].get_value<bool>();
|
preset.enable_scanlines = p["enable_scanlines"].get_value<bool>();
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (p.contains("enable_multisample")) {
|
if (p.contains("enable_multisample")) {
|
||||||
try {
|
try {
|
||||||
preset.enable_multisample = p["enable_multisample"].get_value<bool>();
|
preset.enable_multisample = p["enable_multisample"].get_value<bool>();
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (p.contains("enable_gamma")) {
|
if (p.contains("enable_gamma")) {
|
||||||
try {
|
try {
|
||||||
preset.enable_gamma = p["enable_gamma"].get_value<bool>();
|
preset.enable_gamma = p["enable_gamma"].get_value<bool>();
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (p.contains("enable_curvature")) {
|
if (p.contains("enable_curvature")) {
|
||||||
try {
|
try {
|
||||||
preset.enable_curvature = p["enable_curvature"].get_value<bool>();
|
preset.enable_curvature = p["enable_curvature"].get_value<bool>();
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (p.contains("enable_sharper")) {
|
if (p.contains("enable_sharper")) {
|
||||||
try {
|
try {
|
||||||
preset.enable_sharper = p["enable_sharper"].get_value<bool>();
|
preset.enable_sharper = p["enable_sharper"].get_value<bool>();
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
crtpi_presets.push_back(preset);
|
crtpi_presets.push_back(preset);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint> // Para uint8_t
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Namespace SceneManager: gestiona el flujo entre las diferentes escenas del juego.
|
Namespace SceneManager: gestiona el flujo entre las diferentes escenas del juego.
|
||||||
|
|
||||||
@@ -10,7 +12,7 @@
|
|||||||
namespace SceneManager {
|
namespace SceneManager {
|
||||||
|
|
||||||
// --- Escenas del programa ---
|
// --- Escenas del programa ---
|
||||||
enum class Scene {
|
enum class Scene : std::uint8_t {
|
||||||
BOOT_LOADER, // Carga inicial de recursos dirigida por iterate()
|
BOOT_LOADER, // Carga inicial de recursos dirigida por iterate()
|
||||||
LOGO, // Pantalla del logo
|
LOGO, // Pantalla del logo
|
||||||
LOADING_SCREEN, // Pantalla de carga
|
LOADING_SCREEN, // Pantalla de carga
|
||||||
@@ -26,7 +28,7 @@ namespace SceneManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// --- Opciones para transiciones entre escenas ---
|
// --- Opciones para transiciones entre escenas ---
|
||||||
enum class Options {
|
enum class Options : std::uint8_t {
|
||||||
NONE, // Sin opciones especiales
|
NONE, // Sin opciones especiales
|
||||||
LOGO_TO_LOADING_SCREEN, // Del logo a la intro
|
LOGO_TO_LOADING_SCREEN, // Del logo a la intro
|
||||||
LOGO_TO_TITLE, // Del logo al título
|
LOGO_TO_TITLE, // Del logo al título
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <memory> // Para shared_ptr
|
#include <cstdint> // Para uint8_t
|
||||||
#include <string> // Para string
|
#include <memory> // Para shared_ptr
|
||||||
#include <vector> // Para vector
|
#include <string> // Para string
|
||||||
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "game/scenes/scene.hpp" // Para Scene
|
#include "game/scenes/scene.hpp" // Para Scene
|
||||||
class AnimatedSprite; // lines 11-11
|
class AnimatedSprite; // lines 11-11
|
||||||
@@ -24,7 +25,7 @@ class Credits : public Scene {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Tipos anidados ---
|
// --- Tipos anidados ---
|
||||||
enum class State {
|
enum class State : std::uint8_t {
|
||||||
REVEALING_TEXT,
|
REVEALING_TEXT,
|
||||||
PAUSE_1,
|
PAUSE_1,
|
||||||
REVEALING_TEXT_2,
|
REVEALING_TEXT_2,
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <memory> // Para shared_ptr
|
#include <cstdint> // Para uint8_t
|
||||||
#include <string> // Para string
|
#include <memory> // Para shared_ptr
|
||||||
#include <vector> // Para vector
|
#include <string> // Para string
|
||||||
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "game/scenes/scene.hpp" // Para Scene
|
#include "game/scenes/scene.hpp" // Para Scene
|
||||||
class Sprite; // lines 8-8
|
class Sprite; // lines 8-8
|
||||||
@@ -24,7 +25,7 @@ class Ending : public Scene {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Enumeraciones ---
|
// --- Enumeraciones ---
|
||||||
enum class State {
|
enum class State : std::uint8_t {
|
||||||
WARMING_UP,
|
WARMING_UP,
|
||||||
SCENE_0,
|
SCENE_0,
|
||||||
SCENE_1,
|
SCENE_1,
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ Ending2::Ending2()
|
|||||||
// Inicializa el vector de colores
|
// Inicializa el vector de colores
|
||||||
const std::vector<std::string> COLORS = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
|
const std::vector<std::string> COLORS = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
|
||||||
colors_.reserve(COLORS.size());
|
colors_.reserve(COLORS.size());
|
||||||
std::ranges::transform(COLORS, std::back_inserter(colors_),
|
std::ranges::transform(COLORS, std::back_inserter(colors_), [](const auto& color) { return stringToColor(color); });
|
||||||
[](const auto& color) { return stringToColor(color); });
|
|
||||||
|
|
||||||
Screen::get()->setBorderColor(static_cast<Uint8>(PaletteColor::BLACK)); // Cambia el color del borde
|
Screen::get()->setBorderColor(static_cast<Uint8>(PaletteColor::BLACK)); // Cambia el color del borde
|
||||||
iniSpriteList(); // Inicializa la lista de sprites
|
iniSpriteList(); // Inicializa la lista de sprites
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <memory> // Para shared_ptr
|
#include <cstdint> // Para uint8_t
|
||||||
#include <string> // Para string
|
#include <memory> // Para shared_ptr
|
||||||
#include <vector> // Para vector
|
#include <string> // Para string
|
||||||
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "core/rendering/sprite/dissolve_sprite.hpp" // Para SurfaceDissolveSprite
|
#include "core/rendering/sprite/dissolve_sprite.hpp" // Para SurfaceDissolveSprite
|
||||||
#include "game/scenes/scene.hpp" // Para Scene
|
#include "game/scenes/scene.hpp" // Para Scene
|
||||||
@@ -25,7 +26,7 @@ class Ending2 : public Scene {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Enumeraciones ---
|
// --- Enumeraciones ---
|
||||||
enum class EndingState : int {
|
enum class EndingState : std::uint8_t {
|
||||||
PRE_CREDITS, // Estado previo a los créditos
|
PRE_CREDITS, // Estado previo a los créditos
|
||||||
CREDITS, // Estado de los créditos
|
CREDITS, // Estado de los créditos
|
||||||
POST_CREDITS, // Estado posterior a los créditos
|
POST_CREDITS, // Estado posterior a los créditos
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <cmath> // Para std::sqrt, std::min
|
#include <cmath> // Para std::sqrt, std::min
|
||||||
#include <numeric> // Para std::accumulate
|
#include <numeric> // Para std::accumulate
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
@@ -867,8 +867,7 @@ auto Game::checkEndGame() -> bool {
|
|||||||
// Obtiene la cantidad total de items que hay en el mapeado del juego
|
// Obtiene la cantidad total de items que hay en el mapeado del juego
|
||||||
auto Game::getTotalItems() -> int {
|
auto Game::getTotalItems() -> int {
|
||||||
const auto& rooms = Resource::Cache::get()->getRooms();
|
const auto& rooms = Resource::Cache::get()->getRooms();
|
||||||
return static_cast<int>(std::accumulate(rooms.begin(), rooms.end(), size_t{0},
|
return static_cast<int>(std::accumulate(rooms.begin(), rooms.end(), size_t{0}, [](size_t acc, const auto& room) { return acc + room.room->items.size(); }));
|
||||||
[](size_t acc, const auto& room) { return acc + room.room->items.size(); }));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pone el juego en pausa
|
// Pone el juego en pausa
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include <cstdint> // Para uint8_t
|
||||||
#include <initializer_list> // Para initializer_list
|
#include <initializer_list> // Para initializer_list
|
||||||
#include <memory> // Para shared_ptr
|
#include <memory> // Para shared_ptr
|
||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
@@ -19,12 +20,12 @@ class Surface;
|
|||||||
class Game : public Scene {
|
class Game : public Scene {
|
||||||
public:
|
public:
|
||||||
// --- Estructuras ---
|
// --- Estructuras ---
|
||||||
enum class Mode {
|
enum class Mode : std::uint8_t {
|
||||||
DEMO,
|
DEMO,
|
||||||
GAME
|
GAME
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class State {
|
enum class State : std::uint8_t {
|
||||||
PLAYING, // Normal gameplay
|
PLAYING, // Normal gameplay
|
||||||
BLACK_SCREEN, // Black screen after death (0.30s)
|
BLACK_SCREEN, // Black screen after death (0.30s)
|
||||||
GAME_OVER, // Intermediate state before changing scene
|
GAME_OVER, // Intermediate state before changing scene
|
||||||
|
|||||||
@@ -39,8 +39,7 @@ GameOver::GameOver()
|
|||||||
// Inicializa el vector de colores (de brillante a oscuro para fade)
|
// Inicializa el vector de colores (de brillante a oscuro para fade)
|
||||||
const std::vector<std::string> COLORS = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
|
const std::vector<std::string> COLORS = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
|
||||||
colors_.reserve(COLORS.size());
|
colors_.reserve(COLORS.size());
|
||||||
std::ranges::transform(COLORS, std::back_inserter(colors_),
|
std::ranges::transform(COLORS, std::back_inserter(colors_), [](const auto& color) { return stringToColor(color); });
|
||||||
[](const auto& color) { return stringToColor(color); });
|
|
||||||
color_ = colors_.back(); // Empieza en black
|
color_ = colors_.back(); // Empieza en black
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <memory> // Para shared_ptr
|
#include <cstdint> // Para uint8_t
|
||||||
#include <vector> // Para vector
|
#include <memory> // Para shared_ptr
|
||||||
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "game/scenes/scene.hpp" // Para Scene
|
#include "game/scenes/scene.hpp" // Para Scene
|
||||||
class AnimatedSprite; // lines 7-7
|
class AnimatedSprite; // lines 7-7
|
||||||
@@ -21,7 +22,7 @@ class GameOver : public Scene {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Enumeraciones ---
|
// --- Enumeraciones ---
|
||||||
enum class State {
|
enum class State : std::uint8_t {
|
||||||
WAITING, // Espera inicial antes de empezar
|
WAITING, // Espera inicial antes de empezar
|
||||||
FADE_IN, // Fade in de colores desde black
|
FADE_IN, // Fade in de colores desde black
|
||||||
DISPLAY, // Mostrando contenido con color brillante
|
DISPLAY, // Mostrando contenido con color brillante
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <array> // Para std::array
|
#include <array> // Para std::array
|
||||||
#include <memory> // Para shared_ptr
|
#include <cstdint> // Para uint8_t
|
||||||
|
#include <memory> // Para shared_ptr
|
||||||
|
|
||||||
#include "game/scenes/scene.hpp" // Para Scene
|
#include "game/scenes/scene.hpp" // Para Scene
|
||||||
#include "utils/delta_timer.hpp" // Para DeltaTimer
|
#include "utils/delta_timer.hpp" // Para DeltaTimer
|
||||||
@@ -24,7 +25,7 @@ class LoadingScreen : public Scene {
|
|||||||
private:
|
private:
|
||||||
// --- Enumeraciones ---
|
// --- Enumeraciones ---
|
||||||
// Estados de la secuencia de carga
|
// Estados de la secuencia de carga
|
||||||
enum class State {
|
enum class State : std::uint8_t {
|
||||||
SILENT1, // Pausa inicial antes de empezar
|
SILENT1, // Pausa inicial antes de empezar
|
||||||
HEADER1, // Cabecera
|
HEADER1, // Cabecera
|
||||||
DATA1, // Datos
|
DATA1, // Datos
|
||||||
@@ -37,7 +38,7 @@ class LoadingScreen : public Scene {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Tipos de borde para la pantalla de carga
|
// Tipos de borde para la pantalla de carga
|
||||||
enum class Border {
|
enum class Border : std::uint8_t {
|
||||||
NONE,
|
NONE,
|
||||||
YELLOW_AND_BLUE,
|
YELLOW_AND_BLUE,
|
||||||
RED_AND_CYAN,
|
RED_AND_CYAN,
|
||||||
|
|||||||
@@ -238,9 +238,6 @@ void Logo::endSection() {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SceneManager::Options::LOGO_TO_LOADING_SCREEN:
|
case SceneManager::Options::LOGO_TO_LOADING_SCREEN:
|
||||||
SceneManager::current = SceneManager::Scene::LOADING_SCREEN;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
SceneManager::current = SceneManager::Scene::LOADING_SCREEN;
|
SceneManager::current = SceneManager::Scene::LOADING_SCREEN;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include <cstdint> // Para uint8_t
|
||||||
#include <functional> // Para std::function
|
#include <functional> // Para std::function
|
||||||
#include <memory> // Para shared_ptr
|
#include <memory> // Para shared_ptr
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
@@ -17,7 +18,7 @@ class Logo : public Scene {
|
|||||||
using EasingFunction = std::function<float(float)>; // Función de easing (permite lambdas)
|
using EasingFunction = std::function<float(float)>; // Función de easing (permite lambdas)
|
||||||
|
|
||||||
// --- Enumeraciones ---
|
// --- Enumeraciones ---
|
||||||
enum class State {
|
enum class State : std::uint8_t {
|
||||||
INITIAL, // Espera inicial
|
INITIAL, // Espera inicial
|
||||||
JAILGAMES_SLIDE_IN, // Las líneas de JAILGAMES se deslizan hacia el centro
|
JAILGAMES_SLIDE_IN, // Las líneas de JAILGAMES se deslizan hacia el centro
|
||||||
SINCE_1998_FADE_IN, // Aparición gradual del texto "Since 1998"
|
SINCE_1998_FADE_IN, // Aparición gradual del texto "Since 1998"
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <array> // Para std::array
|
#include <array> // Para std::array
|
||||||
#include <memory> // Para shared_ptr
|
#include <cstdint> // Para uint8_t
|
||||||
#include <string> // Para string
|
#include <memory> // Para shared_ptr
|
||||||
#include <vector> // Para vector
|
#include <string> // Para string
|
||||||
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "game/scene_manager.hpp" // Para SceneManager::Scene
|
#include "game/scene_manager.hpp" // Para SceneManager::Scene
|
||||||
#include "game/scenes/scene.hpp" // Para Scene
|
#include "game/scenes/scene.hpp" // Para Scene
|
||||||
@@ -34,7 +35,7 @@ class Title : public Scene {
|
|||||||
bool enabled{false}; // Solo se escriben y mueven si estan habilitadas
|
bool enabled{false}; // Solo se escriben y mueven si estan habilitadas
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class State {
|
enum class State : std::uint8_t {
|
||||||
SHOW_LOADING_SCREEN,
|
SHOW_LOADING_SCREEN,
|
||||||
FADE_LOADING_SCREEN,
|
FADE_LOADING_SCREEN,
|
||||||
MAIN_MENU,
|
MAIN_MENU,
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <algorithm> // Para ranges::transform
|
#include <algorithm> // Para ranges::transform
|
||||||
#include <numeric> // Para std::accumulate
|
|
||||||
#include <cctype> // Para toupper
|
#include <cctype> // Para toupper
|
||||||
|
#include <numeric> // Para std::accumulate
|
||||||
#include <sstream> // Para std::istringstream
|
#include <sstream> // Para std::istringstream
|
||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
@@ -66,9 +66,11 @@ auto Console::wrapText(const std::string& text) const -> std::vector<std::string
|
|||||||
std::istringstream word_stream(segment);
|
std::istringstream word_stream(segment);
|
||||||
std::string word;
|
std::string word;
|
||||||
while (word_stream >> word) {
|
while (word_stream >> word) {
|
||||||
const std::string TEST = current_line.empty() ? word : (current_line + ' ' + word);
|
std::string test = current_line;
|
||||||
if (text_->length(TEST) <= MAX_PX) {
|
if (!test.empty()) { test += ' '; }
|
||||||
current_line = TEST;
|
test += word;
|
||||||
|
if (text_->length(test) <= MAX_PX) {
|
||||||
|
current_line = std::move(test);
|
||||||
} else {
|
} else {
|
||||||
if (!current_line.empty()) { result.push_back(current_line); }
|
if (!current_line.empty()) { result.push_back(current_line); }
|
||||||
current_line = word;
|
current_line = word;
|
||||||
@@ -182,11 +184,10 @@ void Console::update(float delta_time) { // NOLINT(readability-function-cogniti
|
|||||||
|
|
||||||
// Efecto typewriter: revelar letras una a una (solo cuando ACTIVE)
|
// Efecto typewriter: revelar letras una a una (solo cuando ACTIVE)
|
||||||
if (status_ == Status::ACTIVE) {
|
if (status_ == Status::ACTIVE) {
|
||||||
const int total_chars = std::accumulate(msg_lines_.begin(), msg_lines_.end(), 0,
|
const int TOTAL_CHARS = std::accumulate(msg_lines_.begin(), msg_lines_.end(), 0, [](int acc, const auto& line) { return acc + static_cast<int>(line.size()); });
|
||||||
[](int acc, const auto& line) { return acc + static_cast<int>(line.size()); });
|
if (typewriter_chars_ < TOTAL_CHARS) {
|
||||||
if (typewriter_chars_ < total_chars) {
|
|
||||||
typewriter_timer_ += delta_time;
|
typewriter_timer_ += delta_time;
|
||||||
while (typewriter_timer_ >= TYPEWRITER_CHAR_DELAY && typewriter_chars_ < total_chars) {
|
while (typewriter_timer_ >= TYPEWRITER_CHAR_DELAY && typewriter_chars_ < TOTAL_CHARS) {
|
||||||
typewriter_timer_ -= TYPEWRITER_CHAR_DELAY;
|
typewriter_timer_ -= TYPEWRITER_CHAR_DELAY;
|
||||||
++typewriter_chars_;
|
++typewriter_chars_;
|
||||||
}
|
}
|
||||||
@@ -339,15 +340,17 @@ void Console::handleEvent(const SDL_Event& event) { // NOLINT(readability-funct
|
|||||||
if (SPACE_POS == std::string::npos) {
|
if (SPACE_POS == std::string::npos) {
|
||||||
// Modo comando: ciclar keywords visibles que empiecen por el prefijo
|
// Modo comando: ciclar keywords visibles que empiecen por el prefijo
|
||||||
const auto KEYWORDS = registry_.getVisibleKeywords();
|
const auto KEYWORDS = registry_.getVisibleKeywords();
|
||||||
std::ranges::copy_if(KEYWORDS, std::back_inserter(tab_matches_),
|
std::ranges::copy_if(KEYWORDS, std::back_inserter(tab_matches_), [&upper](const auto& kw) { return upper.empty() || kw.starts_with(upper); });
|
||||||
[&upper](const auto& kw) { return upper.empty() || kw.starts_with(upper); });
|
|
||||||
} else {
|
} else {
|
||||||
const std::string BASE_CMD = upper.substr(0, SPACE_POS);
|
const std::string BASE_CMD = upper.substr(0, SPACE_POS);
|
||||||
const std::string SUB_PREFIX = upper.substr(SPACE_POS + 1);
|
const std::string SUB_PREFIX = upper.substr(SPACE_POS + 1);
|
||||||
const auto OPTS = registry_.getCompletions(BASE_CMD);
|
const auto OPTS = registry_.getCompletions(BASE_CMD);
|
||||||
for (const auto& arg : OPTS) {
|
for (const auto& arg : OPTS) {
|
||||||
if (SUB_PREFIX.empty() || std::string_view{arg}.starts_with(SUB_PREFIX)) {
|
if (SUB_PREFIX.empty() || std::string_view{arg}.starts_with(SUB_PREFIX)) {
|
||||||
tab_matches_.emplace_back(BASE_CMD + " " + arg);
|
std::string match = BASE_CMD;
|
||||||
|
match += ' ';
|
||||||
|
match += arg;
|
||||||
|
tab_matches_.push_back(std::move(match));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -356,8 +359,7 @@ void Console::handleEvent(const SDL_Event& event) { // NOLINT(readability-funct
|
|||||||
if (tab_matches_.empty()) { break; }
|
if (tab_matches_.empty()) { break; }
|
||||||
tab_index_ = (tab_index_ + 1) % static_cast<int>(tab_matches_.size());
|
tab_index_ = (tab_index_ + 1) % static_cast<int>(tab_matches_.size());
|
||||||
std::string result = tab_matches_[static_cast<size_t>(tab_index_)];
|
std::string result = tab_matches_[static_cast<size_t>(tab_index_)];
|
||||||
std::ranges::transform(result, result.begin(),
|
std::ranges::transform(result, result.begin(), [](char c) { return static_cast<char>(std::tolower(static_cast<unsigned char>(c))); });
|
||||||
[](char c) { return static_cast<char>(std::tolower(static_cast<unsigned char>(c))); });
|
|
||||||
input_line_ = result;
|
input_line_ = result;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -403,8 +405,7 @@ void Console::processCommand() {
|
|||||||
|
|
||||||
// Typewriter: instantáneo si el comando lo requiere, letra a letra si no
|
// Typewriter: instantáneo si el comando lo requiere, letra a letra si no
|
||||||
if (instant) {
|
if (instant) {
|
||||||
typewriter_chars_ = std::accumulate(msg_lines_.begin(), msg_lines_.end(), 0,
|
typewriter_chars_ = std::accumulate(msg_lines_.begin(), msg_lines_.end(), 0, [](int acc, const auto& l) { return acc + static_cast<int>(l.size()); });
|
||||||
[](int acc, const auto& l) { return acc + static_cast<int>(l.size()); });
|
|
||||||
} else {
|
} else {
|
||||||
typewriter_chars_ = 0;
|
typewriter_chars_ = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include <cstdint> // Para uint8_t
|
||||||
#include <deque> // Para deque (historial)
|
#include <deque> // Para deque (historial)
|
||||||
#include <functional> // Para function
|
#include <functional> // Para function
|
||||||
#include <memory> // Para shared_ptr
|
#include <memory> // Para shared_ptr
|
||||||
@@ -43,7 +44,7 @@ class Console {
|
|||||||
std::function<void(bool)> on_toggle;
|
std::function<void(bool)> on_toggle;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class Status {
|
enum class Status : std::uint8_t {
|
||||||
HIDDEN,
|
HIDDEN,
|
||||||
RISING,
|
RISING,
|
||||||
ACTIVE,
|
ACTIVE,
|
||||||
|
|||||||
@@ -259,7 +259,8 @@ static auto cmdZoom(const std::vector<std::string>& args) -> std::string {
|
|||||||
if (N == Options::window.zoom) { return "Zoom already " + std::to_string(N); }
|
if (N == Options::window.zoom) { return "Zoom already " + std::to_string(N); }
|
||||||
Screen::get()->setWindowZoom(N);
|
Screen::get()->setWindowZoom(N);
|
||||||
return "Zoom " + std::to_string(Options::window.zoom);
|
return "Zoom " + std::to_string(Options::window.zoom);
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
return "usage: zoom [up|down|<1-" + std::to_string(Screen::getMaxZoom()) + ">]";
|
return "usage: zoom [up|down|<1-" + std::to_string(Screen::getMaxZoom()) + ">]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -912,7 +913,8 @@ static auto cmdPlayer(const std::vector<std::string>& args) -> std::string {
|
|||||||
int color = -1;
|
int color = -1;
|
||||||
try {
|
try {
|
||||||
color = std::stoi(args[1]);
|
color = std::stoi(args[1]);
|
||||||
} catch (...) {}
|
} catch (...) { /* @INTENTIONAL: camp YAML malformat → conservem default */
|
||||||
|
}
|
||||||
if (color < 0 || color > 15) { return "usage: player color <0-15>|default"; }
|
if (color < 0 || color > 15) { return "usage: player color <0-15>|default"; }
|
||||||
if (!GameControl::change_player_color) { return "Game not initialized"; }
|
if (!GameControl::change_player_color) { return "Game not initialized"; }
|
||||||
GameControl::change_player_color(color);
|
GameControl::change_player_color(color);
|
||||||
@@ -1013,8 +1015,7 @@ void CommandRegistry::registerHandlers() { // NOLINT(readability-function-cogni
|
|||||||
std::vector<std::string> result = {"NEXT", "PREV", "SORT", "DEFAULT"};
|
std::vector<std::string> result = {"NEXT", "PREV", "SORT", "DEFAULT"};
|
||||||
if (Screen::get() != nullptr) {
|
if (Screen::get() != nullptr) {
|
||||||
const auto NAMES = Screen::get()->getPaletteNames();
|
const auto NAMES = Screen::get()->getPaletteNames();
|
||||||
std::ranges::transform(NAMES, std::back_inserter(result),
|
std::ranges::transform(NAMES, std::back_inserter(result), [](const auto& name) { return toUpper(name); });
|
||||||
[](const auto& name) { return toUpper(name); });
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
@@ -1120,8 +1121,7 @@ void CommandRegistry::load(const std::string& yaml_path) { // NOLINT(readabilit
|
|||||||
if (cat_node.contains("scope")) {
|
if (cat_node.contains("scope")) {
|
||||||
const auto& scope_node = cat_node["scope"];
|
const auto& scope_node = cat_node["scope"];
|
||||||
if (scope_node.is_sequence()) {
|
if (scope_node.is_sequence()) {
|
||||||
std::ranges::transform(scope_node, std::back_inserter(cat_scopes),
|
std::ranges::transform(scope_node, std::back_inserter(cat_scopes), [](const auto& s) { return s.template get_value<std::string>(); });
|
||||||
[](const auto& s) { return s.template get_value<std::string>(); });
|
|
||||||
} else {
|
} else {
|
||||||
cat_scopes.push_back(scope_node.get_value<std::string>());
|
cat_scopes.push_back(scope_node.get_value<std::string>());
|
||||||
}
|
}
|
||||||
@@ -1162,8 +1162,7 @@ void CommandRegistry::load(const std::string& yaml_path) { // NOLINT(readabilit
|
|||||||
for (auto it = completions_node.begin(); it != completions_node.end(); ++it) {
|
for (auto it = completions_node.begin(); it != completions_node.end(); ++it) {
|
||||||
auto path = it.key().get_value<std::string>();
|
auto path = it.key().get_value<std::string>();
|
||||||
std::vector<std::string> opts;
|
std::vector<std::string> opts;
|
||||||
std::ranges::transform(*it, std::back_inserter(opts),
|
std::ranges::transform(*it, std::back_inserter(opts), [](const auto& opt) { return opt.template get_value<std::string>(); });
|
||||||
[](const auto& opt) { return opt.template get_value<std::string>(); });
|
|
||||||
def.completions[path] = std::move(opts);
|
def.completions[path] = std::move(opts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1182,8 +1181,7 @@ void CommandRegistry::load(const std::string& yaml_path) { // NOLINT(readabilit
|
|||||||
for (auto it = extras_completions.begin(); it != extras_completions.end(); ++it) {
|
for (auto it = extras_completions.begin(); it != extras_completions.end(); ++it) {
|
||||||
auto path = it.key().get_value<std::string>();
|
auto path = it.key().get_value<std::string>();
|
||||||
std::vector<std::string> opts;
|
std::vector<std::string> opts;
|
||||||
std::ranges::transform(*it, std::back_inserter(opts),
|
std::ranges::transform(*it, std::back_inserter(opts), [](const auto& opt) { return opt.template get_value<std::string>(); });
|
||||||
[](const auto& opt) { return opt.template get_value<std::string>(); });
|
|
||||||
def.completions[path] = std::move(opts);
|
def.completions[path] = std::move(opts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ void Notifier::render() {
|
|||||||
// Actualiza el estado de las notificaiones
|
// Actualiza el estado de las notificaiones
|
||||||
void Notifier::update(float delta_time) {
|
void Notifier::update(float delta_time) {
|
||||||
// Base Y leída cada frame: cada notificación se dibuja en rect.y (relativo a BASE) + BASE
|
// Base Y leída cada frame: cada notificación se dibuja en rect.y (relativo a BASE) + BASE
|
||||||
const float BASE = static_cast<float>(getStackBaseY());
|
const auto BASE = static_cast<float>(getStackBaseY());
|
||||||
|
|
||||||
for (auto& notification : notifications_) {
|
for (auto& notification : notifications_) {
|
||||||
// Si la notificación anterior está "entrando", no hagas nada (stall del resto)
|
// Si la notificación anterior está "entrando", no hagas nada (stall del resto)
|
||||||
@@ -88,7 +88,7 @@ void Notifier::update(float delta_time) {
|
|||||||
|
|
||||||
switch (notification.state) {
|
switch (notification.state) {
|
||||||
case Status::RISING: {
|
case Status::RISING: {
|
||||||
const float TARGET = static_cast<float>(notification.y);
|
const auto TARGET = static_cast<float>(notification.y);
|
||||||
notification.rect.y += SLIDE_SPEED * delta_time;
|
notification.rect.y += SLIDE_SPEED * delta_time;
|
||||||
if (notification.rect.y >= TARGET) {
|
if (notification.rect.y >= TARGET) {
|
||||||
notification.rect.y = TARGET;
|
notification.rect.y = TARGET;
|
||||||
@@ -107,7 +107,7 @@ void Notifier::update(float delta_time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case Status::VANISHING: {
|
case Status::VANISHING: {
|
||||||
const float TARGET_Y = static_cast<float>(notification.y - notification.travel_dist);
|
const auto TARGET_Y = static_cast<float>(notification.y - notification.travel_dist);
|
||||||
notification.rect.y -= SLIDE_SPEED * delta_time;
|
notification.rect.y -= SLIDE_SPEED * delta_time;
|
||||||
if (notification.rect.y <= TARGET_Y) {
|
if (notification.rect.y <= TARGET_Y) {
|
||||||
notification.rect.y = TARGET_Y;
|
notification.rect.y = TARGET_Y;
|
||||||
@@ -117,8 +117,6 @@ void Notifier::update(float delta_time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case Status::FINISHED:
|
case Status::FINISHED:
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -172,7 +170,7 @@ void Notifier::show(std::vector<std::string> texts, const Style& style, int icon
|
|||||||
const int ICON_SPACE = icon >= 0 ? ICON_SIZE + PADDING_IN_H : 0;
|
const int ICON_SPACE = icon >= 0 ? ICON_SIZE + PADDING_IN_H : 0;
|
||||||
const TextAlign TEXT_IS = ICON_SPACE > 0 ? TextAlign::LEFT : style.text_align;
|
const TextAlign TEXT_IS = ICON_SPACE > 0 ? TextAlign::LEFT : style.text_align;
|
||||||
const float WIDTH = Options::game.width - (PADDING_OUT * 2);
|
const float WIDTH = Options::game.width - (PADDING_OUT * 2);
|
||||||
const float HEIGHT = (TEXT_SIZE * texts.size()) + (PADDING_IN_V * 2);
|
const float HEIGHT = (TEXT_SIZE * static_cast<float>(texts.size())) + (PADDING_IN_V * 2);
|
||||||
const auto SHAPE = style.shape;
|
const auto SHAPE = style.shape;
|
||||||
|
|
||||||
// Posición horizontal
|
// Posición horizontal
|
||||||
@@ -287,7 +285,7 @@ void Notifier::clearNotifications() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Y absoluta de la base de la pila (justo debajo de Console, o 0 si no hay Console)
|
// Y absoluta de la base de la pila (justo debajo de Console, o 0 si no hay Console)
|
||||||
auto Notifier::getStackBaseY() const -> int {
|
auto Notifier::getStackBaseY() -> int {
|
||||||
return Console::get() != nullptr ? Console::get()->getVisibleHeight() : 0;
|
return Console::get() != nullptr ? Console::get()->getVisibleHeight() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,7 +295,7 @@ auto Notifier::getVisibleHeight() const -> int {
|
|||||||
for (const auto& n : notifications_) {
|
for (const auto& n : notifications_) {
|
||||||
if (n.state == Status::FINISHED) { continue; }
|
if (n.state == Status::FINISHED) { continue; }
|
||||||
const int N_BOTTOM = static_cast<int>(n.rect.y + n.rect.h);
|
const int N_BOTTOM = static_cast<int>(n.rect.y + n.rect.h);
|
||||||
if (N_BOTTOM > bottom) { bottom = N_BOTTOM; }
|
bottom = std::max(N_BOTTOM, bottom);
|
||||||
}
|
}
|
||||||
return bottom;
|
return bottom;
|
||||||
}
|
}
|
||||||
@@ -306,7 +304,6 @@ auto Notifier::getVisibleHeight() const -> int {
|
|||||||
auto Notifier::getCodes() -> std::vector<std::string> {
|
auto Notifier::getCodes() -> std::vector<std::string> {
|
||||||
std::vector<std::string> codes;
|
std::vector<std::string> codes;
|
||||||
codes.reserve(notifications_.size());
|
codes.reserve(notifications_.size());
|
||||||
std::ranges::transform(notifications_, std::back_inserter(codes),
|
std::ranges::transform(notifications_, std::back_inserter(codes), [](const auto& notification) { return notification.code; });
|
||||||
[](const auto& notification) { return notification.code; });
|
|
||||||
return codes;
|
return codes;
|
||||||
}
|
}
|
||||||
@@ -2,24 +2,25 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <memory> // Para shared_ptr
|
#include <cstdint> // Para uint8_t
|
||||||
#include <string> // Para string, basic_string
|
#include <memory> // Para shared_ptr
|
||||||
#include <vector> // Para vector
|
#include <string> // Para string, basic_string
|
||||||
class Sprite; // lines 8-8
|
#include <vector> // Para vector
|
||||||
class Surface; // lines 10-10
|
class Sprite; // lines 8-8
|
||||||
class Text; // lines 9-9
|
class Surface; // lines 10-10
|
||||||
class DeltaTimer; // lines 11-11
|
class Text; // lines 9-9
|
||||||
|
class DeltaTimer; // lines 11-11
|
||||||
|
|
||||||
class Notifier {
|
class Notifier {
|
||||||
public:
|
public:
|
||||||
// Justificado para las notificaciones
|
// Justificado para las notificaciones
|
||||||
enum class TextAlign {
|
enum class TextAlign : std::uint8_t {
|
||||||
LEFT,
|
LEFT,
|
||||||
CENTER,
|
CENTER,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Forma de las notificaciones
|
// Forma de las notificaciones
|
||||||
enum class Shape {
|
enum class Shape : std::uint8_t {
|
||||||
ROUNDED,
|
ROUNDED,
|
||||||
SQUARED,
|
SQUARED,
|
||||||
};
|
};
|
||||||
@@ -65,7 +66,7 @@ class Notifier {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Tipos anidados
|
// Tipos anidados
|
||||||
enum class Status {
|
enum class Status : std::uint8_t {
|
||||||
RISING,
|
RISING,
|
||||||
STAY,
|
STAY,
|
||||||
VANISHING,
|
VANISHING,
|
||||||
@@ -97,9 +98,9 @@ class Notifier {
|
|||||||
static Notifier* notifier;
|
static Notifier* notifier;
|
||||||
|
|
||||||
// Métodos privados
|
// Métodos privados
|
||||||
void clearFinishedNotifications(); // Elimina las notificaciones finalizadas
|
void clearFinishedNotifications(); // Elimina las notificaciones finalizadas
|
||||||
void clearNotifications(); // Finaliza y elimina todas las notificaciones activas
|
void clearNotifications(); // Finaliza y elimina todas las notificaciones activas
|
||||||
[[nodiscard]] auto getStackBaseY() const -> int; // Y absoluta de la base de la pila (leída de Console)
|
[[nodiscard]] static auto getStackBaseY() -> int; // Y absoluta de la base de la pila (leída de Console)
|
||||||
|
|
||||||
// Constructor y destructor privados [SINGLETON]
|
// Constructor y destructor privados [SINGLETON]
|
||||||
Notifier(const std::string& icon_file, const std::string& text);
|
Notifier(const std::string& icon_file, const std::string& text);
|
||||||
|
|||||||
@@ -10,16 +10,16 @@ Empezado en Castalla el 01/07/2022.
|
|||||||
|
|
||||||
#include "core/system/director.hpp"
|
#include "core/system/director.hpp"
|
||||||
|
|
||||||
SDL_AppResult SDL_AppInit(void** appstate, int /*argc*/, char* /*argv*/[]) {
|
auto SDL_AppInit(void** appstate, int /*argc*/, char* /*argv*/[]) -> SDL_AppResult {
|
||||||
*appstate = new Director();
|
*appstate = new Director();
|
||||||
return SDL_APP_CONTINUE;
|
return SDL_APP_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_AppResult SDL_AppIterate(void* appstate) {
|
auto SDL_AppIterate(void* appstate) -> SDL_AppResult {
|
||||||
return static_cast<Director*>(appstate)->iterate();
|
return static_cast<Director*>(appstate)->iterate();
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) {
|
auto SDL_AppEvent(void* appstate, SDL_Event* event) -> SDL_AppResult {
|
||||||
return static_cast<Director*>(appstate)->handleEvent(*event);
|
return static_cast<Director*>(appstate)->handleEvent(*event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
DeltaTimer::DeltaTimer() noexcept
|
DeltaTimer::DeltaTimer() noexcept
|
||||||
: last_counter_(SDL_GetPerformanceCounter()),
|
: last_counter_(SDL_GetPerformanceCounter()),
|
||||||
perf_freq_(static_cast<double>(SDL_GetPerformanceFrequency())),
|
perf_freq_(static_cast<double>(SDL_GetPerformanceFrequency())) {
|
||||||
time_scale_(1.0F) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto DeltaTimer::tick() noexcept -> float {
|
auto DeltaTimer::tick() noexcept -> float {
|
||||||
|
|||||||
@@ -24,5 +24,5 @@ class DeltaTimer {
|
|||||||
private:
|
private:
|
||||||
Uint64 last_counter_;
|
Uint64 last_counter_;
|
||||||
double perf_freq_;
|
double perf_freq_;
|
||||||
float time_scale_;
|
float time_scale_{1.0F};
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user