feat(ui): captura F9, tema a data/ui.yaml i retocs estètics

Captura de pantalla amb F9: volca el canvas ARGB a
screenshots/scr_<timestamp>.png via stb_image_write.

Tot el tema d'UI (colors, timings, fonts, flag hud.bg_enabled)
passa a data/ui.yaml via UiConfig; els valors de Defaults::UI
queden com a fallbacks si el fitxer falta o li manca alguna clau.

Retocs estètics: paleta "uzebox" per a la UI, strings del HUD
(P1/P2/V/T/PIRAMIDE/SALA) traduïts a locale, i fons del marcador
opcional amb backdrop continu de franja per evitar el trencament
visual durant el shake o l'animació d'entrada dels panells.
This commit is contained in:
JailDesigner committed 2026-04-24 10:58:02 +02:00
1 parent 82b229222f
commit dc8a7723e3
26 files changed
+2593 -210

No files matched your search

+24 -28
View File
@@ -25,6 +25,7 @@
#include "core/resources/resource_helper.hpp"
#include "core/scene/scene.hpp"
#include "core/system/event_buffer.hpp"
#include "core/ui/ui_config.hpp"
#include "game/debug_config.hpp"
#include "game/options.hpp"
#include "game/scenes/game_scene.hpp"
@@ -32,7 +33,6 @@
#include "game/scenes/logo_scene.hpp"
#include "game/scenes/title_scene.hpp"
#include "game/ui/service_menu.hpp"
#include "game/ui/ui_palette.hpp"
#include "utils/defaults.hpp"
Director::Director() {
@@ -97,15 +97,19 @@ Director::Director() {
// Hotkeys globals. GlobalInputs::update() les consumirà a cada frame.
KeyConfig::get().load("data/input/keys.yaml");
// Tema d'UI (colors, timings, fonts, flags). Qualsevol clau absent a
// data/ui.yaml cau al valor compilat a Defaults::UI.
UiConfig::get().load("data/ui.yaml");
// Recursos compartits d'UI (paleta + fonts). Es carreguen abans que els
// overlays perquè tots els reaprofiten sense duplicar la lògica. Els
// noms de font viuen a Defaults::UI::Font (un únic lloc per canviar-los).
Resource::Cache::get().loadPalette("ui", "data/palettes/sega-cube.pal");
const std::string HUD_FONT_GIF_KEY = std::string(Defaults::UI::Font::HUD_NAME) + ".gif";
Resource::Cache::get().loadSurface(HUD_FONT_GIF_KEY, Defaults::UI::Font::HUD_GIF);
// noms de font viuen al fitxer data/ui.yaml via UiConfig.
Resource::Cache::get().loadPalette("ui", "data/palettes/uzebox.pal");
const std::string HUD_FONT_GIF_KEY = UiConfig::get().hudFont().name + ".gif";
Resource::Cache::get().loadSurface(HUD_FONT_GIF_KEY, UiConfig::get().hudFont().gif);
Resource::Cache::get().getSurface(HUD_FONT_GIF_KEY)->setPalette(Resource::Cache::get().getPalette("ui"));
const std::string PLACEHOLDER_FONT_GIF_KEY = std::string(Defaults::UI::Font::PLACEHOLDER_NAME) + ".gif";
Resource::Cache::get().loadSurface(PLACEHOLDER_FONT_GIF_KEY, Defaults::UI::Font::PLACEHOLDER_GIF);
const std::string PLACEHOLDER_FONT_GIF_KEY = UiConfig::get().placeholderFont().name + ".gif";
Resource::Cache::get().loadSurface(PLACEHOLDER_FONT_GIF_KEY, UiConfig::get().placeholderFont().gif);
Resource::Cache::get().getSurface(PLACEHOLDER_FONT_GIF_KEY)->setPalette(Resource::Cache::get().getPalette("ui"));
// Música de la piràmide 1 (primer i únic track de moment). Carreguem ací
@@ -126,41 +130,33 @@ Director::Director() {
// i la injectem als consumidors (Notifier, RenderInfo) per a que cap
// d'ells hagi de conèixer els noms dels recursos concrets.
auto hud_font_surface = Resource::Cache::get().getSurface(HUD_FONT_GIF_KEY);
auto hud_text = std::make_shared<Text>(hud_font_surface, Defaults::UI::Font::HUD_FNT);
hud_text->setDefaultKerning(Defaults::UI::Font::HUD_KERNING);
auto hud_text = std::make_shared<Text>(hud_font_surface, UiConfig::get().hudFont().fnt);
hud_text->setDefaultKerning(UiConfig::get().hudFont().kerning);
const auto& ui_palette = Resource::Cache::get().getPalette("ui");
RenderInfo::get().init(Options::buildRenderInfoFrame(UiColor::RENDER_INFO_TEXT, UiColor::RENDER_INFO_SHADOW), hud_text);
RenderInfo::get().init(Options::buildRenderInfoFrame(UiConfig::get().renderInfoText(), UiConfig::get().renderInfoShadow()), hud_text);
Notifier::get().init(hud_text, ui_palette);
// Font dels placeholders (LOGO / TITLE / INTRO). És una font distinta a
// la de HUD perquè els placeholders desapareixeran amb les seues escenes
// finals; mentrestant tenen estètica pròpia.
auto placeholder_font_surface = Resource::Cache::get().getSurface(PLACEHOLDER_FONT_GIF_KEY);
auto placeholder_text = std::make_shared<Text>(placeholder_font_surface, Defaults::UI::Font::PLACEHOLDER_FNT);
placeholder_text->setDefaultKerning(Defaults::UI::Font::PLACEHOLDER_KERNING);
auto placeholder_text = std::make_shared<Text>(placeholder_font_surface, UiConfig::get().placeholderFont().fnt);
placeholder_text->setDefaultKerning(UiConfig::get().placeholderFont().kerning);
// Font del menú de servei (F9). El títol va amb la variant `display`
// i els items amb `condensed-display` (més compacte perquè caben més
// files). Els dos noms i kernings viuen a `Defaults::UI::Font`.
auto load_menu_font = [&](const char* name, const char* gif, const char* fnt, int kerning) {
const std::string KEY = std::string(name) + ".gif";
Resource::Cache::get().loadSurface(KEY, gif);
// files). Els dos noms i kernings viuen a data/ui.yaml via UiConfig.
auto load_menu_font = [&](const UiConfig::Font& font) {
const std::string KEY = font.name + ".gif";
Resource::Cache::get().loadSurface(KEY, font.gif);
Resource::Cache::get().getSurface(KEY)->setPalette(Resource::Cache::get().getPalette("ui"));
auto text = std::make_shared<Text>(Resource::Cache::get().getSurface(KEY), fnt);
text->setDefaultKerning(kerning);
auto text = std::make_shared<Text>(Resource::Cache::get().getSurface(KEY), font.fnt);
text->setDefaultKerning(font.kerning);
return text;
};
auto menu_title_text = load_menu_font(
Defaults::UI::Font::MENU_TITLE_NAME,
Defaults::UI::Font::MENU_TITLE_GIF,
Defaults::UI::Font::MENU_TITLE_FNT,
Defaults::UI::Font::MENU_TITLE_KERNING);
auto menu_items_text = load_menu_font(
Defaults::UI::Font::MENU_ITEMS_NAME,
Defaults::UI::Font::MENU_ITEMS_GIF,
Defaults::UI::Font::MENU_ITEMS_FNT,
Defaults::UI::Font::MENU_ITEMS_KERNING);
auto menu_title_text = load_menu_font(UiConfig::get().menuTitleFont());
auto menu_items_text = load_menu_font(UiConfig::get().menuItemsFont());
ServiceMenu::get().init(menu_title_text, menu_items_text, ui_palette);
// Overlay hook: Screen::present() cridarà aquesta lambda al principi,