From e1bd75e00d12c92317747254ea5826cee388a92b Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Thu, 7 May 2026 14:04:48 +0200 Subject: [PATCH] feat(logo): so glitch.wav sincronitzat amb el scanline reveal --- data/ui.yaml | 3 +++ source/core/system/director.cpp | 4 ++++ source/core/ui/ui_config.cpp | 2 ++ source/core/ui/ui_config.hpp | 2 ++ source/game/scenes/logo_scene.cpp | 6 ++++++ source/utils/defaults.hpp | 7 +++++++ 6 files changed, 24 insertions(+) diff --git a/data/ui.yaml b/data/ui.yaml index 2c77699..b0b4802 100644 --- a/data/ui.yaml +++ b/data/ui.yaml @@ -110,6 +110,9 @@ sounds: # Disparat quan un jugador prem START a la TITLE (primera pulsació o # la del segon jugador dins de la finestra de STARTING). player_start: "player_start.wav" + # Soroll/scratch sincronitzat amb la fase SCAN de LogoScene (scanline + # reveal). Es dispara al constructor de l'escena. + logo_glitch: "glitch.wav" # Escena TITLE (placeholder visual mentre no hi haja artwork). # `bg_color` i `text_color` són índexs sobre la paleta "ui" (uzebox.pal): diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index ee5f760..f1a4a70 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -170,6 +170,10 @@ Director::Director() { // prem START (vore enterStarting i el reset del segon jugador). const auto& player_start = UiConfig::get().playerStartSound(); Resource::Cache::get().loadSound(player_start, "data/sounds/" + player_start); + // Soroll de LogoScene (scanline reveal). El dispara LogoScene al + // ctor; amb fallback al nom de Defaults si la clau YAML no hi és. + const auto& logo_glitch = UiConfig::get().logoGlitchSound(); + Resource::Cache::get().loadSound(logo_glitch, "data/sounds/" + logo_glitch); // Catàleg de presets d'efectes per als sons. Es carrega abans d'Audio // perquè els primers playSoundWith* (al començament del joc) ja diff --git a/source/core/ui/ui_config.cpp b/source/core/ui/ui_config.cpp index 2a8b4c0..5adfe66 100644 --- a/source/core/ui/ui_config.cpp +++ b/source/core/ui/ui_config.cpp @@ -146,6 +146,7 @@ UiConfig::UiConfig() menu_select_sound_(Defaults::UI::MENU_SELECT_SOUND), menu_accept_sound_(Defaults::UI::MENU_ACCEPT_SOUND), player_start_sound_(Defaults::UI::PLAYER_START_SOUND), + logo_glitch_sound_(Defaults::UI::LOGO_GLITCH_SOUND), hud_font_{.name = Defaults::UI::Font::HUD_NAME, .gif = Defaults::UI::Font::HUD_GIF, .fnt = Defaults::UI::Font::HUD_FNT, .kerning = Defaults::UI::Font::HUD_KERNING}, placeholder_font_{.name = Defaults::UI::Font::PLACEHOLDER_NAME, .gif = Defaults::UI::Font::PLACEHOLDER_GIF, .fnt = Defaults::UI::Font::PLACEHOLDER_FNT, .kerning = Defaults::UI::Font::PLACEHOLDER_KERNING}, room_text_font_{.name = Defaults::UI::Font::ROOM_TEXT_NAME, .gif = Defaults::UI::Font::ROOM_TEXT_GIF, .fnt = Defaults::UI::Font::ROOM_TEXT_FNT, .kerning = Defaults::UI::Font::ROOM_TEXT_KERNING}, @@ -253,6 +254,7 @@ void UiConfig::load(const std::string& file_path) { readField(s, "menu_select", menu_select_sound_); readField(s, "menu_accept", menu_accept_sound_); readField(s, "player_start", player_start_sound_); + readField(s, "logo_glitch", logo_glitch_sound_); } if (yaml.contains("title")) { diff --git a/source/core/ui/ui_config.hpp b/source/core/ui/ui_config.hpp index b5b5b84..a8978d2 100644 --- a/source/core/ui/ui_config.hpp +++ b/source/core/ui/ui_config.hpp @@ -158,6 +158,7 @@ class UiConfig { [[nodiscard]] auto menuSelectSound() const -> const std::string& { return menu_select_sound_; } [[nodiscard]] auto menuAcceptSound() const -> const std::string& { return menu_accept_sound_; } [[nodiscard]] auto playerStartSound() const -> const std::string& { return player_start_sound_; } + [[nodiscard]] auto logoGlitchSound() const -> const std::string& { return logo_glitch_sound_; } // Fonts de UI. [[nodiscard]] auto hudFont() const -> const Font& { return hud_font_; } @@ -232,6 +233,7 @@ class UiConfig { std::string menu_select_sound_; std::string menu_accept_sound_; std::string player_start_sound_; + std::string logo_glitch_sound_; Font hud_font_; Font placeholder_font_; diff --git a/source/game/scenes/logo_scene.cpp b/source/game/scenes/logo_scene.cpp index 68d47b8..f6c147d 100644 --- a/source/game/scenes/logo_scene.cpp +++ b/source/game/scenes/logo_scene.cpp @@ -38,6 +38,12 @@ LogoScene::LogoScene(std::shared_ptr logo, bool reset) audio->stopAllSounds(); } } + // So del scanline reveal: una sola pulsació al començament de la + // fase SCAN, en grup INTERFACE perquè no es vegi afectat pel volum + // de sons del joc i quedi sempre audible. + if (auto* audio = Audio::get(); audio != nullptr) { + audio->playSound(UiConfig::get().logoGlitchSound(), Audio::Group::INTERFACE); + } // Arranca el revelat CRT: el primer frame ja pinta zero files (banda // damunt del logo) i avança fins a tenir-lo visible al final. const auto& s = UiConfig::get().logoScan(); diff --git a/source/utils/defaults.hpp b/source/utils/defaults.hpp index e8722c4..46ad21a 100644 --- a/source/utils/defaults.hpp +++ b/source/utils/defaults.hpp @@ -261,6 +261,13 @@ namespace Defaults { // `data/sounds/`. constexpr const char* PLAYER_START_SOUND = "player_start.wav"; + // So curt de "soroll/scratch" disparat al constructor de LogoScene + // i sincronitzat amb la fase SCAN del scanline reveal. Playback + // únic via Audio::Group::INTERFACE; si dura més que el scan, la + // cua sona pinçada al començament de MIDDLE — pretès com a + // "eco" sonor de l'efecte. + constexpr const char* LOGO_GLITCH_SOUND = "glitch.wav"; + // Escena TITLE (provisional fins que tinguem artwork). Colors // referits a la paleta "ui" (uzebox.pal): BG_COLOR és el to més // proper al negre sense ser-ho (índex 1 = 36,0,0); TEXT_COLOR és