From ade02997d47ee1bccb5301839ddff04f2708927a Mon Sep 17 00:00:00 2001 From: "Daniel K. O. (dkosmari)" Date: Sat, 20 Dec 2025 20:20:44 -0300 Subject: [PATCH 1/8] Fixed format string. --- source/gfx/gfx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/gfx/gfx.c b/source/gfx/gfx.c index 5bc9078..df33e02 100644 --- a/source/gfx/gfx.c +++ b/source/gfx/gfx.c @@ -200,7 +200,7 @@ static BOOL initBucketHeap() { sGfxHeapForeground = MEMCreateExpHeapEx(base, size, 0); if (!sGfxHeapForeground) { - WHBLogPrintf("%s: MEMCreateExpHeapEx(0x%08X, 0x%X, 0)", __FUNCTION__, base, size); + WHBLogPrintf("%s: MEMCreateExpHeapEx(%p, 0x%X, 0)", __FUNCTION__, base, size); return FALSE; } @@ -476,4 +476,4 @@ BOOL GfxInitShaderAttribute(WHBGfxShaderGroup *group, attrib->mask = GfxGetAttribFormatSel(format); attrib->endianSwap = GX2_ENDIAN_SWAP_DEFAULT; return TRUE; -} \ No newline at end of file +} From 8f6e0ce46d1bad1440c4ec0bf81e5ea08c6f338f Mon Sep 17 00:00:00 2001 From: "Daniel K. O. (dkosmari)" Date: Sat, 20 Dec 2025 20:52:50 -0300 Subject: [PATCH 2/8] Try sd:/wiiu as a fallback path for loading splashes. --- source/gfx/SplashScreenDrawer.cpp | 54 ++++++++++++++++++------------- source/gfx/SplashScreenDrawer.h | 6 +++- source/main.cpp | 25 +++++++++++--- 3 files changed, 57 insertions(+), 28 deletions(-) diff --git a/source/gfx/SplashScreenDrawer.cpp b/source/gfx/SplashScreenDrawer.cpp index e9f9793..646fc98 100644 --- a/source/gfx/SplashScreenDrawer.cpp +++ b/source/gfx/SplashScreenDrawer.cpp @@ -142,7 +142,15 @@ static GX2Texture *LoadImageAsTexture(const std::filesystem::path &filename) { return nullptr; } +SplashScreenDrawer::SplashScreenDrawer() +{ + mTexture = PNG_LoadTexture(empty_png); + InitResources(); +} + SplashScreenDrawer::SplashScreenDrawer(const std::filesystem::path &splash_base_path) { + if (splash_base_path.empty()) + throw std::runtime_error{"empty base dir"}; mTexture = LoadImageAsTexture(splash_base_path / "splash.png"); if (!mTexture) { mTexture = LoadImageAsTexture(splash_base_path / "splash.jpg"); @@ -155,35 +163,35 @@ SplashScreenDrawer::SplashScreenDrawer(const std::filesystem::path &splash_base_ } if (!mTexture) { // try to load a random one from "splashes/*" - try { - std::vector candidates; - for (const auto &entry : std::filesystem::directory_iterator{splash_base_path / "splashes"}) { - if (!entry.is_regular_file()) { - continue; - } - auto ext = ToLower(entry.path().extension()); - if (ext == ".png" || ext == ".tga" || ext == ".jpg" || ext == ".jpeg") { - candidates.push_back(entry.path()); - } + std::vector candidates; + for (const auto &entry : std::filesystem::directory_iterator{splash_base_path / "splashes"}) { + if (!entry.is_regular_file()) { + continue; } - if (!candidates.empty()) { - auto t = static_cast(OSGetTime()); - std::seed_seq seed{static_cast(t), - static_cast(t >> 32)}; - std::minstd_rand eng{seed}; - std::uniform_int_distribution dist{0, candidates.size() - 1}; - auto selected = dist(eng); - mTexture = LoadImageAsTexture(candidates[selected]); + auto ext = ToLower(entry.path().extension()); + if (ext == ".png" || ext == ".tga" || ext == ".jpg" || ext == ".jpeg") { + candidates.push_back(entry.path()); } - } catch (std::exception &) {} - } - if (!mTexture) { - mTexture = PNG_LoadTexture(empty_png); + } + if (!candidates.empty()) { + auto t = static_cast(OSGetTime()); + std::seed_seq seed{static_cast(t), + static_cast(t >> 32)}; + std::minstd_rand eng{seed}; + std::uniform_int_distribution dist{0, candidates.size() - 1}; + auto selected = dist(eng); + mTexture = LoadImageAsTexture(candidates[selected]); + } } + if (!mTexture) { - return; + throw std::runtime_error{"failed to load texture"}; } + InitResources(); +} + +void SplashScreenDrawer::InitResources() { // create shader group mVertexShaderWrapper = DeserializeVertexShader(s_textureVertexShaderCompiled); mPixelShaderWrapper = DeserializePixelShader(s_texturePixelShaderCompiled); diff --git a/source/gfx/SplashScreenDrawer.h b/source/gfx/SplashScreenDrawer.h index 2576fa3..2375714 100644 --- a/source/gfx/SplashScreenDrawer.h +++ b/source/gfx/SplashScreenDrawer.h @@ -11,7 +11,9 @@ class SplashScreenDrawer { public: - explicit SplashScreenDrawer(const std::filesystem::path &meta_dir); + + SplashScreenDrawer(); + explicit SplashScreenDrawer(const std::filesystem::path &baseDir); void Draw(); @@ -47,4 +49,6 @@ class SplashScreenDrawer { GX2RBuffer mTexCoordBuffer = {}; GX2Texture *mTexture = nullptr; GX2Sampler mSampler = {}; + + void InitResources(); }; diff --git a/source/main.cpp b/source/main.cpp index 64fef0d..7e2db8b 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,5 +1,7 @@ +#include #include "gfx/SplashScreenDrawer.h" #include "gfx/gfx.h" +#include #include "utils/logger.h" #include "utils/utils.h" #include "version.h" @@ -11,15 +13,30 @@ int32_t main(int32_t argc, char **argv) { initLogging(); DEBUG_FUNCTION_LINE_INFO("Running SplashScreen Module " MODULE_VERSION_FULL ""); - std::filesystem::path basePath = "fs:/vol/external01/wiiu"; + using std::filesystem::path; + path envDir; if (argc >= 1) { - basePath = argv[0]; + envDir = argv[0]; } GfxInit(); { - SplashScreenDrawer splashScreenDrawer(basePath); - splashScreenDrawer.Draw(); + std::optional splashScreenDrawer; + for (const auto& dir : {envDir, path{"fs:/vol/external01/wiiu"}}) { + try { + splashScreenDrawer.emplace(dir); + break; + } + catch (std::exception &e) { + DEBUG_FUNCTION_LINE_INFO("Failed to use %s: %s", dir.c_str(), e.what()); + } + } + // Fallback: use built-in empty splash. + if (!splashScreenDrawer) { + splashScreenDrawer.emplace(); + } + splashScreenDrawer->Draw(); + } GfxShutdown(); From 9c114b88fd91f4a4b3b611d538cc5eff5df154b6 Mon Sep 17 00:00:00 2001 From: "Daniel K. O. (dkosmari)" Date: Sat, 20 Dec 2025 21:13:49 -0300 Subject: [PATCH 3/8] Updated README. --- README.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index d2c4f61..857f56b 100644 --- a/README.md +++ b/README.md @@ -5,18 +5,25 @@ other modules of the environment are loading. ## Usage Place the `01_splashscreen.rpx` in the `[ENVIRONMENT]/modules/setup` folder and run the -EnvironmentLoader. The module will attempt to load the splash image, in this order: - 1. `[ENVIRONMENT]/splash.png` - 2. `[ENVIRONMENT]/splash.jpg` or `[ENVIRONMENT]/splash.jpeg` - 3. `[ENVIRONMENT]/splash.tga` - 4. A random image (PNG, JPEG or TGA) from the directory `[ENVIRONMENT]/splashes/`. +EnvironmentLoader. -If no splash image is found on the sd card, this module will effectively do nothing. +Place your splash images in the folder `SD:/wiiu/splashes/`. One of them will be randomly +loaded during boot. **Notes:** - - `[ENVIRONMENT]` is the directory of the environment, for Aroma with would be `sd:/wiiu/enviroments/aroma/splash.png` - - When using a `tga` make sure its 24 bit and uncompressed - - In theory any (reasonable) resolution is supported, something like 1280x720 is recommended + - `[ENVIRONMENT]` is the directory of the environment, for Aroma with would be `SD:/wiiu/enviroments/aroma`. + - When using a `tga` image, make sure its 24 bit and uncompressed, + - In theory any (reasonable) resolution is supported, something like 1280x720 is recommended. + +## Path priority +The module will attempt to load a splash image from multiple places, in this order: + 1. `[ENVIRONMENT]/splash.{png,jpg,jpeg,tga}` + 2. `[ENVIRONMENT]/splashes/*.{png,jpg,jpeg,tga}` + 3. `SD:/wiiu/splash.{png,jpg,jpeg,tga}` + 4. `SD:/wiiu/splashes/*.{png,jpg,jpeg,tga}` + +You should use the last path (`SD:/wiiu/splashes/`), and leave the others for when you +want to override the splash. ## Buildflags From 2af9ab1b785101ba1f545e79edeb6891c2c06c5f Mon Sep 17 00:00:00 2001 From: "Daniel K. O. (dkosmari)" Date: Sat, 20 Dec 2025 21:14:50 -0300 Subject: [PATCH 4/8] Better formatting. --- README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 857f56b..116055e 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,10 @@ This module is supposed to be loaded with the [EnvironmentLoader](https://github other modules of the environment are loading. ## Usage -Place the `01_splashscreen.rpx` in the `[ENVIRONMENT]/modules/setup` folder and run the -EnvironmentLoader. - -Place your splash images in the folder `SD:/wiiu/splashes/`. One of them will be randomly -loaded during boot. + 1. Place the `01_splashscreen.rpx` in the `[ENVIRONMENT]/modules/setup` folder and run + the EnvironmentLoader. + 2. Place your splash images in the folder `SD:/wiiu/splashes/`. One of them will be randomly + loaded during boot. **Notes:** - `[ENVIRONMENT]` is the directory of the environment, for Aroma with would be `SD:/wiiu/enviroments/aroma`. From 3260e255ed9775885c7907edeb8247274cc040b1 Mon Sep 17 00:00:00 2001 From: "Daniel K. O. (dkosmari)" Date: Sat, 20 Dec 2025 21:17:02 -0300 Subject: [PATCH 5/8] Simpler wording. --- README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 116055e..a51e717 100644 --- a/README.md +++ b/README.md @@ -4,22 +4,20 @@ This module is supposed to be loaded with the [EnvironmentLoader](https://github other modules of the environment are loading. ## Usage - 1. Place the `01_splashscreen.rpx` in the `[ENVIRONMENT]/modules/setup` folder and run - the EnvironmentLoader. - 2. Place your splash images in the folder `SD:/wiiu/splashes/`. One of them will be randomly - loaded during boot. + 1. Place the `01_splashscreen.rpx` in the `[ENVIRONMENT]/modules/setup` folder. + 2. Place your splash images (PNG, TGA, JPEG)) in the folder `SD:/wiiu/splashes/`. **Notes:** - `[ENVIRONMENT]` is the directory of the environment, for Aroma with would be `SD:/wiiu/enviroments/aroma`. - - When using a `tga` image, make sure its 24 bit and uncompressed, + - When using a TGA image, make sure its 24 bit and uncompressed, - In theory any (reasonable) resolution is supported, something like 1280x720 is recommended. ## Path priority The module will attempt to load a splash image from multiple places, in this order: 1. `[ENVIRONMENT]/splash.{png,jpg,jpeg,tga}` - 2. `[ENVIRONMENT]/splashes/*.{png,jpg,jpeg,tga}` + 2. `[ENVIRONMENT]/splashes/*.{png,jpg,jpeg,tga}` (selected randomly) 3. `SD:/wiiu/splash.{png,jpg,jpeg,tga}` - 4. `SD:/wiiu/splashes/*.{png,jpg,jpeg,tga}` + 4. `SD:/wiiu/splashes/*.{png,jpg,jpeg,tga}` (selected randomly) You should use the last path (`SD:/wiiu/splashes/`), and leave the others for when you want to override the splash. From 92f5902fba0657bdaf1411afa6d8e49f7d71c553 Mon Sep 17 00:00:00 2001 From: "Daniel K. O. (dkosmari)" Date: Sat, 20 Dec 2025 21:17:42 -0300 Subject: [PATCH 6/8] Fixed typo. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a51e717..c2a631f 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ other modules of the environment are loading. ## Usage 1. Place the `01_splashscreen.rpx` in the `[ENVIRONMENT]/modules/setup` folder. - 2. Place your splash images (PNG, TGA, JPEG)) in the folder `SD:/wiiu/splashes/`. + 2. Place your splash images (PNG, TGA or JPEG) in the folder `SD:/wiiu/splashes/`. **Notes:** - `[ENVIRONMENT]` is the directory of the environment, for Aroma with would be `SD:/wiiu/enviroments/aroma`. From 0a219d52b0bd97a3bbd56f0ae4228e42e76f361f Mon Sep 17 00:00:00 2001 From: "Daniel K. O. (dkosmari)" Date: Sat, 20 Dec 2025 21:22:44 -0300 Subject: [PATCH 7/8] Formatting code. --- source/gfx/SplashScreenDrawer.cpp | 3 +-- source/gfx/SplashScreenDrawer.h | 1 - source/main.cpp | 10 ++++------ 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/source/gfx/SplashScreenDrawer.cpp b/source/gfx/SplashScreenDrawer.cpp index 646fc98..a87ae13 100644 --- a/source/gfx/SplashScreenDrawer.cpp +++ b/source/gfx/SplashScreenDrawer.cpp @@ -142,8 +142,7 @@ static GX2Texture *LoadImageAsTexture(const std::filesystem::path &filename) { return nullptr; } -SplashScreenDrawer::SplashScreenDrawer() -{ +SplashScreenDrawer::SplashScreenDrawer() { mTexture = PNG_LoadTexture(empty_png); InitResources(); } diff --git a/source/gfx/SplashScreenDrawer.h b/source/gfx/SplashScreenDrawer.h index 2375714..c4f7291 100644 --- a/source/gfx/SplashScreenDrawer.h +++ b/source/gfx/SplashScreenDrawer.h @@ -11,7 +11,6 @@ class SplashScreenDrawer { public: - SplashScreenDrawer(); explicit SplashScreenDrawer(const std::filesystem::path &baseDir); diff --git a/source/main.cpp b/source/main.cpp index 7e2db8b..e300f07 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,10 +1,10 @@ -#include #include "gfx/SplashScreenDrawer.h" #include "gfx/gfx.h" -#include #include "utils/logger.h" #include "utils/utils.h" #include "version.h" +#include +#include #define MODULE_VERSION "v0.3" #define MODULE_VERSION_FULL MODULE_VERSION SPLASHSCREEN_MODULE_VERSION_EXTRA @@ -22,12 +22,11 @@ int32_t main(int32_t argc, char **argv) { GfxInit(); { std::optional splashScreenDrawer; - for (const auto& dir : {envDir, path{"fs:/vol/external01/wiiu"}}) { + for (const auto &dir : {envDir, path{"fs:/vol/external01/wiiu"}}) { try { splashScreenDrawer.emplace(dir); break; - } - catch (std::exception &e) { + } catch (std::exception &e) { DEBUG_FUNCTION_LINE_INFO("Failed to use %s: %s", dir.c_str(), e.what()); } } @@ -36,7 +35,6 @@ int32_t main(int32_t argc, char **argv) { splashScreenDrawer.emplace(); } splashScreenDrawer->Draw(); - } GfxShutdown(); From 8d438d1634c469f5123ad2d0d5ef0f5bc6b130ff Mon Sep 17 00:00:00 2001 From: "Daniel K. O. (dkosmari)" Date: Sat, 20 Dec 2025 22:11:48 -0300 Subject: [PATCH 8/8] Avoid seeding RNG more than once. --- source/gfx/SplashScreenDrawer.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/source/gfx/SplashScreenDrawer.cpp b/source/gfx/SplashScreenDrawer.cpp index a87ae13..325b878 100644 --- a/source/gfx/SplashScreenDrawer.cpp +++ b/source/gfx/SplashScreenDrawer.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -147,6 +148,18 @@ SplashScreenDrawer::SplashScreenDrawer() { InitResources(); } +static std::size_t get_random_index(std::size_t size) { + static std::optional engine; + if (!engine) { + auto t = static_cast(OSGetTime()); + std::seed_seq seeder{static_cast(t), + static_cast(t >> 32)}; + engine.emplace(seeder); + } + std::uniform_int_distribution dist{0, size - 1}; + return dist(*engine); +} + SplashScreenDrawer::SplashScreenDrawer(const std::filesystem::path &splash_base_path) { if (splash_base_path.empty()) throw std::runtime_error{"empty base dir"}; @@ -173,12 +186,7 @@ SplashScreenDrawer::SplashScreenDrawer(const std::filesystem::path &splash_base_ } } if (!candidates.empty()) { - auto t = static_cast(OSGetTime()); - std::seed_seq seed{static_cast(t), - static_cast(t >> 32)}; - std::minstd_rand eng{seed}; - std::uniform_int_distribution dist{0, candidates.size() - 1}; - auto selected = dist(eng); + auto selected = get_random_index(candidates.size()); mTexture = LoadImageAsTexture(candidates[selected]); } }