Fix rare crashes when quick starting titles

This commit is contained in:
Maschell 2024-07-14 11:58:05 +02:00
parent 3d1995e41d
commit 3505afad72

View File

@ -113,18 +113,22 @@ private:
FSCmdBlock mCmdBlock{}; FSCmdBlock mCmdBlock{};
}; };
static bool sQuickStartTitleSelected = false;
class QuickStartAutoAbort { class QuickStartAutoAbort {
public: public:
QuickStartAutoAbort() { QuickStartAutoAbort() {
OSCreateAlarm(&mDRCConnectedAlarm); OSCreateAlarm(&mDRCConnectedAlarm);
OSSetAlarmUserData(&mDRCConnectedAlarm, &disconnectedCount);
OSSetPeriodicAlarm(&mDRCConnectedAlarm, OSSetPeriodicAlarm(&mDRCConnectedAlarm,
OSGetTime() + OSSecondsToTicks(10), OSGetTime() + OSSecondsToTicks(10),
OSSecondsToTicks(1), OSSecondsToTicks(3),
&AbortOnDRCDisconnect); &AbortOnDRCDisconnect);
OSCreateAlarm(&mAlarm); OSCreateAlarm(&mAlarm);
OSSetAlarm(&mAlarm, OSSecondsToTicks(120), AbortQuickStartTitle); OSSetAlarm(&mAlarm, OSSecondsToTicks(120), AbortQuickStartTitle);
mDRCConnected = IsDRCConnected(); mDRCConnected = IsDRCConnected();
} }
~QuickStartAutoAbort() { ~QuickStartAutoAbort() {
OSCancelAlarm(&mDRCConnectedAlarm); OSCancelAlarm(&mDRCConnectedAlarm);
OSCancelAlarm(&mAlarm); OSCancelAlarm(&mAlarm);
@ -149,15 +153,17 @@ public:
} }
static void AbortQuickStartTitle(OSAlarm *alarm, OSContext *) { static void AbortQuickStartTitle(OSAlarm *alarm, OSContext *) {
DEBUG_FUNCTION_LINE_INFO("GamePad was disconnected, lets abort the quick start menu"); DEBUG_FUNCTION_LINE_INFO("Canceling quick start menu after 2 minutes");
CCRSysCaffeineBootCheckAbort(); CCRSysCaffeineBootCheckAbort();
} }
static void AbortOnDRCDisconnect(OSAlarm *alarm, OSContext *) { static void AbortOnDRCDisconnect(OSAlarm *alarm, OSContext *) {
if (sQuickStartTitleSelected) {
return;
}
if (!IsDRCConnected()) { if (!IsDRCConnected()) {
// The gamepad does reconnect after selecting a title, make sure it's still disconnected after waiting 3 seconds int *disconnectedCount = (int *) OSGetAlarmUserData(alarm);
OSSleepTicks(OSSecondsToTicks(3)); if (++(*disconnectedCount) >= 2) {
if (!IsDRCConnected()) {
DEBUG_FUNCTION_LINE_INFO("GamePad was disconnected, lets abort the quick start menu"); DEBUG_FUNCTION_LINE_INFO("GamePad was disconnected, lets abort the quick start menu");
CCRSysCaffeineBootCheckAbort(); CCRSysCaffeineBootCheckAbort();
} }
@ -167,7 +173,8 @@ public:
private: private:
OSAlarm mDRCConnectedAlarm{}; OSAlarm mDRCConnectedAlarm{};
OSAlarm mAlarm{}; OSAlarm mAlarm{};
bool mDRCConnected = false; bool mDRCConnected = false;
int disconnectedCount = 0;
}; };
bool launchQuickStartTitle() { bool launchQuickStartTitle() {
@ -177,6 +184,8 @@ bool launchQuickStartTitle() {
// Waits until the quick start menu has been closed. // Waits until the quick start menu has been closed.
auto bootCheck = CCRSysCaffeineBootCheck(); auto bootCheck = CCRSysCaffeineBootCheck();
if (bootCheck == 0) { if (bootCheck == 0) {
sQuickStartTitleSelected = true;
nn::sl::Initialize(MEMAllocFromDefaultHeapEx, MEMFreeToDefaultHeap); nn::sl::Initialize(MEMAllocFromDefaultHeapEx, MEMFreeToDefaultHeap);
char path[0x80]; char path[0x80];
nn::sl::GetDefaultDatabasePath(path, 0x80, 0x0005001010066000); // ECO process nn::sl::GetDefaultDatabasePath(path, 0x80, 0x0005001010066000); // ECO process
@ -184,7 +193,7 @@ bool launchQuickStartTitle() {
nn::sl::LaunchInfo info; nn::sl::LaunchInfo info;
{ {
// In theory the region doesn't even matter. // In theory the region doesn't even matter.
// The region is to load a "system table" into the LaunchInfoDatabase which provides the LaunchInfos for // The region is used to load a "system table" into the LaunchInfoDatabase which provides the LaunchInfos for
// the Wii U Menu and System Settings. In the code below we check for all possible System Settings title id and // the Wii U Menu and System Settings. In the code below we check for all possible System Settings title id and
// have a fallback to the Wii U Menu... This means we could get away a wrong region, but let's use the correct one // have a fallback to the Wii U Menu... This means we could get away a wrong region, but let's use the correct one
// anyway // anyway