Render simple safe mode screen

This commit is contained in:
Maschell 2024-08-09 19:43:11 +02:00
parent 48b1a3679d
commit c6c3b1754d
6 changed files with 173 additions and 125 deletions

View File

@ -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();

View File

@ -1,6 +1,7 @@
#include "DrawUtils.h"
#include "dc.h"
#include "globals.h"
#include "logger.h"
#include "utils.h"
#include <avm/tv.h>
@ -8,6 +9,8 @@
#include <coreinit/memory.h>
#include <coreinit/screen.h>
#include <cstdlib>
#include <memory/mappedmemory.h>
#include <padscore/kpad.h>
#include <png.h>
// buffer width
@ -432,3 +435,121 @@ uint32_t DrawUtils::getTextWidth(const wchar_t *string) {
return width;
}
void DrawUtils::RenderScreen(const std::function<void()>& 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;
}

View File

@ -2,11 +2,23 @@
#include "schrift.h"
#include <cstdint>
#include <functional>
// 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<void()>& callback);
private:
static bool mIsBackBuffer;

View File

@ -3,15 +3,6 @@
#include <cstdint>
#include <gx2/surface.h>
#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 {

View File

@ -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

View File

@ -17,7 +17,6 @@
#include <algorithm>
#include <coreinit/title.h>
#include <globals.h>
#include <memory/mappedmemory.h>
#include <memory>
#include <sysapp/launch.h>
#include <vector>
@ -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) {