diff --git a/source/main.cpp b/source/main.cpp index 6b1b697..f422bd6 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -5,6 +5,7 @@ #include "hooks.h" #include "patcher/hooks_patcher_static.h" #include "plugin/PluginDataFactory.h" +#include "utils/DrawUtils.h" #include "utils/WUPSBackendSettings.h" #include "utils/input/VPADInput.h" #include "utils/logger.h" @@ -22,6 +23,8 @@ WUMS_DEPENDS_ON(homebrew_functionpatcher); WUMS_DEPENDS_ON(homebrew_memorymapping); WUMS_DEPENDS_ON(homebrew_notifications); +using namespace std::chrono_literals; + WUMS_INITIALIZE() { initLogging(); @@ -47,6 +50,38 @@ WUMS_INITIALIZE() { vpadInput.update(1280, 720); auto buttomComboSafeMode = Input::eButtons::BUTTON_L | Input::eButtons::BUTTON_UP | Input::eButtons::BUTTON_MINUS; if ((vpadInput.data.buttons_h & (buttomComboSafeMode)) == buttomComboSafeMode) { + DrawUtils::RenderScreen([] { + DrawUtils::beginDraw(); + DrawUtils::clear(COLOR_BACKGROUND_WARN); + DrawUtils::setFontColor(COLOR_WARNING); + + // draw top bar + DrawUtils::setFontSize(48); + const char *title = "! Plugin System Safe Mode triggered !"; + DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(title) / 2, 48 + 8, title, true); + DrawUtils::drawRectFilled(8, 48 + 8 + 16, SCREEN_WIDTH - 8 * 2, 3, COLOR_WHITE); + + DrawUtils::setFontSize(24); + const char *message = "The Safe Mode of the Plugin System has been triggered."; + DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(message) / 2, SCREEN_HEIGHT / 2 - 48, message, true); + message = "Any plugins 3rd party plugins have been disabled!"; + DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(message) / 2, SCREEN_HEIGHT / 2 - 24, message, true); + + message = "To enable them again, open the plugin config menu (\ue004 + \ue07a + \ue046)."; + DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(message) / 2, SCREEN_HEIGHT / 2 + 24, message, true); + message = "Press then \ue002 to manage active plugins"; + DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(message) / 2, SCREEN_HEIGHT / 2 + 48, message, true); + + // draw bottom bar + DrawUtils::drawRectFilled(8, SCREEN_HEIGHT - 24 - 8 - 4, SCREEN_WIDTH - 8 * 2, 3, COLOR_WHITE); + DrawUtils::setFontSize(18); + const char *exitHints = "The console will continue to boot in 10 seconds."; + DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHints) / 2, SCREEN_HEIGHT - 8, exitHints, true); + + DrawUtils::endDraw(); + + std::this_thread::sleep_for(10s); + }); DEBUG_FUNCTION_LINE_INFO("Safe Mode activated!"); auto tobeIgnoredFilePath = getNonBaseAromaPluginFilenames(getPluginPath()); WUPSBackendSettings::LoadSettings(); diff --git a/source/utils/DrawUtils.cpp b/source/utils/DrawUtils.cpp index e9d3612..955d392 100644 --- a/source/utils/DrawUtils.cpp +++ b/source/utils/DrawUtils.cpp @@ -1,6 +1,7 @@ #include "DrawUtils.h" #include "dc.h" +#include "globals.h" #include "logger.h" #include "utils.h" #include @@ -8,6 +9,8 @@ #include #include #include +#include +#include #include // buffer width @@ -432,3 +435,121 @@ uint32_t DrawUtils::getTextWidth(const wchar_t *string) { return width; } + +void DrawUtils::RenderScreen(const std::function& callback) { + gOnlyAcceptFromThread = OSGetCurrentThread(); + bool wasHomeButtonMenuEnabled = OSIsHomeButtonMenuEnabled(); + + // Save copy of DC reg values + auto tvRender1 = DCReadReg32(SCREEN_TV, D1GRPH_CONTROL_REG); + auto tvRender2 = DCReadReg32(SCREEN_TV, D1GRPH_ENABLE_REG); + auto tvPitch1 = DCReadReg32(SCREEN_TV, D1GRPH_PITCH_REG); + auto tvPitch2 = DCReadReg32(SCREEN_TV, D1OVL_PITCH_REG); + + auto drcRender1 = DCReadReg32(SCREEN_DRC, D1GRPH_CONTROL_REG); + auto drcRender2 = DCReadReg32(SCREEN_DRC, D1GRPH_ENABLE_REG); + auto drcPitch1 = DCReadReg32(SCREEN_DRC, D1GRPH_PITCH_REG); + auto drcPitch2 = DCReadReg32(SCREEN_DRC, D1OVL_PITCH_REG); + + OSScreenInit(); + + uint32_t screen_buf0_size = OSScreenGetBufferSizeEx(SCREEN_TV); + uint32_t screen_buf1_size = OSScreenGetBufferSizeEx(SCREEN_DRC); + void *screenbuffer0 = MEMAllocFromMappedMemoryForGX2Ex(screen_buf0_size, 0x100); + void *screenbuffer1 = MEMAllocFromMappedMemoryForGX2Ex(screen_buf1_size, 0x100); + + bool skipScreen0Free = false; + bool skipScreen1Free = false; + bool doShutdownKPAD = false; + + if (!screenbuffer0 || !screenbuffer1) { + if (screenbuffer0 == nullptr) { + if (gStoredTVBuffer.buffer_size >= screen_buf0_size) { + screenbuffer0 = gStoredTVBuffer.buffer; + skipScreen0Free = true; + DEBUG_FUNCTION_LINE_VERBOSE("Use storedTVBuffer"); + } + } + if (screenbuffer1 == nullptr) { + if (gStoredDRCBuffer.buffer_size >= screen_buf1_size) { + screenbuffer1 = gStoredDRCBuffer.buffer; + skipScreen1Free = true; + DEBUG_FUNCTION_LINE_VERBOSE("Use storedDRCBuffer"); + } + } + if (!screenbuffer0 || !screenbuffer1) { + DEBUG_FUNCTION_LINE_ERR("Failed to alloc buffers"); + goto error_exit; + } + } + + OSScreenSetBufferEx(SCREEN_TV, screenbuffer0); + OSScreenSetBufferEx(SCREEN_DRC, screenbuffer1); + + // Clear screens + OSScreenClearBufferEx(SCREEN_TV, 0); + OSScreenClearBufferEx(SCREEN_DRC, 0); + + // Flip buffers + OSScreenFlipBuffersEx(SCREEN_TV); + OSScreenFlipBuffersEx(SCREEN_DRC); + + // Clear screens + OSScreenClearBufferEx(SCREEN_TV, 0); + OSScreenClearBufferEx(SCREEN_DRC, 0); + + // Flip buffers + OSScreenFlipBuffersEx(SCREEN_TV); + OSScreenFlipBuffersEx(SCREEN_DRC); + + OSScreenEnableEx(SCREEN_TV, 1); + OSScreenEnableEx(SCREEN_DRC, 1); + + DrawUtils::initBuffers(screenbuffer0, screen_buf0_size, screenbuffer1, screen_buf1_size); + if (!DrawUtils::initFont()) { + DEBUG_FUNCTION_LINE_ERR("Failed to init Font"); + goto error_exit; + } + + // disable the home button menu to prevent opening it when exiting + OSEnableHomeButtonMenu(false); + + KPADStatus status; + KPADError err; + if (KPADReadEx(WPAD_CHAN_0, &status, 0, &err) == 0 && err == KPAD_ERROR_UNINITIALIZED) { + doShutdownKPAD = true; + KPADInit(); + } + + callback(); + + if (doShutdownKPAD) { + KPADShutdown(); + } + + OSEnableHomeButtonMenu(wasHomeButtonMenuEnabled); + + DrawUtils::deinitFont(); + +error_exit: + // Restore DC reg values + DCWriteReg32(SCREEN_TV, D1GRPH_CONTROL_REG, tvRender1); + DCWriteReg32(SCREEN_TV, D1GRPH_ENABLE_REG, tvRender2); + DCWriteReg32(SCREEN_TV, D1GRPH_PITCH_REG, tvPitch1); + DCWriteReg32(SCREEN_TV, D1OVL_PITCH_REG, tvPitch2); + + DCWriteReg32(SCREEN_DRC, D1GRPH_CONTROL_REG, drcRender1); + DCWriteReg32(SCREEN_DRC, D1GRPH_ENABLE_REG, drcRender2); + DCWriteReg32(SCREEN_DRC, D1GRPH_PITCH_REG, drcPitch1); + DCWriteReg32(SCREEN_DRC, D1OVL_PITCH_REG, drcPitch2); + + if (!skipScreen0Free && screenbuffer0) { + MEMFreeToMappedMemory(screenbuffer0); + } + + if (!skipScreen1Free && screenbuffer1) { + MEMFreeToMappedMemory(screenbuffer1); + } + + gOnlyAcceptFromThread = nullptr; +} \ No newline at end of file diff --git a/source/utils/DrawUtils.h b/source/utils/DrawUtils.h index 5ccc5e8..843e361 100644 --- a/source/utils/DrawUtils.h +++ b/source/utils/DrawUtils.h @@ -2,11 +2,23 @@ #include "schrift.h" #include +#include // visible screen sizes #define SCREEN_WIDTH 854 #define SCREEN_HEIGHT 480 +#define COLOR_BACKGROUND Color(238, 238, 238, 255) +#define COLOR_BACKGROUND_WARN Color(255, 251, 4, 255) +#define COLOR_TEXT Color(51, 51, 51, 255) +#define COLOR_TEXT2 Color(72, 72, 72, 255) +#define COLOR_DISABLED Color(255, 0, 0, 255) +#define COLOR_BORDER Color(204, 204, 204, 255) +#define COLOR_BORDER_HIGHLIGHTED Color(0x3478e4FF) +#define COLOR_WHITE Color(0xFFFFFFFF) +#define COLOR_BLACK Color(0, 0, 0, 255) +#define COLOR_WARNING COLOR_BLACK + union Color { explicit Color(const uint32_t color) { this->color = color; @@ -66,6 +78,8 @@ public: static uint32_t getTextWidth(const wchar_t *string); + static void RenderScreen(const std::function& callback); + private: static bool mIsBackBuffer; diff --git a/source/utils/config/ConfigDefines.h b/source/utils/config/ConfigDefines.h index ee60f36..b5f9325 100644 --- a/source/utils/config/ConfigDefines.h +++ b/source/utils/config/ConfigDefines.h @@ -3,15 +3,6 @@ #include #include -#define COLOR_BACKGROUND Color(238, 238, 238, 255) -#define COLOR_TEXT Color(51, 51, 51, 255) -#define COLOR_TEXT2 Color(72, 72, 72, 255) -#define COLOR_DISABLED Color(255, 0, 0, 255) -#define COLOR_BORDER Color(204, 204, 204, 255) -#define COLOR_BORDER_HIGHLIGHTED Color(0x3478e4FF) -#define COLOR_WHITE Color(0xFFFFFFFF) -#define COLOR_BLACK Color(0, 0, 0, 255) - #define MAX_BUTTONS_ON_SCREEN 8 struct StoredBuffer { diff --git a/source/utils/config/ConfigRenderer.cpp b/source/utils/config/ConfigRenderer.cpp index 623e325..86a8ab3 100644 --- a/source/utils/config/ConfigRenderer.cpp +++ b/source/utils/config/ConfigRenderer.cpp @@ -151,6 +151,7 @@ ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) { return SUB_STATE_RUNNING; } + void ConfigRenderer::RenderStateMain() const { auto &configs = GetConfigList(); @@ -212,7 +213,7 @@ void ConfigRenderer::RenderStateMain() const { if (mSetActivePluginsMode) { DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, "\ue000 Activate | \uE045 Apply", true); } else if (totalElementSize > 0) { - DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, "\ue000 Select", true); + DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, "\ue000 Select | \uE002 Manage plugins", true); } // draw scroll indicator diff --git a/source/utils/config/ConfigUtils.cpp b/source/utils/config/ConfigUtils.cpp index b8f265c..199c034 100644 --- a/source/utils/config/ConfigUtils.cpp +++ b/source/utils/config/ConfigUtils.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -275,120 +274,7 @@ void ConfigUtils::displayMenu() { } void ConfigUtils::openConfigMenu() { - gOnlyAcceptFromThread = OSGetCurrentThread(); - const bool wasHomeButtonMenuEnabled = OSIsHomeButtonMenuEnabled(); - - // Save copy of DC reg values - const auto tvRender1 = DCReadReg32(SCREEN_TV, D1GRPH_CONTROL_REG); - const auto tvRender2 = DCReadReg32(SCREEN_TV, D1GRPH_ENABLE_REG); - const auto tvPitch1 = DCReadReg32(SCREEN_TV, D1GRPH_PITCH_REG); - const auto tvPitch2 = DCReadReg32(SCREEN_TV, D1OVL_PITCH_REG); - - const auto drcRender1 = DCReadReg32(SCREEN_DRC, D1GRPH_CONTROL_REG); - const auto drcRender2 = DCReadReg32(SCREEN_DRC, D1GRPH_ENABLE_REG); - const auto drcPitch1 = DCReadReg32(SCREEN_DRC, D1GRPH_PITCH_REG); - const auto drcPitch2 = DCReadReg32(SCREEN_DRC, D1OVL_PITCH_REG); - - OSScreenInit(); - - const uint32_t screen_buf0_size = OSScreenGetBufferSizeEx(SCREEN_TV); - const uint32_t screen_buf1_size = OSScreenGetBufferSizeEx(SCREEN_DRC); - void *screenbuffer0 = MEMAllocFromMappedMemoryForGX2Ex(screen_buf0_size, 0x100); - void *screenbuffer1 = MEMAllocFromMappedMemoryForGX2Ex(screen_buf1_size, 0x100); - - bool skipScreen0Free = false; - bool skipScreen1Free = false; - bool doShutdownKPAD = false; - - if (!screenbuffer0 || !screenbuffer1) { - if (screenbuffer0 == nullptr) { - if (gStoredTVBuffer.buffer_size >= screen_buf0_size) { - screenbuffer0 = gStoredTVBuffer.buffer; - skipScreen0Free = true; - DEBUG_FUNCTION_LINE_VERBOSE("Use storedTVBuffer"); - } - } - if (screenbuffer1 == nullptr) { - if (gStoredDRCBuffer.buffer_size >= screen_buf1_size) { - screenbuffer1 = gStoredDRCBuffer.buffer; - skipScreen1Free = true; - DEBUG_FUNCTION_LINE_VERBOSE("Use storedDRCBuffer"); - } - } - if (!screenbuffer0 || !screenbuffer1) { - DEBUG_FUNCTION_LINE_ERR("Failed to alloc buffers"); - goto error_exit; - } - } - - OSScreenSetBufferEx(SCREEN_TV, screenbuffer0); - OSScreenSetBufferEx(SCREEN_DRC, screenbuffer1); - - // Clear screens - OSScreenClearBufferEx(SCREEN_TV, 0); - OSScreenClearBufferEx(SCREEN_DRC, 0); - - // Flip buffers - OSScreenFlipBuffersEx(SCREEN_TV); - OSScreenFlipBuffersEx(SCREEN_DRC); - - // Clear screens - OSScreenClearBufferEx(SCREEN_TV, 0); - OSScreenClearBufferEx(SCREEN_DRC, 0); - - // Flip buffers - OSScreenFlipBuffersEx(SCREEN_TV); - OSScreenFlipBuffersEx(SCREEN_DRC); - - OSScreenEnableEx(SCREEN_TV, 1); - OSScreenEnableEx(SCREEN_DRC, 1); - - DrawUtils::initBuffers(screenbuffer0, screen_buf0_size, screenbuffer1, screen_buf1_size); - if (!DrawUtils::initFont()) { - DEBUG_FUNCTION_LINE_ERR("Failed to init Font"); - goto error_exit; - } - - // disable the home button menu to prevent opening it when exiting - OSEnableHomeButtonMenu(false); - - KPADStatus status; - KPADError err; - if (KPADReadEx(WPAD_CHAN_0, &status, 0, &err) == 0 && err == KPAD_ERROR_UNINITIALIZED) { - doShutdownKPAD = true; - KPADInit(); - } - - displayMenu(); - - if (doShutdownKPAD) { - KPADShutdown(); - } - - OSEnableHomeButtonMenu(wasHomeButtonMenuEnabled); - - DrawUtils::deinitFont(); - -error_exit: - // Restore DC reg values - DCWriteReg32(SCREEN_TV, D1GRPH_CONTROL_REG, tvRender1); - DCWriteReg32(SCREEN_TV, D1GRPH_ENABLE_REG, tvRender2); - DCWriteReg32(SCREEN_TV, D1GRPH_PITCH_REG, tvPitch1); - DCWriteReg32(SCREEN_TV, D1OVL_PITCH_REG, tvPitch2); - - DCWriteReg32(SCREEN_DRC, D1GRPH_CONTROL_REG, drcRender1); - DCWriteReg32(SCREEN_DRC, D1GRPH_ENABLE_REG, drcRender2); - DCWriteReg32(SCREEN_DRC, D1GRPH_PITCH_REG, drcPitch1); - DCWriteReg32(SCREEN_DRC, D1OVL_PITCH_REG, drcPitch2); - - if (!skipScreen0Free && screenbuffer0) { - MEMFreeToMappedMemory(screenbuffer0); - } - - if (!skipScreen1Free && screenbuffer1) { - MEMFreeToMappedMemory(screenbuffer1); - } - gOnlyAcceptFromThread = nullptr; + DrawUtils::RenderScreen(&displayMenu); } void ConfigUtils::renderBasicScreen(std::string_view text) {