rosalina: add SS3D toggle option

Closes #2062
This commit is contained in:
TuxSH 2024-09-12 00:42:02 +02:00
parent a7bd3208a5
commit 2aa2013318
5 changed files with 72 additions and 4 deletions

View File

@ -67,6 +67,7 @@ typedef struct Menu {
extern u32 menuCombo; extern u32 menuCombo;
extern bool isHidInitialized; extern bool isHidInitialized;
extern bool isQtmInitialized;
extern u32 mcuFwVersion; extern u32 mcuFwVersion;
extern u8 mcuInfoTable[9]; extern u8 mcuInfoTable[9];
extern bool mcuInfoTableRead; extern bool mcuInfoTableRead;

View File

@ -31,6 +31,10 @@
extern Menu N3DSMenu; extern Menu N3DSMenu;
bool N3DSMenu_CheckNotN2dsXl(void);
void N3DSMenu_UpdateStatus(void); void N3DSMenu_UpdateStatus(void);
void N3DSMenu_ChangeClockRate(void); void N3DSMenu_ChangeClockRate(void);
void N3DSMenu_EnableDisableL2Cache(void); void N3DSMenu_EnableDisableL2Cache(void);
void N3DSMenu_ToggleSs3d(void);

View File

@ -166,7 +166,7 @@ static void handleShellNotification(u32 notificationId)
{ {
// Quick dirty fix // Quick dirty fix
Sleep__HandleNotification(notificationId); Sleep__HandleNotification(notificationId);
if (notificationId == 0x213) { if (notificationId == 0x213) {
// Shell opened // Shell opened
// Note that this notification is also fired on system init. // Note that this notification is also fired on system init.
@ -205,6 +205,8 @@ static void handlePreTermNotification(u32 notificationId)
Draw_Lock(); Draw_Lock();
if (isHidInitialized) if (isHidInitialized)
hidExit(); hidExit();
if (isQtmInitialized)
qtmExit();
// Termination request // Termination request
menuShouldExit = true; menuShouldExit = true;

View File

@ -42,6 +42,7 @@
u32 menuCombo = 0; u32 menuCombo = 0;
bool isHidInitialized = false; bool isHidInitialized = false;
bool isQtmInitialized = false;
u32 mcuFwVersion = 0; u32 mcuFwVersion = 0;
u8 mcuInfoTable[9] = {0}; u8 mcuInfoTable[9] = {0};
bool mcuInfoTableRead = false; bool mcuInfoTableRead = false;
@ -283,6 +284,16 @@ static void menuReadScreenTypes(void)
} }
} }
static void menuInitializeQtm(void)
{
if (isQtmInitialized)
return;
// Open last remaining qtm:sp session (out of 3) on >= 9.3,
// or one of the two qtm:s handles below 9.3
isQtmInitialized = R_SUCCEEDED(qtmInit(GET_VERSION_MINOR(osGetKernelVersion()) >= 48 ? QTM_SERVICE_SYSTEM_PROCESS : QTM_SERVICE_SYSTEM));
}
static inline u32 menuAdvanceCursor(u32 pos, u32 numItems, s32 displ) static inline u32 menuAdvanceCursor(u32 pos, u32 numItems, s32 displ)
{ {
return (pos + numItems + displ) % numItems; return (pos + numItems + displ) % numItems;
@ -317,12 +328,16 @@ u32 g_blockMenuOpen = 0;
void menuThreadMain(void) void menuThreadMain(void)
{ {
if(isN3DS)
N3DSMenu_UpdateStatus();
while (!isServiceUsable("ac:u") || !isServiceUsable("hid:USER") || !isServiceUsable("gsp::Gpu") || !isServiceUsable("gsp::Lcd") || !isServiceUsable("cdc:CHK")) while (!isServiceUsable("ac:u") || !isServiceUsable("hid:USER") || !isServiceUsable("gsp::Gpu") || !isServiceUsable("gsp::Lcd") || !isServiceUsable("cdc:CHK"))
svcSleepThread(250 * 1000 * 1000LL); svcSleepThread(250 * 1000 * 1000LL);
if (isN3DS)
{
while (!isServiceUsable("qtm:u"))
svcSleepThread(250 * 1000 * 1000LL);
N3DSMenu_UpdateStatus();
}
handleShellOpened(); handleShellOpened();
hidInit(); // assume this doesn't fail hidInit(); // assume this doesn't fail
@ -330,6 +345,8 @@ void menuThreadMain(void)
menuReadScreenTypes(); menuReadScreenTypes();
menuInitializeQtm();
while(!preTerminationRequested) while(!preTerminationRequested)
{ {
svcSleepThread(50 * 1000 * 1000LL); svcSleepThread(50 * 1000 * 1000LL);

View File

@ -37,11 +37,20 @@ Menu N3DSMenu = {
{ {
{ "Enable L2 cache", METHOD, .method = &N3DSMenu_EnableDisableL2Cache }, { "Enable L2 cache", METHOD, .method = &N3DSMenu_EnableDisableL2Cache },
{ clkRateBuf, METHOD, .method = &N3DSMenu_ChangeClockRate }, { clkRateBuf, METHOD, .method = &N3DSMenu_ChangeClockRate },
{ "Temporarily disable Super-Stable 3D", METHOD, .method = &N3DSMenu_ToggleSs3d, .visibility = &N3DSMenu_CheckNotN2dsXl },
{}, {},
} }
}; };
static s64 clkRate = 0, higherClkRate = 0, L2CacheEnabled = 0; static s64 clkRate = 0, higherClkRate = 0, L2CacheEnabled = 0;
static bool qtmUnavailableAndNotBlacklisted = false; // true on N2DSXL, though we check MCU system model data first
static QtmStatus lastUpdatedQtmStatus;
bool N3DSMenu_CheckNotN2dsXl(void)
{
// Also check if qtm could be initialized
return isQtmInitialized && mcuInfoTableRead && mcuInfoTable[9] != 5 && !qtmUnavailableAndNotBlacklisted;
}
void N3DSMenu_UpdateStatus(void) void N3DSMenu_UpdateStatus(void)
{ {
@ -51,6 +60,28 @@ void N3DSMenu_UpdateStatus(void)
N3DSMenu.items[0].title = L2CacheEnabled ? "Disable L2 cache" : "Enable L2 cache"; N3DSMenu.items[0].title = L2CacheEnabled ? "Disable L2 cache" : "Enable L2 cache";
sprintf(clkRateBuf, "Set clock rate to %luMHz", clkRate != 268 ? 268 : (u32)higherClkRate); sprintf(clkRateBuf, "Set clock rate to %luMHz", clkRate != 268 ? 268 : (u32)higherClkRate);
if (N3DSMenu_CheckNotN2dsXl())
{
// Read status
if (R_FAILED(QTMS_GetQtmStatus(&lastUpdatedQtmStatus)))
qtmUnavailableAndNotBlacklisted = true; // stop showing QTM options if unavailable but not blacklisted
if ((lastUpdatedQtmStatus & 0xFF) == QTM_STATUS_UNAVAILABLE)
__builtin_trap();
bool blacklisted = false;
if (lastUpdatedQtmStatus == QTM_STATUS_UNAVAILABLE)
qtmUnavailableAndNotBlacklisted = R_FAILED(QTMU_IsCurrentAppBlacklisted(&blacklisted)) || !blacklisted;
MenuItem *item = &N3DSMenu.items[2];
if (lastUpdatedQtmStatus == QTM_STATUS_ENABLED)
item->title = "Temporarily disable Super-Stable 3D";
else
item->title = "Temporarily enable Super-Stable 3D";
}
} }
void N3DSMenu_ChangeClockRate(void) void N3DSMenu_ChangeClockRate(void)
@ -72,3 +103,16 @@ void N3DSMenu_EnableDisableL2Cache(void)
N3DSMenu_UpdateStatus(); N3DSMenu_UpdateStatus();
} }
void N3DSMenu_ToggleSs3d(void)
{
if (qtmUnavailableAndNotBlacklisted)
return;
if (lastUpdatedQtmStatus == QTM_STATUS_ENABLED)
QTMS_SetQtmStatus(QTM_STATUS_SS3D_DISABLED);
else // both SS3D disabled and unavailable/blacklisted states
QTMS_SetQtmStatus(QTM_STATUS_ENABLED);
N3DSMenu_UpdateStatus();
}