From bec797ffe73f269c504b91dca03e197e74f1e0b6 Mon Sep 17 00:00:00 2001 From: Gericom Date: Sat, 4 Apr 2026 10:01:15 +0200 Subject: [PATCH] Add ability to set the position of the top screen cover image in custom themes --- CHANGELOG.md | 3 +++ _pico/themes/raspberry/theme.json | 6 ++++++ .../romBrowser/Theme/IRomBrowserViewFactory.h | 2 ++ .../Material/MaterialRomBrowserViewFactory.h | 5 +++++ .../Theme/custom/CustomRomBrowserViewFactory.h | 7 ++++++- .../romBrowser/views/RomBrowserTopScreenView.cpp | 7 ++++--- .../romBrowser/views/RomBrowserTopScreenView.h | 1 + arm9/source/themes/custom/CustomTheme.cpp | 15 +++++++++++++++ arm9/source/themes/custom/CustomThemeInfo.h | 2 ++ arm9/source/themes/custom/CustomTopCoverInfo.h | 14 ++++++++++++++ docs/Themes.md | 4 ++++ 11 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 arm9/source/themes/custom/CustomTopCoverInfo.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 85918a4..fa39f31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## [Unreleased] +### Added +- Ability to set the position of the top screen cover image in custom themes + ## [v1.2.0] - 29 Mar 2026 ### Added diff --git a/_pico/themes/raspberry/theme.json b/_pico/themes/raspberry/theme.json index d4f1323..fbf7cc2 100644 --- a/_pico/themes/raspberry/theme.json +++ b/_pico/themes/raspberry/theme.json @@ -88,6 +88,12 @@ "b": 200 } }, + "topCover": { + "position": { + "x": 75, + "y": 18 + } + }, "gridIcon": { "blendColor": { "r": 200, diff --git a/arm9/source/romBrowser/Theme/IRomBrowserViewFactory.h b/arm9/source/romBrowser/Theme/IRomBrowserViewFactory.h index 63605ee..7ee7463 100644 --- a/arm9/source/romBrowser/Theme/IRomBrowserViewFactory.h +++ b/arm9/source/romBrowser/Theme/IRomBrowserViewFactory.h @@ -35,6 +35,8 @@ public: virtual FileRecyclerAdapter* CreateCoverFlowRecyclerAdapter( RomBrowserViewModel* viewModel, const IThemeFileIconFactory* themeFileIconFactory, VBlankTextureLoader* vblankTextureLoader) const = 0; + + virtual Point GetTopCoverPosition() const = 0; }; inline IRomBrowserViewFactory::~IRomBrowserViewFactory() { } diff --git a/arm9/source/romBrowser/Theme/Material/MaterialRomBrowserViewFactory.h b/arm9/source/romBrowser/Theme/Material/MaterialRomBrowserViewFactory.h index db17690..e100b01 100644 --- a/arm9/source/romBrowser/Theme/Material/MaterialRomBrowserViewFactory.h +++ b/arm9/source/romBrowser/Theme/Material/MaterialRomBrowserViewFactory.h @@ -65,6 +65,11 @@ public: themeFileIconFactory, this, vblankTextureLoader, &viewModel->GetCoverRepository()); } + Point GetTopCoverPosition() const override + { + return Point(75, 18); + } + private: const MaterialColorScheme* _materialColorScheme; const IFontRepository* _fontRepository; diff --git a/arm9/source/romBrowser/Theme/custom/CustomRomBrowserViewFactory.h b/arm9/source/romBrowser/Theme/custom/CustomRomBrowserViewFactory.h index 4e3d539..97dc2d2 100644 --- a/arm9/source/romBrowser/Theme/custom/CustomRomBrowserViewFactory.h +++ b/arm9/source/romBrowser/Theme/custom/CustomRomBrowserViewFactory.h @@ -7,12 +7,12 @@ #include "romBrowser/views/CoverFlowRecyclerView.h" #include "romBrowser/viewModels/RomBrowserViewModel.h" #include "romBrowser/DisplayMode/CoverFlowFileRecyclerAdapter.h" +#include "themes/custom/CustomThemeInfo.h" class MaterialColorScheme; class ITheme; class VramContext; class IFontRepository; -class CustomThemeInfo; class CustomRomBrowserViewFactory : public IRomBrowserViewFactory { @@ -65,6 +65,11 @@ public: themeFileIconFactory, this, vblankTextureLoader, &viewModel->GetCoverRepository()); } + Point GetTopCoverPosition() const override + { + return _customThemeInfo->topCoverInfo.GetPosition(); + } + void LoadResources(const ITheme& theme, const VramContext& mainVramContext); private: diff --git a/arm9/source/romBrowser/views/RomBrowserTopScreenView.cpp b/arm9/source/romBrowser/views/RomBrowserTopScreenView.cpp index 2328987..10c494e 100644 --- a/arm9/source/romBrowser/views/RomBrowserTopScreenView.cpp +++ b/arm9/source/romBrowser/views/RomBrowserTopScreenView.cpp @@ -20,6 +20,7 @@ RomBrowserTopScreenView::RomBrowserTopScreenView( , _themeFileIconFactory(themeFileIconFactory) , _fileInfoView(romBrowserViewFactory->CreateFileInfoView()) , _showCover(displayMode->ShowCoverOnTopScreen()) + , _coverPosition(romBrowserViewFactory->GetTopCoverPosition()) { AddChildTail(_fileInfoView.get()); } @@ -135,11 +136,11 @@ void RomBrowserTopScreenView::VBlank() REG_BG3PB_SUB = 0; REG_BG3PC_SUB = 0; REG_BG3PD_SUB = -0x100; - REG_BG3X_SUB = -75 << 8; - REG_BG3Y_SUB = 113 << 8; + REG_BG3X_SUB = (-_coverPosition.x) << 8; + REG_BG3Y_SUB = (96 + _coverPosition.y - 1) << 8; REG_BG3CNT_SUB = 0x0705; REG_DISPCNT_SUB |= ((1 << 3) | (1 << 5)) << 8; - gfx_setSubWindow0(75, 18, 75 + 106, 18 + 96); + gfx_setSubWindow0(_coverPosition.x, _coverPosition.y, _coverPosition.x + 106, _coverPosition.y + 96); REG_WININ_SUB = 0x002A; REG_WINOUT_SUB = ~(1 << 3); } diff --git a/arm9/source/romBrowser/views/RomBrowserTopScreenView.h b/arm9/source/romBrowser/views/RomBrowserTopScreenView.h index 2e954b1..140bc56 100644 --- a/arm9/source/romBrowser/views/RomBrowserTopScreenView.h +++ b/arm9/source/romBrowser/views/RomBrowserTopScreenView.h @@ -36,4 +36,5 @@ private: bool _iconGraphicsUploaded = false; bool _coverGraphicsUploaded = false; bool _showCover; + Point _coverPosition; }; \ No newline at end of file diff --git a/arm9/source/themes/custom/CustomTheme.cpp b/arm9/source/themes/custom/CustomTheme.cpp index 4ceee5f..3c9da38 100644 --- a/arm9/source/themes/custom/CustomTheme.cpp +++ b/arm9/source/themes/custom/CustomTheme.cpp @@ -25,6 +25,7 @@ #define KEY_TOP_BANNER_TEXT_LINE_1 "topBannerTextLine1" #define KEY_TOP_BANNER_TEXT_LINE_2 "topBannerTextLine2" #define KEY_TOP_FILE_NAME_TEXT "topFileNameText" +#define KEY_TOP_COVER "topCover" #define KEY_GRID_ICON "gridIcon" #define KEY_BANNER_LIST_ICON "bannerListIcon" #define KEY_BANNER_LIST_TEXT_LINE_0 "bannerListTextLine0" @@ -43,6 +44,7 @@ static const CustomThemeInfo sDefaultCustomThemeInfo .topBannerTextLine1Info = CustomTopTextElementInfo(Point(70, 141), 176, Rgb8(30, 30, 30), Rgb8(200, 200, 200)), .topBannerTextLine2Info = CustomTopTextElementInfo(Point(70, 155), 176, Rgb8(30, 30, 30), Rgb8(200, 200, 200)), .topFileNameTextInfo = CustomTopTextElementInfo(Point(18, 170), 220, Rgb8(30, 30, 30), Rgb8(200, 200, 200)), + .topCoverInfo = CustomTopCoverInfo(Point(75, 18)), .gridIconInfo = CustomBottomIconInfo(Rgb8(200, 200, 200)), @@ -122,6 +124,18 @@ static CustomTopIconInfo parseCustomTopIconInfo(const JsonObjectConst& json, con ); } +static CustomTopCoverInfo parseCustomTopCoverInfo(const JsonObjectConst& json, const CustomTopCoverInfo& defaultInfo) +{ + if (json.isNull()) + { + return defaultInfo; + } + + return CustomTopCoverInfo( + parsePoint(json[KEY_ELEMENT_POSITION], defaultInfo.GetPosition()) + ); +} + static CustomTopTextElementInfo parseCustomTextElementInfo( const JsonObjectConst& json, const CustomTopTextElementInfo& defaultInfo) { @@ -151,6 +165,7 @@ static CustomThemeInfo parseCustomThemeInfo(const JsonDocument& json) json[KEY_TOP_BANNER_TEXT_LINE_2], sDefaultCustomThemeInfo.topBannerTextLine2Info), .topFileNameTextInfo = parseCustomTextElementInfo( json[KEY_TOP_FILE_NAME_TEXT], sDefaultCustomThemeInfo.topFileNameTextInfo), + .topCoverInfo = parseCustomTopCoverInfo(json[KEY_TOP_COVER], sDefaultCustomThemeInfo.topCoverInfo), .gridIconInfo = parseCustomBottomIconInfo(json[KEY_GRID_ICON], sDefaultCustomThemeInfo.gridIconInfo), diff --git a/arm9/source/themes/custom/CustomThemeInfo.h b/arm9/source/themes/custom/CustomThemeInfo.h index 032c168..92072e5 100644 --- a/arm9/source/themes/custom/CustomThemeInfo.h +++ b/arm9/source/themes/custom/CustomThemeInfo.h @@ -1,6 +1,7 @@ #pragma once #include "CustomBannerListTextElementInfo.h" #include "CustomBottomIconInfo.h" +#include "CustomTopCoverInfo.h" #include "CustomTopIconInfo.h" #include "CustomTextElementInfo.h" @@ -11,6 +12,7 @@ struct CustomThemeInfo CustomTopTextElementInfo topBannerTextLine1Info; CustomTopTextElementInfo topBannerTextLine2Info; CustomTopTextElementInfo topFileNameTextInfo; + CustomTopCoverInfo topCoverInfo; CustomBottomIconInfo gridIconInfo; diff --git a/arm9/source/themes/custom/CustomTopCoverInfo.h b/arm9/source/themes/custom/CustomTopCoverInfo.h new file mode 100644 index 0000000..5c8bf5c --- /dev/null +++ b/arm9/source/themes/custom/CustomTopCoverInfo.h @@ -0,0 +1,14 @@ +#pragma once +#include "core/math/Point.h" + +class CustomTopCoverInfo +{ +public: + CustomTopCoverInfo(const Point& position) + : _position(position) { } + + const Point& GetPosition() const { return _position; } + +private: + Point _position; +}; diff --git a/docs/Themes.md b/docs/Themes.md index c0dc3a2..5dc972c 100644 --- a/docs/Themes.md +++ b/docs/Themes.md @@ -61,6 +61,7 @@ Custom themes support additional properties in the `theme.json` file to allow fo - **topBannerTextLine1** - Properties of the second banner text line displayed on the top screen. - **topBannerTextLine2** - Properties of the third banner text line displayed on the top screen. - **topFileNameText** - Properties of the file name text displayed on the top screen. +- **topCover** - Properties of the cover image displayed on the top screen. - **gridIcon** - Properties of the icons displayed on the bottom screen in grid display modes. - **bannerListIcon** - Properties of the icons displayed on the bottom screen in banner list display mode. - **bannerListTextLine0** - Properties of the first banner text line displayed on the bottom screen in banner list display mode. @@ -105,6 +106,9 @@ Blend colors are used to fake translucency. They should be set to an approximati "textColor": { "r": 30, "g": 30, "b": 30 }, "blendColor": { "r": 200, "g": 200, "b": 200 } }, + "topCover": { + "position": { "x": 75, "y": 18 } + }, "gridIcon": { "blendColor": { "r": 200, "g": 200, "b": 200 } },