From 53fe6940df5c3f562799757c4cea1aa3ce6c7a4d Mon Sep 17 00:00:00 2001 From: iota97 Date: Thu, 31 Mar 2022 17:03:34 +0200 Subject: [PATCH] Allow to change atlas per theme --- Common/UI/Context.cpp | 11 +++++--- Common/UI/Context.h | 6 ++++ UI/GameSettingsScreen.cpp | 4 +-- UI/NativeApp.cpp | 39 ++++---------------------- UI/Theme.cpp | 58 ++++++++++++++++++++++++++++++++++++++- UI/Theme.h | 5 +++- 6 files changed, 81 insertions(+), 42 deletions(-) diff --git a/Common/UI/Context.cpp b/Common/UI/Context.cpp index 73520c661d..c6bc911e23 100644 --- a/Common/UI/Context.cpp +++ b/Common/UI/Context.cpp @@ -10,7 +10,6 @@ #include "Common/UI/Context.h" #include "Common/Render/DrawBuffer.h" #include "Common/Render/Text/draw_text.h" - #include "Common/Log.h" #include "UI/TextureUtil.h" @@ -36,10 +35,14 @@ void UIContext::Init(Draw::DrawContext *thin3d, Draw::Pipeline *uipipe, Draw::Pi textDrawer_ = TextDrawer::Create(thin3d); // May return nullptr if no implementation is available for this platform. } +void UIContext::setUIAtlas(const std::string &name) { + UIAtlas_ = name; +} + void UIContext::BeginFrame() { - if (!uitexture_) { - uitexture_ = CreateTextureFromFile(draw_, "ui_atlas.zim", ImageFileType::ZIM, false); - _dbg_assert_msg_(uitexture_, "Failed to load ui_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory."); + if (!uitexture_ || UIAtlas_ != lastUIAtlas_) { + uitexture_ = CreateTextureFromFile(draw_, UIAtlas_.c_str(), ImageFileType::ZIM, false); + lastUIAtlas_ = UIAtlas_; if (!fontTexture_) { #if PPSSPP_PLATFORM(WINDOWS) || PPSSPP_PLATFORM(ANDROID) // Don't bother with loading font_atlas.zim diff --git a/Common/UI/Context.h b/Common/UI/Context.h index 699935628d..ad02b4027c 100644 --- a/Common/UI/Context.h +++ b/Common/UI/Context.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "Common/Math/geom2d.h" #include "Common/Math/lin/vec3.h" @@ -100,6 +101,8 @@ public: void PopTransform(); Bounds TransformBounds(const Bounds &bounds); + void setUIAtlas(const std::string &name); + private: Draw::DrawContext *draw_ = nullptr; Bounds bounds_; @@ -120,4 +123,7 @@ private: std::vector scissorStack_; std::vector transformStack_; + + std::string lastUIAtlas_; + std::string UIAtlas_ = "ui_atlas.zim"; }; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index a19019fe13..67c0e31469 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -885,9 +885,9 @@ void GameSettingsScreen::CreateViews() { backgroundChoice_->OnClick.Handle(this, &GameSettingsScreen::OnChangeBackground); } - PopupMultiChoiceDynamic *theme = systemSettings->Add(new PopupMultiChoiceDynamic(&g_Config.sThemeName, sy->T("Color Theme"), GetThemeInfoNames(), th->GetName(), screenManager())); + PopupMultiChoiceDynamic *theme = systemSettings->Add(new PopupMultiChoiceDynamic(&g_Config.sThemeName, sy->T("Theme"), GetThemeInfoNames(), th->GetName(), screenManager())); theme->OnChoice.Add([=](EventParams &e) { - UpdateTheme(); + UpdateTheme(screenManager()->getUIContext()); return UI::EVENT_CONTINUE; }); diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 52a43b6f3c..de8ca08662 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -130,11 +130,6 @@ #include "android/jni/app-android.h" #endif -// The new UI framework, for initialization - -static Atlas g_ui_atlas; -static Atlas g_font_atlas; - #if PPSSPP_ARCH(ARM) && defined(__ANDROID__) #include "../../android/jni/ArmEmitterTest.h" #elif PPSSPP_ARCH(ARM64) && defined(__ANDROID__) @@ -876,22 +871,6 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch void RenderOverlays(UIContext *dc, void *userdata); bool CreateGlobalPipelines(); -static void LoadAtlasMetadata(Atlas &metadata, const char *filename, bool required) { - size_t atlas_data_size = 0; - if (!metadata.IsMetadataLoaded()) { - const uint8_t *atlas_data = VFSReadFile(filename, &atlas_data_size); - bool load_success = atlas_data != nullptr && metadata.Load(atlas_data, atlas_data_size); - if (!load_success) { - if (required) - ERROR_LOG(G3D, "Failed to load %s - graphics will be broken", filename); - else - WARN_LOG(G3D, "Failed to load %s", filename); - // Stumble along with broken visuals instead of dying... - } - delete[] atlas_data; - } -} - bool NativeInitGraphics(GraphicsContext *graphicsContext) { INFO_LOG(SYSTEM, "NativeInitGraphics"); @@ -906,22 +885,14 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) { return false; } - // Load any missing atlas metadata (the images are loaded from UIContext). - LoadAtlasMetadata(g_ui_atlas, "ui_atlas.meta", true); -#if !(PPSSPP_PLATFORM(WINDOWS) || PPSSPP_PLATFORM(ANDROID)) - LoadAtlasMetadata(g_font_atlas, "font_atlas.meta", g_ui_atlas.num_fonts == 0); -#else - LoadAtlasMetadata(g_font_atlas, "asciifont_atlas.meta", g_ui_atlas.num_fonts == 0); -#endif + ui_draw2d.SetAtlas(GetUIAtlas()); + ui_draw2d.SetFontAtlas(GetFontAtlas()); + ui_draw2d_front.SetAtlas(GetUIAtlas()); + ui_draw2d_front.SetFontAtlas(GetFontAtlas()); - ui_draw2d.SetAtlas(&g_ui_atlas); - ui_draw2d.SetFontAtlas(&g_font_atlas); - ui_draw2d_front.SetAtlas(&g_ui_atlas); - ui_draw2d_front.SetFontAtlas(&g_font_atlas); - - UpdateTheme(); uiContext = new UIContext(); uiContext->theme = GetTheme(); + UpdateTheme(uiContext); ui_draw2d.Init(g_draw, texColorPipeline); ui_draw2d_front.Init(g_draw, texColorPipeline); diff --git a/UI/Theme.cpp b/UI/Theme.cpp index 88cb02b188..91e1ea780d 100644 --- a/UI/Theme.cpp +++ b/UI/Theme.cpp @@ -25,6 +25,7 @@ #include "Common/File/VFS/VFS.h" #include "Common/Data/Format/IniFile.h" #include "Common/File/DirListing.h" +#include "Common/LogManager.h" #include "Core/Config.h" @@ -52,6 +53,8 @@ struct ThemeInfo { uint32_t uPopupStyleBg = 0xFF303030; uint32_t uBackgroundColor = 0xFF754D24; + std::string UIAtlas; + bool operator == (const std::string &other) { return name == other; } @@ -63,6 +66,9 @@ struct ThemeInfo { static UI::Theme ui_theme; static std::vector themeInfos; +static Atlas ui_atlas; +static Atlas font_atlas; + static void LoadThemeInfo(const std::vector &directories) { themeInfos.clear(); ThemeInfo def{}; @@ -128,6 +134,22 @@ static void LoadThemeInfo(const std::vector &directories) { section.Get("PopupStyleBg", &info.uPopupStyleBg, info.uPopupStyleBg); section.Get("BackgroundColor", &info.uBackgroundColor, info.uBackgroundColor); + std::string tmpPath; + section.Get("UIAtlas", &tmpPath, ""); + if (tmpPath != "") { + tmpPath = (path / tmpPath).ToString(); + + File::FileInfo tmpInfo; + if (VFSGetFileInfo((tmpPath+".meta").c_str(), &tmpInfo) && VFSGetFileInfo((tmpPath+".zim").c_str(), &tmpInfo)) { + info.UIAtlas = tmpPath; + } else { + // Files not found, fallback to default + info.UIAtlas = "ui_atlas"; + } + } else { + info.UIAtlas = "ui_atlas"; + } + appendTheme(info); } } @@ -141,7 +163,23 @@ static UI::Style MakeStyle(uint32_t fg, uint32_t bg) { return s; } -void UpdateTheme() { +static void LoadAtlasMetadata(Atlas &metadata, const char *filename, bool required) { + size_t atlas_data_size = 0; + if (!metadata.IsMetadataLoaded()) { + const uint8_t *atlas_data = VFSReadFile(filename, &atlas_data_size); + bool load_success = atlas_data != nullptr && metadata.Load(atlas_data, atlas_data_size); + if (!load_success) { + if (required) + ERROR_LOG(G3D, "Failed to load %s - graphics will be broken", filename); + else + WARN_LOG(G3D, "Failed to load %s", filename); + // Stumble along with broken visuals instead of dying... + } + delete[] atlas_data; + } +} + +void UpdateTheme(UIContext *ctx) { // First run, get the default in at least if (themeInfos.empty()) { ReloadAllThemeInfo(); @@ -188,12 +226,30 @@ void UpdateTheme() { ui_theme.popupTitle.fgColor = themeInfos[i].uPopupTitleStyleFg; ui_theme.popupStyle = MakeStyle(themeInfos[i].uPopupStyleFg, themeInfos[i].uPopupStyleBg); ui_theme.backgroundColor = themeInfos[i].uBackgroundColor; + + // Load any missing atlas metadata (the images are loaded from UIContext). + LoadAtlasMetadata(ui_atlas, (themeInfos[i].UIAtlas+".meta").c_str(), true); +#if !(PPSSPP_PLATFORM(WINDOWS) || PPSSPP_PLATFORM(ANDROID)) + LoadAtlasMetadata(font_atlas, "font_atlas.meta", ui_atlas.num_fonts == 0); +#else + LoadAtlasMetadata(font_atlas, "asciifont_atlas.meta", ui_atlas.num_fonts == 0); +#endif + + ctx->setUIAtlas(themeInfos[i].UIAtlas+".zim"); } UI::Theme *GetTheme() { return &ui_theme; } +Atlas *GetFontAtlas() { + return &font_atlas; +} + +Atlas *GetUIAtlas() { + return &ui_atlas; +} + void ReloadAllThemeInfo() { std::vector directories; directories.push_back(Path("themes")); // For VFS diff --git a/UI/Theme.h b/UI/Theme.h index adff861c04..d34d79cbe3 100644 --- a/UI/Theme.h +++ b/UI/Theme.h @@ -21,9 +21,12 @@ #include #include "Common/UI/Context.h" +#include "Common/Render/TextureAtlas.h" void ReloadAllThemeInfo(); std::vector GetThemeInfoNames(); -void UpdateTheme(); +void UpdateTheme(UIContext *ctx); +Atlas *GetFontAtlas(); +Atlas *GetUIAtlas(); UI::Theme *GetTheme(); \ No newline at end of file