diff --git a/source/DrawUtils.cpp b/source/DrawUtils.cpp index a47e0fb..2732435 100644 --- a/source/DrawUtils.cpp +++ b/source/DrawUtils.cpp @@ -5,8 +5,11 @@ #include "utils.h" #include #include +#include #include #include +#include +#include #include #include @@ -24,7 +27,23 @@ static SFT pFont = {}; static Color font_col(0xFFFFFFFF); +void DrawUtils::ClearSavedFrameBuffers() { + // If GX2 is running make sure to shut it down and free all existing memory in the saved-frame area. + if (GX2GetMainCoreId() != -1) { + GX2SetTVEnable(FALSE); + GX2SetDRCEnable(FALSE); + GX2Shutdown(); + } + + __OSClearSavedFrame(OS_SAVED_FRAME_A, OS_SAVED_FRAME_SCREEN_TV); + __OSClearSavedFrame(OS_SAVED_FRAME_A, OS_SAVED_FRAME_SCREEN_DRC); + __OSClearSavedFrame(OS_SAVED_FRAME_B, OS_SAVED_FRAME_SCREEN_TV); + __OSClearSavedFrame(OS_SAVED_FRAME_B, OS_SAVED_FRAME_SCREEN_DRC); +} + void *DrawUtils::InitOSScreen() { + ClearSavedFrameBuffers(); + OSScreenInit(); uint32_t tvBufferSize = OSScreenGetBufferSizeEx(SCREEN_TV); diff --git a/source/DrawUtils.h b/source/DrawUtils.h index c7a7254..343ad49 100644 --- a/source/DrawUtils.h +++ b/source/DrawUtils.h @@ -30,6 +30,8 @@ union Color { class DrawUtils { public: + static void ClearSavedFrameBuffers(); + static void *InitOSScreen(); static void initBuffers(void *tvBuffer, uint32_t tvSize, void *drcBuffer, uint32_t drcSize); diff --git a/source/MenuUtils.cpp b/source/MenuUtils.cpp index cf30865..4ba1f79 100644 --- a/source/MenuUtils.cpp +++ b/source/MenuUtils.cpp @@ -452,6 +452,8 @@ void handleUpdateWarningScreen() { DrawUtils::deinitFont(); + GX2Init(nullptr); + free(screenBuffer); } @@ -492,23 +494,6 @@ bool handleDiscInsertScreen(uint64_t expectedTitleId, uint64_t *titleIdToLaunch) return true; } - auto result = false; - auto screenBuffer = DrawUtils::InitOSScreen(); - if (!screenBuffer) { - OSFatal("Failed to alloc memory for screen"); - } - - uint32_t tvBufferSize = OSScreenGetBufferSizeEx(SCREEN_TV); - uint32_t drcBufferSize = OSScreenGetBufferSizeEx(SCREEN_DRC); - - DrawUtils::initBuffers(screenBuffer, tvBufferSize, (void *) ((uint32_t) screenBuffer + tvBufferSize), drcBufferSize); - if (!DrawUtils::initFont()) { - OSFatal("Failed to init font"); - } - DrawUtils::beginDraw(); - DrawUtils::clear(COLOR_BACKGROUND); - DrawUtils::endDraw(); - uint64_t titleIdOfDisc = 0; bool discInserted; @@ -524,17 +509,32 @@ bool handleDiscInsertScreen(uint64_t expectedTitleId, uint64_t *titleIdToLaunch) if (discInserted && !wrongDiscInserted) { *titleIdToLaunch = expectedTitleId; - DrawUtils::deinitFont(); - free(screenBuffer); return true; } if (!AXIsInit()) { AXInit(); } + + bool result; + auto screenBuffer = DrawUtils::InitOSScreen(); + if (!screenBuffer) { + OSFatal("AutobootModule: Failed to alloc memory for screen"); + } + + uint32_t tvBufferSize = OSScreenGetBufferSizeEx(SCREEN_TV); + uint32_t drcBufferSize = OSScreenGetBufferSizeEx(SCREEN_DRC); + + DrawUtils::initBuffers(screenBuffer, tvBufferSize, (void *) ((uint32_t) screenBuffer + tvBufferSize), drcBufferSize); + if (!DrawUtils::initFont()) { + OSFatal("AutobootModule: Failed to init font"); + } + DrawUtils::beginDraw(); + DrawUtils::clear(COLOR_BACKGROUND); + DrawUtils::endDraw(); + // When an unexpected disc was inserted we need to eject it first. bool allowDisc = !wrongDiscInserted; - { PairMenu pairMenu; @@ -574,6 +574,9 @@ bool handleDiscInsertScreen(uint64_t expectedTitleId, uint64_t *titleIdToLaunch) DrawUtils::deinitFont(); + // Call GX2Init to shut down OSScreen + GX2Init(nullptr); + free(screenBuffer); return result; diff --git a/source/main.cpp b/source/main.cpp index 435ff0b..70e4110 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -7,9 +7,8 @@ #include "logger.h" #include #include +#include #include -#include -#include #include #include #include @@ -18,19 +17,6 @@ #include #include -void clearScreen() { - auto buffer = DrawUtils::InitOSScreen(); - if (!buffer) { - OSFatal("Failed to alloc memory for screen"); - } - DrawUtils::clear(COLOR_BACKGROUND); - - // Call GX2Init to shut down OSScreen - GX2Init(nullptr); - - free(buffer); -} - bool gUpdatesBlocked = false; int32_t main(int32_t argc, char **argv) { @@ -39,9 +25,6 @@ int32_t main(int32_t argc, char **argv) { InputUtils::Init(); - // Clear screen to avoid screen corruptions when loading the Wii U Menu - clearScreen(); - initExternalStorage(); // Use librpxloader. @@ -68,6 +51,8 @@ int32_t main(int32_t argc, char **argv) { InputUtils::InputData buttons = InputUtils::getControllerInput(); + bool hadMenu = false; + FSAInit(); auto client = FSAAddClient(nullptr); if (client > 0) { @@ -81,6 +66,7 @@ int32_t main(int32_t argc, char **argv) { AXInit(); } handleUpdateWarningScreen(); + hadMenu = true; } else { FSAStat st{}; if (FSAGetStat(client, "/vol/storage_mlc01/sys/update", &st) != FS_ERROR_OK) { @@ -132,6 +118,7 @@ int32_t main(int32_t argc, char **argv) { AXInit(); } bootSelection = handleMenuScreen(configPath, bootSelection, menu); + hadMenu = true; } if (bootSelection >= 0) { @@ -171,6 +158,9 @@ int32_t main(int32_t argc, char **argv) { AXQuit(); } + if (!hadMenu) { + DrawUtils::ClearSavedFrameBuffers(); + } return 0; }