Avoid/reduce screen corruption on boot

This commit is contained in:
Maschell 2024-07-04 17:28:32 +02:00
parent 469e1d15f6
commit d58ea5aad3
4 changed files with 52 additions and 38 deletions

View File

@ -5,8 +5,11 @@
#include "utils.h" #include "utils.h"
#include <coreinit/cache.h> #include <coreinit/cache.h>
#include <coreinit/memory.h> #include <coreinit/memory.h>
#include <coreinit/savedframe.h>
#include <coreinit/screen.h> #include <coreinit/screen.h>
#include <cstdlib> #include <cstdlib>
#include <gx2/display.h>
#include <gx2/state.h>
#include <malloc.h> #include <malloc.h>
#include <png.h> #include <png.h>
@ -24,7 +27,23 @@ static SFT pFont = {};
static Color font_col(0xFFFFFFFF); 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() { void *DrawUtils::InitOSScreen() {
ClearSavedFrameBuffers();
OSScreenInit(); OSScreenInit();
uint32_t tvBufferSize = OSScreenGetBufferSizeEx(SCREEN_TV); uint32_t tvBufferSize = OSScreenGetBufferSizeEx(SCREEN_TV);

View File

@ -30,6 +30,8 @@ union Color {
class DrawUtils { class DrawUtils {
public: public:
static void ClearSavedFrameBuffers();
static void *InitOSScreen(); static void *InitOSScreen();
static void initBuffers(void *tvBuffer, uint32_t tvSize, void *drcBuffer, uint32_t drcSize); static void initBuffers(void *tvBuffer, uint32_t tvSize, void *drcBuffer, uint32_t drcSize);

View File

@ -452,6 +452,8 @@ void handleUpdateWarningScreen() {
DrawUtils::deinitFont(); DrawUtils::deinitFont();
GX2Init(nullptr);
free(screenBuffer); free(screenBuffer);
} }
@ -492,23 +494,6 @@ bool handleDiscInsertScreen(uint64_t expectedTitleId, uint64_t *titleIdToLaunch)
return true; 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; uint64_t titleIdOfDisc = 0;
bool discInserted; bool discInserted;
@ -524,17 +509,32 @@ bool handleDiscInsertScreen(uint64_t expectedTitleId, uint64_t *titleIdToLaunch)
if (discInserted && !wrongDiscInserted) { if (discInserted && !wrongDiscInserted) {
*titleIdToLaunch = expectedTitleId; *titleIdToLaunch = expectedTitleId;
DrawUtils::deinitFont();
free(screenBuffer);
return true; return true;
} }
if (!AXIsInit()) { if (!AXIsInit()) {
AXInit(); 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. // When an unexpected disc was inserted we need to eject it first.
bool allowDisc = !wrongDiscInserted; bool allowDisc = !wrongDiscInserted;
{ {
PairMenu pairMenu; PairMenu pairMenu;
@ -574,6 +574,9 @@ bool handleDiscInsertScreen(uint64_t expectedTitleId, uint64_t *titleIdToLaunch)
DrawUtils::deinitFont(); DrawUtils::deinitFont();
// Call GX2Init to shut down OSScreen
GX2Init(nullptr);
free(screenBuffer); free(screenBuffer);
return result; return result;

View File

@ -7,9 +7,8 @@
#include "logger.h" #include "logger.h"
#include <coreinit/debug.h> #include <coreinit/debug.h>
#include <coreinit/filesystem_fsa.h> #include <coreinit/filesystem_fsa.h>
#include <coreinit/thread.h>
#include <coreinit/title.h> #include <coreinit/title.h>
#include <gx2/state.h>
#include <malloc.h>
#include <mocha/mocha.h> #include <mocha/mocha.h>
#include <rpxloader/rpxloader.h> #include <rpxloader/rpxloader.h>
#include <sndcore2/core.h> #include <sndcore2/core.h>
@ -18,19 +17,6 @@
#include <sysapp/launch.h> #include <sysapp/launch.h>
#include <vpad/input.h> #include <vpad/input.h>
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; bool gUpdatesBlocked = false;
int32_t main(int32_t argc, char **argv) { int32_t main(int32_t argc, char **argv) {
@ -39,9 +25,6 @@ int32_t main(int32_t argc, char **argv) {
InputUtils::Init(); InputUtils::Init();
// Clear screen to avoid screen corruptions when loading the Wii U Menu
clearScreen();
initExternalStorage(); initExternalStorage();
// Use librpxloader. // Use librpxloader.
@ -68,6 +51,8 @@ int32_t main(int32_t argc, char **argv) {
InputUtils::InputData buttons = InputUtils::getControllerInput(); InputUtils::InputData buttons = InputUtils::getControllerInput();
bool hadMenu = false;
FSAInit(); FSAInit();
auto client = FSAAddClient(nullptr); auto client = FSAAddClient(nullptr);
if (client > 0) { if (client > 0) {
@ -81,6 +66,7 @@ int32_t main(int32_t argc, char **argv) {
AXInit(); AXInit();
} }
handleUpdateWarningScreen(); handleUpdateWarningScreen();
hadMenu = true;
} else { } else {
FSAStat st{}; FSAStat st{};
if (FSAGetStat(client, "/vol/storage_mlc01/sys/update", &st) != FS_ERROR_OK) { 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(); AXInit();
} }
bootSelection = handleMenuScreen(configPath, bootSelection, menu); bootSelection = handleMenuScreen(configPath, bootSelection, menu);
hadMenu = true;
} }
if (bootSelection >= 0) { if (bootSelection >= 0) {
@ -171,6 +158,9 @@ int32_t main(int32_t argc, char **argv) {
AXQuit(); AXQuit();
} }
if (!hadMenu) {
DrawUtils::ClearSavedFrameBuffers();
}
return 0; return 0;
} }