From 158968e2c27f89db53305599faa0a784f558a824 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Wed, 6 May 2026 10:00:30 +0200 Subject: [PATCH] =?UTF-8?q?feat(title):=20peu=20amb=20minilogo=20i=20copyr?= =?UTF-8?q?ight;=20fonts=20ari=20regenerades=20amb=20=C2=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/fonts/ari-w9500-condensed-display.fnt | 11 ++++----- data/fonts/ari-w9500-condensed-display.gif | Bin 2320 -> 2229 bytes data/fonts/ari-w9500-display.fnt | 11 ++++----- data/fonts/ari-w9500-display.gif | Bin 2366 -> 2263 bytes data/logo/logo_jailgames.gif | Bin 0 -> 494 bytes data/logo/logo_jailgames_mini.gif | Bin 0 -> 200 bytes data/logo/logo_since_1998.gif | Bin 0 -> 99 bytes data/ui.yaml | 1 + source/core/system/director.cpp | 12 ++++++++-- source/core/ui/ui_config.cpp | 2 ++ source/core/ui/ui_config.hpp | 2 ++ source/game/scenes/title_scene.cpp | 25 ++++++++++++++++++++- source/game/scenes/title_scene.hpp | 4 +++- source/utils/defaults.hpp | 1 + 14 files changed, 55 insertions(+), 14 deletions(-) create mode 100644 data/logo/logo_jailgames.gif create mode 100644 data/logo/logo_jailgames_mini.gif create mode 100644 data/logo/logo_since_1998.gif diff --git a/data/fonts/ari-w9500-condensed-display.fnt b/data/fonts/ari-w9500-condensed-display.fnt index 7314c59..ecf0287 100644 --- a/data/fonts/ari-w9500-condensed-display.fnt +++ b/data/fonts/ari-w9500-condensed-display.fnt @@ -1,5 +1,5 @@ # Font: ari-w9500-condensed-display — generado desde ari-w9500-condensed-display.ttf size 11 -# Generado con tools/font_gen/font_gen.py +# Generado con font_gen.py box_width 12 box_height 11 @@ -105,8 +105,8 @@ columns 15 193 8 # Á 200 7 # È 201 7 # É -204 3 # Ì -205 3 # Í +204 4 # Ì +205 4 # Í 210 9 # Ò 211 9 # Ó 217 7 # Ù @@ -118,7 +118,7 @@ columns 15 232 7 # è 233 7 # é 236 4 # ì -237 3 # í +237 4 # í 242 7 # ò 243 7 # ó 249 7 # ù @@ -126,7 +126,8 @@ columns 15 241 7 # ñ 231 7 # ç 161 3 # ¡ -191 7 # ¿ +191 5 # ¿ 171 10 # « 187 10 # » 183 3 # · +169 10 # © diff --git a/data/fonts/ari-w9500-condensed-display.gif b/data/fonts/ari-w9500-condensed-display.gif index b293b0d78ca36c9b1d183942deb1a78e02405984..a4791e908cad4169d76b3a1ed81d530c0098d5ef 100644 GIT binary patch delta 1450 zcmV;b1y%Zx615Sq9s_@{puvL(6DnNDu%W|;5F<*QI50o}iUKWa)Oe61!i^q5T8uby zVM&Q1QEtR|vS7)U6+ODV2mt2Hk1}H_wAs<-OPU0K8sr%i=uV>a2;B?9rTK(Prf;mTX(IW0QW33s-+GRkUDxCe=FE?pwTe z69Oi>S1@3?Q6Um0S+-$chl>+So=my2<%e$z<22h+=*_xm%X-cmcJt=Jhcmlvyt?OO z(4UVQ*38v#R6{+H%(=WdzC8)dqs2Onae zt<)V)xB(c~dh9iaA6x&C#}|VV`lcU-{Jqy9Yp*p3SA`^MwqSyyHTYV6EVek^fbkjV z9E=~{)*NxdrKp^MItupPO?Pn^69GX|oAA7knbwXrq_M zd6i+AF(O(Xm+q~Wq-un&DOI7^S$JWjff>o?mYQBD$Zcew?)?ODj;niIC`bxUfP+_ed=xR<(SE@G%HVk#9^;(@Hw4gq{7rec$T=m9OMtvxf zd^3Ol%j~IqcPzM`q~1$*&*Yvr_?$7bTdu3nVZHd|l~OLa$TyN}XwGoTt#o@IKZ*Im z>(&icmldXrH|YE_#pJNK9bUQWjzPL?=+x0__vTe$EuG|RTQ2lvc4)yeq+wgjDntf%0WN zAnnRx8ibn%g$2K%ROB)xL*NXj$UuKMrEZOyOjO`9IYBsj=x?7SWFJ?_%2pcEeybd0 zeJr@e*wJr@&Ff(Ha#=+=f(JsRG~*=0SVUirQfOOSBl^`2uWu*wW?9n+$8-^cWMQMV&o6@}#+v<^2)8VYv0~l zIQQ@1!@K{6>z#jd;@s?h25tg>$X0tg*n{;KV$DxGbVf(fQpf$Lr7S$oNa#*tly3EA9qX|kC$N+pT4lKZ8(LvDDguin;6uf6v+tLQ_FLF*uh zlxF6mnTu8?FSVFqIcBeDPAjOg>$>}`rxaIg9#wx(nVRW~2uB#V@YxI#CatrXoC(HDq%G*Y5 zA)Xr7+2yT3%bYREe8~vaz`Q;xo5M>gDVD?&+iBv*BxlWB&(1#m*wbd?8|&Dhf);J0 z!@ht29ILYzd)y+kzb&2O&4{C1u*_I;E48{!ubgt-`s%84-ic@48{B_u?m2jw0=lNn zpO@aF>8MM3Xq52sm-N)noqf9LtK%wf>W4_w3mIH)@}`4-DMly#tOrPC4uRBGgwe zIy~uG|GuU4;Hr-Kry8FIz4C&)Om@a$!-;=u_X1Ze>dN6ZE9SN(Z(jM*;LjZXplJTx ze4Wg@O{Vzs&qaLuEW;SuU3)H3g>bg4v-Sff|P% z813zNEIfZ; z3jgb3wF(yRd?M>m3_<8P8h)^ZkyG3LNGO>OY7m1IlUs-&2r=H>$BTXopb(SPudMtl zf98@M!H`rYx-CdWVpLz2CO5K6`6f>G`=RhoWE(Ap(2o*inB11$nRY7l#=9> z;%a!L>k-Rs9DJPX`bWh)%FlwXd?DnZ7_?x~QHG$pRe1hLNCu`WWIP&U+-w=klO!^g z2Kt|S0BAgH0`qez>j)8R3C3umYn zKa~|TPBOEP?nI+8r4^+U;)j>as`Mv!pFu2vf`2fB*nHr7Rvx diff --git a/data/fonts/ari-w9500-display.fnt b/data/fonts/ari-w9500-display.fnt index 74dac58..31d1592 100644 --- a/data/fonts/ari-w9500-display.fnt +++ b/data/fonts/ari-w9500-display.fnt @@ -1,5 +1,5 @@ # Font: ari-w9500-display — generado desde ari-w9500-display.ttf size 11 -# Generado con tools/font_gen/font_gen.py +# Generado con font_gen.py box_width 12 box_height 11 @@ -105,8 +105,8 @@ columns 15 193 9 # Á 200 8 # È 201 8 # É -204 3 # Ì -205 3 # Í +204 4 # Ì +205 4 # Í 210 10 # Ò 211 10 # Ó 217 8 # Ù @@ -118,7 +118,7 @@ columns 15 232 8 # è 233 8 # é 236 4 # ì -237 3 # í +237 4 # í 242 8 # ò 243 8 # ó 249 8 # ù @@ -126,7 +126,8 @@ columns 15 241 8 # ñ 231 8 # ç 161 3 # ¡ -191 8 # ¿ +191 5 # ¿ 171 10 # « 187 10 # » 183 3 # · +169 10 # © diff --git a/data/fonts/ari-w9500-display.gif b/data/fonts/ari-w9500-display.gif index 11c0d38184512045d3b7c4a126da49d84b8f7fc4..b408156faca6d70993ad33e267a1db9679f43478 100644 GIT binary patch delta 1484 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 mfws*pYk(E7R_bp{sZd zmrF6cIy0?OZ*EPDM*`yqVqzMuQO33icfDl|mNDGjZX2Whgu~v9#j}}Iz8%TwIQgQz zAoG~g5V5&p17*}9pJVEG%EejF+-1cQf_!(zOD(YD{TByhtdMbGX`r25^c^ixA8p&!Zm<0x$ znyCrfi(8BOwp)B`Y}+*%q$?xqYt#zVsYXn_tSu~^?KtZlER)U6{Cx+V94&qwu3o(g zxA}Zl9?zCeProK#y(ZiKonv<}VKZ#<&@~MBPL-d63V#VSxUgSCgvIIjA2TTAJ^G)iIF8ZlNlYZoTgA3$9>k6jVt4?=1!Ivb;hLFGuKg%OO*~oDG-Xq zp~~9%d7VOg8Z0wjvete2Fu$Wvr+I77fa`qtr5@Gg*A>*-Nz3lQ9GI k3J(g$%{R%d`K)#8YhkiwV3^zG+8)8g9#TZ)InH5xyn-#kK3kSIwO(*mkyM zNMwFIxU00V std::unique_ptr { return std::make_unique(placeholder_text, make_game); }; - auto make_title = [menu_title_text, placeholder_text, make_intro]() -> std::unique_ptr { - return std::make_unique(menu_title_text, placeholder_text, make_intro); + auto make_title = [menu_title_text, placeholder_text, mini_logo_surface, make_intro]() -> std::unique_ptr { + return std::make_unique(menu_title_text, placeholder_text, mini_logo_surface, make_intro); }; switch (START) { diff --git a/source/core/ui/ui_config.cpp b/source/core/ui/ui_config.cpp index bf1754a..2c39ecf 100644 --- a/source/core/ui/ui_config.cpp +++ b/source/core/ui/ui_config.cpp @@ -99,6 +99,7 @@ UiConfig::UiConfig() title_duration_ms_(Defaults::UI::Title::DURATION_MS), title_bg_color_(Defaults::UI::Title::BG_COLOR), title_text_color_(Defaults::UI::Title::TEXT_COLOR), + title_copyright_color_(Defaults::UI::Title::COPYRIGHT_COLOR), title_blink_visible_ms_(Defaults::UI::Title::BLINK_VISIBLE_MS), title_blink_hidden_ms_(Defaults::UI::Title::BLINK_HIDDEN_MS), menu_select_sound_(Defaults::UI::MENU_SELECT_SOUND), @@ -214,6 +215,7 @@ void UiConfig::load(const std::string& file_path) { readField(t, "duration_ms", title_duration_ms_); readColorIndex(t, "bg_color", title_bg_color_); readColorIndex(t, "text_color", title_text_color_); + readColorIndex(t, "copyright_color", title_copyright_color_); readField(t, "blink_visible_ms", title_blink_visible_ms_); readField(t, "blink_hidden_ms", title_blink_hidden_ms_); } diff --git a/source/core/ui/ui_config.hpp b/source/core/ui/ui_config.hpp index 6ea4d12..c1abac0 100644 --- a/source/core/ui/ui_config.hpp +++ b/source/core/ui/ui_config.hpp @@ -85,6 +85,7 @@ class UiConfig { [[nodiscard]] auto titleDurationMs() const -> int { return title_duration_ms_; } [[nodiscard]] auto titleBgColor() const -> Uint8 { return title_bg_color_; } [[nodiscard]] auto titleTextColor() const -> Uint8 { return title_text_color_; } + [[nodiscard]] auto titleCopyrightColor() const -> Uint8 { return title_copyright_color_; } [[nodiscard]] auto titleBlinkVisibleMs() const -> int { return title_blink_visible_ms_; } [[nodiscard]] auto titleBlinkHiddenMs() const -> int { return title_blink_hidden_ms_; } @@ -155,6 +156,7 @@ class UiConfig { int title_duration_ms_; Uint8 title_bg_color_; Uint8 title_text_color_; + Uint8 title_copyright_color_; int title_blink_visible_ms_; int title_blink_hidden_ms_; diff --git a/source/game/scenes/title_scene.cpp b/source/game/scenes/title_scene.cpp index 873f0cb..2b6390d 100644 --- a/source/game/scenes/title_scene.cpp +++ b/source/game/scenes/title_scene.cpp @@ -13,6 +13,7 @@ #include "core/rendering/notifier.hpp" #include "core/rendering/render_info.hpp" #include "core/rendering/screen.hpp" +#include "core/rendering/surface.hpp" #include "core/rendering/text.hpp" #include "core/resources/resource_cache.hpp" #include "core/system/event_buffer.hpp" @@ -34,6 +35,8 @@ namespace { constexpr int TITLE_Y_PERCENT = 25; constexpr int PROMPT_Y_PERCENT = 60; + constexpr int COPYRIGHT_Y_PERCENT = 90; + constexpr int LOGO_GAP_PX = 2; // Separació vertical entre el minilogo i el text de copyright. // Separació vertical entre la primera i segona línia del títol. Una // alçada de línia és l'opció més llegible al canvas de 240 px sense @@ -45,9 +48,10 @@ namespace { } // namespace -TitleScene::TitleScene(std::shared_ptr display_font, std::shared_ptr condensed_font, SceneFactory next_factory) +TitleScene::TitleScene(std::shared_ptr display_font, std::shared_ptr condensed_font, std::shared_ptr mini_logo, SceneFactory next_factory) : display_font_(std::move(display_font)), condensed_font_(std::move(condensed_font)), + mini_logo_(std::move(mini_logo)), next_factory_(std::move(next_factory)), timer_ms_(UiConfig::get().titleDurationMs()) { std::cout << "[scene] " << SCENE_NAME << " start\n"; @@ -120,6 +124,25 @@ void TitleScene::render() { } } + // Footer: minilogo centrat horitzontalment damunt del © de + // copyright. El text va al 90% Y, el logo just damunt amb un petit + // gap (LOGO_GAP_PX). Tots dos blocs són hardcodejats fins que + // tinguem artwork final. + if (condensed_font_) { + const int COPY_Y = (GameCanvas::HEIGHT * COPYRIGHT_Y_PERCENT) / 100; + if (mini_logo_) { + const int LOGO_X = GameCanvas::CENTER_X - (mini_logo_->getWidth() / 2); + const int LOGO_Y = COPY_Y - mini_logo_->getHeight() - LOGO_GAP_PX; + mini_logo_->render(LOGO_X, LOGO_Y); + } + condensed_font_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, + GameCanvas::CENTER_X, + COPY_Y, + "© 2026 JailDesigner", + condensed_font_->getDefaultKerning() - 1, + ui_config.titleCopyrightColor()); + } + Notifier::get().render(); RenderInfo::get().render(); Screen::get().present(); diff --git a/source/game/scenes/title_scene.hpp b/source/game/scenes/title_scene.hpp index 65ebfb9..d4d6a7b 100644 --- a/source/game/scenes/title_scene.hpp +++ b/source/game/scenes/title_scene.hpp @@ -5,6 +5,7 @@ #include "core/scene/scene.hpp" +class Surface; class Text; // Escena TITLE provisional. Pinta dos blocs de text sobre un fons gairebé @@ -15,7 +16,7 @@ class TitleScene : public Scene { public: using SceneFactory = std::function()>; - TitleScene(std::shared_ptr display_font, std::shared_ptr condensed_font, SceneFactory next_factory); + TitleScene(std::shared_ptr display_font, std::shared_ptr condensed_font, std::shared_ptr mini_logo, SceneFactory next_factory); ~TitleScene() override; void update(int delta_ms) override; @@ -24,6 +25,7 @@ class TitleScene : public Scene { private: std::shared_ptr display_font_; std::shared_ptr condensed_font_; + std::shared_ptr mini_logo_; SceneFactory next_factory_; int timer_ms_; int blink_elapsed_ms_{0}; diff --git a/source/utils/defaults.hpp b/source/utils/defaults.hpp index f4d7d4c..9ce4d79 100644 --- a/source/utils/defaults.hpp +++ b/source/utils/defaults.hpp @@ -255,6 +255,7 @@ namespace Defaults { constexpr int DURATION_MS = 30000; constexpr Uint8 BG_COLOR = 1; constexpr Uint8 TEXT_COLOR = 31; + constexpr Uint8 COPYRIGHT_COLOR = 246; // (218,218,255) off-white amb un mínim de fred. constexpr int BLINK_VISIBLE_MS = 800; constexpr int BLINK_HIDDEN_MS = 200; } // namespace Title