neteja tidy (29 → 0) i migració JA_* → Ja::
This commit is contained in:
+31
-31
@@ -9,7 +9,7 @@
|
|||||||
// Ací només en veiem les declaracions via jail_audio.hpp (que inclou amb
|
// Ací només en veiem les declaracions via jail_audio.hpp (que inclou amb
|
||||||
// STB_VORBIS_HEADER_ONLY).
|
// STB_VORBIS_HEADER_ONLY).
|
||||||
#include "core/audio/audio_adapter.hpp" // Para AudioResource::getMusic/getSound
|
#include "core/audio/audio_adapter.hpp" // Para AudioResource::getMusic/getSound
|
||||||
#include "core/audio/jail_audio.hpp" // Para JA_*
|
#include "core/audio/jail_audio.hpp" // Para Ja::*
|
||||||
#include "game/options.hpp" // Para Options::audio
|
#include "game/options.hpp" // Para Options::audio
|
||||||
|
|
||||||
// Singleton
|
// Singleton
|
||||||
@@ -32,15 +32,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,18 +54,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;
|
||||||
@@ -74,16 +74,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
|
||||||
@@ -94,7 +94,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,7 +110,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,42 +118,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;
|
||||||
}
|
}
|
||||||
@@ -164,7 +164,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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +173,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +195,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-11
@@ -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
|
||||||
|
|||||||
+595
-575
File diff suppressed because it is too large
Load Diff
@@ -322,10 +322,12 @@ namespace GlobalInputs {
|
|||||||
|
|
||||||
case InputAction::TOGGLE_INFO:
|
case InputAction::TOGGLE_INFO:
|
||||||
if (RenderInfo::get() != nullptr) {
|
if (RenderInfo::get() != nullptr) {
|
||||||
|
#ifdef _DEBUG
|
||||||
// Leemos la intención antes del toggle: isActive() incluye la
|
// Leemos la intención antes del toggle: isActive() incluye la
|
||||||
// animación VANISHING, así que justo después de un toggle ACTIVE→OFF
|
// animación VANISHING, així que just després d'un toggle ACTIVE→OFF
|
||||||
// seguiría devolviendo true y la persistencia no detectaría el cambio.
|
// seguiria retornant true i la persistència no detectaria el canvi.
|
||||||
const bool WAS_ACTIVE = RenderInfo::get()->isActive();
|
const bool WAS_ACTIVE = RenderInfo::get()->isActive();
|
||||||
|
#endif
|
||||||
RenderInfo::get()->toggle();
|
RenderInfo::get()->toggle();
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if (Debug::get() != nullptr) { Debug::get()->setRenderInfoEnabled(!WAS_ACTIVE); }
|
if (Debug::get() != nullptr) { Debug::get()->setRenderInfoEnabled(!WAS_ACTIVE); }
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,19 +12,19 @@
|
|||||||
|
|
||||||
// ── Singleton ────────────────────────────────────────────────────────────────
|
// ── Singleton ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
KeyConfig* KeyConfig::instance_ = nullptr;
|
KeyConfig* KeyConfig::instance = nullptr;
|
||||||
|
|
||||||
void KeyConfig::init(const std::string& yaml_path) {
|
void KeyConfig::init(const std::string& yaml_path) {
|
||||||
instance_ = new KeyConfig();
|
instance = new KeyConfig();
|
||||||
instance_->load(yaml_path);
|
instance->load(yaml_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyConfig::destroy() {
|
void KeyConfig::destroy() {
|
||||||
delete instance_;
|
delete instance;
|
||||||
instance_ = nullptr;
|
instance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto KeyConfig::get() -> KeyConfig* { return instance_; }
|
auto KeyConfig::get() -> KeyConfig* { return instance; }
|
||||||
|
|
||||||
// ── Carga del YAML ──────────────────────────────────────────────────────────
|
// ── Carga del YAML ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class KeyConfig {
|
|||||||
[[nodiscard]] auto getScope(const std::string& name) const -> const KeyConfigScope*;
|
[[nodiscard]] auto getScope(const std::string& name) const -> const KeyConfigScope*;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static KeyConfig* instance_;
|
static KeyConfig* instance;
|
||||||
|
|
||||||
KeyConfig() = default;
|
KeyConfig() = default;
|
||||||
~KeyConfig() = default;
|
~KeyConfig() = default;
|
||||||
|
|||||||
@@ -271,12 +271,12 @@ void Screen::setBorderColor(Uint8 color) {
|
|||||||
|
|
||||||
// Captura el contenido actual (borde + juego si el borde está activo, solo juego si no)
|
// Captura el contenido actual (borde + juego si el borde está activo, solo juego si no)
|
||||||
void Screen::captureComposite(std::vector<Uint32>& buffer, int& out_width, int& out_height) const {
|
void Screen::captureComposite(std::vector<Uint32>& buffer, int& out_width, int& out_height) const {
|
||||||
const int GAME_W = static_cast<int>(game_surface_->getWidth());
|
const int GAME_W = game_surface_->getWidth();
|
||||||
const int GAME_H = static_cast<int>(game_surface_->getHeight());
|
const int GAME_H = game_surface_->getHeight();
|
||||||
|
|
||||||
if (Options::video.border.enabled) {
|
if (Options::video.border.enabled) {
|
||||||
const int BORDER_W = static_cast<int>(border_surface_->getWidth());
|
const int BORDER_W = border_surface_->getWidth();
|
||||||
const int BORDER_H = static_cast<int>(border_surface_->getHeight());
|
const int BORDER_H = border_surface_->getHeight();
|
||||||
const int OFF_X = Options::video.border.width;
|
const int OFF_X = Options::video.border.width;
|
||||||
const int OFF_Y = Options::video.border.height;
|
const int OFF_Y = Options::video.border.height;
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ auto DissolveSprite::computePixelRank(int col, int row, int frame_h, DissolveDir
|
|||||||
DissolveSprite::DissolveSprite(std::shared_ptr<Surface> surface, SDL_FRect pos)
|
DissolveSprite::DissolveSprite(std::shared_ptr<Surface> surface, SDL_FRect pos)
|
||||||
: AnimatedSprite(std::move(surface), pos) {
|
: AnimatedSprite(std::move(surface), pos) {
|
||||||
if (surface_) {
|
if (surface_) {
|
||||||
const int W = static_cast<int>(surface_->getWidth());
|
const int W = surface_->getWidth();
|
||||||
const int H = static_cast<int>(surface_->getHeight());
|
const int H = surface_->getHeight();
|
||||||
surface_display_ = std::make_shared<Surface>(W, H);
|
surface_display_ = std::make_shared<Surface>(W, H);
|
||||||
surface_display_->setTransparentColor(surface_->getTransparentColor());
|
surface_display_->setTransparentColor(surface_->getTransparentColor());
|
||||||
surface_display_->clear(surface_->getTransparentColor());
|
surface_display_->clear(surface_->getTransparentColor());
|
||||||
@@ -47,8 +47,8 @@ DissolveSprite::DissolveSprite(std::shared_ptr<Surface> surface, SDL_FRect pos)
|
|||||||
DissolveSprite::DissolveSprite(const AnimationResource& data)
|
DissolveSprite::DissolveSprite(const AnimationResource& data)
|
||||||
: AnimatedSprite(data) {
|
: AnimatedSprite(data) {
|
||||||
if (surface_) {
|
if (surface_) {
|
||||||
const int W = static_cast<int>(surface_->getWidth());
|
const int W = surface_->getWidth();
|
||||||
const int H = static_cast<int>(surface_->getHeight());
|
const int H = surface_->getHeight();
|
||||||
surface_display_ = std::make_shared<Surface>(W, H);
|
surface_display_ = std::make_shared<Surface>(W, H);
|
||||||
surface_display_->setTransparentColor(surface_->getTransparentColor());
|
surface_display_->setTransparentColor(surface_->getTransparentColor());
|
||||||
// Inicialitza tots els píxels com a transparents
|
// Inicialitza tots els píxels com a transparents
|
||||||
@@ -75,8 +75,8 @@ void DissolveSprite::rebuildDisplaySurface() {
|
|||||||
auto src_data = surface_->getSurfaceData();
|
auto src_data = surface_->getSurfaceData();
|
||||||
auto dst_data = surface_display_->getSurfaceData();
|
auto dst_data = surface_display_->getSurfaceData();
|
||||||
|
|
||||||
const int SRC_W = static_cast<int>(src_data->width);
|
const int SRC_W = src_data->width;
|
||||||
const int DST_W = static_cast<int>(dst_data->width);
|
const int DST_W = dst_data->width;
|
||||||
const Uint8 TRANSPARENT = surface_->getTransparentColor();
|
const Uint8 TRANSPARENT = surface_->getTransparentColor();
|
||||||
|
|
||||||
// Esborra frame anterior si ha canviat
|
// Esborra frame anterior si ha canviat
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ void Surface::fillRect(const SDL_FRect* rect, Uint8 color) { // NOLINT(readabil
|
|||||||
|
|
||||||
// Rellenar fila a fila con memset (memoria contigua por fila)
|
// Rellenar fila a fila con memset (memoria contigua por fila)
|
||||||
Uint8* data_ptr = surface_data_->data.get();
|
Uint8* data_ptr = surface_data_->data.get();
|
||||||
const int SURF_WIDTH = surface_data_->width;
|
const ptrdiff_t 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 + (y * SURF_WIDTH) + static_cast<int>(x_start), color, ROW_WIDTH);
|
||||||
@@ -194,7 +194,7 @@ void Surface::drawRectBorder(const SDL_FRect* rect, Uint8 color) { // NOLINT(re
|
|||||||
|
|
||||||
// Dibujar bordes horizontales con memset (líneas contiguas en memoria)
|
// Dibujar bordes horizontales con memset (líneas contiguas en memoria)
|
||||||
Uint8* data_ptr = surface_data_->data.get();
|
Uint8* data_ptr = surface_data_->data.get();
|
||||||
const int SURF_WIDTH = surface_data_->width;
|
const ptrdiff_t 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<int>(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<int>(y_end) - 1) * SURF_WIDTH) + static_cast<int>(x_start), color, ROW_WIDTH);
|
||||||
@@ -551,17 +551,17 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture) { //
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convertir `pitch` de bytes a Uint32 (asegurando alineación correcta en hardware)
|
// Convertir `pitch` de bytes a Uint32 (asegurando alineación correcta en hardware)
|
||||||
int row_stride = pitch / sizeof(Uint32);
|
const ptrdiff_t ROW_STRIDE = pitch / sizeof(Uint32);
|
||||||
|
|
||||||
// Cachear punteros fuera del bucle para permitir autovectorización SIMD
|
// Cachear punteros fuera del bucle para permitir autovectorización SIMD
|
||||||
const Uint8* src = surface_data_->data.get();
|
const Uint8* src = surface_data_->data.get();
|
||||||
const Uint32* pal = palette_.data();
|
const Uint32* pal = palette_.data();
|
||||||
const int WIDTH = surface_data_->width;
|
const ptrdiff_t 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 + (y * WIDTH);
|
||||||
Uint32* dst_row = pixels + (y * row_stride);
|
Uint32* dst_row = pixels + (y * ROW_STRIDE);
|
||||||
for (int x = 0; x < WIDTH; ++x) {
|
for (ptrdiff_t x = 0; x < WIDTH; ++x) {
|
||||||
dst_row[x] = pal[src_row[x]];
|
dst_row[x] = pal[src_row[x]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -600,17 +600,17 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_FR
|
|||||||
throw std::runtime_error("Failed to lock texture: " + std::string(SDL_GetError()));
|
throw std::runtime_error("Failed to lock texture: " + std::string(SDL_GetError()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int row_stride = pitch / sizeof(Uint32);
|
const ptrdiff_t ROW_STRIDE = pitch / sizeof(Uint32);
|
||||||
|
|
||||||
// Cachear punteros fuera del bucle para permitir autovectorización SIMD
|
// Cachear punteros fuera del bucle para permitir autovectorización SIMD
|
||||||
const Uint8* src = surface_data_->data.get();
|
const Uint8* src = surface_data_->data.get();
|
||||||
const Uint32* pal = palette_.data();
|
const Uint32* pal = palette_.data();
|
||||||
const int WIDTH = surface_data_->width;
|
const ptrdiff_t 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 + (y * WIDTH);
|
||||||
Uint32* dst_row = pixels + (y * row_stride);
|
Uint32* dst_row = pixels + (y * ROW_STRIDE);
|
||||||
for (int x = 0; x < WIDTH; ++x) {
|
for (ptrdiff_t x = 0; x < WIDTH; ++x) {
|
||||||
dst_row[x] = pal[src_row[x]];
|
dst_row[x] = pal[src_row[x]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|
||||||
@@ -88,7 +90,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* {
|
auto Cache::getSound(const std::string& name) -> Ja::Sound* {
|
||||||
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()) {
|
||||||
@@ -103,7 +105,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* {
|
auto Cache::getMusic(const std::string& name) -> Ja::Music* {
|
||||||
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()) {
|
||||||
@@ -261,17 +263,17 @@ namespace Resource {
|
|||||||
for (const auto& l : list) {
|
for (const auto& l : list) {
|
||||||
try {
|
try {
|
||||||
auto name = getFileName(l);
|
auto name = getFileName(l);
|
||||||
JA_Sound_t* sound = nullptr;
|
Ja::Sound* sound = nullptr;
|
||||||
|
|
||||||
// Try loading from resource pack first
|
// Try loading from resource pack first
|
||||||
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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to file path if memory loading failed
|
// Fallback to file path if memory loading failed
|
||||||
if (sound == nullptr) {
|
if (sound == nullptr) {
|
||||||
sound = JA_LoadSound(l.c_str());
|
sound = Ja::loadSound(l.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sound == nullptr) {
|
if (sound == nullptr) {
|
||||||
@@ -296,17 +298,17 @@ namespace Resource {
|
|||||||
for (const auto& l : list) {
|
for (const auto& l : list) {
|
||||||
try {
|
try {
|
||||||
auto name = getFileName(l);
|
auto name = getFileName(l);
|
||||||
JA_Music_t* music = nullptr;
|
Ja::Music* music = nullptr;
|
||||||
|
|
||||||
// Try loading from resource pack first
|
// Try loading from resource pack first
|
||||||
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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to file path if memory loading failed
|
// Fallback to file path if memory loading failed
|
||||||
if (music == nullptr) {
|
if (music == nullptr) {
|
||||||
music = JA_LoadMusic(l.c_str());
|
music = Ja::loadMusic(l.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (music == nullptr) {
|
if (music == nullptr) {
|
||||||
@@ -448,10 +450,10 @@ namespace Resource {
|
|||||||
|
|
||||||
// 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -460,10 +462,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -592,9 +594,9 @@ namespace Resource {
|
|||||||
auto path = List::get()->get(name);
|
auto path = List::get()->get(name);
|
||||||
try {
|
try {
|
||||||
auto bytes = Helper::loadFile(path);
|
auto bytes = Helper::loadFile(path);
|
||||||
JA_Sound_t* sound = nullptr;
|
Ja::Sound* sound = nullptr;
|
||||||
if (!bytes.empty()) { sound = JA_LoadSound(bytes.data(), static_cast<Uint32>(bytes.size())); }
|
if (!bytes.empty()) { sound = Ja::loadSound(bytes.data(), static_cast<Uint32>(bytes.size())); }
|
||||||
if (sound == nullptr) { sound = JA_LoadSound(path.c_str()); }
|
if (sound == nullptr) { sound = Ja::loadSound(path.c_str()); }
|
||||||
if (sound == nullptr) { throw std::runtime_error("Failed to decode audio file"); }
|
if (sound == nullptr) { throw std::runtime_error("Failed to decode audio file"); }
|
||||||
it->sound = sound;
|
it->sound = sound;
|
||||||
std::cout << "[lazy] Sound loaded: " << name << '\n';
|
std::cout << "[lazy] Sound loaded: " << name << '\n';
|
||||||
@@ -609,9 +611,9 @@ namespace Resource {
|
|||||||
auto path = List::get()->get(name);
|
auto path = List::get()->get(name);
|
||||||
try {
|
try {
|
||||||
auto bytes = Helper::loadFile(path);
|
auto bytes = Helper::loadFile(path);
|
||||||
JA_Music_t* music = nullptr;
|
Ja::Music* music = nullptr;
|
||||||
if (!bytes.empty()) { music = JA_LoadMusic(bytes.data(), static_cast<Uint32>(bytes.size())); }
|
if (!bytes.empty()) { music = Ja::loadMusic(bytes.data(), static_cast<Uint32>(bytes.size())); }
|
||||||
if (music == nullptr) { music = JA_LoadMusic(path.c_str()); }
|
if (music == nullptr) { music = Ja::loadMusic(path.c_str()); }
|
||||||
if (music == nullptr) { throw std::runtime_error("Failed to decode music file"); }
|
if (music == nullptr) { throw std::runtime_error("Failed to decode music file"); }
|
||||||
it->music = music;
|
it->music = music;
|
||||||
std::cout << "[lazy] Music loaded: " << name << '\n';
|
std::cout << "[lazy] Music loaded: " << name << '\n';
|
||||||
|
|||||||
@@ -21,8 +21,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>;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ void Key::update(float delta_time) {
|
|||||||
sprite_->animate(delta_time);
|
sprite_->animate(delta_time);
|
||||||
|
|
||||||
// Oscilacion sinusoidal sincronizada (mismo tiempo global para todas las llaves)
|
// Oscilacion sinusoidal sincronizada (mismo tiempo global para todas las llaves)
|
||||||
const float t = static_cast<float>(SDL_GetTicks()) / 1000.0F;
|
const float T = static_cast<float>(SDL_GetTicks()) / 1000.0F;
|
||||||
const float offset = std::sin(t * 2.0F * SDL_PI_F / FLOAT_PERIOD_S) * FLOAT_AMPLITUDE;
|
const float OFFSET = std::sin(T * 2.0F * SDL_PI_F / FLOAT_PERIOD_S) * FLOAT_AMPLITUDE;
|
||||||
sprite_->setPosY(base_y_ + offset);
|
sprite_->setPosY(base_y_ + OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Posición base (el collider y el tracker usan la posición sin oscilación)
|
// Posición base (el collider y el tracker usan la posición sin oscilación)
|
||||||
|
|||||||
@@ -156,71 +156,85 @@ void Player::handleInput() {
|
|||||||
// Fase 2: Velocidades
|
// Fase 2: Velocidades
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
void Player::updateVelocity(float delta_time) {
|
auto Player::computeHorizontalTarget() const -> float {
|
||||||
float target = 0.0F;
|
|
||||||
switch (wanna_go_) {
|
switch (wanna_go_) {
|
||||||
case Direction::LEFT:
|
case Direction::LEFT:
|
||||||
target = -HORIZONTAL_VELOCITY;
|
return -HORIZONTAL_VELOCITY;
|
||||||
break;
|
|
||||||
case Direction::RIGHT:
|
case Direction::RIGHT:
|
||||||
target = HORIZONTAL_VELOCITY;
|
return HORIZONTAL_VELOCITY;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
target = 0.0F;
|
return 0.0F;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::updateFacing(float target) {
|
||||||
|
if (state_ == State::ON_AIR) { return; }
|
||||||
|
|
||||||
// Detectar cambio de dirección (solo en suelo — en el aire no se gira)
|
// Detectar cambio de dirección (solo en suelo — en el aire no se gira)
|
||||||
if (state_ != State::ON_AIR && target != 0.0F) {
|
if (target != 0.0F) {
|
||||||
Direction new_facing = (target > 0.0F) ? Direction::RIGHT : Direction::LEFT;
|
const Direction NEW_FACING = (target > 0.0F) ? Direction::RIGHT : Direction::LEFT;
|
||||||
if (new_facing != facing_) {
|
if (NEW_FACING != facing_) {
|
||||||
facing_ = new_facing;
|
facing_ = NEW_FACING;
|
||||||
turning_ = true;
|
turning_ = true;
|
||||||
sprite_->resetAnimation();
|
sprite_->resetAnimation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Orientación del sprite (solo en suelo, en el aire se mantiene la dirección del salto)
|
// Orientación del sprite
|
||||||
if (state_ != State::ON_AIR) {
|
if (target > 0.0F) {
|
||||||
if (target > 0.0F) {
|
sprite_->setFlip(Flip::RIGHT);
|
||||||
sprite_->setFlip(Flip::RIGHT);
|
} else if (target < 0.0F) {
|
||||||
} else if (target < 0.0F) {
|
sprite_->setFlip(Flip::LEFT);
|
||||||
sprite_->setFlip(Flip::LEFT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::applyAirInertia(float target, float step) {
|
||||||
|
// En el aire, permitir mantener velocidad boosteada si vamos en la misma dirección
|
||||||
|
float air_target = target;
|
||||||
|
if ((target > 0.0F && vx_ > target) || (target < 0.0F && vx_ < target)) {
|
||||||
|
air_target = vx_;
|
||||||
|
}
|
||||||
|
if (vx_ < air_target) {
|
||||||
|
vx_ = std::min(vx_ + step, air_target);
|
||||||
|
} else if (vx_ > air_target) {
|
||||||
|
vx_ = std::max(vx_ - step, air_target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::applyGroundInertia(float target, float step, float delta_time) {
|
||||||
|
if (target != 0.0F) {
|
||||||
|
// Reset al cambiar de dirección: un giro breve también para en seco.
|
||||||
|
if (vx_ != 0.0F && ((target > 0.0F) != (vx_ > 0.0F))) {
|
||||||
|
walk_time_ = 0.0F;
|
||||||
|
}
|
||||||
|
vx_ = target;
|
||||||
|
walk_time_ += delta_time;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (walk_time_ < WALK_INERTIA_THRESHOLD) {
|
||||||
|
// Tap corto: parada seca, sin inercia (permite pasos finos).
|
||||||
|
vx_ = 0.0F;
|
||||||
|
walk_time_ = 0.0F;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (vx_ > 0.0F) {
|
||||||
|
vx_ = std::max(vx_ - step, 0.0F);
|
||||||
|
} else if (vx_ < 0.0F) {
|
||||||
|
vx_ = std::min(vx_ + step, 0.0F);
|
||||||
|
}
|
||||||
|
if (vx_ == 0.0F) { walk_time_ = 0.0F; }
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::updateVelocity(float delta_time) {
|
||||||
|
const float TARGET = computeHorizontalTarget();
|
||||||
|
updateFacing(TARGET);
|
||||||
|
|
||||||
// Inercia: aire = gradual ambas direcciones, suelo = instantáneo arranque, gradual frenada
|
// Inercia: aire = gradual ambas direcciones, suelo = instantáneo arranque, gradual frenada
|
||||||
const float STEP = HORIZONTAL_ACCEL * delta_time;
|
const float STEP = HORIZONTAL_ACCEL * delta_time;
|
||||||
if (state_ == State::ON_AIR) {
|
if (state_ == State::ON_AIR) {
|
||||||
// En el aire, permitir mantener velocidad boosteada si vamos en la misma dirección
|
applyAirInertia(TARGET, STEP);
|
||||||
float air_target = target;
|
|
||||||
if ((target > 0.0F && vx_ > target) || (target < 0.0F && vx_ < target)) {
|
|
||||||
air_target = vx_; // No frenar el boost
|
|
||||||
}
|
|
||||||
if (vx_ < air_target) {
|
|
||||||
vx_ = std::min(vx_ + STEP, air_target);
|
|
||||||
} else if (vx_ > air_target) {
|
|
||||||
vx_ = std::max(vx_ - STEP, air_target);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (target != 0.0F) {
|
applyGroundInertia(TARGET, STEP, delta_time);
|
||||||
// Reset al cambiar de dirección: un giro breve también para en seco.
|
|
||||||
if (vx_ != 0.0F && ((target > 0.0F) != (vx_ > 0.0F))) {
|
|
||||||
walk_time_ = 0.0F;
|
|
||||||
}
|
|
||||||
vx_ = target;
|
|
||||||
walk_time_ += delta_time;
|
|
||||||
} else if (walk_time_ < WALK_INERTIA_THRESHOLD) {
|
|
||||||
// Tap corto: parada seca, sin inercia (permite pasos finos).
|
|
||||||
vx_ = 0.0F;
|
|
||||||
walk_time_ = 0.0F;
|
|
||||||
} else if (vx_ > 0.0F) {
|
|
||||||
vx_ = std::max(vx_ - STEP, 0.0F);
|
|
||||||
if (vx_ == 0.0F) { walk_time_ = 0.0F; }
|
|
||||||
} else if (vx_ < 0.0F) {
|
|
||||||
vx_ = std::min(vx_ + STEP, 0.0F);
|
|
||||||
if (vx_ == 0.0F) { walk_time_ = 0.0F; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,9 @@
|
|||||||
#include "game/gameplay/tile_collider.hpp" // Para TileCollider::Tile
|
#include "game/gameplay/tile_collider.hpp" // Para TileCollider::Tile
|
||||||
#include "game/options.hpp" // Para Cheat, Options
|
#include "game/options.hpp" // Para Cheat, Options
|
||||||
#include "utils/defines.hpp" // Para PlayArea, Tile, Flip
|
#include "utils/defines.hpp" // Para PlayArea, Tile, Flip
|
||||||
struct JA_Sound_t;
|
namespace Ja {
|
||||||
|
struct Sound;
|
||||||
|
} // namespace Ja
|
||||||
class SolidActor;
|
class SolidActor;
|
||||||
|
|
||||||
class Player {
|
class Player {
|
||||||
@@ -128,12 +130,16 @@ class Player {
|
|||||||
int last_grounded_position_ = 0;
|
int last_grounded_position_ = 0;
|
||||||
|
|
||||||
// --- Renderizado y sonido ---
|
// --- Renderizado y sonido ---
|
||||||
JA_Sound_t* jump_sound_ = nullptr;
|
Ja::Sound* jump_sound_ = nullptr;
|
||||||
JA_Sound_t* land_sound_ = nullptr;
|
Ja::Sound* land_sound_ = nullptr;
|
||||||
|
|
||||||
// --- Pipeline de update ---
|
// --- Pipeline de update ---
|
||||||
void handleInput();
|
void handleInput();
|
||||||
void updateVelocity(float delta_time);
|
void updateVelocity(float delta_time);
|
||||||
|
[[nodiscard]] auto computeHorizontalTarget() const -> float;
|
||||||
|
void updateFacing(float target);
|
||||||
|
void applyAirInertia(float target, float step);
|
||||||
|
void applyGroundInertia(float target, float step, float delta_time);
|
||||||
void applyGravity(float delta_time);
|
void applyGravity(float delta_time);
|
||||||
void handleJumpAndDrop();
|
void handleJumpAndDrop();
|
||||||
[[nodiscard]] auto stuckAgainstWall() const -> bool;
|
[[nodiscard]] auto stuckAgainstWall() const -> bool;
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class Game {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// --- Métodos ---
|
// --- Métodos ---
|
||||||
void handleEvents(); // Comprueba los eventos de la cola
|
static void handleEvents(); // Comprueba los eventos de la cola
|
||||||
void transitionToState(State new_state); // Cambia al estado especificado y resetea los timers
|
void transitionToState(State new_state); // Cambia al estado especificado y resetea los timers
|
||||||
void updatePlaying(float delta_time); // Actualiza el juego en estado PLAYING
|
void updatePlaying(float delta_time); // Actualiza el juego en estado PLAYING
|
||||||
void updateBlackScreen(float delta_time); // Actualiza el juego en estado BLACK_SCREEN
|
void updateBlackScreen(float delta_time); // Actualiza el juego en estado BLACK_SCREEN
|
||||||
|
|||||||
@@ -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