From f7ee398253dbd2586e64ccd307481b63b6b4447c Mon Sep 17 00:00:00 2001
From: unresolvedsymbol <48220091+unresolvedsymbol@users.noreply.github.com>
Date: Mon, 2 Nov 2020 17:22:34 -0600
Subject: [PATCH 1/8] Initial flashcard detection update
---
.../arm9/source/common/dsimenusettings.cpp | 2 +-
.../arm9/source/common/dsimenusettings.h | 15 +-
quickmenu/arm9/source/main.cpp | 83 +-
.../arm9/source/common/bootstrapconfig.cpp | 5 +-
.../arm9/source/common/dsimenusettings.cpp | 3 +
.../arm9/source/common/dsimenusettings.h | 25 +
.../arm9/source/common/flashcardlaunch.cpp | 56 +-
.../arm9/source/windows/mainlist.cpp | 2 +-
.../arm9/source/windows/mainwnd.cpp | 4 +-
romsel_dsimenutheme/arm9/source/cheat.cpp | 996 +++++++++---------
.../arm9/source/common/dsimenusettings.h | 15 +-
romsel_dsimenutheme/arm9/source/main.cpp | 80 +-
.../arm9/source/perGameSettings.cpp | 6 +-
romsel_r4theme/arm9/source/cheat.cpp | 980 ++++++++---------
romsel_r4theme/arm9/source/main.cpp | 84 +-
.../arm9/source/perGameSettings.cpp | 6 +-
rungame/arm9/source/main.cpp | 62 +-
.../arm9/source/common/dsimenusettings.cpp | 2 +-
settings/arm9/source/common/dsimenusettings.h | 30 +-
title/arm9/source/common/dsimenusettings.cpp | 4 +-
title/arm9/source/common/dsimenusettings.h | 15 +-
title/arm9/source/main.cpp | 69 +-
22 files changed, 1340 insertions(+), 1204 deletions(-)
diff --git a/quickmenu/arm9/source/common/dsimenusettings.cpp b/quickmenu/arm9/source/common/dsimenusettings.cpp
index d1c470c75b..60f1c59925 100644
--- a/quickmenu/arm9/source/common/dsimenusettings.cpp
+++ b/quickmenu/arm9/source/common/dsimenusettings.cpp
@@ -44,7 +44,7 @@ TWLSettings::TWLSettings()
secondaryDevice = false;
fcSaveOnSd = false;
- flashcard = EDSTTClone;
+ flashcard = EFCUnknown;
slot1LaunchMethod = EDirect;
diff --git a/quickmenu/arm9/source/common/dsimenusettings.h b/quickmenu/arm9/source/common/dsimenusettings.h
index b785c861c8..4ff9875372 100644
--- a/quickmenu/arm9/source/common/dsimenusettings.h
+++ b/quickmenu/arm9/source/common/dsimenusettings.h
@@ -41,13 +41,14 @@ class TWLSettings
enum TFlashCard
{
- EDSTTClone = 0,
- ER4Original = 1,
- ER4iGoldClone = 2,
- EAcekard2i = 3,
- EAcekardRPG = 4,
- EGatewayBlue = 5,
- ESupercardDSTWO = 6
+ EFCUnknown = 0,
+ EDSTTClone = 1,
+ ER4Original = 2,
+ ER4iGoldClone = 3,
+ EAcekard2i = 4,
+ EAcekardRPG = 5,
+ EGatewayBlue = 6,
+ ESupercardDSTWO = 7
};
// Do not reorder these, just add to the end
diff --git a/quickmenu/arm9/source/main.cpp b/quickmenu/arm9/source/main.cpp
index 3ac9136bfb..95fb289de0 100644
--- a/quickmenu/arm9/source/main.cpp
+++ b/quickmenu/arm9/source/main.cpp
@@ -96,6 +96,7 @@ int consoleModel = 0;
3 = New Nintendo 3DS */
bool isRegularDS = true;
bool isDSLite = false;
+int flashcard = 0;
extern bool showdialogbox;
@@ -217,6 +218,8 @@ void LoadSettings(void) {
launcherApp = settingsini.GetInt("SRLOADER", "LAUNCHER_APP", launcherApp);
}
+ flashcard = settingsini.GetInt("SRLOADER", "FLASHCARD", flashcard);
+
previousUsedDevice = settingsini.GetInt("SRLOADER", "PREVIOUS_USED_DEVICE", previousUsedDevice);
secondaryDevice = bothSDandFlashcard() ? settingsini.GetInt("SRLOADER", "SECONDARY_DEVICE", secondaryDevice) : flashcardFound();
fcSaveOnSd = settingsini.GetInt("SRLOADER", "FC_SAVE_ON_SD", fcSaveOnSd);
@@ -664,36 +667,50 @@ void loadGameOnFlashcard (const char* ndsPath, bool dsGame) {
std::string fcPath;
int err = 0;
- if ((memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 26) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4TF", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0)) {
- CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
- fcPath = replaceAll(ndsPath, "fat:/", woodfat);
- fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
- fcrompathini.SaveIniFile("fat:/_wfwd/lastsave.ini");
- err = runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- } else if (memcmp(io_dldi_data->friendlyName, "Acekard AK2", 0xB) == 0) {
- CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
- fcPath = replaceAll(ndsPath, "fat:/", woodfat);
- fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
- fcrompathini.SaveIniFile("fat:/_afwd/lastsave.ini");
- err = runNdsFile("fat:/Afwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- } else if (memcmp(io_dldi_data->friendlyName, "DSTWO(Slot-1)", 0xD) == 0) {
- CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
- fcPath = replaceAll(ndsPath, "fat:/", dstwofat);
- fcrompathini.SetString("Dir Info", "fullName", fcPath);
- fcrompathini.SaveIniFile("fat:/_dstwo/autoboot.ini");
- err = runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- } else if ((memcmp(io_dldi_data->friendlyName, "TTCARD", 6) == 0)
- || (memcmp(io_dldi_data->friendlyName, "DSTT", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "DEMON", 5) == 0)) {
- CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
- fcPath = replaceAll(ndsPath, "fat:/", slashchar);
- fcrompathini.SetString("YSMENU", "AUTO_BOOT", fcPath);
- fcrompathini.SaveIniFile("fat:/TTMenu/YSMenu.ini");
- err = runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+
+ switch (flashcard) {
+ case EDSTTClone: {
+ CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
+ fcPath = replaceAll(ndsPath, "fat:/", slashchar);
+ fcrompathini.SetString("YSMENU", "AUTO_BOOT", fcPath);
+ fcrompathini.SaveIniFile("fat:/TTMenu/YSMenu.ini");
+ err = runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ case EGatewayBlue: // Blue card can run wood 1.62 so this should work?
+ case ER4Original: // And clones that can run wood (no N5)
+ case ER4iGoldClone: {
+ CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
+ fcPath = replaceAll(ndsPath, "fat:/", woodfat);
+ fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
+ fcrompathini.SaveIniFile("fat:/_wfwd/lastsave.ini");
+ err = runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ case ESupercardDSTWO: {
+ CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
+ fcPath = replaceAll(ndsPath, "fat:/", dstwofat);
+ fcrompathini.SetString("Dir Info", "fullName", fcPath);
+ fcrompathini.SaveIniFile("fat:/_dstwo/autoboot.ini");
+ err = runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ case EAcekardRPG: // ?
+ case EAcekard2i: {
+ CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
+ fcPath = replaceAll(ndsPath, "fat:/", woodfat);
+ fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
+ fcrompathini.SaveIniFile("fat:/_afwd/lastsave.ini");
+ err = runNdsFile("fat:/Afwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ default: {
+ err = 1337;
+ return;
+ }
}
+
char text[32];
snprintf(text, sizeof(text), "Start failed. Error %i", err);
ClearBrightness();
@@ -2048,10 +2065,7 @@ int main(int argc, char **argv) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", 1);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(forceSleepPatch
- || (memcmp(io_dldi_data->friendlyName, "TTCARD", 6) == 0 && !isRegularDS)
- || (memcmp(io_dldi_data->friendlyName, "DSTT", 4) == 0 && !isRegularDS)
- || (memcmp(io_dldi_data->friendlyName, "DEMON", 5) == 0 && !isRegularDS)
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0 && !isRegularDS))
+ || ((flashcard == EDSTTClone || flashcard == ER4iGoldClone) && !isRegularDS))
);
bootstrapini.SaveIniFile(bootstrapinipath);
@@ -2297,10 +2311,7 @@ int main(int argc, char **argv) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", ceCached);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(forceSleepPatch
- || (memcmp(io_dldi_data->friendlyName, "TTCARD", 6) == 0 && !isRegularDS)
- || (memcmp(io_dldi_data->friendlyName, "DSTT", 4) == 0 && !isRegularDS)
- || (memcmp(io_dldi_data->friendlyName, "DEMON", 5) == 0 && !isRegularDS)
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0 && !isRegularDS))
+ || ((flashcard == EDSTTClone || flascard == R4iGoldClone) && !isRegulards))
);
bootstrapini.SaveIniFile( bootstrapinipath );
diff --git a/romsel_aktheme/arm9/source/common/bootstrapconfig.cpp b/romsel_aktheme/arm9/source/common/bootstrapconfig.cpp
index c4c8ecd786..0fc64bffb7 100755
--- a/romsel_aktheme/arm9/source/common/bootstrapconfig.cpp
+++ b/romsel_aktheme/arm9/source/common/bootstrapconfig.cpp
@@ -30,10 +30,7 @@ BootstrapConfig::BootstrapConfig(const std::string &fileName, const std::string
_mpuRegion = 0;
_ceCached = true;
_forceSleepPatch = (ms().forceSleepPatch
- || (memcmp(io_dldi_data->friendlyName, "TTCARD", 6) == 0 && !sys().isRegularDS())
- || (memcmp(io_dldi_data->friendlyName, "DSTT", 4) == 0 && !sys().isRegularDS())
- || (memcmp(io_dldi_data->friendlyName, "DEMON", 5) == 0 && !sys().isRegularDS())
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0 && !sys().isRegularDS()));
+ || ((ms().flashcard == EDSTTClone || ms().flashcard == ER4iGoldClone) && !sys().isRegularDS());
_isHomebrew = _gametid.empty() || _sdkVersion == 0;
_saveSize = 0x80000;
_dsiMode = 0;
diff --git a/romsel_aktheme/arm9/source/common/dsimenusettings.cpp b/romsel_aktheme/arm9/source/common/dsimenusettings.cpp
index 670bb40147..08af4ed99a 100644
--- a/romsel_aktheme/arm9/source/common/dsimenusettings.cpp
+++ b/romsel_aktheme/arm9/source/common/dsimenusettings.cpp
@@ -48,6 +48,7 @@ TWLSettings::TWLSettings()
secondaryDevice = false;
fcSaveOnSd = false;
+ flashcard = EFCUnknown;
slot1LaunchMethod = EReboot;
useBootstrap = isDSiMode();
@@ -142,6 +143,8 @@ void TWLSettings::loadSettings()
launcherApp = settingsini.GetInt("SRLOADER", "LAUNCHER_APP", launcherApp);
}
+ flashcard = settingsini.GetInt("SRLOADER", "FLASHCARD", flashcard);
+
slot1LaunchMethod = settingsini.GetInt("SRLOADER", "SLOT1_LAUNCHMETHOD", slot1LaunchMethod);
bootstrapFile = settingsini.GetInt("SRLOADER", "BOOTSTRAP_FILE", bootstrapFile);
useBootstrap = settingsini.GetInt("SRLOADER", "USE_BOOTSTRAP", useBootstrap);
diff --git a/romsel_aktheme/arm9/source/common/dsimenusettings.h b/romsel_aktheme/arm9/source/common/dsimenusettings.h
index 2cd08cb9a0..160b6dd2a7 100644
--- a/romsel_aktheme/arm9/source/common/dsimenusettings.h
+++ b/romsel_aktheme/arm9/source/common/dsimenusettings.h
@@ -29,6 +29,30 @@ class TWLSettings
EViewInternal = 2
};
+
+ /*
+ 0: Unknown
+ 1: DSTT/R4i Gold/R4i-SDHC/R4 SDHC Dual-Core/R4 SDHC Upgrade/SC DSONE
+ 2: R4DS (Original Non-SDHC version)/ M3 Simply
+ 3: R4iDSN/R4i Gold RTS/R4 Ultra
+ 4: Acekard 2(i)/Galaxy Eagle/M3DS Real
+ 5: Acekard RPG
+ 6: Ace 3DS+/Gateway Blue Card/R4iTT
+ 7: SuperCard DSTWO
+ */
+
+ enum TFlashCard
+ {
+ EFCUnknown = 0,
+ EDSTTClone = 1,
+ ER4Original = 2,
+ ER4iGoldClone = 3,
+ EAcekard2i = 4,
+ EAcekardRPG = 5,
+ EGatewayBlue = 6,
+ ESupercardDSTWO = 7
+ };
+
// Do not reorder these, just add to the end
enum TLanguage
{
@@ -150,6 +174,7 @@ class TWLSettings
bool secondaryDevice;
bool fcSaveOnSd;
+ int flashcard;
int slot1LaunchMethod;
bool useBootstrap;
bool bootstrapFile;
diff --git a/romsel_aktheme/arm9/source/common/flashcardlaunch.cpp b/romsel_aktheme/arm9/source/common/flashcardlaunch.cpp
index 5b807cdadd..574dde4b1d 100644
--- a/romsel_aktheme/arm9/source/common/flashcardlaunch.cpp
+++ b/romsel_aktheme/arm9/source/common/flashcardlaunch.cpp
@@ -29,31 +29,37 @@ int loadGameOnFlashcard (std::string ndsPath, bool usePerGameSettings) {
}
std::string launchPath;
- if ((memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 26) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4TF", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0)) {
- LoaderConfig config("fat:/Wfwd.dat", "fat:/_wfwd/lastsave.ini");
- launchPath = replaceAll(ndsPath.c_str(), FC_PREFIX_FAT, FC_PREFIX_FAT0);
- config.option("Save Info", "lastLoaded", launchPath);
- return config.launch(0, NULL, true, true, runNds_boostCpu, runNds_boostVram);
- } else if (memcmp(io_dldi_data->friendlyName, "Acekard AK2", 0xB) == 0) {
- LoaderConfig config("fat:/Afwd.dat", "fat:/_afwd/lastsave.ini");
- launchPath = replaceAll(ndsPath.c_str(), FC_PREFIX_FAT, FC_PREFIX_FAT0);
- config.option("Save Info", "lastLoaded", launchPath);
- return config.launch(0, NULL, true, true, runNds_boostCpu, runNds_boostVram);
- } else if (memcmp(io_dldi_data->friendlyName, "DSTWO(Slot-1)", 0xD) == 0) {
- LoaderConfig config("fat:/_dstwo/autoboot.nds", "fat:/_dstwo/autoboot.ini");
- launchPath = replaceAll(ndsPath.c_str(), FC_PREFIX_FAT, FC_PREFIX_FAT1);
- config.option("Dir Info", "fullName", launchPath);
- return config.launch(0, NULL, true, true, runNds_boostCpu, runNds_boostVram);
- } else if ((memcmp(io_dldi_data->friendlyName, "TTCARD", 6) == 0)
- || (memcmp(io_dldi_data->friendlyName, "DSTT", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "DEMON", 5) == 0)) {
- LoaderConfig config("fat:/YSMenu.nds", "fat:/TTMenu/YSMenu.ini");
- launchPath = replaceAll(ndsPath.c_str(), FC_PREFIX_FAT, FC_PREFIX_SLASH);
- config.option("YSMENU", "AUTO_BOOT", launchPath);
- return config.launch(0, NULL, true, true, runNds_boostCpu, runNds_boostVram);
+
+
+ switch (ms().flashcard) {
+ case EDSTTClone: {
+ LoaderConfig config("fat:/YSMenu.nds", "fat:/TTMenu/YSMenu.ini");
+ launchPath = replaceAll(ndsPath.c_str(), FC_PREFIX_FAT, FC_PREFIX_SLASH);
+ config.option("YSMENU", "AUTO_BOOT", launchPath);
+ return config.launch(0, NULL, true, true, runNds_boostCpu, runNds_boostVram);
+ }
+ case EGatewayBlue: // Blue card can run wood 1.62 so this should work?
+ case ER4Original: // And clones that can run wood (no N5)
+ case ER4iGoldClone: {
+ LoaderConfig config("fat:/Wfwd.dat", "fat:/_wfwd/lastsave.ini");
+ launchPath = replaceAll(ndsPath.c_str(), FC_PREFIX_FAT, FC_PREFIX_FAT0);
+ config.option("Save Info", "lastLoaded", launchPath);
+ return config.launch(0, NULL, true, true, runNds_boostCpu, runNds_boostVram);
+ }
+ case ESupercardDSTWO: {
+ LoaderConfig config("fat:/_dstwo/autoboot.nds", "fat:/_dstwo/autoboot.ini");
+ launchPath = replaceAll(ndsPath.c_str(), FC_PREFIX_FAT, FC_PREFIX_FAT1);
+ config.option("Dir Info", "fullName", launchPath);
+ return config.launch(0, NULL, true, true, runNds_boostCpu, runNds_boostVram);
+ }
+ case EAcekardRPG: // ?
+ case EAcekard2i: {
+ LoaderConfig config("fat:/Afwd.dat", "fat:/_afwd/lastsave.ini");
+ launchPath = replaceAll(ndsPath.c_str(), FC_PREFIX_FAT, FC_PREFIX_FAT0);
+ config.option("Save Info", "lastLoaded", launchPath);
+ return config.launch(0, NULL, true, true, runNds_boostCpu, runNds_boostVram);
+ }
}
return 100;
-}
\ No newline at end of file
+}
diff --git a/romsel_aktheme/arm9/source/windows/mainlist.cpp b/romsel_aktheme/arm9/source/windows/mainlist.cpp
index 6f5f3271f2..c7596d899f 100644
--- a/romsel_aktheme/arm9/source/windows/mainlist.cpp
+++ b/romsel_aktheme/arm9/source/windows/mainlist.cpp
@@ -149,7 +149,7 @@ void MainList::setupExtnames()
_extnameFilter.emplace_back(std::string(".app"));
_extnameFilter.emplace_back(std::string(".argv"));
}
- if (memcmp(io_dldi_data->friendlyName, "DSTWO(Slot-1)", 0xD) == 0) {
+ if (ms().flashcard == ESupercardDSTWO) {
_extnameFilter.emplace_back(std::string(".plg"));
}
if (ms().showRvid)
diff --git a/romsel_aktheme/arm9/source/windows/mainwnd.cpp b/romsel_aktheme/arm9/source/windows/mainwnd.cpp
index 646e5f5609..651da0d135 100644
--- a/romsel_aktheme/arm9/source/windows/mainwnd.cpp
+++ b/romsel_aktheme/arm9/source/windows/mainwnd.cpp
@@ -1351,7 +1351,7 @@ void MainWnd::launchSelected()
extension = fullPath.substr(lastDotPos);
// DSTWO Plugin Launch
- if (extension == ".plg" && ms().secondaryDevice && memcmp(io_dldi_data->friendlyName, "DSTWO(Slot-1)", 0xD) == 0)
+ if (extension == ".plg" && ms().secondaryDevice && ms().flashcard == ESupercardDSTWO)
{
ms().launchType[ms().secondaryDevice] = TWLSettings::ESDFlashcardLaunch;
ms().saveSettings();
@@ -1891,4 +1891,4 @@ Window *MainWnd::windowBelow(const Point &p)
if (_startMenu->isVisible() && wbp != _startButton)
wbp = _startMenu;
return wbp;
-}
\ No newline at end of file
+}
diff --git a/romsel_dsimenutheme/arm9/source/cheat.cpp b/romsel_dsimenutheme/arm9/source/cheat.cpp
index f68d1c26d3..58832713ff 100644
--- a/romsel_dsimenutheme/arm9/source/cheat.cpp
+++ b/romsel_dsimenutheme/arm9/source/cheat.cpp
@@ -1,21 +1,21 @@
/*
- cheat.cpp
- Portions copyright (C) 2008 Normmatt, www.normmatt.com, Smiths (www.emuholic.com)
- Portions copyright (C) 2008 bliss (bliss@hanirc.org)
- Copyright (C) 2009 yellow wood goblin
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
+ cheat.cpp
+ Portions copyright (C) 2008 Normmatt, www.normmatt.com, Smiths (www.emuholic.com)
+ Portions copyright (C) 2008 bliss (bliss@hanirc.org)
+ Copyright (C) 2009 yellow wood goblin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
*/
#include
@@ -46,527 +46,555 @@ CheatCodelist::~CheatCodelist(void) {}
inline u32 gamecode(const char *aGameCode)
{
- u32 gameCode;
- tonccpy(&gameCode, aGameCode, sizeof(gameCode));
- return gameCode;
+ u32 gameCode;
+ tonccpy(&gameCode, aGameCode, sizeof(gameCode));
+ return gameCode;
}
#define CRCPOLY 0xedb88320
static u32 crc32(const u8* p,size_t len)
{
- u32 crc=-1;
- while(len--)
- {
- crc^=*p++;
- for(int ii=0;ii<8;++ii) crc=(crc>>1)^((crc&1)?CRCPOLY:0);
- }
- return crc;
+ u32 crc=-1;
+ while(len--)
+ {
+ crc^=*p++;
+ for(int ii=0;ii<8;++ii) crc=(crc>>1)^((crc&1)?CRCPOLY:0);
+ }
+ return crc;
}
bool CheatCodelist::parse(const std::string& aFileName)
{
- bool res=false;
- u32 romcrc32,gamecode;
- if(romData(aFileName,gamecode,romcrc32))
- {
- const char* usrcheatPath = (sdFound() || !ms().secondaryDevice) ? "sd:/_nds/TWiLightMenu/extras/usrcheat.dat" : "fat:/_nds/TWiLightMenu/extras/usrcheat.dat";
- if (ms().secondaryDevice && !ms().useBootstrap) {
- if ((memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 26) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4TF", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0)) {
- usrcheatPath = "fat:/_wfwd/cheats/usrcheat.dat";
- } else if (memcmp(io_dldi_data->friendlyName, "Acekard AK2", 0xB) == 0) {
- usrcheatPath = "fat:/_afwd/cheats/usrcheat.dat";
+ bool res=false;
+ u32 romcrc32,gamecode;
+ if(romData(aFileName,gamecode,romcrc32))
+ {
+ const char* usrcheatPath = (sdFound() || !ms().secondaryDevice) ? "sd:/_nds/TWiLightMenu/extras/usrcheat.dat" : "fat:/_nds/TWiLightMenu/extras/usrcheat.dat";
+ if (ms().secondaryDevice && !ms().useBootstrap) {
+ switch (ms().flashcard) {
+ case EDSTTClone: {
+ usrcheatPath = "fat:/TTMenu/usrcheat.dat";
+ break;
+ }
+ case ER4iGoldClone:
+ case EGatewayBlue:
+ case ER4Original: {
+ usrcheatPath = "fat:/_wfwd/cheats/usrcheat.dat";
+ break;
+ }
+ case EAcekardRPG: // TODO: WoodRPG? Test
+ case EAcekard2i: {
+ usrcheatPath = "fat:/_afwd/cheats/usrcheat.dat";
+ break;
+ }
+ case ESupercardDSTWO: {
+ usrcheatPath = "fat:/_dstwo/usrcheat.dat";
+ break;
+ }
+ }
+ }
+ FILE* dat = fopen(usrcheatPath,"rb");
+ if (dat) {
+ res=parseInternal(dat,gamecode,romcrc32);
+ fclose(dat);
}
}
- FILE* dat=fopen(usrcheatPath,"rb");
- if(dat)
- {
- res=parseInternal(dat,gamecode,romcrc32);
- fclose(dat);
- }
- }
- return res;
+ return res;
}
bool CheatCodelist::searchCheatData(FILE* aDat,u32 gamecode,u32 crc32,long& aPos,size_t& aSize)
{
- aPos=0;
- aSize=0;
- const char* KHeader="R4 CheatCode";
- char header[12];
- fread(header,12,1,aDat);
- if(strncmp(KHeader,header,12)) return false;
-
- sDatIndex idx,nidx;
-
- fseek(aDat,0,SEEK_END);
- long fileSize=ftell(aDat);
-
- fseek(aDat,0x100,SEEK_SET);
- fread(&nidx,sizeof(nidx),1,aDat);
-
- bool done=false;
-
- while(!done)
- {
- tonccpy(&idx,&nidx,sizeof(idx));
- fread(&nidx,sizeof(nidx),1,aDat);
- if(gamecode==idx._gameCode&&crc32==idx._crc32)
- {
- aSize=((nidx._offset)?nidx._offset:fileSize)-idx._offset;
- aPos=idx._offset;
- done=true;
- }
- if(!nidx._offset) done=true;
- }
- return (aPos&&aSize);
+ aPos=0;
+ aSize=0;
+ const char* KHeader="R4 CheatCode";
+ char header[12];
+ fread(header,12,1,aDat);
+ if(strncmp(KHeader,header,12)) return false;
+
+ sDatIndex idx,nidx;
+
+ fseek(aDat,0,SEEK_END);
+ long fileSize=ftell(aDat);
+
+ fseek(aDat,0x100,SEEK_SET);
+ fread(&nidx,sizeof(nidx),1,aDat);
+
+ bool done=false;
+
+ while(!done)
+ {
+ tonccpy(&idx,&nidx,sizeof(idx));
+ fread(&nidx,sizeof(nidx),1,aDat);
+ if(gamecode==idx._gameCode&&crc32==idx._crc32)
+ {
+ aSize=((nidx._offset)?nidx._offset:fileSize)-idx._offset;
+ aPos=idx._offset;
+ done=true;
+ }
+ if(!nidx._offset) done=true;
+ }
+ return (aPos&&aSize);
}
bool CheatCodelist::parseInternal(FILE* aDat,u32 gamecode,u32 crc32)
{
- dbg_printf("%x, %x\n",gamecode,crc32);
-
- _data.clear();
-
- long dataPos; size_t dataSize;
- if(!searchCheatData(aDat,gamecode,crc32,dataPos,dataSize)) return false;
- fseek(aDat,dataPos,SEEK_SET);
-
- dbg_printf("record found: %d\n",dataSize);
-
- char* buffer=(char*)malloc(dataSize);
- if(!buffer) return false;
- fread(buffer,dataSize,1,aDat);
- char* gameTitle=buffer;
-
- u32* ccode=(u32*)(((u32)gameTitle+strlen(gameTitle)+4)&~3);
- u32 cheatCount=*ccode;
- cheatCount&=0x0fffffff;
- ccode+=9;
-
- u32 cc=0;
- while(cc>28)&1)
- {
- flagItem|=cParsedItem::EInFolder;
- if((*ccode>>24)==0x11) flagItem|=cParsedItem::EOne;
- folderCount=*ccode&0x00ffffff;
- folderName=(char*)((u32)ccode+4);
- folderNote=(char*)((u32)folderName+strlen(folderName)+1);
- _data.push_back(cParsedItem(folderName,folderNote,cParsedItem::EFolder));
- cc++;
- ccode=(u32*)(((u32)folderName+strlen(folderName)+1+strlen(folderNote)+1+3)&~3);
- }
-
- u32 selectValue=cParsedItem::ESelected;
- for(size_t ii=0;ii>28)&1)
+ {
+ flagItem|=cParsedItem::EInFolder;
+ if((*ccode>>24)==0x11) flagItem|=cParsedItem::EOne;
+ folderCount=*ccode&0x00ffffff;
+ folderName=(char*)((u32)ccode+4);
+ folderNote=(char*)((u32)folderName+strlen(folderName)+1);
+ _data.push_back(cParsedItem(folderName,folderNote,cParsedItem::EFolder));
+ cc++;
+ ccode=(u32*)(((u32)folderName+strlen(folderName)+1+strlen(folderNote)+1+3)&~3);
+ }
+
+ u32 selectValue=cParsedItem::ESelected;
+ for(size_t ii=0;ii::iterator itr=_data.begin();
- while(itr!=_data.end())
- {
- std::vector row;
- row.push_back("");
- row.push_back((*itr)._title);
- // _List.insertRow(_List.getRowCount(),row);
- _indexes.push_back(itr-_data.begin());
- u32 flags=(*itr)._flags;
- ++itr;
- if((flags&cParsedItem::EFolder)&&(flags&cParsedItem::EOpen)==0)
- {
- while(((*itr)._flags&cParsedItem::EInFolder)&&itr!=_data.end()) ++itr;
- }
- }
+ _indexes.clear();
+ // _List.removeAllRows();
+
+ std::vector::iterator itr=_data.begin();
+ while(itr!=_data.end())
+ {
+ std::vector row;
+ row.push_back("");
+ row.push_back((*itr)._title);
+ // _List.insertRow(_List.getRowCount(),row);
+ _indexes.push_back(itr-_data.begin());
+ u32 flags=(*itr)._flags;
+ ++itr;
+ if((flags&cParsedItem::EFolder)&&(flags&cParsedItem::EOpen)==0)
+ {
+ while(((*itr)._flags&cParsedItem::EInFolder)&&itr!=_data.end()) ++itr;
+ }
+ }
}
void CheatCodelist::deselectFolder(size_t anIndex)
{
- std::vector::iterator itr=_data.begin()+anIndex;
- while(--itr>=_data.begin())
- {
- if((*itr)._flags&cParsedItem::EFolder)
- {
- ++itr;
- break;
- }
- }
- while(((*itr)._flags&cParsedItem::EInFolder)&&itr!=_data.end())
- {
- (*itr)._flags&=~cParsedItem::ESelected;
- ++itr;
- }
+ std::vector::iterator itr=_data.begin()+anIndex;
+ while(--itr>=_data.begin())
+ {
+ if((*itr)._flags&cParsedItem::EFolder)
+ {
+ ++itr;
+ break;
+ }
+ }
+ while(((*itr)._flags&cParsedItem::EInFolder)&&itr!=_data.end())
+ {
+ (*itr)._flags&=~cParsedItem::ESelected;
+ ++itr;
+ }
}
bool CheatCodelist::romData(const std::string& aFileName,u32& aGameCode,u32& aCrc32)
{
- bool res=false;
- FILE* rom=fopen(aFileName.c_str(),"rb");
- if(rom)
- {
- u8 header[512];
- if(1==fread(header,sizeof(header),1,rom))
- {
- aCrc32=crc32(header,sizeof(header));
- aGameCode=gamecode((const char*)(header+12));
- res=true;
- }
- fclose(rom);
- }
- return res;
+ bool res=false;
+ FILE* rom=fopen(aFileName.c_str(),"rb");
+ if(rom)
+ {
+ u8 header[512];
+ if(1==fread(header,sizeof(header),1,rom))
+ {
+ aCrc32=crc32(header,sizeof(header));
+ aGameCode=gamecode((const char*)(header+12));
+ res=true;
+ }
+ fclose(rom);
+ }
+ return res;
}
std::string CheatCodelist::getCheats()
{
- std::string cheats;
- for(uint i=0;i< _data.size();i++)
- {
- if(_data[i]._flags&cParsedItem::ESelected)
- {
- cheats += _data[i]._cheat.substr(0, _data[i]._cheat.size());
- }
- }
- std::replace( cheats.begin(), cheats.end(), '\n', ' ');
- return cheats;
+ std::string cheats;
+ for(uint i=0;i< _data.size();i++)
+ {
+ if(_data[i]._flags&cParsedItem::ESelected)
+ {
+ cheats += _data[i]._cheat.substr(0, _data[i]._cheat.size());
+ }
+ }
+ std::replace( cheats.begin(), cheats.end(), '\n', ' ');
+ return cheats;
}
void CheatCodelist::drawCheatList(std::vector& list, uint curPos, uint screenPos) {
- // Print Cheats at the top
- printLarge(false, 0, 30, STR_CHEATS, Alignment::center);
-
- // Print bottom text
- if(list[curPos]->_comment != "") {
- if(list[curPos]->_flags&cParsedItem::EFolder) {
- printSmall(false, 0, 160, STR_CHEATS_FOLDER_INFO, Alignment::center);
- } else if(list[curPos]->_flags&cParsedItem::ESelected) {
- printSmall(false, 0, 160, STR_CHEATS_SELECTED_INFO, Alignment::center);
- } else {
- printSmall(false, 0, 160, STR_CHEATS_DESELECTED_INFO, Alignment::center);
- }
- } else {
- if(list[curPos]->_flags&cParsedItem::EFolder) {
- printSmall(false, 0, 160, STR_CHEATS_FOLDER, Alignment::center);
- } else if(list[curPos]->_flags&cParsedItem::ESelected) {
- printSmall(false, 0, 160, STR_CHEATS_SELECTED, Alignment::center);
- } else {
- printSmall(false, 0, 160, STR_CHEATS_DESELECTED, Alignment::center);
- }
- }
-
- // Print the list
- for(uint i=0;i<8 && i_flags&cParsedItem::EFolder) {
- printSmall(false, 15+((screenPos+i == curPos) ? 5 : 0), 60+(i*12), ">");
- printSmall(false, 28+((screenPos+i == curPos) ? 4 : 0), 60+(i*12), list[screenPos+i]->_title);
- } else {
- if(list[screenPos+i]->_flags&cParsedItem::ESelected) {
- printSmall(false, 13, 60+(i*12), "x");
- }
- printSmall(false, 21+((screenPos+i == curPos) ? 4 : 0), 60+(i*12), "-");
- printSmall(false, 28+((screenPos+i == curPos) ? 7 : 0), 60+(i*12), list[screenPos+i]->_title);
- }
- }
+ // Print Cheats at the top
+ printLarge(false, 0, 30, STR_CHEATS, Alignment::center);
+
+ // Print bottom text
+ if(list[curPos]->_comment != "") {
+ if(list[curPos]->_flags&cParsedItem::EFolder) {
+ printSmall(false, 0, 160, STR_CHEATS_FOLDER_INFO, Alignment::center);
+ } else if(list[curPos]->_flags&cParsedItem::ESelected) {
+ printSmall(false, 0, 160, STR_CHEATS_SELECTED_INFO, Alignment::center);
+ } else {
+ printSmall(false, 0, 160, STR_CHEATS_DESELECTED_INFO, Alignment::center);
+ }
+ } else {
+ if(list[curPos]->_flags&cParsedItem::EFolder) {
+ printSmall(false, 0, 160, STR_CHEATS_FOLDER, Alignment::center);
+ } else if(list[curPos]->_flags&cParsedItem::ESelected) {
+ printSmall(false, 0, 160, STR_CHEATS_SELECTED, Alignment::center);
+ } else {
+ printSmall(false, 0, 160, STR_CHEATS_DESELECTED, Alignment::center);
+ }
+ }
+
+ // Print the list
+ for(uint i=0;i<8 && i_flags&cParsedItem::EFolder) {
+ printSmall(false, 15+((screenPos+i == curPos) ? 5 : 0), 60+(i*12), ">");
+ printSmall(false, 28+((screenPos+i == curPos) ? 4 : 0), 60+(i*12), list[screenPos+i]->_title);
+ } else {
+ if(list[screenPos+i]->_flags&cParsedItem::ESelected) {
+ printSmall(false, 13, 60+(i*12), "x");
+ }
+ printSmall(false, 21+((screenPos+i == curPos) ? 4 : 0), 60+(i*12), "-");
+ printSmall(false, 28+((screenPos+i == curPos) ? 7 : 0), 60+(i*12), list[screenPos+i]->_title);
+ }
+ }
}
void CheatCodelist::selectCheats(std::string filename)
{
- int pressed = 0;
- int held = 0;
-
- clearText();
-
- dbox_showIcon = true;
-
- printLarge(false, 0, 30, STR_CHEATS, Alignment::center);
- printSmall(false, 0, 100, STR_LOADING, Alignment::center);
-
- parse(filename);
-
- bool cheatsFound = true;
- // If no cheats are found
- if(_data.size() == 0) {
- snd().playWrong();
- cheatsFound = false;
- clearText();
- printLarge(false, 0, 30, STR_CHEATS, Alignment::center);
- printSmall(false, 0, 100, STR_NO_CHEATS_FOUND, Alignment::center);
- printSmall(false, 0, 160, STR_B_BACK, Alignment::center);
-
- while(1) {
- scanKeys();
- pressed = keysDownRepeat();
- checkSdEject();
- tex().drawVolumeImageCached();
- tex().drawBatteryImageCached();
- drawCurrentTime();
- drawCurrentDate();
- drawClockColon();
- snd().updateStream();
- swiWaitForVBlank();
- if(pressed & KEY_B) {
- snd().playBack();
- break;
- }
- }
- }
-
- // Make list of all cheats not in folders and folders
- std::vector currentList;
- for(uint i=0;i<_data.size();i++) {
- if(!(_data[i]._flags&cParsedItem::EInFolder)) {
- currentList.push_back(&_data[i]);
- }
- }
-
- int mainListCurPos = -1, mainListScreenPos = -1,
- cheatWnd_cursorPosition = 0, cheatWnd_screenPosition = 0;
-
- while(cheatsFound) {
- // Scroll screen if needed
- if(cheatWnd_cursorPosition < cheatWnd_screenPosition) {
- cheatWnd_screenPosition = cheatWnd_cursorPosition;
- } else if(cheatWnd_cursorPosition > cheatWnd_screenPosition + 8 - 1) {
- cheatWnd_screenPosition = cheatWnd_cursorPosition - 8 + 1;
- }
-
- clearText();
- drawCheatList(currentList, cheatWnd_cursorPosition, cheatWnd_screenPosition);
-
- do {
- scanKeys();
- pressed = keysDown();
- held = keysDownRepeat();
- checkSdEject();
- tex().drawVolumeImageCached();
- tex().drawBatteryImageCached();
- drawCurrentTime();
- drawCurrentDate();
- drawClockColon();
- snd().updateStream();
- swiWaitForVBlank();
- } while(!pressed && !held);
-
- if(held & KEY_UP) {
- if(cheatWnd_cursorPosition>0) {
- snd().playSelect();
- cheatWnd_cursorPosition--;
- }
- } else if(held & KEY_DOWN) {
- if(cheatWnd_cursorPosition<((int)currentList.size()-1)) {
- snd().playSelect();
- cheatWnd_cursorPosition++;
- }
- } else if(held & KEY_LEFT) {
- snd().playSelect();
- cheatWnd_cursorPosition -= (cheatWnd_cursorPosition > 8 ? 8 : cheatWnd_cursorPosition);
- } else if(held & KEY_RIGHT) {
- snd().playSelect();
- cheatWnd_cursorPosition += (cheatWnd_cursorPosition < (int)(currentList.size()-8) ? 8 : currentList.size()-cheatWnd_cursorPosition-1);
- } else if(pressed & KEY_A) {
- (ms().theme == 4) ? snd().playLaunch() : snd().playSelect();
- if(currentList[cheatWnd_cursorPosition]->_flags&cParsedItem::EFolder) {
- uint i = std::distance(&_data[0], currentList[cheatWnd_cursorPosition]) + 1;
- currentList.clear();
- for(; !(_data[i]._flags & cParsedItem::EFolder) && i < _data.size(); i++) {
- currentList.push_back(&_data[i]);
- }
- mainListCurPos = cheatWnd_cursorPosition;
- mainListScreenPos = cheatWnd_screenPosition;
- cheatWnd_cursorPosition = 0;
- } else {
- cParsedItem &cheat = *currentList[cheatWnd_cursorPosition];
- bool select = !(cheat._flags & cParsedItem::ESelected);
- if(cheat._flags & cParsedItem::EOne)
- deselectFolder(std::distance(&_data[0], currentList[cheatWnd_cursorPosition]));
- if(select || !(cheat._flags & cParsedItem::EOne))
- cheat._flags ^= cParsedItem::ESelected;
- }
- } else if(pressed & KEY_B) {
- snd().playBack();
- if(mainListCurPos != -1) {
- currentList.clear();
- for(uint i=0;i<_data.size();i++) {
- if(!(_data[i]._flags&cParsedItem::EInFolder)) {
- currentList.push_back(&_data[i]);
- }
- }
- cheatWnd_cursorPosition = mainListCurPos;
- cheatWnd_screenPosition = mainListScreenPos;
- mainListCurPos = -1;
- } else {
- break;
- }
- } else if(pressed & KEY_X) {
- snd().playLaunch();
- clearText();
- printLarge(false, 0, 30, STR_CHEATS, Alignment::center);
- printSmall(false, 0, 100, STR_SAVING, Alignment::center);
- onGenerate();
- break;
- } else if(pressed & KEY_Y) {
- if(currentList[cheatWnd_cursorPosition]->_comment != "") {
- (ms().theme == 4) ? snd().playLaunch() : snd().playSelect();
- clearText();
- printLarge(false, 0, 30, STR_CHEATS, Alignment::center);
-
- std::string _topText = "";
- std::string _topTextStr(currentList[cheatWnd_cursorPosition]->_comment);
- std::vector words;
- std::size_t pos;
-
- // Process comment to stay within the box
- while((pos = _topTextStr.find(' ')) != std::string::npos) {
- words.push_back(_topTextStr.substr(0, pos));
- _topTextStr = _topTextStr.substr(pos + 1);
- }
- if(_topTextStr.size())
- words.push_back(_topTextStr);
- std::string temp;
- for(auto word : words) {
- // Split word if the word is too long for a line
- int width = calcSmallFontWidth(word);
- if(width > 240) {
- if(temp.length())
- _topText += temp + '\n';
- for(int i = 0; i < width/240; i++) {
- word.insert((float)((i + 1) * word.length()) / ((width/240) + 1), "\n");
- }
- _topText += word + '\n';
- continue;
- }
-
- width = calcSmallFontWidth(temp + " " + word);
- if(width > 240) {
- _topText += temp + '\n';
- temp = word;
- } else {
- temp += " " + word;
- }
- }
- if(temp.size())
- _topText += temp;
-
- // Print comment
- printSmall(false, 0, 60, _topText, Alignment::center);
-
- // Print 'Back' text
- printSmall(false, 0, 160, STR_B_BACK, Alignment::center);
- while(1) {
- scanKeys();
- pressed = keysDown();
- checkSdEject();
- tex().drawVolumeImageCached();
- tex().drawBatteryImageCached();
- drawCurrentTime();
- drawCurrentDate();
- drawClockColon();
- snd().updateStream();
- swiWaitForVBlank();
- if(pressed & KEY_B) {
- snd().playBack();
- break;
- }
- }
- }
- } else if(pressed & KEY_L) {
- // Delect all in the actual data so it doesn't just get the folder
- for(auto itr = _data.begin(); itr != _data.end(); itr++) {
- (*itr)._flags &= ~cParsedItem::ESelected;
- }
- // Also deselect them in the current list so that it updates the display
- for(auto itr = currentList.begin(); itr != currentList.end(); itr++) {
- (*itr)->_flags &= ~cParsedItem::ESelected;
- }
- }
- }
+ int pressed = 0;
+ int held = 0;
+
+ clearText();
+
+ dbox_showIcon = true;
+
+ printLarge(false, 0, 30, STR_CHEATS, Alignment::center);
+ printSmall(false, 0, 100, STR_LOADING, Alignment::center);
+
+ parse(filename);
+
+ bool cheatsFound = true;
+ // If no cheats are found
+ if(_data.size() == 0) {
+ snd().playWrong();
+ cheatsFound = false;
+ clearText();
+ printLarge(false, 0, 30, STR_CHEATS, Alignment::center);
+ printSmall(false, 0, 100, STR_NO_CHEATS_FOUND, Alignment::center);
+ printSmall(false, 0, 160, STR_B_BACK, Alignment::center);
+
+ while(1) {
+ scanKeys();
+ pressed = keysDownRepeat();
+ checkSdEject();
+ tex().drawVolumeImageCached();
+ tex().drawBatteryImageCached();
+ drawCurrentTime();
+ drawCurrentDate();
+ drawClockColon();
+ snd().updateStream();
+ swiWaitForVBlank();
+ if(pressed & KEY_B) {
+ snd().playBack();
+ break;
+ }
+ }
+ }
+
+ // Make list of all cheats not in folders and folders
+ std::vector currentList;
+ for(uint i=0;i<_data.size();i++) {
+ if(!(_data[i]._flags&cParsedItem::EInFolder)) {
+ currentList.push_back(&_data[i]);
+ }
+ }
+
+ int mainListCurPos = -1, mainListScreenPos = -1,
+ cheatWnd_cursorPosition = 0, cheatWnd_screenPosition = 0;
+
+ while(cheatsFound) {
+ // Scroll screen if needed
+ if(cheatWnd_cursorPosition < cheatWnd_screenPosition) {
+ cheatWnd_screenPosition = cheatWnd_cursorPosition;
+ } else if(cheatWnd_cursorPosition > cheatWnd_screenPosition + 8 - 1) {
+ cheatWnd_screenPosition = cheatWnd_cursorPosition - 8 + 1;
+ }
+
+ clearText();
+ drawCheatList(currentList, cheatWnd_cursorPosition, cheatWnd_screenPosition);
+
+ do {
+ scanKeys();
+ pressed = keysDown();
+ held = keysDownRepeat();
+ checkSdEject();
+ tex().drawVolumeImageCached();
+ tex().drawBatteryImageCached();
+ drawCurrentTime();
+ drawCurrentDate();
+ drawClockColon();
+ snd().updateStream();
+ swiWaitForVBlank();
+ } while(!pressed && !held);
+
+ if(held & KEY_UP) {
+ if(cheatWnd_cursorPosition>0) {
+ snd().playSelect();
+ cheatWnd_cursorPosition--;
+ }
+ } else if(held & KEY_DOWN) {
+ if(cheatWnd_cursorPosition<((int)currentList.size()-1)) {
+ snd().playSelect();
+ cheatWnd_cursorPosition++;
+ }
+ } else if(held & KEY_LEFT) {
+ snd().playSelect();
+ cheatWnd_cursorPosition -= (cheatWnd_cursorPosition > 8 ? 8 : cheatWnd_cursorPosition);
+ } else if(held & KEY_RIGHT) {
+ snd().playSelect();
+ cheatWnd_cursorPosition += (cheatWnd_cursorPosition < (int)(currentList.size()-8) ? 8 : currentList.size()-cheatWnd_cursorPosition-1);
+ } else if(pressed & KEY_A) {
+ (ms().theme == 4) ? snd().playLaunch() : snd().playSelect();
+ if(currentList[cheatWnd_cursorPosition]->_flags&cParsedItem::EFolder) {
+ uint i = std::distance(&_data[0], currentList[cheatWnd_cursorPosition]) + 1;
+ currentList.clear();
+ for(; !(_data[i]._flags & cParsedItem::EFolder) && i < _data.size(); i++) {
+ currentList.push_back(&_data[i]);
+ }
+ mainListCurPos = cheatWnd_cursorPosition;
+ mainListScreenPos = cheatWnd_screenPosition;
+ cheatWnd_cursorPosition = 0;
+ } else {
+ cParsedItem &cheat = *currentList[cheatWnd_cursorPosition];
+ bool select = !(cheat._flags & cParsedItem::ESelected);
+ if(cheat._flags & cParsedItem::EOne)
+ deselectFolder(std::distance(&_data[0], currentList[cheatWnd_cursorPosition]));
+ if(select || !(cheat._flags & cParsedItem::EOne))
+ cheat._flags ^= cParsedItem::ESelected;
+ }
+ } else if(pressed & KEY_B) {
+ snd().playBack();
+ if(mainListCurPos != -1) {
+ currentList.clear();
+ for(uint i=0;i<_data.size();i++) {
+ if(!(_data[i]._flags&cParsedItem::EInFolder)) {
+ currentList.push_back(&_data[i]);
+ }
+ }
+ cheatWnd_cursorPosition = mainListCurPos;
+ cheatWnd_screenPosition = mainListScreenPos;
+ mainListCurPos = -1;
+ } else {
+ break;
+ }
+ } else if(pressed & KEY_X) {
+ snd().playLaunch();
+ clearText();
+ printLarge(false, 0, 30, STR_CHEATS, Alignment::center);
+ printSmall(false, 0, 100, STR_SAVING, Alignment::center);
+ onGenerate();
+ break;
+ } else if(pressed & KEY_Y) {
+ if(currentList[cheatWnd_cursorPosition]->_comment != "") {
+ (ms().theme == 4) ? snd().playLaunch() : snd().playSelect();
+ clearText();
+ printLarge(false, 0, 30, STR_CHEATS, Alignment::center);
+
+ std::string _topText = "";
+ std::string _topTextStr(currentList[cheatWnd_cursorPosition]->_comment);
+ std::vector words;
+ std::size_t pos;
+
+ // Process comment to stay within the box
+ while((pos = _topTextStr.find(' ')) != std::string::npos) {
+ words.push_back(_topTextStr.substr(0, pos));
+ _topTextStr = _topTextStr.substr(pos + 1);
+ }
+ if(_topTextStr.size())
+ words.push_back(_topTextStr);
+ std::string temp;
+ for(auto word : words) {
+ // Split word if the word is too long for a line
+ int width = calcSmallFontWidth(word);
+ if(width > 240) {
+ if(temp.length())
+ _topText += temp + '\n';
+ for(int i = 0; i < width/240; i++) {
+ word.insert((float)((i + 1) * word.length()) / ((width/240) + 1), "\n");
+ }
+ _topText += word + '\n';
+ continue;
+ }
+
+ width = calcSmallFontWidth(temp + " " + word);
+ if(width > 240) {
+ _topText += temp + '\n';
+ temp = word;
+ } else {
+ temp += " " + word;
+ }
+ }
+ if(temp.size())
+ _topText += temp;
+
+ // Print comment
+ printSmall(false, 0, 60, _topText, Alignment::center);
+
+ // Print 'Back' text
+ printSmall(false, 0, 160, STR_B_BACK, Alignment::center);
+ while(1) {
+ scanKeys();
+ pressed = keysDown();
+ checkSdEject();
+ tex().drawVolumeImageCached();
+ tex().drawBatteryImageCached();
+ drawCurrentTime();
+ drawCurrentDate();
+ drawClockColon();
+ snd().updateStream();
+ swiWaitForVBlank();
+ if(pressed & KEY_B) {
+ snd().playBack();
+ break;
+ }
+ }
+ }
+ } else if(pressed & KEY_L) {
+ // Delect all in the actual data so it doesn't just get the folder
+ for(auto itr = _data.begin(); itr != _data.end(); itr++) {
+ (*itr)._flags &= ~cParsedItem::ESelected;
+ }
+ // Also deselect them in the current list so that it updates the display
+ for(auto itr = currentList.begin(); itr != currentList.end(); itr++) {
+ (*itr)->_flags &= ~cParsedItem::ESelected;
+ }
+ }
+ }
}
static void updateDB(u8 value,u32 offset,FILE* db)
{
- u8 oldvalue;
- if(!db) return;
- if(!offset) return;
- if(fseek(db,offset,SEEK_SET)) return;
- if(fread(&oldvalue,sizeof(oldvalue),1,db)!=1) return;
- if(oldvalue!=value)
- {
- if(fseek(db,offset,SEEK_SET)) return;
- fwrite(&value,sizeof(value),1,db);
- }
+ u8 oldvalue;
+ if(!db) return;
+ if(!offset) return;
+ if(fseek(db,offset,SEEK_SET)) return;
+ if(fread(&oldvalue,sizeof(oldvalue),1,db)!=1) return;
+ if(oldvalue!=value)
+ {
+ if(fseek(db,offset,SEEK_SET)) return;
+ fwrite(&value,sizeof(value),1,db);
+ }
}
void CheatCodelist::onGenerate(void)
{
- const char* usrcheatPath = (sdFound() || !ms().secondaryDevice) ? "sd:/_nds/TWiLightMenu/extras/usrcheat.dat" : "fat:/_nds/TWiLightMenu/extras/usrcheat.dat";
+ const char* usrcheatPath = (sdFound() || !ms().secondaryDevice) ? "sd:/_nds/TWiLightMenu/extras/usrcheat.dat" : "fat:/_nds/TWiLightMenu/extras/usrcheat.dat";
if (ms().secondaryDevice && !ms().useBootstrap) {
- if ((memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 26) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4TF", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0)) {
- usrcheatPath = "fat:/_wfwd/cheats/usrcheat.dat";
- } else if (memcmp(io_dldi_data->friendlyName, "Acekard AK2", 0xB) == 0) {
- usrcheatPath = "fat:/_afwd/cheats/usrcheat.dat";
+ switch (ms().flashcard) {
+ case EDSTTClone: {
+ usrcheatPath = "fat:/TTMenu/usrcheat.dat";
+ break;
+ }
+ case ER4iGoldClone:
+ case EGatewayBlue:
+ case ER4Original: {
+ usrcheatPath = "fat:/_wfwd/cheats/usrcheat.dat";
+ break;
+ }
+ case EAcekardRPG: // TODO: WoodRPG? Test
+ case EAcekard2i: {
+ usrcheatPath = "fat:/_afwd/cheats/usrcheat.dat";
+ break;
+ }
+ case ESupercardDSTWO: {
+ usrcheatPath = "fat:/_dstwo/usrcheat.dat";
+ break;
+ }
}
}
- FILE* db=fopen(usrcheatPath,"r+b");
- if(db)
- {
- std::vector::iterator itr=_data.begin();
- while(itr!=_data.end())
- {
- updateDB(((*itr)._flags&cParsedItem::ESelected)?1:0,(*itr)._offset,db);
- ++itr;
- }
- fclose(db);
- }
+
+ FILE* db=fopen(usrcheatPath,"r+b");
+ if(db)
+ {
+ std::vector::iterator itr=_data.begin();
+ while(itr!=_data.end())
+ {
+ updateDB(((*itr)._flags&cParsedItem::ESelected)?1:0,(*itr)._offset,db);
+ ++itr;
+ }
+ fclose(db);
+ }
}
void writeCheatsToFile(std::string data, const char* path) {
- std::fstream fs;
- fs.open(path, std::ios::binary | std::fstream::out);
- std::stringstream str;
- u32 value;
- while(1) {
- str.clear();
- str << data.substr(0, data.find(" "));
- str >> std::hex >> value;
- fs.write(reinterpret_cast(&value),sizeof(value));
- data = data.substr(data.find(" ")+1);
- if((int)data.find(" ") == -1) break;
- }
- fs.write("\0\0\0\xCF", 4);
- fs.close();
+ std::fstream fs;
+ fs.open(path, std::ios::binary | std::fstream::out);
+ std::stringstream str;
+ u32 value;
+ while(1) {
+ str.clear();
+ str << data.substr(0, data.find(" "));
+ str >> std::hex >> value;
+ fs.write(reinterpret_cast(&value),sizeof(value));
+ data = data.substr(data.find(" ")+1);
+ if((int)data.find(" ") == -1) break;
+ }
+ fs.write("\0\0\0\xCF", 4);
+ fs.close();
}
diff --git a/romsel_dsimenutheme/arm9/source/common/dsimenusettings.h b/romsel_dsimenutheme/arm9/source/common/dsimenusettings.h
index 8b76e7e0ef..eb59f95577 100644
--- a/romsel_dsimenutheme/arm9/source/common/dsimenusettings.h
+++ b/romsel_dsimenutheme/arm9/source/common/dsimenusettings.h
@@ -44,13 +44,14 @@ class TWLSettings
enum TFlashCard
{
- EDSTTClone = 0,
- ER4Original = 1,
- ER4iGoldClone = 2,
- EAcekard2i = 3,
- EAcekardRPG = 4,
- EGatewayBlue = 5,
- ESupercardDSTWO = 6
+ EFCUnknown = 0,
+ EDSTTClone = 1,
+ ER4Original = 2,
+ ER4iGoldClone = 3,
+ EAcekard2i = 4,
+ EAcekardRPG = 5,
+ EGatewayBlue = 6,
+ ESupercardDSTWO = 7
};
// Do not reorder these, just add to the end
diff --git a/romsel_dsimenutheme/arm9/source/main.cpp b/romsel_dsimenutheme/arm9/source/main.cpp
index 46eb42ab3e..ea4a35c351 100644
--- a/romsel_dsimenutheme/arm9/source/main.cpp
+++ b/romsel_dsimenutheme/arm9/source/main.cpp
@@ -379,34 +379,46 @@ void loadGameOnFlashcard (const char *ndsPath, bool dsGame) {
int err = 0;
snd().stopStream();
- if ((memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 26) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4TF", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0)) {
- CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
- fcPath = replaceAll(ndsPath, "fat:/", woodfat);
- fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
- fcrompathini.SaveIniFile("fat:/_wfwd/lastsave.ini");
- err = runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- } else if (memcmp(io_dldi_data->friendlyName, "Acekard AK2", 0xB) == 0) {
- CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
- fcPath = replaceAll(ndsPath, "fat:/", woodfat);
- fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
- fcrompathini.SaveIniFile("fat:/_afwd/lastsave.ini");
- err = runNdsFile("fat:/Afwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- } else if (memcmp(io_dldi_data->friendlyName, "DSTWO(Slot-1)", 0xD) == 0) {
- CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
- fcPath = replaceAll(ndsPath, "fat:/", dstwofat);
- fcrompathini.SetString("Dir Info", "fullName", fcPath);
- fcrompathini.SaveIniFile("fat:/_dstwo/autoboot.ini");
- err = runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- } else if ((memcmp(io_dldi_data->friendlyName, "TTCARD", 6) == 0)
- || (memcmp(io_dldi_data->friendlyName, "DSTT", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "DEMON", 5) == 0)) {
- CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
- fcPath = replaceAll(ndsPath, "fat:/", slashchar);
- fcrompathini.SetString("YSMENU", "AUTO_BOOT", fcPath);
- fcrompathini.SaveIniFile("fat:/TTMenu/YSMenu.ini");
- err = runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ switch (ms().flashcard) {
+ case EDSTTClone: {
+ CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
+ fcPath = replaceAll(ndsPath, "fat:/", slashchar);
+ fcrompathini.SetString("YSMENU", "AUTO_BOOT", fcPath);
+ fcrompathini.SaveIniFile("fat:/TTMenu/YSMenu.ini");
+ err = runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ case EGatewayBlue: // Blue card can run wood 1.62 so this should work?
+ case ER4Original: // And clones that can run wood (no N5)
+ case ER4iGoldClone: {
+ CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
+ fcPath = replaceAll(ndsPath, "fat:/", woodfat);
+ fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
+ fcrompathini.SaveIniFile("fat:/_wfwd/lastsave.ini");
+ err = runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ case ESupercardDSTWO: {
+ CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
+ fcPath = replaceAll(ndsPath, "fat:/", dstwofat);
+ fcrompathini.SetString("Dir Info", "fullName", fcPath);
+ fcrompathini.SaveIniFile("fat:/_dstwo/autoboot.ini");
+ err = runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ case EAcekardRPG: // ?
+ case EAcekard2i: {
+ CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
+ fcPath = replaceAll(ndsPath, "fat:/", woodfat);
+ fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
+ fcrompathini.SaveIniFile("fat:/_afwd/lastsave.ini");
+ err = runNdsFile("fat:/Afwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ default: {
+ err = 1337;
+ break;
+ }
}
char text[64];
@@ -681,7 +693,7 @@ int main(int argc, char **argv) {
extensionList.emplace_back(".app");
extensionList.emplace_back(".argv");
}
- if (memcmp(io_dldi_data->friendlyName, "DSTWO(Slot-1)", 0xD) == 0) {
+ if (ms().flashcard == ESupercardDSTWO) {
extensionList.emplace_back(".plg");
}
if (ms().showRvid) {
@@ -1024,10 +1036,7 @@ int main(int argc, char **argv) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", 1);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(ms().forceSleepPatch
- || (memcmp(io_dldi_data->friendlyName, "TTCARD", 6) == 0 && !sys().isRegularDS())
- || (memcmp(io_dldi_data->friendlyName, "DSTT", 4) == 0 && !sys().isRegularDS())
- || (memcmp(io_dldi_data->friendlyName, "DEMON", 5) == 0 && !sys().isRegularDS())
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0 && !sys().isRegularDS()))
+ || ((flashcard == EDSTTClone || flashcard == ER4iGoldclone) && !sys().isRegularDS())
);
bootstrapini.SaveIniFile(bootstrapinipath);
@@ -1341,10 +1350,7 @@ int main(int argc, char **argv) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", ceCached);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(ms().forceSleepPatch
- || (memcmp(io_dldi_data->friendlyName, "TTCARD", 6) == 0 && !sys().isRegularDS())
- || (memcmp(io_dldi_data->friendlyName, "DSTT", 4) == 0 && !sys().isRegularDS())
- || (memcmp(io_dldi_data->friendlyName, "DEMON", 5) == 0 && !sys().isRegularDS())
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0 && !sys().isRegularDS()))
+ || ((flashcard == EDSTTClone || flashcard == ER4iGoldclone) && !sys().isRegularDS()))
);
if (!isDSiMode() && ms().secondaryDevice && sdFound()) {
CIniFile bootstrapiniSD("sd:/_nds/nds-bootstrap.ini");
diff --git a/romsel_dsimenutheme/arm9/source/perGameSettings.cpp b/romsel_dsimenutheme/arm9/source/perGameSettings.cpp
index f8ca707740..7e3e46e307 100644
--- a/romsel_dsimenutheme/arm9/source/perGameSettings.cpp
+++ b/romsel_dsimenutheme/arm9/source/perGameSettings.cpp
@@ -324,11 +324,9 @@ void perGameSettings (std::string filename) {
}*/
bool showCheats = ((isDSiMode() && ms().useBootstrap)
+ // TODO: Enable
/*|| (ms().secondaryDevice && !ms().useBootstrap
- && ((memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 26) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4TF", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0)
- || (memcmp(io_dldi_data->friendlyName, "Acekard AK2", 0xB) == 0)))*/
+ && ms().flashcard != EFCUnknown))*/
|| !ms().secondaryDevice);
firstPerGameOpShown = 0;
diff --git a/romsel_r4theme/arm9/source/cheat.cpp b/romsel_r4theme/arm9/source/cheat.cpp
index 046fe56f25..10021f4cba 100644
--- a/romsel_r4theme/arm9/source/cheat.cpp
+++ b/romsel_r4theme/arm9/source/cheat.cpp
@@ -1,21 +1,21 @@
/*
- cheat.cpp
- Portions copyright (C) 2008 Normmatt, www.normmatt.com, Smiths (www.emuholic.com)
- Portions copyright (C) 2008 bliss (bliss@hanirc.org)
- Copyright (C) 2009 yellow wood goblin
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
+ cheat.cpp
+ Portions copyright (C) 2008 Normmatt, www.normmatt.com, Smiths (www.emuholic.com)
+ Portions copyright (C) 2008 bliss (bliss@hanirc.org)
+ Copyright (C) 2009 yellow wood goblin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
*/
#include
@@ -42,520 +42,548 @@ CheatCodelist::~CheatCodelist(void) {}
inline u32 gamecode(const char *aGameCode)
{
- u32 gameCode;
- memcpy(&gameCode, aGameCode, sizeof(gameCode));
- return gameCode;
+ u32 gameCode;
+ memcpy(&gameCode, aGameCode, sizeof(gameCode));
+ return gameCode;
}
#define CRCPOLY 0xedb88320
static u32 crc32(const u8* p,size_t len)
{
- u32 crc=-1;
- while(len--)
- {
- crc^=*p++;
- for(int ii=0;ii<8;++ii) crc=(crc>>1)^((crc&1)?CRCPOLY:0);
- }
- return crc;
+ u32 crc=-1;
+ while(len--)
+ {
+ crc^=*p++;
+ for(int ii=0;ii<8;++ii) crc=(crc>>1)^((crc&1)?CRCPOLY:0);
+ }
+ return crc;
}
bool CheatCodelist::parse(const std::string& aFileName)
{
- bool res=false;
- u32 romcrc32,gamecode;
- if(romData(aFileName,gamecode,romcrc32))
- {
- const char* usrcheatPath = (sdFound() || !secondaryDevice) ? "sd:/_nds/TWiLightMenu/extras/usrcheat.dat" : "fat:/_nds/TWiLightMenu/extras/usrcheat.dat";
+ bool res=false;
+ u32 romcrc32,gamecode;
+ if(romData(aFileName,gamecode,romcrc32))
+ {
+ const char* usrcheatPath = (sdFound() || !secondaryDevice) ? "sd:/_nds/TWiLightMenu/extras/usrcheat.dat" : "fat:/_nds/TWiLightMenu/extras/usrcheat.dat";
if (secondaryDevice && !useBootstrap) {
- if ((memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 26) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4TF", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0)) {
- usrcheatPath = "fat:/_wfwd/cheats/usrcheat.dat";
- } else if (memcmp(io_dldi_data->friendlyName, "Acekard AK2", 0xB) == 0) {
- usrcheatPath = "fat:/_afwd/cheats/usrcheat.dat";
+ switch (flashcard) {
+ case EDSTTClone: {
+ usrcheatPath = "fat:/TTMenu/usrcheat.dat";
+ break;
+ }
+ case ER4iGoldClone:
+ case EGatewayBlue:
+ case ER4Original: {
+ usrcheatPath = "fat:/_wfwd/cheats/usrcheat.dat";
+ break;
+ }
+ case EAcekardRPG: // TODO: WoodRPG? Test
+ case EAcekard2i: {
+ usrcheatPath = "fat:/_afwd/cheats/usrcheat.dat";
+ break;
+ }
+ case ESupercardDSTWO: {
+ usrcheatPath = "fat:/_dstwo/usrcheat.dat";
+ break;
+ }
+ }
+ }
+ FILE* dat=fopen(usrcheatPath,"rb");
+ if(dat)
+ {
+ res=parseInternal(dat,gamecode,romcrc32);
+ fclose(dat);
}
}
- FILE* dat=fopen(usrcheatPath,"rb");
- if(dat)
- {
- res=parseInternal(dat,gamecode,romcrc32);
- fclose(dat);
- }
- }
- return res;
+ return res;
}
bool CheatCodelist::searchCheatData(FILE* aDat,u32 gamecode,u32 crc32,long& aPos,size_t& aSize)
{
- aPos=0;
- aSize=0;
- const char* KHeader="R4 CheatCode";
- char header[12];
- fread(header,12,1,aDat);
- if(strncmp(KHeader,header,12)) return false;
-
- sDatIndex idx,nidx;
-
- fseek(aDat,0,SEEK_END);
- long fileSize=ftell(aDat);
-
- fseek(aDat,0x100,SEEK_SET);
- fread(&nidx,sizeof(nidx),1,aDat);
-
- bool done=false;
-
- while(!done)
- {
- tonccpy(&idx,&nidx,sizeof(idx));
- fread(&nidx,sizeof(nidx),1,aDat);
- if(gamecode==idx._gameCode&&crc32==idx._crc32)
- {
- aSize=((nidx._offset)?nidx._offset:fileSize)-idx._offset;
- aPos=idx._offset;
- done=true;
- }
- if(!nidx._offset) done=true;
- }
- return (aPos&&aSize);
+ aPos=0;
+ aSize=0;
+ const char* KHeader="R4 CheatCode";
+ char header[12];
+ fread(header,12,1,aDat);
+ if(strncmp(KHeader,header,12)) return false;
+
+ sDatIndex idx,nidx;
+
+ fseek(aDat,0,SEEK_END);
+ long fileSize=ftell(aDat);
+
+ fseek(aDat,0x100,SEEK_SET);
+ fread(&nidx,sizeof(nidx),1,aDat);
+
+ bool done=false;
+
+ while(!done)
+ {
+ tonccpy(&idx,&nidx,sizeof(idx));
+ fread(&nidx,sizeof(nidx),1,aDat);
+ if(gamecode==idx._gameCode&&crc32==idx._crc32)
+ {
+ aSize=((nidx._offset)?nidx._offset:fileSize)-idx._offset;
+ aPos=idx._offset;
+ done=true;
+ }
+ if(!nidx._offset) done=true;
+ }
+ return (aPos&&aSize);
}
bool CheatCodelist::parseInternal(FILE* aDat,u32 gamecode,u32 crc32)
{
- dbg_printf("%x, %x\n",gamecode,crc32);
-
- _data.clear();
-
- long dataPos; size_t dataSize;
- if(!searchCheatData(aDat,gamecode,crc32,dataPos,dataSize)) return false;
- fseek(aDat,dataPos,SEEK_SET);
-
- dbg_printf("record found: %d\n",dataSize);
-
- char* buffer=(char*)malloc(dataSize);
- if(!buffer) return false;
- fread(buffer,dataSize,1,aDat);
- char* gameTitle=buffer;
-
- u32* ccode=(u32*)(((u32)gameTitle+strlen(gameTitle)+4)&~3);
- u32 cheatCount=*ccode;
- cheatCount&=0x0fffffff;
- ccode+=9;
-
- u32 cc=0;
- while(cc>28)&1)
- {
- flagItem|=cParsedItem::EInFolder;
- if((*ccode>>24)==0x11) flagItem|=cParsedItem::EOne;
- folderCount=*ccode&0x00ffffff;
- folderName=(char*)((u32)ccode+4);
- folderNote=(char*)((u32)folderName+strlen(folderName)+1);
- _data.push_back(cParsedItem(folderName,folderNote,cParsedItem::EFolder));
- cc++;
- ccode=(u32*)(((u32)folderName+strlen(folderName)+1+strlen(folderNote)+1+3)&~3);
- }
-
- u32 selectValue=cParsedItem::ESelected;
- for(size_t ii=0;ii>28)&1)
+ {
+ flagItem|=cParsedItem::EInFolder;
+ if((*ccode>>24)==0x11) flagItem|=cParsedItem::EOne;
+ folderCount=*ccode&0x00ffffff;
+ folderName=(char*)((u32)ccode+4);
+ folderNote=(char*)((u32)folderName+strlen(folderName)+1);
+ _data.push_back(cParsedItem(folderName,folderNote,cParsedItem::EFolder));
+ cc++;
+ ccode=(u32*)(((u32)folderName+strlen(folderName)+1+strlen(folderNote)+1+3)&~3);
+ }
+
+ u32 selectValue=cParsedItem::ESelected;
+ for(size_t ii=0;ii::iterator itr=_data.begin();
- while(itr!=_data.end())
- {
- std::vector row;
- row.push_back("");
- row.push_back((*itr)._title);
- // _List.insertRow(_List.getRowCount(),row);
- _indexes.push_back(itr-_data.begin());
- u32 flags=(*itr)._flags;
- ++itr;
- if((flags&cParsedItem::EFolder)&&(flags&cParsedItem::EOpen)==0)
- {
- while(((*itr)._flags&cParsedItem::EInFolder)&&itr!=_data.end()) ++itr;
- }
- }
+ _indexes.clear();
+ // _List.removeAllRows();
+
+ std::vector::iterator itr=_data.begin();
+ while(itr!=_data.end())
+ {
+ std::vector row;
+ row.push_back("");
+ row.push_back((*itr)._title);
+ // _List.insertRow(_List.getRowCount(),row);
+ _indexes.push_back(itr-_data.begin());
+ u32 flags=(*itr)._flags;
+ ++itr;
+ if((flags&cParsedItem::EFolder)&&(flags&cParsedItem::EOpen)==0)
+ {
+ while(((*itr)._flags&cParsedItem::EInFolder)&&itr!=_data.end()) ++itr;
+ }
+ }
}
void CheatCodelist::deselectFolder(size_t anIndex)
{
- std::vector::iterator itr=_data.begin()+anIndex;
- while(--itr>=_data.begin())
- {
- if((*itr)._flags&cParsedItem::EFolder)
- {
- ++itr;
- break;
- }
- }
- while(((*itr)._flags&cParsedItem::EInFolder)&&itr!=_data.end())
- {
- (*itr)._flags&=~cParsedItem::ESelected;
- ++itr;
- }
+ std::vector::iterator itr=_data.begin()+anIndex;
+ while(--itr>=_data.begin())
+ {
+ if((*itr)._flags&cParsedItem::EFolder)
+ {
+ ++itr;
+ break;
+ }
+ }
+ while(((*itr)._flags&cParsedItem::EInFolder)&&itr!=_data.end())
+ {
+ (*itr)._flags&=~cParsedItem::ESelected;
+ ++itr;
+ }
}
bool CheatCodelist::romData(const std::string& aFileName,u32& aGameCode,u32& aCrc32)
{
- bool res=false;
- FILE* rom=fopen(aFileName.c_str(),"rb");
- if(rom)
- {
- u8 header[512];
- if(1==fread(header,sizeof(header),1,rom))
- {
- aCrc32=crc32(header,sizeof(header));
- aGameCode=gamecode((const char*)(header+12));
- res=true;
- }
- fclose(rom);
- }
- return res;
+ bool res=false;
+ FILE* rom=fopen(aFileName.c_str(),"rb");
+ if(rom)
+ {
+ u8 header[512];
+ if(1==fread(header,sizeof(header),1,rom))
+ {
+ aCrc32=crc32(header,sizeof(header));
+ aGameCode=gamecode((const char*)(header+12));
+ res=true;
+ }
+ fclose(rom);
+ }
+ return res;
}
std::string CheatCodelist::getCheats()
{
- std::string cheats;
- for(uint i=0;i< _data.size();i++)
- {
- if(_data[i]._flags&cParsedItem::ESelected)
- {
- cheats += _data[i]._cheat.substr(0, _data[i]._cheat.size());
- }
- }
- std::replace( cheats.begin(), cheats.end(), '\n', ' ');
- return cheats;
+ std::string cheats;
+ for(uint i=0;i< _data.size();i++)
+ {
+ if(_data[i]._flags&cParsedItem::ESelected)
+ {
+ cheats += _data[i]._cheat.substr(0, _data[i]._cheat.size());
+ }
+ }
+ std::replace( cheats.begin(), cheats.end(), '\n', ' ');
+ return cheats;
}
void CheatCodelist::drawCheatList(std::vector& list, uint curPos, uint screenPos) {
- for(uint i=0;(int)i<(dialogboxHeight+2) && i_flags&cParsedItem::EFolder) {
- if(screenPos+i == curPos) {
- printSmall(false, 27, 90+(i*10), ">");
- printSmall(false, 35, 90+(i*10), list[screenPos+i]->_title.c_str());
- } else {
- printSmall(false, 22, 90+(i*10), ">");
- printSmall(false, 30, 90+(i*10), list[screenPos+i]->_title.c_str());
- }
- } else {
- if(list[screenPos+i]->_flags&cParsedItem::ESelected) {
- printSmall(false, 16, 89+(i*10), "x");
- }
- if(screenPos+i == curPos) {
- printSmall(false, 25, 90+(i*10), "-");
- printSmall(false, 32, 90+(i*10), list[screenPos+i]->_title.c_str());
- } else {
- printSmall(false, 21, 90+(i*10), "-");
- printSmall(false, 28, 90+(i*10), list[screenPos+i]->_title.c_str());
- }
- }
- }
+ for(uint i=0;(int)i<(dialogboxHeight+2) && i_flags&cParsedItem::EFolder) {
+ if(screenPos+i == curPos) {
+ printSmall(false, 27, 90+(i*10), ">");
+ printSmall(false, 35, 90+(i*10), list[screenPos+i]->_title.c_str());
+ } else {
+ printSmall(false, 22, 90+(i*10), ">");
+ printSmall(false, 30, 90+(i*10), list[screenPos+i]->_title.c_str());
+ }
+ } else {
+ if(list[screenPos+i]->_flags&cParsedItem::ESelected) {
+ printSmall(false, 16, 89+(i*10), "x");
+ }
+ if(screenPos+i == curPos) {
+ printSmall(false, 25, 90+(i*10), "-");
+ printSmall(false, 32, 90+(i*10), list[screenPos+i]->_title.c_str());
+ } else {
+ printSmall(false, 21, 90+(i*10), "-");
+ printSmall(false, 28, 90+(i*10), list[screenPos+i]->_title.c_str());
+ }
+ }
+ }
}
void CheatCodelist::selectCheats(std::string filename)
{
- int pressed = 0;
- int held = 0;
-
- clearText();
-
- int oldDialogboxHeight = dialogboxHeight;
- dialogboxHeight = 5;
-
- titleUpdate(isDirectory, filename.c_str());
- printLargeCentered(false, 74, "Cheats");
- printSmallCentered(false, 100, "Loading...");
-
- parse(filename);
-
- bool cheatsFound = true;
- // If no cheats are found
- if(_data.size() == 0) {
- cheatsFound = false;
- clearText();
- titleUpdate(isDirectory, filename.c_str());
- printLargeCentered(false, 74, "Cheats");
- printSmallCentered(false, 100, "No cheats found");
- printSmallCentered(false, 160, "B: Back");
-
- while(1) {
- snd().updateStream();
- scanKeys();
- pressed = keysDownRepeat();
- checkSdEject();
- swiWaitForVBlank();
- if(pressed & KEY_B) {
- break;
- }
- }
- }
-
- // Make list of all cheats not in folders and folders
- std::vector currentList;
- for(uint i=0;i<_data.size();i++) {
- if(!(_data[i]._flags&cParsedItem::EInFolder)) {
- currentList.push_back(&_data[i]);
- }
- }
-
- int mainListCurPos = -1, mainListScreenPos = -1,
- cheatWnd_cursorPosition = 0, cheatWnd_screenPosition = 0;
-
- while(cheatsFound) {
- clearText();
- titleUpdate(isDirectory, filename.c_str());
- printLargeCentered(false, 74, "Cheats");
-
- // Print bottom text
- if(currentList[cheatWnd_cursorPosition]->_comment != "") {
- if(currentList[cheatWnd_cursorPosition]->_flags&cParsedItem::EFolder) {
- printSmallCentered(false, 167, "A: Open Y: Info X: Save B: Cancel");
- } else if(currentList[cheatWnd_cursorPosition]->_flags&cParsedItem::ESelected) {
- printSmallCentered(false, 167, "A: Deselect Y: Info X: Save B: Cancel");
- } else {
- printSmallCentered(false, 167, "A: Select Y: Info X: Save B: Cancel");
- }
- } else {
- if(currentList[cheatWnd_cursorPosition]->_flags&cParsedItem::EFolder) {
- printSmallCentered(false, 167, "A: Open X: Save B: Cancel");
- } else if(currentList[cheatWnd_cursorPosition]->_flags&cParsedItem::ESelected) {
- printSmallCentered(false, 167, "A: Deselect X: Save B: Cancel");
- } else {
- printSmallCentered(false, 167, "A: Select X: Save B: Cancel");
- }
- }
-
- // Scroll screen if needed
- if(cheatWnd_cursorPosition < cheatWnd_screenPosition) {
- cheatWnd_screenPosition = cheatWnd_cursorPosition;
- } else if(cheatWnd_cursorPosition > cheatWnd_screenPosition + (dialogboxHeight+2) - 1) {
- cheatWnd_screenPosition = cheatWnd_cursorPosition - (dialogboxHeight+2) + 1;
- }
-
- drawCheatList(currentList, cheatWnd_cursorPosition, cheatWnd_screenPosition);
-
- do {
- snd().updateStream();
- scanKeys();
- pressed = keysDown();
- held = keysDownRepeat();
- checkSdEject();
- swiWaitForVBlank();
- } while(!pressed && !held);
-
- if(held & KEY_UP) {
- if(cheatWnd_cursorPosition>0) {
- cheatWnd_cursorPosition--;
- }
- } else if(held & KEY_DOWN) {
- if(cheatWnd_cursorPosition<((int)currentList.size()-1)) {
- cheatWnd_cursorPosition++;
- }
- } else if(held & KEY_LEFT) {
- cheatWnd_cursorPosition -= (cheatWnd_cursorPosition > (dialogboxHeight+2) ? (dialogboxHeight+2) : cheatWnd_cursorPosition);
- } else if(held & KEY_RIGHT) {
- cheatWnd_cursorPosition += (cheatWnd_cursorPosition < (int)(currentList.size()-(dialogboxHeight+2)) ? (dialogboxHeight+2) : currentList.size()-cheatWnd_cursorPosition-1);
- } else if(pressed & KEY_A) {
- if(currentList[cheatWnd_cursorPosition]->_flags&cParsedItem::EFolder) {
- uint i = std::distance(&_data[0], currentList[cheatWnd_cursorPosition]) + 1;
- currentList.clear();
- for(; !(_data[i]._flags & cParsedItem::EFolder) && i < _data.size(); i++) {
- currentList.push_back(&_data[i]);
- }
- mainListCurPos = cheatWnd_cursorPosition;
- mainListScreenPos = cheatWnd_screenPosition;
- cheatWnd_cursorPosition = 0;
- } else {
- cParsedItem &cheat = *currentList[cheatWnd_cursorPosition];
- bool select = !(cheat._flags & cParsedItem::ESelected);
- if(cheat._flags & cParsedItem::EOne)
- deselectFolder(std::distance(&_data[0], currentList[cheatWnd_cursorPosition]));
- if(select || !(cheat._flags & cParsedItem::EOne))
- cheat._flags ^= cParsedItem::ESelected;
- }
- } else if(pressed & KEY_B) {
- if(mainListCurPos != -1) {
- currentList.clear();
- for(uint i=0;i<_data.size();i++) {
- if(!(_data[i]._flags&cParsedItem::EInFolder)) {
- currentList.push_back(&_data[i]);
- }
- }
- cheatWnd_cursorPosition = mainListCurPos;
- cheatWnd_screenPosition = mainListScreenPos;
- mainListCurPos = -1;
- } else {
- break;
- }
- } else if(pressed & KEY_X) {
- clearText();
- titleUpdate(isDirectory, filename.c_str());
- printLargeCentered(false, 74, "Cheats");
- printSmallCentered(false, 100, "Saving...");
- onGenerate();
- break;
- }
- if(pressed & KEY_Y) {
- if(currentList[cheatWnd_cursorPosition]->_comment != "") {
- clearText();
- titleUpdate(isDirectory, filename.c_str());
- printLargeCentered(false, 74, "Cheats");
-
- std::vector _topText;
- std::string _topTextStr(currentList[cheatWnd_cursorPosition]->_comment);
- std::vector words;
- std::size_t pos;
-
- // Process comment to stay within the box
- while((pos = _topTextStr.find(' ')) != std::string::npos) {
- words.push_back(_topTextStr.substr(0, pos));
- _topTextStr = _topTextStr.substr(pos + 1);
- }
- if(_topTextStr.size())
- words.push_back(_topTextStr);
- std::string temp;
- for(auto word : words) {
- // Split word if the word is too long for a line
- int width = calcLargeFontWidth(word.c_str());
- if(width > 220) {
- if(temp.length())
- _topText.push_back(temp);
- for(int i = 0; i < width/240; i++) {
- word.insert((float)((i + 1) * word.length()) / ((width/240) + 1), "\n");
- }
- _topText.push_back(word);
- continue;
- }
-
- width = calcSmallFontWidth((temp + " " + word).c_str());
- if(width > 240) {
- _topText.push_back(temp);
- temp = word;
- } else {
- temp += " " + word;
- }
- }
- if(temp.size())
- _topText.push_back(temp);
-
- // Print comment
- for (int i = 0; i < (int)_topText.size(); i++) {
- printSmallCentered(false, 90 + (i*10), _topText[i].c_str());
- }
-
- // Print 'Back' text
- printSmallCentered(false, 167, "B: Back");
- while(1) {
- snd().updateStream();
- scanKeys();
- pressed = keysDown();
- checkSdEject();
- swiWaitForVBlank();
- if(pressed & KEY_B) {
- break;
- }
- }
- }
- }
- if(pressed & KEY_L) {
- // Delect all in the actual data so it doesn't just get the folder
- for(auto itr = _data.begin(); itr != _data.end(); itr++) {
- (*itr)._flags &= ~cParsedItem::ESelected;
- }
- // Also deselect them in the current list so that it updates the display
- for(auto itr = currentList.begin(); itr != currentList.end(); itr++) {
- (*itr)->_flags &= ~cParsedItem::ESelected;
- }
- }
- }
- dialogboxHeight = oldDialogboxHeight;
+ int pressed = 0;
+ int held = 0;
+
+ clearText();
+
+ int oldDialogboxHeight = dialogboxHeight;
+ dialogboxHeight = 5;
+
+ titleUpdate(isDirectory, filename.c_str());
+ printLargeCentered(false, 74, "Cheats");
+ printSmallCentered(false, 100, "Loading...");
+
+ parse(filename);
+
+ bool cheatsFound = true;
+ // If no cheats are found
+ if(_data.size() == 0) {
+ cheatsFound = false;
+ clearText();
+ titleUpdate(isDirectory, filename.c_str());
+ printLargeCentered(false, 74, "Cheats");
+ printSmallCentered(false, 100, "No cheats found");
+ printSmallCentered(false, 160, "B: Back");
+
+ while(1) {
+ snd().updateStream();
+ scanKeys();
+ pressed = keysDownRepeat();
+ checkSdEject();
+ swiWaitForVBlank();
+ if(pressed & KEY_B) {
+ break;
+ }
+ }
+ }
+
+ // Make list of all cheats not in folders and folders
+ std::vector currentList;
+ for(uint i=0;i<_data.size();i++) {
+ if(!(_data[i]._flags&cParsedItem::EInFolder)) {
+ currentList.push_back(&_data[i]);
+ }
+ }
+
+ int mainListCurPos = -1, mainListScreenPos = -1,
+ cheatWnd_cursorPosition = 0, cheatWnd_screenPosition = 0;
+
+ while(cheatsFound) {
+ clearText();
+ titleUpdate(isDirectory, filename.c_str());
+ printLargeCentered(false, 74, "Cheats");
+
+ // Print bottom text
+ if(currentList[cheatWnd_cursorPosition]->_comment != "") {
+ if(currentList[cheatWnd_cursorPosition]->_flags&cParsedItem::EFolder) {
+ printSmallCentered(false, 167, "A: Open Y: Info X: Save B: Cancel");
+ } else if(currentList[cheatWnd_cursorPosition]->_flags&cParsedItem::ESelected) {
+ printSmallCentered(false, 167, "A: Deselect Y: Info X: Save B: Cancel");
+ } else {
+ printSmallCentered(false, 167, "A: Select Y: Info X: Save B: Cancel");
+ }
+ } else {
+ if(currentList[cheatWnd_cursorPosition]->_flags&cParsedItem::EFolder) {
+ printSmallCentered(false, 167, "A: Open X: Save B: Cancel");
+ } else if(currentList[cheatWnd_cursorPosition]->_flags&cParsedItem::ESelected) {
+ printSmallCentered(false, 167, "A: Deselect X: Save B: Cancel");
+ } else {
+ printSmallCentered(false, 167, "A: Select X: Save B: Cancel");
+ }
+ }
+
+ // Scroll screen if needed
+ if(cheatWnd_cursorPosition < cheatWnd_screenPosition) {
+ cheatWnd_screenPosition = cheatWnd_cursorPosition;
+ } else if(cheatWnd_cursorPosition > cheatWnd_screenPosition + (dialogboxHeight+2) - 1) {
+ cheatWnd_screenPosition = cheatWnd_cursorPosition - (dialogboxHeight+2) + 1;
+ }
+
+ drawCheatList(currentList, cheatWnd_cursorPosition, cheatWnd_screenPosition);
+
+ do {
+ snd().updateStream();
+ scanKeys();
+ pressed = keysDown();
+ held = keysDownRepeat();
+ checkSdEject();
+ swiWaitForVBlank();
+ } while(!pressed && !held);
+
+ if(held & KEY_UP) {
+ if(cheatWnd_cursorPosition>0) {
+ cheatWnd_cursorPosition--;
+ }
+ } else if(held & KEY_DOWN) {
+ if(cheatWnd_cursorPosition<((int)currentList.size()-1)) {
+ cheatWnd_cursorPosition++;
+ }
+ } else if(held & KEY_LEFT) {
+ cheatWnd_cursorPosition -= (cheatWnd_cursorPosition > (dialogboxHeight+2) ? (dialogboxHeight+2) : cheatWnd_cursorPosition);
+ } else if(held & KEY_RIGHT) {
+ cheatWnd_cursorPosition += (cheatWnd_cursorPosition < (int)(currentList.size()-(dialogboxHeight+2)) ? (dialogboxHeight+2) : currentList.size()-cheatWnd_cursorPosition-1);
+ } else if(pressed & KEY_A) {
+ if(currentList[cheatWnd_cursorPosition]->_flags&cParsedItem::EFolder) {
+ uint i = std::distance(&_data[0], currentList[cheatWnd_cursorPosition]) + 1;
+ currentList.clear();
+ for(; !(_data[i]._flags & cParsedItem::EFolder) && i < _data.size(); i++) {
+ currentList.push_back(&_data[i]);
+ }
+ mainListCurPos = cheatWnd_cursorPosition;
+ mainListScreenPos = cheatWnd_screenPosition;
+ cheatWnd_cursorPosition = 0;
+ } else {
+ cParsedItem &cheat = *currentList[cheatWnd_cursorPosition];
+ bool select = !(cheat._flags & cParsedItem::ESelected);
+ if(cheat._flags & cParsedItem::EOne)
+ deselectFolder(std::distance(&_data[0], currentList[cheatWnd_cursorPosition]));
+ if(select || !(cheat._flags & cParsedItem::EOne))
+ cheat._flags ^= cParsedItem::ESelected;
+ }
+ } else if(pressed & KEY_B) {
+ if(mainListCurPos != -1) {
+ currentList.clear();
+ for(uint i=0;i<_data.size();i++) {
+ if(!(_data[i]._flags&cParsedItem::EInFolder)) {
+ currentList.push_back(&_data[i]);
+ }
+ }
+ cheatWnd_cursorPosition = mainListCurPos;
+ cheatWnd_screenPosition = mainListScreenPos;
+ mainListCurPos = -1;
+ } else {
+ break;
+ }
+ } else if(pressed & KEY_X) {
+ clearText();
+ titleUpdate(isDirectory, filename.c_str());
+ printLargeCentered(false, 74, "Cheats");
+ printSmallCentered(false, 100, "Saving...");
+ onGenerate();
+ break;
+ }
+ if(pressed & KEY_Y) {
+ if(currentList[cheatWnd_cursorPosition]->_comment != "") {
+ clearText();
+ titleUpdate(isDirectory, filename.c_str());
+ printLargeCentered(false, 74, "Cheats");
+
+ std::vector _topText;
+ std::string _topTextStr(currentList[cheatWnd_cursorPosition]->_comment);
+ std::vector words;
+ std::size_t pos;
+
+ // Process comment to stay within the box
+ while((pos = _topTextStr.find(' ')) != std::string::npos) {
+ words.push_back(_topTextStr.substr(0, pos));
+ _topTextStr = _topTextStr.substr(pos + 1);
+ }
+ if(_topTextStr.size())
+ words.push_back(_topTextStr);
+ std::string temp;
+ for(auto word : words) {
+ // Split word if the word is too long for a line
+ int width = calcLargeFontWidth(word.c_str());
+ if(width > 220) {
+ if(temp.length())
+ _topText.push_back(temp);
+ for(int i = 0; i < width/240; i++) {
+ word.insert((float)((i + 1) * word.length()) / ((width/240) + 1), "\n");
+ }
+ _topText.push_back(word);
+ continue;
+ }
+
+ width = calcSmallFontWidth((temp + " " + word).c_str());
+ if(width > 240) {
+ _topText.push_back(temp);
+ temp = word;
+ } else {
+ temp += " " + word;
+ }
+ }
+ if(temp.size())
+ _topText.push_back(temp);
+
+ // Print comment
+ for (int i = 0; i < (int)_topText.size(); i++) {
+ printSmallCentered(false, 90 + (i*10), _topText[i].c_str());
+ }
+
+ // Print 'Back' text
+ printSmallCentered(false, 167, "B: Back");
+ while(1) {
+ snd().updateStream();
+ scanKeys();
+ pressed = keysDown();
+ checkSdEject();
+ swiWaitForVBlank();
+ if(pressed & KEY_B) {
+ break;
+ }
+ }
+ }
+ }
+ if(pressed & KEY_L) {
+ // Delect all in the actual data so it doesn't just get the folder
+ for(auto itr = _data.begin(); itr != _data.end(); itr++) {
+ (*itr)._flags &= ~cParsedItem::ESelected;
+ }
+ // Also deselect them in the current list so that it updates the display
+ for(auto itr = currentList.begin(); itr != currentList.end(); itr++) {
+ (*itr)->_flags &= ~cParsedItem::ESelected;
+ }
+ }
+ }
+ dialogboxHeight = oldDialogboxHeight;
}
static void updateDB(u8 value,u32 offset,FILE* db)
{
- u8 oldvalue;
- if(!db) return;
- if(!offset) return;
- if(fseek(db,offset,SEEK_SET)) return;
- if(fread(&oldvalue,sizeof(oldvalue),1,db)!=1) return;
- if(oldvalue!=value)
- {
- if(fseek(db,offset,SEEK_SET)) return;
- fwrite(&value,sizeof(value),1,db);
- }
+ u8 oldvalue;
+ if(!db) return;
+ if(!offset) return;
+ if(fseek(db,offset,SEEK_SET)) return;
+ if(fread(&oldvalue,sizeof(oldvalue),1,db)!=1) return;
+ if(oldvalue!=value)
+ {
+ if(fseek(db,offset,SEEK_SET)) return;
+ fwrite(&value,sizeof(value),1,db);
+ }
}
void CheatCodelist::onGenerate(void)
{
- const char* usrcheatPath = (sdFound() || !secondaryDevice) ? "sd:/_nds/TWiLightMenu/extras/usrcheat.dat" : "fat:/_nds/TWiLightMenu/extras/usrcheat.dat";
+ const char* usrcheatPath = (sdFound() || !secondaryDevice) ? "sd:/_nds/TWiLightMenu/extras/usrcheat.dat" : "fat:/_nds/TWiLightMenu/extras/usrcheat.dat";
if (secondaryDevice && !useBootstrap) {
- if ((memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 26) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4TF", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0)) {
- usrcheatPath = "fat:/_wfwd/cheats/usrcheat.dat";
- } else if (memcmp(io_dldi_data->friendlyName, "Acekard AK2", 0xB) == 0) {
- usrcheatPath = "fat:/_afwd/cheats/usrcheat.dat";
+ switch (flashcard) {
+ case EDSTTClone: {
+ usrcheatPath = "fat:/TTMenu/usrcheat.dat";
+ break;
+ }
+ case ER4iGoldClone:
+ case EGatewayBlue:
+ case ER4Original: {
+ usrcheatPath = "fat:/_wfwd/cheats/usrcheat.dat";
+ break;
+ }
+ case EAcekardRPG: // TODO: WoodRPG? Test
+ case EAcekard2i: {
+ usrcheatPath = "fat:/_afwd/cheats/usrcheat.dat";
+ break;
+ }
+ case ESupercardDSTWO: {
+ usrcheatPath = "fat:/_dstwo/usrcheat.dat";
+ break;
+ }
+ }
+ }
+ FILE* db=fopen(usrcheatPath,"r+b");
+ if(db)
+ {
+ std::vector::iterator itr=_data.begin();
+ while(itr!=_data.end())
+ {
+ updateDB(((*itr)._flags&cParsedItem::ESelected)?1:0,(*itr)._offset,db);
+ ++itr;
}
+ fclose(db);
}
- FILE* db=fopen(usrcheatPath,"r+b");
- if(db)
- {
- std::vector::iterator itr=_data.begin();
- while(itr!=_data.end())
- {
- updateDB(((*itr)._flags&cParsedItem::ESelected)?1:0,(*itr)._offset,db);
- ++itr;
- }
- fclose(db);
- }
}
void writeCheatsToFile(std::string data, const char* path) {
- std::fstream fs;
- fs.open(path, std::ios::binary | std::fstream::out);
- std::stringstream str;
- u32 value;
- while(1) {
- str.clear();
- str << data.substr(0, data.find(" "));
- str >> std::hex >> value;
- fs.write(reinterpret_cast(&value),sizeof(value));
- data = data.substr(data.find(" ")+1);
- if((int)data.find(" ") == -1) break;
- }
- fs.write("\0\0\0\xCF", 4);
- fs.close();
+ std::fstream fs;
+ fs.open(path, std::ios::binary | std::fstream::out);
+ std::stringstream str;
+ u32 value;
+ while(1) {
+ str.clear();
+ str << data.substr(0, data.find(" "));
+ str >> std::hex >> value;
+ fs.write(reinterpret_cast(&value),sizeof(value));
+ data = data.substr(data.find(" ")+1);
+ if((int)data.find(" ") == -1) break;
+ }
+ fs.write("\0\0\0\xCF", 4);
+ fs.close();
}
diff --git a/romsel_r4theme/arm9/source/main.cpp b/romsel_r4theme/arm9/source/main.cpp
index 158c8cc8c9..58823078ba 100644
--- a/romsel_r4theme/arm9/source/main.cpp
+++ b/romsel_r4theme/arm9/source/main.cpp
@@ -82,6 +82,7 @@ int consoleModel = 0;
2 = Nintendo 3DS
3 = New Nintendo 3DS */
bool isRegularDS = true;
+int flashcard = 0;
extern bool showdialogbox;
extern int dialogboxHeight;
@@ -186,6 +187,8 @@ void LoadSettings(void) {
cursorPosition[1] = settingsini.GetInt("SRLOADER", "SECONDARY_CURSOR_POSITION", 0);
//startMenu_cursorPosition = settingsini.GetInt("SRLOADER", "STARTMENU_CURSOR_POSITION", 1);
consoleModel = settingsini.GetInt("SRLOADER", "CONSOLE_MODEL", 0);
+
+ flashcard = settingsini.GetInt("SRLOADER", "FLASHCARD", flashcard);
showNds = settingsini.GetInt("SRLOADER", "SHOW_NDS", true);
showRvid = settingsini.GetInt("SRLOADER", "SHOW_RVID", true);
@@ -691,34 +694,47 @@ void loadGameOnFlashcard (const char* ndsPath, bool dsGame) {
std::string fcPath;
int err = 0;
- if ((memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 26) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4TF", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0)) {
- CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
- fcPath = replaceAll(ndsPath, "fat:/", woodfat);
- fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
- fcrompathini.SaveIniFile("fat:/_wfwd/lastsave.ini");
- err = runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- } else if (memcmp(io_dldi_data->friendlyName, "Acekard AK2", 0xB) == 0) {
- CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
- fcPath = replaceAll(ndsPath, "fat:/", woodfat);
- fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
- fcrompathini.SaveIniFile("fat:/_afwd/lastsave.ini");
- err = runNdsFile("fat:/Afwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- } else if (memcmp(io_dldi_data->friendlyName, "DSTWO(Slot-1)", 0xD) == 0) {
- CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
- fcPath = replaceAll(ndsPath, "fat:/", dstwofat);
- fcrompathini.SetString("Dir Info", "fullName", fcPath);
- fcrompathini.SaveIniFile("fat:/_dstwo/autoboot.ini");
- err = runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- } else if ((memcmp(io_dldi_data->friendlyName, "TTCARD", 6) == 0)
- || (memcmp(io_dldi_data->friendlyName, "DSTT", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "DEMON", 5) == 0)) {
- CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
- fcPath = replaceAll(ndsPath, "fat:/", slashchar);
- fcrompathini.SetString("YSMENU", "AUTO_BOOT", fcPath);
- fcrompathini.SaveIniFile("fat:/TTMenu/YSMenu.ini");
- err = runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+
+ switch (flashcard) {
+ case EDSTTClone: {
+ CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
+ fcPath = replaceAll(ndsPath, "fat:/", slashchar);
+ fcrompathini.SetString("YSMENU", "AUTO_BOOT", fcPath);
+ fcrompathini.SaveIniFile("fat:/TTMenu/YSMenu.ini");
+ err = runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ case EGatewayBlue: // Blue card can run wood 1.62 so this should work?
+ case ER4Original: // And clones that can run wood (no N5)
+ case ER4iGoldClone: {
+ CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
+ fcPath = replaceAll(ndsPath, "fat:/", woodfat);
+ fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
+ fcrompathini.SaveIniFile("fat:/_wfwd/lastsave.ini");
+ err = runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ case ESupercardDSTWO: {
+ CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
+ fcPath = replaceAll(ndsPath, "fat:/", dstwofat);
+ fcrompathini.SetString("Dir Info", "fullName", fcPath);
+ fcrompathini.SaveIniFile("fat:/_dstwo/autoboot.ini");
+ err = runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ case EAcekardRPG: // ?
+ case EAcekard2i: {
+ CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
+ fcPath = replaceAll(ndsPath, "fat:/", woodfat);
+ fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
+ fcrompathini.SaveIniFile("fat:/_afwd/lastsave.ini");
+ err = runNdsFile("fat:/Afwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ default: {
+ err = 1337;
+ break;
+ }
}
char text[32];
@@ -952,7 +968,7 @@ int main(int argc, char **argv) {
extensionList.push_back(".app");
extensionList.push_back(".argv");
}
- if (memcmp(io_dldi_data->friendlyName, "DSTWO(Slot-1)", 0xD) == 0) {
+ if (flashcard == ESupercardDSTWO) {
extensionList.push_back(".plg");
}
if (showRvid) {
@@ -1473,10 +1489,7 @@ int main(int argc, char **argv) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", 1);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(forceSleepPatch
- || (memcmp(io_dldi_data->friendlyName, "TTCARD", 6) == 0 && !isRegularDS)
- || (memcmp(io_dldi_data->friendlyName, "DSTT", 4) == 0 && !isRegularDS)
- || (memcmp(io_dldi_data->friendlyName, "DEMON", 5) == 0 && !isRegularDS)
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0 && !isRegularDS))
+ || ((flashcard == EDSTTClone || flashcard == ER4iGoldClone) && !isRegularDs))
);
bootstrapini.SaveIniFile(bootstrapinipath);
@@ -1733,10 +1746,7 @@ int main(int argc, char **argv) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", ceCached);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(forceSleepPatch
- || (memcmp(io_dldi_data->friendlyName, "TTCARD", 6) == 0 && !isRegularDS)
- || (memcmp(io_dldi_data->friendlyName, "DSTT", 4) == 0 && !isRegularDS)
- || (memcmp(io_dldi_data->friendlyName, "DEMON", 5) == 0 && !isRegularDS)
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0 && !isRegularDS))
+ || ((flashcard == EDSTTClone || flashcard == ER4iGoldClone) && !isRegularDS))
);
if (!isDSiMode() && secondaryDevice && sdFound()) {
CIniFile bootstrapiniSD("sd:/_nds/nds-bootstrap.ini");
diff --git a/romsel_r4theme/arm9/source/perGameSettings.cpp b/romsel_r4theme/arm9/source/perGameSettings.cpp
index 11fcf2e03d..d634b98d62 100644
--- a/romsel_r4theme/arm9/source/perGameSettings.cpp
+++ b/romsel_r4theme/arm9/source/perGameSettings.cpp
@@ -295,11 +295,9 @@ void perGameSettings (std::string filename) {
}*/
bool showCheats = ((isDSiMode() && useBootstrap)
+ // TODO: Enable
/*|| (secondaryDevice && !useBootstrap
- && ((memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 26) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4TF", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0)
- || (memcmp(io_dldi_data->friendlyName, "Acekard AK2", 0xB) == 0)))*/
+ && flashcard != EFCUnknown))*/
|| !secondaryDevice);
firstPerGameOpShown = 0;
diff --git a/rungame/arm9/source/main.cpp b/rungame/arm9/source/main.cpp
index 248ca7a9cd..0745efda0a 100644
--- a/rungame/arm9/source/main.cpp
+++ b/rungame/arm9/source/main.cpp
@@ -67,6 +67,8 @@ static int consoleModel = 0;
2 = Nintendo 3DS
3 = New Nintendo 3DS */
+static int flashcard = 0;
+
static std::string romPath[2];
/**
@@ -112,6 +114,7 @@ TWL_CODE void LoadSettings(void) {
fcSaveOnSd = settingsini.GetInt("SRLOADER", "FC_SAVE_ON_SD", fcSaveOnSd);
useBootstrap = settingsini.GetInt("SRLOADER", "USE_BOOTSTRAP", useBootstrap);
bootstrapFile = settingsini.GetInt("SRLOADER", "BOOTSTRAP_FILE", 0);
+ flashcard = settingsini.GetInt("SRLOADER", "FLASHCARD", 0);
unlaunchBg = settingsini.GetString("SRLOADER", "UNLAUNCH_BG", unlaunchBg);
charUnlaunchBg = unlaunchBg.c_str();
@@ -327,33 +330,38 @@ TWL_CODE int lastRunROM() {
bool runNds_boostVram = perGameSettings_boostVram == -1 ? boostVram : perGameSettings_boostVram;
std::string path;
- if ((memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 26) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0)) {
- CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
- path = ReplaceAll(romPath[1], "fat:/", woodfat);
- fcrompathini.SetString("Save Info", "lastLoaded", path);
- fcrompathini.SaveIniFile("fat:/_wfwd/lastsave.ini");
- return runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- } else if (memcmp(io_dldi_data->friendlyName, "Acekard AK2", 0xB) == 0) {
- CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
- path = ReplaceAll(romPath[1], "fat:/", woodfat);
- fcrompathini.SetString("Save Info", "lastLoaded", path);
- fcrompathini.SaveIniFile("fat:/_afwd/lastsave.ini");
- return runNdsFile("fat:/Afwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- } else if (memcmp(io_dldi_data->friendlyName, "DSTWO(Slot-1)", 0xD) == 0) {
- CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
- path = ReplaceAll(romPath[1], "fat:/", dstwofat);
- fcrompathini.SetString("Dir Info", "fullName", path);
- fcrompathini.SaveIniFile("fat:/_dstwo/autoboot.ini");
- return runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- } else if ((memcmp(io_dldi_data->friendlyName, "TTCARD", 6) == 0)
- || (memcmp(io_dldi_data->friendlyName, "DSTT", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "DEMON", 5) == 0)) {
- CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
- path = ReplaceAll(romPath[1], "fat:/", slashchar);
- fcrompathini.SetString("YSMENU", "AUTO_BOOT", path);
- fcrompathini.SaveIniFile("fat:/TTMenu/YSMenu.ini");
- return runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ switch (flashcard) {
+ case EDSTTClone: {
+ CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
+ path = ReplaceAll(romPath[1], "fat:/", slashchar);
+ fcrompathini.SetString("YSMENU", "AUTO_BOOT", path);
+ fcrompathini.SaveIniFile("fat:/TTMenu/YSMenu.ini");
+ return runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ }
+ case EGatewayBlue: // Blue card can run wood 1.62 so this should work?
+ case ER4Original: // And clones that can run wood (no N5)
+ case ER4iGoldClone: {
+ CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
+ path = ReplaceAll(romPath[1], "fat:/", woodfat);
+ fcrompathini.SetString("Save Info", "lastLoaded", path);
+ fcrompathini.SaveIniFile("fat:/_wfwd/lastsave.ini");
+ return runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ }
+ case ESupercardDSTWO: {
+ CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
+ path = ReplaceAll(romPath[1], "fat:/", dstwofat);
+ fcrompathini.SetString("Dir Info", "fullName", path);
+ fcrompathini.SaveIniFile("fat:/_dstwo/autoboot.ini");
+ return runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ }
+ case EAcekardRPG: // ?
+ case EAcekard2i: {
+ CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
+ path = ReplaceAll(romPath[1], "fat:/", woodfat);
+ fcrompathini.SetString("Save Info", "lastLoaded", path);
+ fcrompathini.SaveIniFile("fat:/_afwd/lastsave.ini");
+ return runNdsFile("fat:/Afwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ }
}
}
case 2: {
diff --git a/settings/arm9/source/common/dsimenusettings.cpp b/settings/arm9/source/common/dsimenusettings.cpp
index 8ecf0f059a..0bbc0cceb2 100644
--- a/settings/arm9/source/common/dsimenusettings.cpp
+++ b/settings/arm9/source/common/dsimenusettings.cpp
@@ -56,7 +56,7 @@ TWLSettings::TWLSettings()
secondaryDevice = false;
fcSaveOnSd = false;
- flashcard = EDSTTClone;
+ flashcard = EFCUnknown;
slot1LaunchMethod = EDirect;
diff --git a/settings/arm9/source/common/dsimenusettings.h b/settings/arm9/source/common/dsimenusettings.h
index d0b85bdf37..712facc8a8 100644
--- a/settings/arm9/source/common/dsimenusettings.h
+++ b/settings/arm9/source/common/dsimenusettings.h
@@ -30,24 +30,26 @@ class TWLSettings
};
/*
- 0: DSTT/R4i Gold/R4i-SDHC/R4 SDHC Dual-Core/R4 SDHC Upgrade/SC DSONE
- 1: R4DS (Original Non-SDHC version)/ M3 Simply
- 2: R4iDSN/R4i Gold RTS/R4 Ultra
- 3: Acekard 2(i)/Galaxy Eagle/M3DS Real
- 4: Acekard RPG
- 5: Ace 3DS+/Gateway Blue Card/R4iTT
- 6: SuperCard DSTWO
+ 0: Unknown
+ 1: DSTT/R4i Gold/R4i-SDHC/R4 SDHC Dual-Core/R4 SDHC Upgrade/SC DSONE
+ 2: R4DS (Original Non-SDHC version)/ M3 Simply
+ 3: R4iDSN/R4i Gold RTS/R4 Ultra
+ 4: Acekard 2(i)/Galaxy Eagle/M3DS Real
+ 5: Acekard RPG
+ 6: Ace 3DS+/Gateway Blue Card/R4iTT
+ 7: SuperCard DSTWO
*/
enum TFlashCard
{
- EDSTTClone = 0,
- ER4Original = 1,
- ER4iGoldClone = 2,
- EAcekard2i = 3,
- EAcekardRPG = 4,
- EGatewayBlue = 5,
- ESupercardDSTWO = 6
+ EFCUnknown = 0,
+ EDSTTClone = 1,
+ ER4Original = 2,
+ ER4iGoldClone = 3,
+ EAcekard2i = 4,
+ EAcekardRPG = 5,
+ EGatewayBlue = 6,
+ ESupercardDSTWO = 7
};
// Do not reorder these, just add to the end
diff --git a/title/arm9/source/common/dsimenusettings.cpp b/title/arm9/source/common/dsimenusettings.cpp
index c444731773..3e3f48ce6d 100644
--- a/title/arm9/source/common/dsimenusettings.cpp
+++ b/title/arm9/source/common/dsimenusettings.cpp
@@ -39,7 +39,7 @@ TWLSettings::TWLSettings()
secondaryDevice = false;
fcSaveOnSd = false;
- flashcard = EDSTTClone;
+ flashcard = EFCUnknown;
slot1LaunchMethod = EDirect;
@@ -218,4 +218,4 @@ TWLSettings::TLanguage TWLSettings::getGuiLanguage()
return (TLanguage)(useTwlCfg ? *(u8*)0x02000406 : PersonalData->language);
}
return (TLanguage)guiLanguage;
-}
\ No newline at end of file
+}
diff --git a/title/arm9/source/common/dsimenusettings.h b/title/arm9/source/common/dsimenusettings.h
index dfd9495714..3763a945cf 100644
--- a/title/arm9/source/common/dsimenusettings.h
+++ b/title/arm9/source/common/dsimenusettings.h
@@ -40,13 +40,14 @@ class TWLSettings
enum TFlashCard
{
- EDSTTClone = 0,
- ER4Original = 1,
- ER4iGoldClone = 2,
- EAcekard2i = 3,
- EAcekardRPG = 4,
- EGatewayBlue = 5,
- ESupercardDSTWO = 6
+ EFCUnknown = 0,
+ EDSTTClone = 1,
+ ER4Original = 2,
+ ER4iGoldClone = 3,
+ EAcekard2i = 4,
+ EAcekardRPG = 5,
+ EGatewayBlue = 6,
+ ESupercardDSTWO = 7
};
// Do not reorder these, just add to the end
diff --git a/title/arm9/source/main.cpp b/title/arm9/source/main.cpp
index c38797f6f0..89049fde55 100644
--- a/title/arm9/source/main.cpp
+++ b/title/arm9/source/main.cpp
@@ -428,34 +428,47 @@ void lastRunROM()
rename(savepath.c_str(), savepathFc.c_str());
std::string fcPath;
- if ((memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 26) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4TF", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "R4iDSN", 6) == 0)) {
- CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
- fcPath = replaceAll(ms().romPath[ms().secondaryDevice], "fat:/", woodfat);
- fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
- fcrompathini.SaveIniFile("fat:/_wfwd/lastsave.ini");
- err = runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- } else if (memcmp(io_dldi_data->friendlyName, "Acekard AK2", 0xB) == 0) {
- CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
- fcPath = replaceAll(ms().romPath[ms().secondaryDevice], "fat:/", woodfat);
- fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
- fcrompathini.SaveIniFile("fat:/_afwd/lastsave.ini");
- err = runNdsFile("fat:/Afwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- } else if (memcmp(io_dldi_data->friendlyName, "DSTWO(Slot-1)", 0xD) == 0) {
- CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
- fcPath = replaceAll(ms().romPath[ms().secondaryDevice], "fat:/", dstwofat);
- fcrompathini.SetString("Dir Info", "fullName", fcPath);
- fcrompathini.SaveIniFile("fat:/_dstwo/autoboot.ini");
- err = runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- } else if ((memcmp(io_dldi_data->friendlyName, "TTCARD", 6) == 0)
- || (memcmp(io_dldi_data->friendlyName, "DSTT", 4) == 0)
- || (memcmp(io_dldi_data->friendlyName, "DEMON", 5) == 0)) {
- CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
- fcPath = replaceAll(ms().romPath[ms().secondaryDevice], "fat:/", slashchar);
- fcrompathini.SetString("YSMENU", "AUTO_BOOT", fcPath);
- fcrompathini.SaveIniFile("fat:/TTMenu/YSMenu.ini");
- err = runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+
+ switch (ms().flashcard) {
+ case EDSTTClone: {
+ CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
+ fcPath = replaceAll(ms().romPath[ms().secondaryDevice], "fat:/", slashchar);
+ fcrompathini.SetString("YSMENU", "AUTO_BOOT", fcPath);
+ fcrompathini.SaveIniFile("fat:/TTMenu/YSMenu.ini");
+ err = runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ case EGatewayBlue: // Blue card can run wood 1.62 so this should work?
+ case ER4Original: // And clones that can run wood (no N5)
+ case ER4iGoldClone: {
+ CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
+ fcPath = replaceAll(ms().romPath[ms().secondaryDevice], "fat:/", woodfat);
+ fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
+ fcrompathini.SaveIniFile("fat:/_wfwd/lastsave.ini");
+ err = runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ case ESupercardDSTWO: {
+ CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
+ fcPath = replaceAll(ms().romPath[ms().secondaryDevice], "fat:/", dstwofat);
+ fcrompathini.SetString("Dir Info", "fullName", fcPath);
+ fcrompathini.SaveIniFile("fat:/_dstwo/autoboot.ini");
+ err = runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ case EAcekardRPG: // ?
+ case EAcekard2i: {
+ CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
+ fcPath = replaceAll(ms().romPath[ms().secondaryDevice], "fat:/", woodfat);
+ fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
+ fcrompathini.SaveIniFile("fat:/_afwd/lastsave.ini");
+ err = runNdsFile("fat:/Afwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ default: {
+ err = 1337;
+ break;
+ }
}
}
}
From e734ba907fbb3f94f31ad12343d37861f5c4909c Mon Sep 17 00:00:00 2001
From: unresolvedsymbol <48220091+unresolvedsymbol@users.noreply.github.com>
Date: Mon, 2 Nov 2020 17:39:54 -0600
Subject: [PATCH 2/8] Correct quickly typed quickmenu code
---
quickmenu/arm9/source/main.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/quickmenu/arm9/source/main.cpp b/quickmenu/arm9/source/main.cpp
index 95fb289de0..c428bb92af 100644
--- a/quickmenu/arm9/source/main.cpp
+++ b/quickmenu/arm9/source/main.cpp
@@ -31,6 +31,7 @@
#include "graphics/fontHandler.h"
#include "common/inifile.h"
+#include "common/dsimenusettings.h"
#include "tool/stringtool.h"
#include "language.h"
@@ -2311,7 +2312,7 @@ int main(int argc, char **argv) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", ceCached);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(forceSleepPatch
- || ((flashcard == EDSTTClone || flascard == R4iGoldClone) && !isRegulards))
+ || ((flashcard == EDSTTClone || flashcard == ER4iGoldClone) && !isRegularDS))
);
bootstrapini.SaveIniFile( bootstrapinipath );
From 97fac870e66abee8e1752cce72b05c1dac586573 Mon Sep 17 00:00:00 2001
From: unresolvedsymbol <48220091+unresolvedsymbol@users.noreply.github.com>
Date: Mon, 2 Nov 2020 18:13:40 -0600
Subject: [PATCH 3/8] RIP enum
---
.../arm9/source/common/dsimenusettings.cpp | 2 +-
quickmenu/arm9/source/main.cpp | 18 ++++++------
.../arm9/source/common/bootstrapconfig.cpp | 2 +-
.../arm9/source/common/dsimenusettings.cpp | 2 +-
.../arm9/source/common/flashcardlaunch.cpp | 14 +++++-----
.../arm9/source/windows/mainlist.cpp | 2 +-
.../arm9/source/windows/mainwnd.cpp | 2 +-
romsel_dsimenutheme/arm9/source/cheat.cpp | 28 +++++++++----------
.../arm9/source/common/dsimenusettings.cpp | 2 +-
romsel_dsimenutheme/arm9/source/main.cpp | 20 ++++++-------
.../arm9/source/perGameSettings.cpp | 2 +-
romsel_r4theme/arm9/source/cheat.cpp | 28 +++++++++----------
romsel_r4theme/arm9/source/main.cpp | 20 ++++++-------
.../arm9/source/perGameSettings.cpp | 2 +-
rungame/arm9/source/main.cpp | 14 +++++-----
.../arm9/source/common/dsimenusettings.cpp | 2 +-
title/arm9/source/common/dsimenusettings.cpp | 2 +-
title/arm9/source/main.cpp | 14 +++++-----
18 files changed, 88 insertions(+), 88 deletions(-)
diff --git a/quickmenu/arm9/source/common/dsimenusettings.cpp b/quickmenu/arm9/source/common/dsimenusettings.cpp
index 60f1c59925..6095ddcb13 100644
--- a/quickmenu/arm9/source/common/dsimenusettings.cpp
+++ b/quickmenu/arm9/source/common/dsimenusettings.cpp
@@ -44,7 +44,7 @@ TWLSettings::TWLSettings()
secondaryDevice = false;
fcSaveOnSd = false;
- flashcard = EFCUnknown;
+ flashcard = 0;
slot1LaunchMethod = EDirect;
diff --git a/quickmenu/arm9/source/main.cpp b/quickmenu/arm9/source/main.cpp
index c428bb92af..8edbdd066a 100644
--- a/quickmenu/arm9/source/main.cpp
+++ b/quickmenu/arm9/source/main.cpp
@@ -670,7 +670,7 @@ void loadGameOnFlashcard (const char* ndsPath, bool dsGame) {
int err = 0;
switch (flashcard) {
- case EDSTTClone: {
+ case 1: {
CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
fcPath = replaceAll(ndsPath, "fat:/", slashchar);
fcrompathini.SetString("YSMENU", "AUTO_BOOT", fcPath);
@@ -678,9 +678,9 @@ void loadGameOnFlashcard (const char* ndsPath, bool dsGame) {
err = runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
break;
}
- case EGatewayBlue: // Blue card can run wood 1.62 so this should work?
- case ER4Original: // And clones that can run wood (no N5)
- case ER4iGoldClone: {
+ case 6: // Blue card can run wood 1.62 so this should work?
+ case 2: // And clones that can run wood (no N5)
+ case 3: {
CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
fcPath = replaceAll(ndsPath, "fat:/", woodfat);
fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
@@ -688,7 +688,7 @@ void loadGameOnFlashcard (const char* ndsPath, bool dsGame) {
err = runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
break;
}
- case ESupercardDSTWO: {
+ case 7: {
CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
fcPath = replaceAll(ndsPath, "fat:/", dstwofat);
fcrompathini.SetString("Dir Info", "fullName", fcPath);
@@ -696,8 +696,8 @@ void loadGameOnFlashcard (const char* ndsPath, bool dsGame) {
err = runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
break;
}
- case EAcekardRPG: // ?
- case EAcekard2i: {
+ case 5: // ?
+ case 4: {
CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
fcPath = replaceAll(ndsPath, "fat:/", woodfat);
fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
@@ -2066,7 +2066,7 @@ int main(int argc, char **argv) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", 1);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(forceSleepPatch
- || ((flashcard == EDSTTClone || flashcard == ER4iGoldClone) && !isRegularDS))
+ || ((flashcard == 1 || flashcard == 3) && !isRegularDS))
);
bootstrapini.SaveIniFile(bootstrapinipath);
@@ -2312,7 +2312,7 @@ int main(int argc, char **argv) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", ceCached);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(forceSleepPatch
- || ((flashcard == EDSTTClone || flashcard == ER4iGoldClone) && !isRegularDS))
+ || ((flashcard == 1 || flashcard == 3) && !isRegularDS))
);
bootstrapini.SaveIniFile( bootstrapinipath );
diff --git a/romsel_aktheme/arm9/source/common/bootstrapconfig.cpp b/romsel_aktheme/arm9/source/common/bootstrapconfig.cpp
index 0fc64bffb7..698d3fc0ca 100755
--- a/romsel_aktheme/arm9/source/common/bootstrapconfig.cpp
+++ b/romsel_aktheme/arm9/source/common/bootstrapconfig.cpp
@@ -30,7 +30,7 @@ BootstrapConfig::BootstrapConfig(const std::string &fileName, const std::string
_mpuRegion = 0;
_ceCached = true;
_forceSleepPatch = (ms().forceSleepPatch
- || ((ms().flashcard == EDSTTClone || ms().flashcard == ER4iGoldClone) && !sys().isRegularDS());
+ || ((ms().flashcard == 1 || ms().flashcard == 3) && !sys().isRegularDS());
_isHomebrew = _gametid.empty() || _sdkVersion == 0;
_saveSize = 0x80000;
_dsiMode = 0;
diff --git a/romsel_aktheme/arm9/source/common/dsimenusettings.cpp b/romsel_aktheme/arm9/source/common/dsimenusettings.cpp
index 08af4ed99a..e4325bdb5c 100644
--- a/romsel_aktheme/arm9/source/common/dsimenusettings.cpp
+++ b/romsel_aktheme/arm9/source/common/dsimenusettings.cpp
@@ -48,7 +48,7 @@ TWLSettings::TWLSettings()
secondaryDevice = false;
fcSaveOnSd = false;
- flashcard = EFCUnknown;
+ flashcard = 0;
slot1LaunchMethod = EReboot;
useBootstrap = isDSiMode();
diff --git a/romsel_aktheme/arm9/source/common/flashcardlaunch.cpp b/romsel_aktheme/arm9/source/common/flashcardlaunch.cpp
index 574dde4b1d..66c4caec74 100644
--- a/romsel_aktheme/arm9/source/common/flashcardlaunch.cpp
+++ b/romsel_aktheme/arm9/source/common/flashcardlaunch.cpp
@@ -32,28 +32,28 @@ int loadGameOnFlashcard (std::string ndsPath, bool usePerGameSettings) {
switch (ms().flashcard) {
- case EDSTTClone: {
+ case 1: {
LoaderConfig config("fat:/YSMenu.nds", "fat:/TTMenu/YSMenu.ini");
launchPath = replaceAll(ndsPath.c_str(), FC_PREFIX_FAT, FC_PREFIX_SLASH);
config.option("YSMENU", "AUTO_BOOT", launchPath);
return config.launch(0, NULL, true, true, runNds_boostCpu, runNds_boostVram);
}
- case EGatewayBlue: // Blue card can run wood 1.62 so this should work?
- case ER4Original: // And clones that can run wood (no N5)
- case ER4iGoldClone: {
+ case 6: // Blue card can run wood 1.62 so this should work?
+ case 2: // And clones that can run wood (no N5)
+ case 3: {
LoaderConfig config("fat:/Wfwd.dat", "fat:/_wfwd/lastsave.ini");
launchPath = replaceAll(ndsPath.c_str(), FC_PREFIX_FAT, FC_PREFIX_FAT0);
config.option("Save Info", "lastLoaded", launchPath);
return config.launch(0, NULL, true, true, runNds_boostCpu, runNds_boostVram);
}
- case ESupercardDSTWO: {
+ case 7: {
LoaderConfig config("fat:/_dstwo/autoboot.nds", "fat:/_dstwo/autoboot.ini");
launchPath = replaceAll(ndsPath.c_str(), FC_PREFIX_FAT, FC_PREFIX_FAT1);
config.option("Dir Info", "fullName", launchPath);
return config.launch(0, NULL, true, true, runNds_boostCpu, runNds_boostVram);
}
- case EAcekardRPG: // ?
- case EAcekard2i: {
+ case 5: // ?
+ case 4: {
LoaderConfig config("fat:/Afwd.dat", "fat:/_afwd/lastsave.ini");
launchPath = replaceAll(ndsPath.c_str(), FC_PREFIX_FAT, FC_PREFIX_FAT0);
config.option("Save Info", "lastLoaded", launchPath);
diff --git a/romsel_aktheme/arm9/source/windows/mainlist.cpp b/romsel_aktheme/arm9/source/windows/mainlist.cpp
index c7596d899f..1a6a46d14b 100644
--- a/romsel_aktheme/arm9/source/windows/mainlist.cpp
+++ b/romsel_aktheme/arm9/source/windows/mainlist.cpp
@@ -149,7 +149,7 @@ void MainList::setupExtnames()
_extnameFilter.emplace_back(std::string(".app"));
_extnameFilter.emplace_back(std::string(".argv"));
}
- if (ms().flashcard == ESupercardDSTWO) {
+ if (ms().flashcard == 7) {
_extnameFilter.emplace_back(std::string(".plg"));
}
if (ms().showRvid)
diff --git a/romsel_aktheme/arm9/source/windows/mainwnd.cpp b/romsel_aktheme/arm9/source/windows/mainwnd.cpp
index 651da0d135..64a5164ce0 100644
--- a/romsel_aktheme/arm9/source/windows/mainwnd.cpp
+++ b/romsel_aktheme/arm9/source/windows/mainwnd.cpp
@@ -1351,7 +1351,7 @@ void MainWnd::launchSelected()
extension = fullPath.substr(lastDotPos);
// DSTWO Plugin Launch
- if (extension == ".plg" && ms().secondaryDevice && ms().flashcard == ESupercardDSTWO)
+ if (extension == ".plg" && ms().secondaryDevice && ms().flashcard == 7)
{
ms().launchType[ms().secondaryDevice] = TWLSettings::ESDFlashcardLaunch;
ms().saveSettings();
diff --git a/romsel_dsimenutheme/arm9/source/cheat.cpp b/romsel_dsimenutheme/arm9/source/cheat.cpp
index 58832713ff..d127590b3c 100644
--- a/romsel_dsimenutheme/arm9/source/cheat.cpp
+++ b/romsel_dsimenutheme/arm9/source/cheat.cpp
@@ -72,22 +72,22 @@ bool CheatCodelist::parse(const std::string& aFileName)
const char* usrcheatPath = (sdFound() || !ms().secondaryDevice) ? "sd:/_nds/TWiLightMenu/extras/usrcheat.dat" : "fat:/_nds/TWiLightMenu/extras/usrcheat.dat";
if (ms().secondaryDevice && !ms().useBootstrap) {
switch (ms().flashcard) {
- case EDSTTClone: {
+ case 1: {
usrcheatPath = "fat:/TTMenu/usrcheat.dat";
break;
}
- case ER4iGoldClone:
- case EGatewayBlue:
- case ER4Original: {
+ case 3:
+ case 6:
+ case 2: {
usrcheatPath = "fat:/_wfwd/cheats/usrcheat.dat";
break;
}
- case EAcekardRPG: // TODO: WoodRPG? Test
- case EAcekard2i: {
+ case 5: // TODO: WoodRPG? Test
+ case 4: {
usrcheatPath = "fat:/_afwd/cheats/usrcheat.dat";
break;
}
- case ESupercardDSTWO: {
+ case 7: {
usrcheatPath = "fat:/_dstwo/usrcheat.dat";
break;
}
@@ -547,22 +547,22 @@ void CheatCodelist::onGenerate(void)
const char* usrcheatPath = (sdFound() || !ms().secondaryDevice) ? "sd:/_nds/TWiLightMenu/extras/usrcheat.dat" : "fat:/_nds/TWiLightMenu/extras/usrcheat.dat";
if (ms().secondaryDevice && !ms().useBootstrap) {
switch (ms().flashcard) {
- case EDSTTClone: {
+ case 1: {
usrcheatPath = "fat:/TTMenu/usrcheat.dat";
break;
}
- case ER4iGoldClone:
- case EGatewayBlue:
- case ER4Original: {
+ case 3:
+ case 6:
+ case 2: {
usrcheatPath = "fat:/_wfwd/cheats/usrcheat.dat";
break;
}
- case EAcekardRPG: // TODO: WoodRPG? Test
- case EAcekard2i: {
+ case 5: // TODO: WoodRPG? Test
+ case 4: {
usrcheatPath = "fat:/_afwd/cheats/usrcheat.dat";
break;
}
- case ESupercardDSTWO: {
+ case 7: {
usrcheatPath = "fat:/_dstwo/usrcheat.dat";
break;
}
diff --git a/romsel_dsimenutheme/arm9/source/common/dsimenusettings.cpp b/romsel_dsimenutheme/arm9/source/common/dsimenusettings.cpp
index b576c9876f..8dc6523bb2 100644
--- a/romsel_dsimenutheme/arm9/source/common/dsimenusettings.cpp
+++ b/romsel_dsimenutheme/arm9/source/common/dsimenusettings.cpp
@@ -64,7 +64,7 @@ TWLSettings::TWLSettings()
updateRecentlyPlayedList = true;
sortMethod = 0;
- flashcard = EDSTTClone;
+ flashcard = 1;
slot1LaunchMethod = EDirect;
diff --git a/romsel_dsimenutheme/arm9/source/main.cpp b/romsel_dsimenutheme/arm9/source/main.cpp
index ea4a35c351..2ff2a73423 100644
--- a/romsel_dsimenutheme/arm9/source/main.cpp
+++ b/romsel_dsimenutheme/arm9/source/main.cpp
@@ -380,7 +380,7 @@ void loadGameOnFlashcard (const char *ndsPath, bool dsGame) {
snd().stopStream();
switch (ms().flashcard) {
- case EDSTTClone: {
+ case 1: {
CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
fcPath = replaceAll(ndsPath, "fat:/", slashchar);
fcrompathini.SetString("YSMENU", "AUTO_BOOT", fcPath);
@@ -388,9 +388,9 @@ void loadGameOnFlashcard (const char *ndsPath, bool dsGame) {
err = runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
break;
}
- case EGatewayBlue: // Blue card can run wood 1.62 so this should work?
- case ER4Original: // And clones that can run wood (no N5)
- case ER4iGoldClone: {
+ case 6: // Blue card can run wood 1.62 so this should work?
+ case 2: // And clones that can run wood (no N5)
+ case 3: {
CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
fcPath = replaceAll(ndsPath, "fat:/", woodfat);
fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
@@ -398,7 +398,7 @@ void loadGameOnFlashcard (const char *ndsPath, bool dsGame) {
err = runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
break;
}
- case ESupercardDSTWO: {
+ case 7: {
CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
fcPath = replaceAll(ndsPath, "fat:/", dstwofat);
fcrompathini.SetString("Dir Info", "fullName", fcPath);
@@ -406,8 +406,8 @@ void loadGameOnFlashcard (const char *ndsPath, bool dsGame) {
err = runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
break;
}
- case EAcekardRPG: // ?
- case EAcekard2i: {
+ case 5: // ?
+ case 4: {
CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
fcPath = replaceAll(ndsPath, "fat:/", woodfat);
fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
@@ -693,7 +693,7 @@ int main(int argc, char **argv) {
extensionList.emplace_back(".app");
extensionList.emplace_back(".argv");
}
- if (ms().flashcard == ESupercardDSTWO) {
+ if (ms().flashcard == 7) {
extensionList.emplace_back(".plg");
}
if (ms().showRvid) {
@@ -1036,7 +1036,7 @@ int main(int argc, char **argv) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", 1);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(ms().forceSleepPatch
- || ((flashcard == EDSTTClone || flashcard == ER4iGoldclone) && !sys().isRegularDS())
+ || ((flashcard == 1 || flashcard == 3) && !sys().isRegularDS())
);
bootstrapini.SaveIniFile(bootstrapinipath);
@@ -1350,7 +1350,7 @@ int main(int argc, char **argv) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", ceCached);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(ms().forceSleepPatch
- || ((flashcard == EDSTTClone || flashcard == ER4iGoldclone) && !sys().isRegularDS()))
+ || ((flashcard == 1 || flashcard == 3) && !sys().isRegularDS()))
);
if (!isDSiMode() && ms().secondaryDevice && sdFound()) {
CIniFile bootstrapiniSD("sd:/_nds/nds-bootstrap.ini");
diff --git a/romsel_dsimenutheme/arm9/source/perGameSettings.cpp b/romsel_dsimenutheme/arm9/source/perGameSettings.cpp
index 7e3e46e307..dad1050eb0 100644
--- a/romsel_dsimenutheme/arm9/source/perGameSettings.cpp
+++ b/romsel_dsimenutheme/arm9/source/perGameSettings.cpp
@@ -326,7 +326,7 @@ void perGameSettings (std::string filename) {
bool showCheats = ((isDSiMode() && ms().useBootstrap)
// TODO: Enable
/*|| (ms().secondaryDevice && !ms().useBootstrap
- && ms().flashcard != EFCUnknown))*/
+ && ms().flashcard != 0))*/
|| !ms().secondaryDevice);
firstPerGameOpShown = 0;
diff --git a/romsel_r4theme/arm9/source/cheat.cpp b/romsel_r4theme/arm9/source/cheat.cpp
index 10021f4cba..92ff3ce5d5 100644
--- a/romsel_r4theme/arm9/source/cheat.cpp
+++ b/romsel_r4theme/arm9/source/cheat.cpp
@@ -68,22 +68,22 @@ bool CheatCodelist::parse(const std::string& aFileName)
const char* usrcheatPath = (sdFound() || !secondaryDevice) ? "sd:/_nds/TWiLightMenu/extras/usrcheat.dat" : "fat:/_nds/TWiLightMenu/extras/usrcheat.dat";
if (secondaryDevice && !useBootstrap) {
switch (flashcard) {
- case EDSTTClone: {
+ case 1: {
usrcheatPath = "fat:/TTMenu/usrcheat.dat";
break;
}
- case ER4iGoldClone:
- case EGatewayBlue:
- case ER4Original: {
+ case 3:
+ case 6:
+ case 2: {
usrcheatPath = "fat:/_wfwd/cheats/usrcheat.dat";
break;
}
- case EAcekardRPG: // TODO: WoodRPG? Test
- case EAcekard2i: {
+ case 5: // TODO: WoodRPG? Test
+ case 4: {
usrcheatPath = "fat:/_afwd/cheats/usrcheat.dat";
break;
}
- case ESupercardDSTWO: {
+ case 7: {
usrcheatPath = "fat:/_dstwo/usrcheat.dat";
break;
}
@@ -537,22 +537,22 @@ void CheatCodelist::onGenerate(void)
const char* usrcheatPath = (sdFound() || !secondaryDevice) ? "sd:/_nds/TWiLightMenu/extras/usrcheat.dat" : "fat:/_nds/TWiLightMenu/extras/usrcheat.dat";
if (secondaryDevice && !useBootstrap) {
switch (flashcard) {
- case EDSTTClone: {
+ case 1: {
usrcheatPath = "fat:/TTMenu/usrcheat.dat";
break;
}
- case ER4iGoldClone:
- case EGatewayBlue:
- case ER4Original: {
+ case 3:
+ case 6:
+ case 2: {
usrcheatPath = "fat:/_wfwd/cheats/usrcheat.dat";
break;
}
- case EAcekardRPG: // TODO: WoodRPG? Test
- case EAcekard2i: {
+ case 5: // TODO: WoodRPG? Test
+ case 4: {
usrcheatPath = "fat:/_afwd/cheats/usrcheat.dat";
break;
}
- case ESupercardDSTWO: {
+ case 7: {
usrcheatPath = "fat:/_dstwo/usrcheat.dat";
break;
}
diff --git a/romsel_r4theme/arm9/source/main.cpp b/romsel_r4theme/arm9/source/main.cpp
index 58823078ba..44fb959d3c 100644
--- a/romsel_r4theme/arm9/source/main.cpp
+++ b/romsel_r4theme/arm9/source/main.cpp
@@ -696,7 +696,7 @@ void loadGameOnFlashcard (const char* ndsPath, bool dsGame) {
int err = 0;
switch (flashcard) {
- case EDSTTClone: {
+ case 1: {
CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
fcPath = replaceAll(ndsPath, "fat:/", slashchar);
fcrompathini.SetString("YSMENU", "AUTO_BOOT", fcPath);
@@ -704,9 +704,9 @@ void loadGameOnFlashcard (const char* ndsPath, bool dsGame) {
err = runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
break;
}
- case EGatewayBlue: // Blue card can run wood 1.62 so this should work?
- case ER4Original: // And clones that can run wood (no N5)
- case ER4iGoldClone: {
+ case 6: // Blue card can run wood 1.62 so this should work?
+ case 2: // And clones that can run wood (no N5)
+ case 3: {
CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
fcPath = replaceAll(ndsPath, "fat:/", woodfat);
fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
@@ -714,7 +714,7 @@ void loadGameOnFlashcard (const char* ndsPath, bool dsGame) {
err = runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
break;
}
- case ESupercardDSTWO: {
+ case 7: {
CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
fcPath = replaceAll(ndsPath, "fat:/", dstwofat);
fcrompathini.SetString("Dir Info", "fullName", fcPath);
@@ -722,8 +722,8 @@ void loadGameOnFlashcard (const char* ndsPath, bool dsGame) {
err = runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
break;
}
- case EAcekardRPG: // ?
- case EAcekard2i: {
+ case 5: // ?
+ case 4: {
CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
fcPath = replaceAll(ndsPath, "fat:/", woodfat);
fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
@@ -968,7 +968,7 @@ int main(int argc, char **argv) {
extensionList.push_back(".app");
extensionList.push_back(".argv");
}
- if (flashcard == ESupercardDSTWO) {
+ if (flashcard == 7) {
extensionList.push_back(".plg");
}
if (showRvid) {
@@ -1489,7 +1489,7 @@ int main(int argc, char **argv) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", 1);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(forceSleepPatch
- || ((flashcard == EDSTTClone || flashcard == ER4iGoldClone) && !isRegularDs))
+ || ((flashcard == 1 || flashcard == 3) && !isRegularDs))
);
bootstrapini.SaveIniFile(bootstrapinipath);
@@ -1746,7 +1746,7 @@ int main(int argc, char **argv) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", ceCached);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(forceSleepPatch
- || ((flashcard == EDSTTClone || flashcard == ER4iGoldClone) && !isRegularDS))
+ || ((flashcard == 1 || flashcard == 3) && !isRegularDS))
);
if (!isDSiMode() && secondaryDevice && sdFound()) {
CIniFile bootstrapiniSD("sd:/_nds/nds-bootstrap.ini");
diff --git a/romsel_r4theme/arm9/source/perGameSettings.cpp b/romsel_r4theme/arm9/source/perGameSettings.cpp
index d634b98d62..19c4eb7bdb 100644
--- a/romsel_r4theme/arm9/source/perGameSettings.cpp
+++ b/romsel_r4theme/arm9/source/perGameSettings.cpp
@@ -297,7 +297,7 @@ void perGameSettings (std::string filename) {
bool showCheats = ((isDSiMode() && useBootstrap)
// TODO: Enable
/*|| (secondaryDevice && !useBootstrap
- && flashcard != EFCUnknown))*/
+ && flashcard != 0))*/
|| !secondaryDevice);
firstPerGameOpShown = 0;
diff --git a/rungame/arm9/source/main.cpp b/rungame/arm9/source/main.cpp
index 0745efda0a..02c85658e6 100644
--- a/rungame/arm9/source/main.cpp
+++ b/rungame/arm9/source/main.cpp
@@ -331,31 +331,31 @@ TWL_CODE int lastRunROM() {
std::string path;
switch (flashcard) {
- case EDSTTClone: {
+ case 1: {
CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
path = ReplaceAll(romPath[1], "fat:/", slashchar);
fcrompathini.SetString("YSMENU", "AUTO_BOOT", path);
fcrompathini.SaveIniFile("fat:/TTMenu/YSMenu.ini");
return runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
}
- case EGatewayBlue: // Blue card can run wood 1.62 so this should work?
- case ER4Original: // And clones that can run wood (no N5)
- case ER4iGoldClone: {
+ case 6: // Blue card can run wood 1.62 so this should work?
+ case 2: // And clones that can run wood (no N5)
+ case 3: {
CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
path = ReplaceAll(romPath[1], "fat:/", woodfat);
fcrompathini.SetString("Save Info", "lastLoaded", path);
fcrompathini.SaveIniFile("fat:/_wfwd/lastsave.ini");
return runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
}
- case ESupercardDSTWO: {
+ case 7: {
CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
path = ReplaceAll(romPath[1], "fat:/", dstwofat);
fcrompathini.SetString("Dir Info", "fullName", path);
fcrompathini.SaveIniFile("fat:/_dstwo/autoboot.ini");
return runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
}
- case EAcekardRPG: // ?
- case EAcekard2i: {
+ case 5: // ?
+ case 4: {
CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
path = ReplaceAll(romPath[1], "fat:/", woodfat);
fcrompathini.SetString("Save Info", "lastLoaded", path);
diff --git a/settings/arm9/source/common/dsimenusettings.cpp b/settings/arm9/source/common/dsimenusettings.cpp
index 0bbc0cceb2..003489a1a3 100644
--- a/settings/arm9/source/common/dsimenusettings.cpp
+++ b/settings/arm9/source/common/dsimenusettings.cpp
@@ -56,7 +56,7 @@ TWLSettings::TWLSettings()
secondaryDevice = false;
fcSaveOnSd = false;
- flashcard = EFCUnknown;
+ flashcard = 0;
slot1LaunchMethod = EDirect;
diff --git a/title/arm9/source/common/dsimenusettings.cpp b/title/arm9/source/common/dsimenusettings.cpp
index 3e3f48ce6d..96e31c9c16 100644
--- a/title/arm9/source/common/dsimenusettings.cpp
+++ b/title/arm9/source/common/dsimenusettings.cpp
@@ -39,7 +39,7 @@ TWLSettings::TWLSettings()
secondaryDevice = false;
fcSaveOnSd = false;
- flashcard = EFCUnknown;
+ flashcard = 0;
slot1LaunchMethod = EDirect;
diff --git a/title/arm9/source/main.cpp b/title/arm9/source/main.cpp
index 89049fde55..da6360e176 100644
--- a/title/arm9/source/main.cpp
+++ b/title/arm9/source/main.cpp
@@ -430,7 +430,7 @@ void lastRunROM()
std::string fcPath;
switch (ms().flashcard) {
- case EDSTTClone: {
+ case 1: {
CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
fcPath = replaceAll(ms().romPath[ms().secondaryDevice], "fat:/", slashchar);
fcrompathini.SetString("YSMENU", "AUTO_BOOT", fcPath);
@@ -438,9 +438,9 @@ void lastRunROM()
err = runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
break;
}
- case EGatewayBlue: // Blue card can run wood 1.62 so this should work?
- case ER4Original: // And clones that can run wood (no N5)
- case ER4iGoldClone: {
+ case 6: // Blue card can run wood 1.62 so this should work?
+ case 2: // And clones that can run wood (no N5)
+ case 3: {
CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
fcPath = replaceAll(ms().romPath[ms().secondaryDevice], "fat:/", woodfat);
fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
@@ -448,7 +448,7 @@ void lastRunROM()
err = runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
break;
}
- case ESupercardDSTWO: {
+ case 7: {
CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
fcPath = replaceAll(ms().romPath[ms().secondaryDevice], "fat:/", dstwofat);
fcrompathini.SetString("Dir Info", "fullName", fcPath);
@@ -456,8 +456,8 @@ void lastRunROM()
err = runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
break;
}
- case EAcekardRPG: // ?
- case EAcekard2i: {
+ case 5: // ?
+ case 4: {
CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
fcPath = replaceAll(ms().romPath[ms().secondaryDevice], "fat:/", woodfat);
fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
From 029f3a3ddfe385672a69933f7fe8291f19caa947 Mon Sep 17 00:00:00 2001
From: unresolvedsymbol <48220091+unresolvedsymbol@users.noreply.github.com>
Date: Mon, 2 Nov 2020 18:30:43 -0600
Subject: [PATCH 4/8] Derp
---
compile.sh | 0
romsel_dsimenutheme/arm9/source/main.cpp | 6 +++---
romsel_r4theme/arm9/source/cheat.cpp | 1 +
romsel_r4theme/arm9/source/main.cpp | 2 +-
rungame/arm9/source/main.cpp | 2 --
5 files changed, 5 insertions(+), 6 deletions(-)
mode change 100644 => 100755 compile.sh
diff --git a/compile.sh b/compile.sh
old mode 100644
new mode 100755
diff --git a/romsel_dsimenutheme/arm9/source/main.cpp b/romsel_dsimenutheme/arm9/source/main.cpp
index 2ff2a73423..15136926fa 100644
--- a/romsel_dsimenutheme/arm9/source/main.cpp
+++ b/romsel_dsimenutheme/arm9/source/main.cpp
@@ -1036,8 +1036,8 @@ int main(int argc, char **argv) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", 1);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(ms().forceSleepPatch
- || ((flashcard == 1 || flashcard == 3) && !sys().isRegularDS())
- );
+ || ((ms().flashcard == 1 || ms().flashcard == 3) && !sys().isRegularDS())
+ ));
bootstrapini.SaveIniFile(bootstrapinipath);
@@ -1350,7 +1350,7 @@ int main(int argc, char **argv) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", ceCached);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(ms().forceSleepPatch
- || ((flashcard == 1 || flashcard == 3) && !sys().isRegularDS()))
+ || ((ms().flashcard == 1 || ms().flashcard == 3) && !sys().isRegularDS()))
);
if (!isDSiMode() && ms().secondaryDevice && sdFound()) {
CIniFile bootstrapiniSD("sd:/_nds/nds-bootstrap.ini");
diff --git a/romsel_r4theme/arm9/source/cheat.cpp b/romsel_r4theme/arm9/source/cheat.cpp
index 92ff3ce5d5..d002857947 100644
--- a/romsel_r4theme/arm9/source/cheat.cpp
+++ b/romsel_r4theme/arm9/source/cheat.cpp
@@ -37,6 +37,7 @@
extern int dialogboxHeight;
extern bool useBootstrap;
+extern int flashcard;
CheatCodelist::~CheatCodelist(void) {}
diff --git a/romsel_r4theme/arm9/source/main.cpp b/romsel_r4theme/arm9/source/main.cpp
index 44fb959d3c..258c50fd74 100644
--- a/romsel_r4theme/arm9/source/main.cpp
+++ b/romsel_r4theme/arm9/source/main.cpp
@@ -1489,7 +1489,7 @@ int main(int argc, char **argv) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", 1);
bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
(forceSleepPatch
- || ((flashcard == 1 || flashcard == 3) && !isRegularDs))
+ || ((flashcard == 1 || flashcard == 3) && !isRegularDS))
);
bootstrapini.SaveIniFile(bootstrapinipath);
diff --git a/rungame/arm9/source/main.cpp b/rungame/arm9/source/main.cpp
index 02c85658e6..b0613500e1 100644
--- a/rungame/arm9/source/main.cpp
+++ b/rungame/arm9/source/main.cpp
@@ -67,8 +67,6 @@ static int consoleModel = 0;
2 = Nintendo 3DS
3 = New Nintendo 3DS */
-static int flashcard = 0;
-
static std::string romPath[2];
/**
From 121fca12eb47faab2e10b68cd68f4ff7e03aaa82 Mon Sep 17 00:00:00 2001
From: unresolvedsymbol <48220091+unresolvedsymbol@users.noreply.github.com>
Date: Mon, 2 Nov 2020 21:27:15 -0600
Subject: [PATCH 5/8] Detection, CycloDSi, etc - works
---
.../arm9/source/common/dsimenusettings.h | 21 +-
quickmenu/arm9/source/main.cpp | 5368 ++++++++---------
.../arm9/source/common/dsimenusettings.h | 8 +-
romsel_aktheme/arm9/source/dsrom.cpp | 2 +-
.../arm9/source/common/dsimenusettings.h | 21 +-
.../arm9/source/fileBrowse.cpp | 6 +-
.../arm9/source/graphics/graphics.cpp | 25 +-
romsel_dsimenutheme/arm9/source/iconTitle.cpp | 2 +-
romsel_dsimenutheme/arm9/source/main.cpp | 6 +-
.../arm9/source/perGameSettings.cpp | 2 +-
romsel_r4theme/arm9/source/iconTitle.cpp | 4 +-
.../arm9/source/perGameSettings.cpp | 4 +-
settings/arm9/source/common/dsimenusettings.h | 8 +-
title/arm9/source/common/dsimenusettings.h | 22 +-
title/arm9/source/common/flashcard.cpp | 21 +
title/arm9/source/common/flashcard.h | 1 +
title/arm9/source/main.cpp | 2 +
17 files changed, 2777 insertions(+), 2746 deletions(-)
diff --git a/quickmenu/arm9/source/common/dsimenusettings.h b/quickmenu/arm9/source/common/dsimenusettings.h
index 4ff9875372..471b195abf 100644
--- a/quickmenu/arm9/source/common/dsimenusettings.h
+++ b/quickmenu/arm9/source/common/dsimenusettings.h
@@ -30,25 +30,28 @@ class TWLSettings
};
/*
- 0: DSTT/R4i Gold/R4i-SDHC/R4 SDHC Dual-Core/R4 SDHC Upgrade/SC DSONE
- 1: R4DS (Original Non-SDHC version)/ M3 Simply
- 2: R4iDSN/R4i Gold RTS/R4 Ultra
- 3: Acekard 2(i)/Galaxy Eagle/M3DS Real
- 4: Acekard RPG
- 5: Ace 3DS+/Gateway Blue Card/R4iTT
- 6: SuperCard DSTWO
+ 0: Unknown/None
+ 1: DSTT/R4i Gold/R4i-SDHC/R4 SDHC Dual-Core/R4 SDHC Upgrade/SC DSONE
+ 2: R4DS (Original Non-SDHC version)/ M3 Simply
+ 3: R4iDSN/R4i Gold RTS/R4 Ultra
+ 4: Acekard 2(i)/Galaxy Eagle/M3DS Real
+ 5: Acekard RPG
+ 6: Ace 3DS+/Gateway Blue Card/R4iTT
+ 7: SuperCard DSTWO
+ 8: CycloDS iEvolution
*/
enum TFlashCard
{
- EFCUnknown = 0,
+ EUnknown = 0,
EDSTTClone = 1,
ER4Original = 2,
ER4iGoldClone = 3,
EAcekard2i = 4,
EAcekardRPG = 5,
EGatewayBlue = 6,
- ESupercardDSTWO = 7
+ ESupercardDSTWO = 7,
+ ECycloDSi = 8
};
// Do not reorder these, just add to the end
diff --git a/quickmenu/arm9/source/main.cpp b/quickmenu/arm9/source/main.cpp
index 8edbdd066a..3cfd29d28e 100644
--- a/quickmenu/arm9/source/main.cpp
+++ b/quickmenu/arm9/source/main.cpp
@@ -1,2684 +1,2684 @@
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-#include "date.h"
-#include "fileCopy.h"
-#include "nand/nandio.h"
-
-#include "graphics/graphics.h"
-
-#include "common/tonccpy.h"
-#include "common/nitrofs.h"
-#include "read_card.h"
-#include "flashcard.h"
-#include "ndsheaderbanner.h"
-#include "gbaswitch.h"
-#include "nds_loader_arm9.h"
-#include "perGameSettings.h"
-#include "errorScreen.h"
-
-#include "iconTitle.h"
-#include "graphics/fontHandler.h"
-
-#include "common/inifile.h"
-#include "common/dsimenusettings.h"
-#include "tool/stringtool.h"
-
-#include "language.h"
-
-#include "cheat.h"
-#include "crc.h"
-
-#include "soundbank.h"
-#include "soundbank_bin.h"
-
-#include "donorMap.h"
-#include "mpuMap.h"
-#include "speedBumpExcludeMap.h"
-#include "saveMap.h"
-
-#include "sr_data_srllastran.h" // For rebooting into the game
-
-#define gbamodeText "Start GBA game."
-#define featureUnavailableText "This feature is unavailable."
-
-bool useTwlCfg = false;
-
-bool whiteScreen = true;
-bool fadeType = false; // false = out, true = in
-bool fadeSpeed = true; // false = slow (for DSi launch effect), true = fast
-bool controlTopBright = true;
-bool controlBottomBright = true;
-bool widescreenEffects = false;
-int fps = 60;
-int colorMode = 0;
-int blfLevel = 0;
-
-bool cardEjected = false;
-static bool cardRefreshed = false;
-
-extern void ClearBrightness();
-extern int boxArtType[2];
-
-const char* settingsinipath = "sd:/_nds/TWiLightMenu/settings.ini";
-const char* bootstrapinipath = "sd:/_nds/nds-bootstrap.ini";
-
-std::string romPath[2];
-std::string dsiWareSrlPath;
-std::string dsiWarePubPath;
-std::string dsiWarePrvPath;
-
-const char *charUnlaunchBg;
-std::string unlaunchBg = "default.gif";
-bool removeLauncherPatches = true;
-
-const char *unlaunchAutoLoadID = "AutoLoadInfo";
-static char hiyaNdsPath[14] = {'s','d','m','c',':','/','h','i','y','a','.','d','s','i'};
-char unlaunchDevicePath[256];
-
-static char pictochatPath[256];
-static char dlplayPath[256];
-
-bool arm7SCFGLocked = false;
-int consoleModel = 0;
-/* 0 = Nintendo DSi (Retail)
- 1 = Nintendo DSi (Dev/Panda)
- 2 = Nintendo 3DS
- 3 = New Nintendo 3DS */
-bool isRegularDS = true;
-bool isDSLite = false;
-int flashcard = 0;
-
-extern bool showdialogbox;
-
-bool extention(const std::string& filename, const char* ext) {
- if(strcasecmp(filename.c_str() + filename.size() - strlen(ext), ext)) {
- return false;
- } else {
- return true;
- }
-}
-
-/**
- * Remove trailing slashes from a pathname, if present.
- * @param path Pathname to modify.
- */
-void RemoveTrailingSlashes(std::string& path)
-{
- while (!path.empty() && path[path.size()-1] == '/') {
- path.resize(path.size()-1);
- }
-}
-
-/**
- * Remove trailing spaces from a cheat code line, if present.
- * @param path Code line to modify.
- */
-/*static void RemoveTrailingSpaces(std::string& code)
-{
- while (!code.empty() && code[code.size()-1] == ' ') {
- code.resize(code.size()-1);
- }
-}*/
-
-std::string romfolder[2];
-
-// These are used by flashcard functions and must retain their trailing slash.
-static const std::string slashchar = "/";
-static const std::string woodfat = "fat0:/";
-static const std::string dstwofat = "fat1:/";
-
-int mpuregion = 0;
-int mpusize = 0;
-bool ceCached = true;
-
-bool applaunch = false;
-bool showCursor = true;
-bool startMenu = false;
-bool gotosettings = false;
-
-bool slot1Launched = false;
-int launchType[2] = {0}; // 0 = Slot-1, 1 = SD/Flash card, 2 = SD/Flash card (Direct boot), 3 = DSiWare, 4 = NES, 5 = (S)GB(C), 6 = SMS/GG
-int slot1LaunchMethod = 1; // 0 == Reboot, 1 == Direct, 2 == Unlaunch
-bool useBootstrap = true;
-bool bootstrapFile = false;
-bool homebrewBootstrap = false;
-bool homebrewHasWide = false;
-bool show12hrClock = true;
-//bool snesEmulator = true;
-bool smsGgInRam = false;
-bool fcSaveOnSd = false;
-bool wideScreen = false;
-
-bool pictochatFound = false;
-bool dlplayFound = false;
-bool pictochatReboot = false;
-bool dlplayReboot = false;
-bool sdRemoveDetect = true;
-bool useGbarunner = false;
-bool gbar2DldiAccess = false; // false == ARM9, true == ARM7
-int theme = 0;
-int subtheme = 0;
-int showMd = 3;
-int cursorPosition[2] = {0};
-int startMenu_cursorPosition = 0;
-int pagenum[2] = {0};
-bool showDirectories = true;
-int showBoxArt = 1 + isDSiMode();
-bool animateDsiIcons = false;
-int launcherApp = -1;
-int sysRegion = -1;
-
-int guiLanguage = -1;
-int gameLanguage = -1;
-int titleLanguage = -1;
-bool boostCpu = false; // false == NTR, true == TWL
-bool boostVram = false;
-int bstrap_dsiMode = 0;
-int bstrap_extendedMemory = 0;
-bool forceSleepPatch = false;
-bool dsiWareBooter = false;
-
-void LoadSettings(void) {
- useBootstrap = isDSiMode();
-
- // GUI
- CIniFile settingsini( settingsinipath );
-
- // UI settings.
- consoleModel = settingsini.GetInt("SRLOADER", "CONSOLE_MODEL", 0);
-
- showMd = settingsini.GetInt("SRLOADER", "SHOW_MDGEN", showMd);
-
- // Customizable UI settings.
- fps = settingsini.GetInt("SRLOADER", "FRAME_RATE", fps);
- colorMode = settingsini.GetInt("SRLOADER", "COLOR_MODE", 0);
- blfLevel = settingsini.GetInt("SRLOADER", "BLUE_LIGHT_FILTER_LEVEL", 0);
- guiLanguage = settingsini.GetInt("SRLOADER", "LANGUAGE", -1);
- titleLanguage = settingsini.GetInt("SRLOADER", "TITLELANGUAGE", titleLanguage);
- sdRemoveDetect = settingsini.GetInt("SRLOADER", "SD_REMOVE_DETECT", 1);
- useGbarunner = settingsini.GetInt("SRLOADER", "USE_GBARUNNER2", 0);
- if (!isRegularDS) useGbarunner = true;
- gbar2DldiAccess = settingsini.GetInt("SRLOADER", "GBAR2_DLDI_ACCESS", gbar2DldiAccess);
- theme = settingsini.GetInt("SRLOADER", "THEME", 0);
- subtheme = settingsini.GetInt("SRLOADER", "SUB_THEME", 0);
- showDirectories = settingsini.GetInt("SRLOADER", "SHOW_DIRECTORIES", 1);
- showBoxArt = settingsini.GetInt("SRLOADER", "SHOW_BOX_ART", showBoxArt);
- animateDsiIcons = settingsini.GetInt("SRLOADER", "ANIMATE_DSI_ICONS", 0);
- if (consoleModel < 2) {
- launcherApp = settingsini.GetInt("SRLOADER", "LAUNCHER_APP", launcherApp);
- }
-
- flashcard = settingsini.GetInt("SRLOADER", "FLASHCARD", flashcard);
-
- previousUsedDevice = settingsini.GetInt("SRLOADER", "PREVIOUS_USED_DEVICE", previousUsedDevice);
- secondaryDevice = bothSDandFlashcard() ? settingsini.GetInt("SRLOADER", "SECONDARY_DEVICE", secondaryDevice) : flashcardFound();
- fcSaveOnSd = settingsini.GetInt("SRLOADER", "FC_SAVE_ON_SD", fcSaveOnSd);
-
- slot1LaunchMethod = settingsini.GetInt("SRLOADER", "SLOT1_LAUNCHMETHOD", slot1LaunchMethod);
- useBootstrap = settingsini.GetInt("SRLOADER", "USE_BOOTSTRAP", useBootstrap);
- bootstrapFile = settingsini.GetInt("SRLOADER", "BOOTSTRAP_FILE", 0);
- //snesEmulator = settingsini.GetInt("SRLOADER", "SNES_EMULATOR", snesEmulator);
- smsGgInRam = settingsini.GetInt("SRLOADER", "SMS_GG_IN_RAM", smsGgInRam);
-
- show12hrClock = settingsini.GetInt("SRLOADER", "SHOW_12H_CLOCK", show12hrClock);
-
- unlaunchBg = settingsini.GetString("SRLOADER", "UNLAUNCH_BG", unlaunchBg);
- charUnlaunchBg = unlaunchBg.c_str();
- removeLauncherPatches = settingsini.GetInt("SRLOADER", "UNLAUNCH_PATCH_REMOVE", removeLauncherPatches);
-
- // Default nds-bootstrap settings
- gameLanguage = settingsini.GetInt("NDS-BOOTSTRAP", "LANGUAGE", -1);
- boostCpu = settingsini.GetInt("NDS-BOOTSTRAP", "BOOST_CPU", 0);
- boostVram = settingsini.GetInt("NDS-BOOTSTRAP", "BOOST_VRAM", 0);
- bstrap_dsiMode = settingsini.GetInt("NDS-BOOTSTRAP", "DSI_MODE", 0);
- bstrap_extendedMemory = settingsini.GetInt("NDS-BOOTSTRAP", "EXTENDED_MEMORY", 0);
-
- forceSleepPatch = settingsini.GetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH", 0);
- dsiWareBooter = settingsini.GetInt("SRLOADER", "DSIWARE_BOOTER", dsiWareBooter);
-
- dsiWareSrlPath = settingsini.GetString("SRLOADER", "DSIWARE_SRL", dsiWareSrlPath);
- dsiWarePubPath = settingsini.GetString("SRLOADER", "DSIWARE_PUB", dsiWarePubPath);
- dsiWarePrvPath = settingsini.GetString("SRLOADER", "DSIWARE_PRV", dsiWarePrvPath);
- launchType[0] = settingsini.GetInt("SRLOADER", "LAUNCH_TYPE", launchType[0]);
- launchType[1] = settingsini.GetInt("SRLOADER", "SECONDARY_LAUNCH_TYPE", launchType[1]);
- romPath[0] = settingsini.GetString("SRLOADER", "ROM_PATH", romPath[0]);
- romPath[1] = settingsini.GetString("SRLOADER", "SECONDARY_ROM_PATH", romPath[1]);
-
- wideScreen = settingsini.GetInt("SRLOADER", "WIDESCREEN", wideScreen);
-}
-
-void SaveSettings(void) {
- // GUI
- CIniFile settingsini( settingsinipath );
-
- // UI settings.
- if (!gotosettings) {
- settingsini.SetString("SRLOADER", "DSIWARE_SRL", dsiWareSrlPath);
- settingsini.SetString("SRLOADER", "DSIWARE_PUB", dsiWarePubPath);
- settingsini.SetString("SRLOADER", "DSIWARE_PRV", dsiWarePrvPath);
- settingsini.SetInt("SRLOADER", "SLOT1_LAUNCHED", slot1Launched);
- settingsini.SetInt("SRLOADER", "LAUNCH_TYPE", launchType[0]);
- settingsini.SetInt("SRLOADER", "SECONDARY_LAUNCH_TYPE", launchType[1]);
- settingsini.SetInt("SRLOADER", "HOMEBREW_BOOTSTRAP", homebrewBootstrap);
- settingsini.SetInt("SRLOADER", "HOMEBREW_HAS_WIDE", homebrewHasWide);
- }
- //settingsini.SetInt("SRLOADER", "THEME", theme);
- //settingsini.SetInt("SRLOADER", "SUB_THEME", subtheme);
- settingsini.SaveIniFile(settingsinipath);
-}
-
-bool isDSPhat(void) {
- return (isRegularDS && !isDSLite);
-}
-
-bool useBackend = false;
-
-using namespace std;
-
-bool showbubble = false;
-bool showSTARTborder = false;
-
-bool titleboxXmoveleft = false;
-bool titleboxXmoveright = false;
-
-bool applaunchprep = false;
-
-int spawnedtitleboxes = 0;
-
-//char usernameRendered[10];
-//bool usernameRenderedDone = false;
-
-touchPosition touch;
-
-//---------------------------------------------------------------------------------
-void stop (void) {
-//---------------------------------------------------------------------------------
- while (1) {
- swiWaitForVBlank();
- }
-}
-
-/**
- * Set donor SDK version for a specific game.
- */
-int SetDonorSDK(const char* filename) {
- FILE *f_nds_file = fopen(filename, "rb");
-
- char game_TID[5];
- grabTID(f_nds_file, game_TID);
- fclose(f_nds_file);
- game_TID[4] = 0;
- game_TID[3] = 0;
-
- for (auto i : donorMap) {
- if (i.first == 5 && game_TID[0] == 'V')
- return 5;
-
- if (i.second.find(game_TID) != i.second.cend())
- return i.first;
- }
-
- return 0;
-}
-
-/**
- * Set MPU settings for a specific game.
- */
-void SetMPUSettings(const char* filename) {
- FILE *f_nds_file = fopen(filename, "rb");
-
- char game_TID[5];
- fseek(f_nds_file, offsetof(sNDSHeaderExt, gameCode), SEEK_SET);
- fread(game_TID, 1, 4, f_nds_file);
- game_TID[4] = 0;
- game_TID[3] = 0;
- fclose(f_nds_file);
-
- scanKeys();
- int pressed = keysHeld();
-
- if (pressed & KEY_B) {
- mpuregion = 1;
- } else if (pressed & KEY_X) {
- mpuregion = 2;
- } else if (pressed & KEY_Y) {
- mpuregion = 3;
- } else {
- mpuregion = 0;
- }
-
- if(pressed & KEY_RIGHT) {
- mpusize = 3145728;
- } else if(pressed & KEY_LEFT) {
- mpusize = 1;
- } else {
- mpusize = 0;
- }
-
- // Check for games that need an MPU size of 3 MB.
- // TODO: If the list gets large enough, switch to bsearch().
- for (unsigned int i = 0; i < sizeof(mpu_3MB_list)/sizeof(mpu_3MB_list[0]); i++) {
- if (!memcmp(game_TID, mpu_3MB_list[i], 3)) {
- // Found a match.
- mpuregion = 1;
- mpusize = 3145728;
- break;
- }
- }
-}
-
-/**
- * Move nds-bootstrap's cardEngine_arm9 to cached memory region for some games.
- */
-void SetSpeedBumpExclude(const char* filename) {
- if (!isDSiMode() || (perGameSettings_heapShrink >= 0 && perGameSettings_heapShrink < 2)) {
- ceCached = perGameSettings_heapShrink;
- return;
- }
-
- FILE *f_nds_file = fopen(filename, "rb");
-
- char game_TID[5];
- fseek(f_nds_file, offsetof(sNDSHeaderExt, gameCode), SEEK_SET);
- fread(game_TID, 1, 4, f_nds_file);
- fclose(f_nds_file);
-
- // TODO: If the list gets large enough, switch to bsearch().
- for (unsigned int i = 0; i < sizeof(sbeList2)/sizeof(sbeList2[0]); i++) {
- if (memcmp(game_TID, sbeList2[i], 3) == 0) {
- // Found match
- ceCached = false;
- }
- }
-}
-
-/**
- * Fix AP for some games.
- */
-std::string setApFix(const char *filename) {
- remove("fat:/_nds/nds-bootstrap/apFix.ips");
-
- bool ipsFound = false;
- char ipsPath[256];
- snprintf(ipsPath, sizeof(ipsPath), "%s:/_nds/TWiLightMenu/apfix/%s.ips", sdFound() ? "sd" : "fat", filename);
- ipsFound = (access(ipsPath, F_OK) == 0);
-
- if (!ipsFound) {
- FILE *f_nds_file = fopen(filename, "rb");
-
- char game_TID[5];
- u16 headerCRC16 = 0;
- fseek(f_nds_file, offsetof(sNDSHeaderExt, gameCode), SEEK_SET);
- fread(game_TID, 1, 4, f_nds_file);
- fseek(f_nds_file, offsetof(sNDSHeaderExt, headerCRC16), SEEK_SET);
- fread(&headerCRC16, sizeof(u16), 1, f_nds_file);
- fclose(f_nds_file);
- game_TID[4] = 0;
-
- snprintf(ipsPath, sizeof(ipsPath), "%s:/_nds/TWiLightMenu/apfix/%s-%X.ips", sdFound() ? "sd" : "fat", game_TID, headerCRC16);
- ipsFound = (access(ipsPath, F_OK) == 0);
- }
-
- if (ipsFound) {
- if (secondaryDevice && sdFound()) {
- mkdir("fat:/_nds", 0777);
- mkdir("fat:/_nds/nds-bootstrap", 0777);
- fcopy(ipsPath, "fat:/_nds/nds-bootstrap/apFix.ips");
- return "fat:/_nds/nds-bootstrap/apFix.ips";
- }
- return ipsPath;
- }
-
- return "";
-}
-
-/**
- * Enable widescreen for some games.
- */
-void SetWidescreen(const char *filename) {
- remove("/_nds/nds-bootstrap/wideCheatData.bin");
-
- bool useWidescreen = (perGameSettings_wideScreen == -1 ? wideScreen : perGameSettings_wideScreen);
-
- if ((isDSiMode() && arm7SCFGLocked) || consoleModel < 2 || !useWidescreen
- || (access("sd:/luma/sysmodules/TwlBg.cxi", F_OK) != 0)) {
- homebrewHasWide = false;
- return;
- }
-
- bool wideCheatFound = false;
- char wideBinPath[256];
- if (launchType[secondaryDevice] == 1) {
- snprintf(wideBinPath, sizeof(wideBinPath), "sd:/_nds/TWiLightMenu/widescreen/%s.bin", filename);
- wideCheatFound = (access(wideBinPath, F_OK) == 0);
- }
-
- if (slot1Launched) {
- // Reset Slot-1 to allow reading card header
- sysSetCardOwner (BUS_OWNER_ARM9);
- disableSlot1();
- for(int i = 0; i < 25; i++) { swiWaitForVBlank(); }
- enableSlot1();
- for(int i = 0; i < 15; i++) { swiWaitForVBlank(); }
-
- cardReadHeader((uint8*)&ndsCardHeader);
-
- char game_TID[5];
- tonccpy(game_TID, ndsCardHeader.gameCode, 4);
- game_TID[4] = 0;
-
- snprintf(wideBinPath, sizeof(wideBinPath), "sd:/_nds/TWiLightMenu/widescreen/%s-%X.bin", game_TID, ndsCardHeader.headerCRC16);
- wideCheatFound = (access(wideBinPath, F_OK) == 0);
- } else if (!wideCheatFound) {
- FILE *f_nds_file = fopen(filename, "rb");
-
- char game_TID[5];
- u16 headerCRC16 = 0;
- fseek(f_nds_file, offsetof(sNDSHeaderExt, gameCode), SEEK_SET);
- fread(game_TID, 1, 4, f_nds_file);
- fseek(f_nds_file, offsetof(sNDSHeaderExt, headerCRC16), SEEK_SET);
- fread(&headerCRC16, sizeof(u16), 1, f_nds_file);
- fclose(f_nds_file);
- game_TID[4] = 0;
-
- snprintf(wideBinPath, sizeof(wideBinPath), "sd:/_nds/TWiLightMenu/widescreen/%s-%X.bin", game_TID, headerCRC16);
- wideCheatFound = (access(wideBinPath, F_OK) == 0);
- }
-
- if (isHomebrew[secondaryDevice]) {
- FILE *f_nds_file = fopen(filename, "rb");
-
- char game_TID[5];
- u8 romVersion = 0;
- fseek(f_nds_file, offsetof(sNDSHeaderExt, gameCode), SEEK_SET);
- fread(game_TID, 1, 4, f_nds_file);
- fseek(f_nds_file, offsetof(sNDSHeaderExt, romversion), SEEK_SET);
- fread(&romVersion, sizeof(u8), 1, f_nds_file);
- fclose(f_nds_file);
- game_TID[4] = 0;
-
- homebrewHasWide = (game_TID[0] == 'W' || romVersion == 0x57);
- return;
- }
-
- if (wideCheatFound) {
- const char* resultText1;
- const char* resultText2;
- mkdir("/_nds", 0777);
- mkdir("/_nds/nds-bootstrap", 0777);
- if (fcopy(wideBinPath, "/_nds/nds-bootstrap/wideCheatData.bin") == 0) {
- return;
- } else {
- resultText1 = "Failed to copy widescreen";
- resultText2 = "code for the game.";
- }
- remove("/_nds/nds-bootstrap/wideCheatData.bin");
- int textXpos[2] = {0};
- textXpos[0] = 72;
- textXpos[1] = 84;
- clearText();
- printSmallCentered(false, textXpos[0], resultText1);
- printSmallCentered(false, textXpos[1], resultText2);
- fadeType = true; // Fade in from white
- for (int i = 0; i < 60 * 3; i++) {
- swiWaitForVBlank(); // Wait 3 seconds
- }
- fadeType = false; // Fade to white
- for (int i = 0; i < 25; i++) {
- swiWaitForVBlank();
- }
- }
-}
-
-char filePath[PATH_MAX];
-
-//---------------------------------------------------------------------------------
-void doPause() {
-//---------------------------------------------------------------------------------
- // iprintf("Press start...\n");
- // printSmall(false, x, y, "Press start...");
- while(1) {
- scanKeys();
- if(keysDown() & KEY_START)
- break;
- swiWaitForVBlank();
- }
- scanKeys();
-}
-
-mm_sound_effect snd_launch;
-mm_sound_effect snd_select;
-mm_sound_effect snd_stop;
-mm_sound_effect snd_wrong;
-mm_sound_effect snd_back;
-mm_sound_effect snd_switch;
-mm_sound_effect snd_backlight;
-
-void InitSound() {
- mmInitDefaultMem((mm_addr)soundbank_bin);
-
- mmLoadEffect( SFX_LAUNCH );
- mmLoadEffect( SFX_SELECT );
- mmLoadEffect( SFX_STOP );
- mmLoadEffect( SFX_WRONG );
- mmLoadEffect( SFX_BACK );
- mmLoadEffect( SFX_SWITCH );
- mmLoadEffect( SFX_BACKLIGHT );
-
- snd_launch = {
- { SFX_LAUNCH } , // id
- (int)(1.0f * (1<<10)), // rate
- 0, // handle
- 255, // volume
- 128, // panning
- };
- snd_select = {
- { SFX_SELECT } , // id
- (int)(1.0f * (1<<10)), // rate
- 0, // handle
- 255, // volume
- 128, // panning
- };
- snd_stop = {
- { SFX_STOP } , // id
- (int)(1.0f * (1<<10)), // rate
- 0, // handle
- 255, // volume
- 128, // panning
- };
- snd_wrong = {
- { SFX_WRONG } , // id
- (int)(1.0f * (1<<10)), // rate
- 0, // handle
- 255, // volume
- 128, // panning
- };
- snd_back = {
- { SFX_BACK } , // id
- (int)(1.0f * (1<<10)), // rate
- 0, // handle
- 255, // volume
- 128, // panning
- };
- snd_switch = {
- { SFX_SWITCH } , // id
- (int)(1.0f * (1<<10)), // rate
- 0, // handle
- 255, // volume
- 128, // panning
- };
- snd_backlight = {
- { SFX_BACKLIGHT } , // id
- (int)(1.0f * (1<<10)), // rate
- 0, // handle
- 255, // volume
- 128, // panning
- };
-}
-
-void loadGameOnFlashcard (const char* ndsPath, bool dsGame) {
- bool runNds_boostCpu = false;
- bool runNds_boostVram = false;
- std::string filename = ndsPath;
- const size_t last_slash_idx = filename.find_last_of("/");
- if (std::string::npos != last_slash_idx) {
- filename.erase(0, last_slash_idx + 1);
- }
-
- loadPerGameSettings(filename);
-
- if ((REG_SCFG_EXT != 0) && dsGame) {
- runNds_boostCpu = perGameSettings_boostCpu == -1 ? boostCpu : perGameSettings_boostCpu;
- runNds_boostVram = perGameSettings_boostVram == -1 ? boostVram : perGameSettings_boostVram;
- }
- if (dsGame) {
- // Move .sav outside of "saves" folder for flashcard kernel usage
- const char *typeToReplace = ".nds";
- if (extention(filename, ".dsi")) {
- typeToReplace = ".dsi";
- } else if (extention(filename, ".ids")) {
- typeToReplace = ".ids";
- } else if (extention(filename, ".srl")) {
- typeToReplace = ".srl";
- } else if (extention(filename, ".app")) {
- typeToReplace = ".app";
- }
-
- std::string savename = replaceAll(filename, typeToReplace, getSavExtension());
- std::string savenameFc = replaceAll(filename, typeToReplace, ".sav");
- std::string romFolderNoSlash = romfolder[true];
- RemoveTrailingSlashes(romFolderNoSlash);
- std::string saveFolder = romFolderNoSlash + "/saves";
- mkdir(saveFolder.c_str(), 0777);
- std::string savepath = romFolderNoSlash + "/saves/" + savename;
- std::string savepathFc = romFolderNoSlash + "/" + savenameFc;
- rename(savepath.c_str(), savepathFc.c_str());
- }
-
- std::string fcPath;
- int err = 0;
-
- switch (flashcard) {
- case 1: {
- CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
- fcPath = replaceAll(ndsPath, "fat:/", slashchar);
- fcrompathini.SetString("YSMENU", "AUTO_BOOT", fcPath);
- fcrompathini.SaveIniFile("fat:/TTMenu/YSMenu.ini");
- err = runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- break;
- }
- case 6: // Blue card can run wood 1.62 so this should work?
- case 2: // And clones that can run wood (no N5)
- case 3: {
- CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
- fcPath = replaceAll(ndsPath, "fat:/", woodfat);
- fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
- fcrompathini.SaveIniFile("fat:/_wfwd/lastsave.ini");
- err = runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- break;
- }
- case 7: {
- CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
- fcPath = replaceAll(ndsPath, "fat:/", dstwofat);
- fcrompathini.SetString("Dir Info", "fullName", fcPath);
- fcrompathini.SaveIniFile("fat:/_dstwo/autoboot.ini");
- err = runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- break;
- }
- case 5: // ?
- case 4: {
- CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
- fcPath = replaceAll(ndsPath, "fat:/", woodfat);
- fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
- fcrompathini.SaveIniFile("fat:/_afwd/lastsave.ini");
- err = runNdsFile("fat:/Afwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
- break;
- }
- default: {
- err = 1337;
- return;
- }
- }
-
-
- char text[32];
- snprintf(text, sizeof(text), "Start failed. Error %i", err);
- ClearBrightness();
- printSmall(false, 4, 4, text);
- if (err == 0) {
- printSmall(false, 4, 20, "Flashcard may be unsupported.");
- printSmall(false, 4, 52, "Flashcard name:");
- printSmall(false, 4, 68, io_dldi_data->friendlyName);
- }
- stop();
-}
-
-void loadROMselect()
-{
- if (!isDSiMode()) {
- chdir("fat:/");
- } else if (sdFound()) {
- chdir("sd:/");
- }
- /*if (theme == 3)
- {
- runNdsFile("/_nds/TWiLightMenu/akmenu.srldr", 0, NULL, true, false, false, true, true);
- }
- else */if (theme == 2 || theme == 6)
- {
- runNdsFile("/_nds/TWiLightMenu/r4menu.srldr", 0, NULL, true, false, false, true, true);
- }
- else
- {
- runNdsFile("/_nds/TWiLightMenu/dsimenu.srldr", 0, NULL, true, false, false, true, true);
- }
-}
-
-void unlaunchRomBoot(const char* rom) {
- char unlaunchDevicePath[256] = {0};
- if (strncmp(rom, "cart:", 5) == 0) {
- sprintf(unlaunchDevicePath, "cart:");
- } else {
- sprintf(unlaunchDevicePath, "__%s", rom);
- unlaunchDevicePath[0] = 's';
- unlaunchDevicePath[1] = 'd';
- unlaunchDevicePath[2] = 'm';
- unlaunchDevicePath[3] = 'c';
- }
-
- tonccpy((u8*)0x02000800, unlaunchAutoLoadID, 12);
- *(u16*)(0x0200080C) = 0x3F0; // Unlaunch Length for CRC16 (fixed, must be 3F0h)
- *(u16*)(0x0200080E) = 0; // Unlaunch CRC16 (empty)
- *(u32*)(0x02000810) = 0; // Unlaunch Flags
- *(u32*)(0x02000810) |= BIT(0); // Load the title at 2000838h
- *(u32*)(0x02000810) |= BIT(1); // Use colors 2000814h
- *(u16*)(0x02000814) = 0x7FFF; // Unlaunch Upper screen BG color (0..7FFFh)
- *(u16*)(0x02000816) = 0x7FFF; // Unlaunch Lower screen BG color (0..7FFFh)
- toncset((u8*)0x02000818, 0, 0x20+0x208+0x1C0); // Unlaunch Reserved (zero)
- int i2 = 0;
- for (int i = 0; i < (int)sizeof(unlaunchDevicePath); i++) {
- *(u8*)(0x02000838+i2) = unlaunchDevicePath[i]; // Unlaunch Device:/Path/Filename.ext (16bit Unicode,end by 0000h)
- i2 += 2;
- }
- while (*(u16*)(0x0200080E) == 0) { // Keep running, so that CRC16 isn't 0
- *(u16*)(0x0200080E) = swiCRC16(0xFFFF, (void*)0x02000810, 0x3F0); // Unlaunch CRC16
- }
-
- DC_FlushAll(); // Make reboot not fail
- fifoSendValue32(FIFO_USER_02, 1); // Reboot into DSiWare title, booted via Unlaunch
- stop();
-}
-
-void unlaunchSetHiyaBoot(void) {
- tonccpy((u8*)0x02000800, unlaunchAutoLoadID, 12);
- *(u16*)(0x0200080C) = 0x3F0; // Unlaunch Length for CRC16 (fixed, must be 3F0h)
- *(u16*)(0x0200080E) = 0; // Unlaunch CRC16 (empty)
- *(u32*)(0x02000810) |= BIT(0); // Load the title at 2000838h
- *(u32*)(0x02000810) |= BIT(1); // Use colors 2000814h
- *(u16*)(0x02000814) = 0x7FFF; // Unlaunch Upper screen BG color (0..7FFFh)
- *(u16*)(0x02000816) = 0x7FFF; // Unlaunch Lower screen BG color (0..7FFFh)
- toncset((u8*)0x02000818, 0, 0x20+0x208+0x1C0); // Unlaunch Reserved (zero)
- int i2 = 0;
- for (int i = 0; i < 14; i++) {
- *(u8*)(0x02000838+i2) = hiyaNdsPath[i]; // Unlaunch Device:/Path/Filename.ext (16bit Unicode,end by 0000h)
- i2 += 2;
- }
- while (*(u16*)(0x0200080E) == 0) { // Keep running, so that CRC16 isn't 0
- *(u16*)(0x0200080E) = swiCRC16(0xFFFF, (void*)0x02000810, 0x3F0); // Unlaunch CRC16
- }
-}
-
-/**
- * Reboot into an SD game when in DS mode.
- */
-void ntrStartSdGame(void) {
- if (consoleModel == 0) {
- unlaunchRomBoot("sd:/_nds/TWiLightMenu/resetgame.srldr");
- } else {
- tonccpy((u32 *)0x02000300, sr_data_srllastran, 0x020);
- DC_FlushAll(); // Make reboot not fail
- fifoSendValue32(FIFO_USER_02, 1);
- stop();
- }
-}
-
-void dsCardLaunch() {
- *(u32*)(0x02000300) = 0x434E4C54; // Set "CNLT" warmboot flag
- *(u16*)(0x02000304) = 0x1801;
- *(u32*)(0x02000308) = 0x43415254; // "CART"
- *(u32*)(0x0200030C) = 0x00000000;
- *(u32*)(0x02000310) = 0x43415254; // "CART"
- *(u32*)(0x02000314) = 0x00000000;
- *(u32*)(0x02000318) = 0x00000013;
- *(u32*)(0x0200031C) = 0x00000000;
- while (*(u16*)(0x02000306) == 0) { // Keep running, so that CRC16 isn't 0
- *(u16*)(0x02000306) = swiCRC16(0xFFFF, (void*)0x02000308, 0x18);
- }
-
- unlaunchSetHiyaBoot();
-
- DC_FlushAll(); // Make reboot not fail
- fifoSendValue32(FIFO_USER_02, 1); // Reboot into DSiWare title, booted via Launcher
- stop();
-}
-
-void directCardLaunch() {
- /*if (memcmp(ndsCardHeader.gameCode, "ALXX", 4) == 0) {
- u16 alxxBannerCrc = 0;
- extern u32 arm9StartSig[4];
- cardRead(0x75600, &arm9StartSig, 0x10);
- cardRead(0x174602, &alxxBannerCrc, sizeof(u16));
- if ((arm9StartSig[0] == 0xE58D0008
- && arm9StartSig[1] == 0xE1500005
- && arm9StartSig[2] == 0xBAFFFFC5
- && arm9StartSig[3] == 0xE59D100C)
- || alxxBannerCrc != 0xBA52)
- {
- if (sdFound()) {
- chdir("sd:/");
- }
- int err = runNdsFile ("/_nds/TWiLightMenu/dstwoLaunch.srldr", 0, NULL, true, true, true, boostCpu, boostVram);
- char text[32];
- snprintf(text, sizeof(text), "Start failed. Error %i", err);
- ClearBrightness();
- printSmall(false, 4, 4, text);
- stop();
- }
- }*/
- SetWidescreen(NULL);
- if (sdFound()) {
- chdir("sd:/");
- }
- int err = runNdsFile ("/_nds/TWiLightMenu/slot1launch.srldr", 0, NULL, true, true, false, true, true);
- char text[32];
- snprintf(text, sizeof(text), "Start failed. Error %i", err);
- ClearBrightness();
- printSmall(false, 4, 4, text);
- stop();
-}
-
-void printLastPlayedText(int num) {
- printSmallCentered(false, 24, iconYpos[num]+BOX_PY+BOX_PY_spacing2, "Last-played game");
- printSmallCentered(false, 24, iconYpos[num]+BOX_PY+BOX_PY_spacing3, "will appear here.");
-}
-
-void refreshNdsCard() {
- if (cardRefreshed) return;
-
- if (arm7SCFGLocked && showBoxArt) {
- loadBoxArt("nitro:/graphics/boxart_unknown.png");
- } else if ((cardInit(true) == 0) && showBoxArt) {
- char game_TID[5] = {0};
- tonccpy(&game_TID, ndsCardHeader.gameCode, 4);
-
- char boxArtPath[256];
- sprintf (boxArtPath, (sdFound() ? "sd:/_nds/TWiLightMenu/boxart/%s.png" : "fat:/_nds/TWiLightMenu/boxart/%s.png"), game_TID);
- loadBoxArt(boxArtPath); // Load box art
- } else if (showBoxArt) {
- loadBoxArt("nitro:/graphics/boxart_unknown.png");
- }
-
- getGameInfo(1, false, "slot1");
- iconUpdate (1, false, "slot1");
- bnrRomType[1] = 0;
- boxArtType[1] = 0;
-
- // Power off after done retrieving info
- disableSlot1();
-
- cardRefreshed = true;
- cardEjected = false;
-}
-
-void printNdsCartBannerText() {
- if (cardEjected) {
- printSmallCentered(false, 24, iconYpos[0]+BOX_PY+BOX_PY_spacing2, "There is no Game Card");
- printSmallCentered(false, 24, iconYpos[0]+BOX_PY+BOX_PY_spacing3, "inserted.");
- } else if (arm7SCFGLocked) {
- printSmallCentered(false, 24, iconYpos[0]+BOX_PY+BOX_PY_spacing1, "Start Game Card");
- } else {
- titleUpdate(1, false, "slot1");
- }
-}
-
-void printGbaBannerText() {
- printSmallCentered(false, 24, iconYpos[3]+BOX_PY+BOX_PY_spacing1, isRegularDS ? gbamodeText : featureUnavailableText);
-}
-
-//---------------------------------------------------------------------------------
-int main(int argc, char **argv) {
-//---------------------------------------------------------------------------------
-
- defaultExceptionHandler();
-
- useTwlCfg = (REG_SCFG_EXT!=0 && (*(u8*)0x02000400 & 0x0F) && (*(u8*)0x02000401 == 0) && (*(u8*)0x02000402 == 0) && (*(u8*)0x02000404 == 0) && (*(u8*)0x02000448 != 0));
-
- extern const DISC_INTERFACE __my_io_dsisd;
-
- *(u32*)(0x2FFFD0C) = 0x54494D52; // Run reboot timer
- fatMountSimple("sd", &__my_io_dsisd);
- fatMountSimple("fat", dldiGetInternal());
- bool fatInited = (sdFound() || flashcardFound());
- *(u32*)(0x2FFFD0C) = 0;
- chdir(sdFound()&&isDSiMode() ? "sd:/" : "fat:/");
-
- // Read user name
- /*char *username = (char*)PersonalData->name;
-
- // text
- for (int i = 0; i < 10; i++) {
- if (username[i*2] == 0x00)
- username[i*2/2] = 0;
- else
- username[i*2/2] = username[i*2];
- }*/
-
- if (!fatInited) {
- graphicsInit();
- fontInit();
- whiteScreen = true;
- printSmall(false, 64, 32, "fatinitDefault failed!");
- fadeType = true;
- stop();
- }
-
- nitroFSInit("/_nds/TWiLightMenu/mainmenu.srldr");
-
- if (access(settingsinipath, F_OK) != 0 && flashcardFound()) {
- settingsinipath = "fat:/_nds/TWiLightMenu/settings.ini"; // Fallback to .ini path on flashcard, if not found on SD card, or if SD access is disabled
- }
-
- langInit();
-
- std::string filename[2];
-
- fifoWaitValue32(FIFO_USER_06);
- if (fifoGetValue32(FIFO_USER_03) == 0) arm7SCFGLocked = true; // If TWiLight Menu++ is being run from DSiWarehax or flashcard, then arm7 SCFG is locked.
- u16 arm7_SNDEXCNT = fifoGetValue32(FIFO_USER_07);
- if (arm7_SNDEXCNT != 0) isRegularDS = false; // If sound frequency setting is found, then the console is not a DS Phat/Lite
- isDSLite = fifoGetValue32(FIFO_USER_04);
- fifoSendValue32(FIFO_USER_07, 0);
-
- LoadSettings();
- widescreenEffects = (consoleModel >= 2 && wideScreen && access("sd:/luma/sysmodules/TwlBg.cxi", F_OK) == 0);
-
- snprintf(pictochatPath, sizeof(pictochatPath), "/_nds/pictochat.nds");
- pictochatFound = (access(pictochatPath, F_OK) == 0);
-
- if (isDSiMode() && arm7SCFGLocked) {
- if (consoleModel < 2 && !pictochatFound) {
- pictochatFound = true;
- pictochatReboot = true;
- }
- dlplayFound = true;
- dlplayReboot = true;
- } else {
- bool nandInited = false;
- char srcPath[256];
- u8 regions[3] = {0x41, 0x43, 0x4B};
-
- if (!pictochatFound && consoleModel == 0) {
- for (int i = 0; i < 3; i++)
- {
- snprintf(pictochatPath, sizeof(pictochatPath), "/title/00030005/484e45%x/content/00000000.app", regions[i]);
- if (access(pictochatPath, F_OK) == 0)
- {
- pictochatFound = true;
- break;
- }
- }
- }
- if (!pictochatFound && isDSiMode() && sdFound() && consoleModel == 0) {
- if (!nandInited) {
- fatMountSimple("nand", &io_dsi_nand);
- nandInited = true;
- }
- if (access("nand:/", F_OK) == 0) {
- for (int i = 0; i < 3; i++)
- {
- snprintf(srcPath, sizeof(srcPath), "nand:/title/00030005/484e45%x/content/00000000.app", regions[i]);
- if (access(srcPath, F_OK) == 0)
- {
- snprintf(pictochatPath, sizeof(pictochatPath), "/_nds/pictochat.nds");
- remove(pictochatPath);
- fcopy(srcPath, pictochatPath); // Copy from NAND
- pictochatFound = true;
- break;
- }
- }
- }
- }
-
- snprintf(dlplayPath, sizeof(dlplayPath), "/_nds/dlplay.nds");
- dlplayFound = (access(dlplayPath, F_OK) == 0);
- if (!dlplayFound && consoleModel == 0) {
- for (int i = 0; i < 3; i++)
- {
- snprintf(dlplayPath, sizeof(dlplayPath), "/title/00030005/484e44%x/content/00000000.app", regions[i]);
- if (access(dlplayPath, F_OK) == 0) {
- dlplayFound = true;
- break;
- } else if (regions[i] != 0x43 && regions[i] != 0x4B) {
- snprintf(dlplayPath, sizeof(dlplayPath), "/title/00030005/484e4441/content/00000001.app");
- if (access(dlplayPath, F_OK) == 0) {
- dlplayFound = true;
- break;
- }
- }
- }
- }
- if (!dlplayFound && isDSiMode() && sdFound() && consoleModel == 0) {
- if (!nandInited) {
- fatMountSimple("nand", &io_dsi_nand);
- nandInited = true;
- }
- if (access("nand:/", F_OK) == 0) {
- for (int i = 0; i < 3; i++)
- {
- snprintf(srcPath, sizeof(srcPath), "nand:/title/00030005/484e44%x/content/00000000.app", regions[i]);
- if (access(srcPath, F_OK) == 0) {
- snprintf(dlplayPath, sizeof(dlplayPath), "/_nds/dlplay.nds");
- remove(dlplayPath);
- fcopy(srcPath, dlplayPath); // Copy from NAND
- dlplayFound = true;
- break;
- } else if (regions[i] != 0x43 && regions[i] != 0x4B) {
- snprintf(srcPath, sizeof(srcPath), "nand:/title/00030005/484e4441/content/00000001.app");
- if (access(srcPath, F_OK) == 0) {
- snprintf(dlplayPath, sizeof(dlplayPath), "/_nds/dlplay.nds");
- remove(dlplayPath);
- fcopy(srcPath, dlplayPath); // Copy from NAND
- dlplayFound = true;
- break;
- }
- }
- }
- }
- }
- if (!dlplayFound && consoleModel >= 2) {
- dlplayFound = true;
- dlplayReboot = true;
- }
- }
-
- if (isDSiMode() && sdFound() && consoleModel < 2 && launcherApp != -1) {
- u8 setRegion = 0;
- if (sysRegion == -1) {
- // Determine SysNAND region by searching region of System Settings on SDNAND
- char tmdpath[256];
- for (u8 i = 0x41; i <= 0x5A; i++)
- {
- snprintf(tmdpath, sizeof(tmdpath), "sd:/title/00030015/484e42%x/content/title.tmd", i);
- if (access(tmdpath, F_OK) == 0)
- {
- setRegion = i;
- break;
- }
- }
- } else {
- switch(sysRegion) {
- case 0:
- default:
- setRegion = 0x4A; // JAP
- break;
- case 1:
- setRegion = 0x45; // USA
- break;
- case 2:
- setRegion = 0x50; // EUR
- break;
- case 3:
- setRegion = 0x55; // AUS
- break;
- case 4:
- setRegion = 0x43; // CHN
- break;
- case 5:
- setRegion = 0x4B; // KOR
- break;
- }
- }
-
- snprintf(unlaunchDevicePath, sizeof(unlaunchDevicePath), "nand:/title/00030017/484E41%x/content/0000000%i.app", setRegion, launcherApp);
- }
-
- graphicsInit();
- fontInit();
-
- iconTitleInit();
-
- InitSound();
-
- keysSetRepeat(25,5);
-
- srand(time(NULL));
-
- bool menuButtonPressed = false;
-
- if (flashcardFound()) {
- // Move .sav back to "saves" folder
- std::string filename = romPath[true];
- const size_t last_slash_idx = filename.find_last_of("/");
- if (std::string::npos != last_slash_idx) {
- filename.erase(0, last_slash_idx + 1);
- }
-
- loadPerGameSettings(filename);
-
- const char *typeToReplace = ".nds";
- if (extention(filename, ".dsi")) {
- typeToReplace = ".dsi";
- } else if (extention(filename, ".ids")) {
- typeToReplace = ".ids";
- } else if (extention(filename, ".srl")) {
- typeToReplace = ".srl";
- } else if (extention(filename, ".app")) {
- typeToReplace = ".app";
- }
-
- std::string savename = replaceAll(filename, typeToReplace, getSavExtension());
- std::string savenameFc = replaceAll(filename, typeToReplace, ".sav");
- std::string romFolderNoSlash = romfolder[true];
- RemoveTrailingSlashes(romFolderNoSlash);
- std::string savepath = romFolderNoSlash + "/saves/" + savename;
- std::string savepathFc = romFolderNoSlash + "/" + savenameFc;
- if (access(savepathFc.c_str(), F_OK) == 0) {
- rename(savepathFc.c_str(), savepath.c_str());
- }
- }
-
- if (consoleModel < 2
- && previousUsedDevice
- && bothSDandFlashcard()
- && launchType[previousUsedDevice] == 3
- && !dsiWareBooter
- && (
- (access(dsiWarePubPath.c_str(), F_OK) == 0 && extention(dsiWarePubPath.c_str(), ".pub"))
- || (access(dsiWarePrvPath.c_str(), F_OK) == 0 && extention(dsiWarePrvPath.c_str(), ".prv"))
- )
- ) {
- controlTopBright = false;
- whiteScreen = true;
- fadeType = true; // Fade in from white
- printSmallCentered(false, 24, "If this takes a while, close and open");
- printSmallCentered(false, 38, "the console's lid.");
- printSmallCentered(false, 86, "Now copying data...");
- printSmallCentered(false, 100, "Do not turn off the power.");
- for (int i = 0; i < 30; i++) swiWaitForVBlank();
- if (access(dsiWarePubPath.c_str(), F_OK) == 0) {
- fcopy("sd:/_nds/TWiLightMenu/tempDSiWare.pub", dsiWarePubPath.c_str());
- }
- if (access(dsiWarePrvPath.c_str(), F_OK) == 0) {
- fcopy("sd:/_nds/TWiLightMenu/tempDSiWare.prv", dsiWarePrvPath.c_str());
- }
- fadeType = false; // Fade to white
- for (int i = 0; i < 30; i++) swiWaitForVBlank();
- clearText(false);
- whiteScreen = false;
- controlTopBright = true;
- }
-
- topBgLoad();
- bottomBgLoad();
-
- bool romFound[2] = {false};
-
- // SD card
- if (sdFound() && romPath[0] != "" && access(romPath[0].c_str(), F_OK) == 0) {
- romFound[0] = true;
-
- romfolder[0] = romPath[0];
- while (!romfolder[0].empty() && romfolder[0][romfolder[0].size()-1] != '/') {
- romfolder[0].resize(romfolder[0].size()-1);
- }
- chdir(romfolder[0].c_str());
-
- filename[0] = romPath[0];
- const size_t last_slash_idx = filename[0].find_last_of("/");
- if (std::string::npos != last_slash_idx)
- {
- filename[0].erase(0, last_slash_idx + 1);
- }
-
- if (extention(filename[0], ".nds") || extention(filename[0], ".dsi") || extention(filename[0], ".ids") || extention(filename[0], ".app") || extention(filename[0], ".srl") || extention(filename[0], ".argv")) {
- getGameInfo(0, false, filename[0].c_str());
- iconUpdate (0, false, filename[0].c_str());
- bnrRomType[0] = 0;
- boxArtType[0] = 0;
- } else if (extention(filename[0], ".plg") || extention(filename[0], ".rvid") || extention(filename[0], ".mp4") || extention(filename[0], ".a26") || extention(filename[0], ".pce")) {
- bnrRomType[0] = 9;
- boxArtType[0] = 0;
- } else if (extention(filename[0], ".gba")) {
- bnrRomType[0] = 1;
- boxArtType[0] = 1;
- } else if (extention(filename[0], ".gb") || extention(filename[0], ".sgb")) {
- bnrRomType[0] = 2;
- boxArtType[0] = 1;
- } else if (extention(filename[0], ".gbc")) {
- bnrRomType[0] = 3;
- boxArtType[0] = 1;
- } else if (extention(filename[0], ".nes")) {
- bnrRomType[0] = 4;
- boxArtType[0] = 2;
- } else if (extention(filename[0], ".fds")) {
- bnrRomType[0] = 4;
- boxArtType[0] = 1;
- } else if (extention(filename[0], ".sms")) {
- bnrRomType[0] = 5;
- boxArtType[0] = 2;
- } else if (extention(filename[0], ".gg")) {
- bnrRomType[0] = 6;
- boxArtType[0] = 2;
- } else if (extention(filename[0], ".gen")) {
- bnrRomType[0] = 7;
- boxArtType[0] = 2;
- } else if (extention(filename[0], ".smc")) {
- bnrRomType[0] = 8;
- boxArtType[0] = 3;
- } else if (extention(filename[0], ".sfc")) {
- bnrRomType[0] = 8;
- boxArtType[0] = 2;
- }
- }
-
- // Flashcard (Secondary device)
- if (flashcardFound() && romPath[1] != "" && access(romPath[1].c_str(), F_OK) == 0) {
- romFound[1] = true;
-
- romfolder[1] = romPath[1];
- while (!romfolder[1].empty() && romfolder[1][romfolder[1].size()-1] != '/') {
- romfolder[1].resize(romfolder[1].size()-1);
- }
- chdir(romfolder[1].c_str());
-
- filename[1] = romPath[1];
- const size_t last_slash_idx = filename[1].find_last_of("/");
- if (std::string::npos != last_slash_idx)
- {
- filename[1].erase(0, last_slash_idx + 1);
- }
-
- if (extention(filename[1], ".nds") || extention(filename[1], ".dsi") || extention(filename[1], ".ids") || extention(filename[1], ".app") || extention(filename[1], ".srl") || extention(filename[1], ".argv")) {
- getGameInfo(1, false, filename[1].c_str());
- iconUpdate (1, false, filename[1].c_str());
- bnrRomType[1] = 0;
- boxArtType[1] = 0;
- } else if (extention(filename[1], ".plg") || extention(filename[1], ".rvid") || extention(filename[1], ".mp4") || extention(filename[1], ".a26")) {
- bnrRomType[1] = 9;
- boxArtType[1] = 0;
- } else if (extention(filename[1], ".gba")) {
- bnrRomType[1] = 1;
- boxArtType[1] = 1;
- } else if (extention(filename[1], ".gb") || extention(filename[1], ".sgb")) {
- bnrRomType[1] = 2;
- boxArtType[1] = 1;
- } else if (extention(filename[1], ".gbc")) {
- bnrRomType[1] = 3;
- boxArtType[1] = 1;
- } else if (extention(filename[1], ".nes")) {
- bnrRomType[1] = 4;
- boxArtType[1] = 2;
- } else if (extention(filename[1], ".fds")) {
- bnrRomType[1] = 4;
- boxArtType[1] = 1;
- } else if (extention(filename[1], ".sms")) {
- bnrRomType[1] = 5;
- boxArtType[1] = 2;
- } else if (extention(filename[1], ".gg")) {
- bnrRomType[1] = 6;
- boxArtType[1] = 2;
- } else if (extention(filename[1], ".gen")) {
- bnrRomType[1] = 7;
- boxArtType[1] = 2;
- } else if (extention(filename[1], ".smc")) {
- bnrRomType[1] = 8;
- boxArtType[1] = 3;
- } else if (extention(filename[1], ".sfc")) {
- bnrRomType[1] = 8;
- boxArtType[1] = 2;
- }
-
- if (showBoxArt) {
- // Store box art path
- std::string temp_filename = filename[secondaryDevice];
- char boxArtPath[256];
- snprintf (boxArtPath, sizeof(boxArtPath), (sdFound() ? "sd:/_nds/TWiLightMenu/boxart/%s.png" : "fat:/_nds/TWiLightMenu/boxart/%s.png"), filename[0].c_str());
- if ((access(boxArtPath, F_OK) != 0) && (bnrRomType[secondaryDevice] == 0)) {
- if(extention(filename[0], ".argv")) {
- vector argarray;
-
- FILE *argfile = fopen(filename[0].c_str(),"rb");
- char str[PATH_MAX], *pstr;
- const char seps[]= "\n\r\t ";
-
- while( fgets(str, PATH_MAX, argfile) ) {
- // Find comment and end string there
- if( (pstr = strchr(str, '#')) )
- *pstr= '\0';
-
- // Tokenize arguments
- pstr= strtok(str, seps);
-
- while( pstr != NULL ) {
- argarray.push_back(strdup(pstr));
- pstr= strtok(NULL, seps);
- }
- }
- fclose(argfile);
- temp_filename = argarray.at(0);
- }
- // Get game's TID
- FILE *f_nds_file = fopen(temp_filename.c_str(), "rb");
- char game_TID[5];
- grabTID(f_nds_file, game_TID);
- game_TID[4] = 0;
- fclose(f_nds_file);
-
- sprintf (boxArtPath, (sdFound() ? "sd:/_nds/TWiLightMenu/boxart/%s.png" : "fat:/_nds/TWiLightMenu/boxart/%s.png"), game_TID);
- }
- loadBoxArt(boxArtPath); // Load box art
- }
- }
-
- if (isDSiMode() && !flashcardFound()) {
- if (REG_SCFG_MC == 0x11) {
- if (showBoxArt) loadBoxArt("nitro:/graphics/boxart_unknown.png");
- cardEjected = true;
- } else {
- refreshNdsCard();
- }
- }
-
- whiteScreen = false;
- fadeType = true; // Fade in from white
- for (int i = 0; i < 30; i++) {
- swiWaitForVBlank();
- }
- topBarLoad();
- startMenu = true; // Show bottom screen graphics
- fadeSpeed = false;
-
- while(1) {
-
- if (startMenu) {
- int pressed = 0;
-
- do {
- clearText();
- printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
- printSmallCentered(false, 112, 6, RetTime().c_str());
- if (flashcardFound()) {
- if (romFound[1]) {
- titleUpdate(1, false, filename[1].c_str());
- } else {
- printLastPlayedText(0);
- }
- } else if (isDSiMode() && !flashcardFound()) {
- printNdsCartBannerText();
- }
- if (!sdFound()) {
- printGbaBannerText();
- } else if (romFound[0]) {
- titleUpdate(0, false, filename[0].c_str());
- } else {
- printLastPlayedText(3);
- }
-
- if (isDSiMode() && !flashcardFound()) {
- if (REG_SCFG_MC == 0x11) {
- if (cardRefreshed && showBoxArt) {
- loadBoxArt("nitro:/graphics/boxart_unknown.png");
- }
- cardRefreshed = false;
- cardEjected = true;
- } else if (cardEjected) {
- refreshNdsCard();
- }
- }
-
- scanKeys();
- pressed = keysDownRepeat();
- touchRead(&touch);
- checkSdEject();
- swiWaitForVBlank();
- } while (!pressed);
-
- if (pressed & KEY_UP) {
- if (startMenu_cursorPosition == 2 || startMenu_cursorPosition == 3 || startMenu_cursorPosition == 5) {
- startMenu_cursorPosition -= 2;
- mmEffectEx(&snd_select);
- } else if (startMenu_cursorPosition == 6) {
- startMenu_cursorPosition -= 3;
- mmEffectEx(&snd_select);
- } else {
- startMenu_cursorPosition--;
- mmEffectEx(&snd_select);
- }
- }
-
- if (pressed & KEY_DOWN) {
- if (startMenu_cursorPosition == 1 || startMenu_cursorPosition == 3) {
- startMenu_cursorPosition += 2;
- mmEffectEx(&snd_select);
- } else if (startMenu_cursorPosition >= 0 && startMenu_cursorPosition <= 3) {
- startMenu_cursorPosition++;
- mmEffectEx(&snd_select);
- }
- }
-
- if (pressed & KEY_LEFT) {
- if (startMenu_cursorPosition == 2 || (startMenu_cursorPosition == 5 && isDSiMode() && consoleModel < 2)
- || startMenu_cursorPosition == 6) {
- startMenu_cursorPosition--;
- mmEffectEx(&snd_select);
- }
- }
-
- if (pressed & KEY_RIGHT) {
- if (startMenu_cursorPosition == 1 || startMenu_cursorPosition == 4 || startMenu_cursorPosition == 5) {
- startMenu_cursorPosition++;
- mmEffectEx(&snd_select);
- }
- }
-
- if (pressed & KEY_TOUCH) {
- if (touch.px >= 33 && touch.px <= 221 && touch.py >= 25 && touch.py <= 69) {
- startMenu_cursorPosition = 0;
- menuButtonPressed = true;
- } else if (touch.px >= 33 && touch.px <= 125 && touch.py >= 73 && touch.py <= 117) {
- startMenu_cursorPosition = 1;
- menuButtonPressed = true;
- } else if (touch.px >= 129 && touch.px <= 221 && touch.py >= 73 && touch.py <= 117) {
- startMenu_cursorPosition = 2;
- menuButtonPressed = true;
- } else if (touch.px >= 33 && touch.px <= 221 && touch.py >= 121 && touch.py <= 165) {
- startMenu_cursorPosition = 3;
- menuButtonPressed = true;
- } else if (touch.px >= 10 && touch.px <= 20 && touch.py >= 175 && touch.py <= 185
- && isDSiMode() && consoleModel < 2)
- {
- startMenu_cursorPosition = 4;
- menuButtonPressed = true;
- } else if (touch.px >= 117 && touch.px <= 137 && touch.py >= 170 && touch.py <= 190) {
- startMenu_cursorPosition = 5;
- menuButtonPressed = true;
- } else if (touch.px >= 235 && touch.px <= 244 && touch.py >= 175 && touch.py <= 185) {
- startMenu_cursorPosition = 6;
- menuButtonPressed = true;
- }
- }
-
- if (pressed & KEY_A) {
- menuButtonPressed = true;
- }
-
- if (startMenu_cursorPosition < 0) startMenu_cursorPosition = 0;
- if (startMenu_cursorPosition > 6) startMenu_cursorPosition = 6;
-
- if (menuButtonPressed) {
- switch (startMenu_cursorPosition) {
- case -1:
- default:
- break;
- case 0:
- if (flashcardFound()) {
- // Launch last-run ROM (Secondary)
- if (launchType[1] == 0) {
- showCursor = false;
- fadeType = false; // Fade to white
- mmEffectEx(&snd_launch);
- for (int i = 0; i < 50; i++) {
- iconYpos[0] -= 6;
- clearText();
- printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
- printSmallCentered(false, 112, 6, RetTime().c_str());
- if (romFound[1]) {
- titleUpdate(1, false, filename[1].c_str());
- } else {
- printLastPlayedText(0);
- }
- if (!sdFound()) {
- printGbaBannerText();
- } else if (romFound[0]) {
- titleUpdate(0, false, filename[0].c_str());
- } else {
- printLastPlayedText(3);
- }
- swiWaitForVBlank();
- }
- loadROMselect();
- } else if (launchType[1] > 0) {
- showCursor = false;
- fadeType = false; // Fade to white
- mmEffectEx(&snd_launch);
- for (int i = 0; i < 50; i++) {
- iconYpos[0] -= 6;
- clearText();
- printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
- printSmallCentered(false, 112, 6, RetTime().c_str());
- if (romFound[1]) {
- titleUpdate(1, false, filename[1].c_str());
- } else {
- printLastPlayedText(0);
- }
- if (!sdFound()) {
- printGbaBannerText();
- } else if (romFound[0]) {
- titleUpdate(0, false, filename[0].c_str());
- } else {
- printLastPlayedText(3);
- }
- swiWaitForVBlank();
- }
- if (romFound[1]) {
- applaunch = true;
- } else {
- loadROMselect();
- }
- }
- secondaryDevice = true;
- } else if (!flashcardFound() && REG_SCFG_MC != 0x11) {
- // Launch Slot-1
- showCursor = false;
- fadeType = false; // Fade to white
- mmEffectEx(&snd_launch);
- for (int i = 0; i < 50; i++) {
- iconYpos[0] -= 6;
- clearText();
- printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
- printSmallCentered(false, 112, 6, RetTime().c_str());
- printNdsCartBannerText();
- if (romFound[0]) {
- titleUpdate(0, false, filename[0].c_str());
- } else {
- printLastPlayedText(3);
- }
- swiWaitForVBlank();
- }
- slot1Launched = true;
- SaveSettings();
-
- if (slot1LaunchMethod == 0 || arm7SCFGLocked) {
- dsCardLaunch();
- } else if (slot1LaunchMethod == 2) {
- unlaunchRomBoot("cart:");
- } else {
- directCardLaunch();
- }
- } else {
- mmEffectEx(&snd_wrong);
- }
- break;
- case 1:
- if (pictochatFound) {
- showCursor = false;
- fadeType = false; // Fade to white
- mmEffectEx(&snd_launch);
- for (int i = 0; i < 50; i++) {
- iconYpos[1] -= 6;
- clearText();
- printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
- printSmallCentered(false, 112, 6, RetTime().c_str());
- if (!sdFound()) {
- printGbaBannerText();
- } else if (romFound[0]) {
- titleUpdate(0, false, filename[0].c_str());
- } else {
- printLastPlayedText(3);
- }
- swiWaitForVBlank();
- }
-
- // Clear screen with white
- whiteScreen = true;
- controlTopBright = false;
- clearText();
-
- if (pictochatReboot) {
- *(u32 *)(0x02000300) = 0x434E4C54; // Set "CNLT" warmboot flag
- *(u16 *)(0x02000304) = 0x1801;
-
- switch (sysRegion) {
- case 4:
- *(u32 *)(0x02000308) = 0x484E4543;
- *(u32 *)(0x0200030C) = 0x00030005;
- *(u32 *)(0x02000310) = 0x484E4543;
- break;
- case 5:
- *(u32 *)(0x02000308) = 0x484E454B;
- *(u32 *)(0x0200030C) = 0x00030005;
- *(u32 *)(0x02000310) = 0x484E454B;
- break;
- default:
- *(u32 *)(0x02000308) = 0x484E4541; // "HNEA"
- *(u32 *)(0x0200030C) = 0x00030005;
- *(u32 *)(0x02000310) = 0x484E4541; // "HNEA"
- }
-
- *(u32 *)(0x02000314) = 0x00030005;
- *(u32 *)(0x02000318) = 0x00000017;
- *(u32 *)(0x0200031C) = 0x00000000;
- while (*(u16 *)(0x02000306) == 0x0000)
- { // Keep running, so that CRC16 isn't 0
- *(u16 *)(0x02000306) = swiCRC16(0xFFFF, (void *)0x02000308, 0x18);
- }
-
- if (consoleModel < 2) {
- unlaunchSetHiyaBoot();
- }
-
- fifoSendValue32(FIFO_USER_02, 1); // Reboot into DSiWare title, booted via Launcher
- for (int i = 0; i < 15; i++) swiWaitForVBlank();
- } else {
- if (sdFound()) {
- chdir("sd:/");
- }
- int err = runNdsFile (pictochatPath, 0, NULL, true, true, true, false, false);
- char text[32];
- snprintf (text, sizeof(text), "Start failed. Error %i", err);
- clearText();
- ClearBrightness();
- printSmall(false, 4, 80, text);
- stop();
- }
- } else {
- mmEffectEx(&snd_wrong);
- }
- break;
- case 2:
- if (dlplayFound) {
- showCursor = false;
- fadeType = false; // Fade to white
- mmEffectEx(&snd_launch);
- for (int i = 0; i < 50; i++) {
- iconYpos[2] -= 6;
- clearText();
- printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
- printSmallCentered(false, 112, 6, RetTime().c_str());
- if (!sdFound()) {
- printGbaBannerText();
- } else if (romFound[0]) {
- titleUpdate(0, false, filename[0].c_str());
- } else {
- printLastPlayedText(3);
- }
- swiWaitForVBlank();
- }
-
- // Clear screen with white
- whiteScreen = true;
- controlTopBright = false;
- clearText();
-
- if (dlplayReboot) {
- *(u32 *)(0x02000300) = 0x434E4C54; // Set "CNLT" warmboot flag
- *(u16 *)(0x02000304) = 0x1801;
-
- switch (sysRegion) {
- case 4:
- *(u32 *)(0x02000308) = 0x484E4443;
- *(u32 *)(0x0200030C) = 0x00030005;
- *(u32 *)(0x02000310) = 0x484E4443;
- break;
- case 5:
- *(u32 *)(0x02000308) = 0x484E444B;
- *(u32 *)(0x0200030C) = 0x00030005;
- *(u32 *)(0x02000310) = 0x484E444B;
- break;
- default:
- *(u32 *)(0x02000308) = 0x484E4441; // "HNDA"
- *(u32 *)(0x0200030C) = 0x00030005;
- *(u32 *)(0x02000310) = 0x484E4441; // "HNDA"
- }
-
- *(u32 *)(0x02000314) = 0x00030005;
- *(u32 *)(0x02000318) = 0x00000017;
- *(u32 *)(0x0200031C) = 0x00000000;
- while (*(u16 *)(0x02000306) == 0x0000)
- { // Keep running, so that CRC16 isn't 0
- *(u16 *)(0x02000306) = swiCRC16(0xFFFF, (void *)0x02000308, 0x18);
- }
-
- if (consoleModel < 2) {
- unlaunchSetHiyaBoot();
- }
-
- fifoSendValue32(FIFO_USER_02, 1); // Reboot into DSiWare title, booted via Launcher
- for (int i = 0; i < 15; i++) swiWaitForVBlank();
- } else {
- if (sdFound()) {
- chdir("sd:/");
- }
- int err = runNdsFile (dlplayPath, 0, NULL, true, true, true, false, false);
- char text[32];
- snprintf (text, sizeof(text), "Start failed. Error %i", err);
- clearText();
- ClearBrightness();
- printSmall(false, 4, 80, text);
- stop();
- }
- } else {
- mmEffectEx(&snd_wrong);
- }
- break;
- case 3:
- if (sdFound()) {
- // Launch last-run ROM (SD)
- if (launchType[0] == 0) {
- showCursor = false;
- fadeType = false; // Fade to white
- mmEffectEx(&snd_launch);
- for (int i = 0; i < 50; i++) {
- iconYpos[3] -= 6;
- clearText();
- printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
- printSmallCentered(false, 112, 6, RetTime().c_str());
- if (romFound[0]) {
- titleUpdate(0, false, filename[0].c_str());
- } else {
- printLastPlayedText(3);
- }
- swiWaitForVBlank();
- }
- loadROMselect();
- } else if (launchType[0] > 0) {
- showCursor = false;
- fadeType = false; // Fade to white
- mmEffectEx(&snd_launch);
- for (int i = 0; i < 50; i++) {
- iconYpos[3] -= 6;
- clearText();
- printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
- printSmallCentered(false, 112, 6, RetTime().c_str());
- if (romFound[0]) {
- titleUpdate(0, false, filename[0].c_str());
- } else {
- printLastPlayedText(3);
- }
- swiWaitForVBlank();
- }
- if (romFound[0]) {
- applaunch = true;
- } else {
- loadROMselect();
- }
- }
- secondaryDevice = false;
- } else if (isRegularDS) {
- // Switch to GBA mode
- showCursor = false;
- fadeType = false; // Fade to white
- mmEffectEx(&snd_launch);
- for (int i = 0; i < 50; i++) {
- iconYpos[3] -= 6;
- clearText();
- printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
- printSmallCentered(false, 112, 6, RetTime().c_str());
- printGbaBannerText();
- swiWaitForVBlank();
- }
- gbaSwitch();
- } else {
- mmEffectEx(&snd_wrong);
- }
- break;
- case 4:
- // Adjust backlight level
- if (isDSiMode() && consoleModel < 2) {
- fifoSendValue32(FIFO_USER_04, 1);
- mmEffectEx(&snd_backlight);
- }
- break;
- case 5:
- // Launch settings
- showCursor = false;
- fadeType = false; // Fade to white
- mmEffectEx(&snd_launch);
- for (int i = 0; i < 50; i++) {
- iconYpos[5] -= 6;
- swiWaitForVBlank();
- }
-
- gotosettings = true;
- //SaveSettings();
- if (!isDSiMode()) {
- chdir("fat:/");
- } else if (sdFound()) {
- chdir("sd:/");
- }
- int err = runNdsFile ("/_nds/TWiLightMenu/settings.srldr", 0, NULL, true, false, false, true, true);
- iprintf ("Start failed. Error %i\n", err);
- break;
- }
- if (startMenu_cursorPosition == 6) {
- // Open manual
- showCursor = false;
- fadeType = false; // Fade to white
- mmEffectEx(&snd_launch);
- for (int i = 0; i < 50; i++) {
- iconYpos[6] -= 6;
- swiWaitForVBlank();
- }
- if (!isDSiMode()) {
- chdir("fat:/");
- } else if (sdFound()) {
- chdir("sd:/");
- }
- int err = runNdsFile ("/_nds/TWiLightMenu/manual.srldr", 0, NULL, true, false, false, true, true);
- iprintf ("Start failed. Error %i\n", err);
- }
-
- menuButtonPressed = false;
- }
-
- if (pressed & KEY_B) {
- mmEffectEx(&snd_back);
- fadeType = false; // Fade to white
- for (int i = 0; i < 50; i++) swiWaitForVBlank();
- loadROMselect();
- }
-
- if ((pressed & KEY_X) && !isRegularDS) {
- mmEffectEx(&snd_back);
- fadeType = false; // Fade to white
- for (int i = 0; i < 50; i++) swiWaitForVBlank();
- if (!isDSiMode() || launcherApp == -1) {
- *(u32*)(0x02000300) = 0x434E4C54; // Set "CNLT" warmboot flag
- *(u16*)(0x02000304) = 0x1801;
- *(u32*)(0x02000310) = 0x4D454E55; // "MENU"
- unlaunchSetHiyaBoot();
- } else {
- tonccpy((u8*)0x02000800, unlaunchAutoLoadID, 12);
- *(u16*)(0x0200080C) = 0x3F0; // Unlaunch Length for CRC16 (fixed, must be 3F0h)
- *(u16*)(0x0200080E) = 0; // Unlaunch CRC16 (empty)
- *(u32*)(0x02000810) |= BIT(0); // Load the title at 2000838h
- *(u32*)(0x02000810) |= BIT(1); // Use colors 2000814h
- *(u16*)(0x02000814) = 0x7FFF; // Unlaunch Upper screen BG color (0..7FFFh)
- *(u16*)(0x02000816) = 0x7FFF; // Unlaunch Lower screen BG color (0..7FFFh)
- toncset((u8*)0x02000818, 0, 0x20+0x208+0x1C0); // Unlaunch Reserved (zero)
- int i2 = 0;
- for (int i = 0; i < (int)sizeof(unlaunchDevicePath); i++) {
- *(u8*)(0x02000838+i2) = unlaunchDevicePath[i]; // Unlaunch Device:/Path/Filename.ext (16bit Unicode,end by 0000h)
- i2 += 2;
- }
- while (*(u16*)(0x0200080E) == 0) { // Keep running, so that CRC16 isn't 0
- *(u16*)(0x0200080E) = swiCRC16(0xFFFF, (void*)0x02000810, 0x3F0); // Unlaunch CRC16
- }
- }
- fifoSendValue32(FIFO_USER_02, 1); // ReturntoDSiMenu
- }
-
- }
-
- ////////////////////////////////////
- // Launch the item
-
- if (applaunch) {
- // Clear screen with white
- whiteScreen = true;
- fadeSpeed = true;
- controlTopBright = false;
- clearText();
-
- // Delete previously used DSiWare of flashcard from SD
- if (!gotosettings && consoleModel < 2 && previousUsedDevice && bothSDandFlashcard()) {
- if (access("sd:/_nds/TWiLightMenu/tempDSiWare.dsi", F_OK) == 0) {
- remove("sd:/_nds/TWiLightMenu/tempDSiWare.dsi");
- }
- if (access("sd:/_nds/TWiLightMenu/tempDSiWare.pub", F_OK) == 0) {
- remove("sd:/_nds/TWiLightMenu/tempDSiWare.pub");
- }
- if (access("sd:/_nds/TWiLightMenu/tempDSiWare.prv", F_OK) == 0) {
- remove("sd:/_nds/TWiLightMenu/tempDSiWare.prv");
- }
- }
-
- // Construct a command line
- getcwd (filePath, PATH_MAX);
- int pathLen = strlen(filePath);
- vector argarray;
-
- if (extention(filename[secondaryDevice], ".argv"))
- {
- FILE *argfile = fopen(filename[secondaryDevice].c_str(),"rb");
- char str[PATH_MAX], *pstr;
- const char seps[]= "\n\r\t ";
-
- while( fgets(str, PATH_MAX, argfile) ) {
- // Find comment and end string there
- if( (pstr = strchr(str, '#')) )
- *pstr= '\0';
-
- // Tokenize arguments
- pstr= strtok(str, seps);
-
- while( pstr != NULL ) {
- argarray.push_back(strdup(pstr));
- pstr= strtok(NULL, seps);
- }
- }
- fclose(argfile);
- filename[secondaryDevice] = argarray.at(0);
- } else {
- argarray.push_back(strdup(filename[secondaryDevice].c_str()));
- }
-
- // Launch DSiWare .nds via Unlaunch
- if ((isDSiMode() || sdFound()) && isDSiWare[secondaryDevice]) {
- const char *typeToReplace = ".nds";
- if (extention(filename[secondaryDevice], ".dsi")) {
- typeToReplace = ".dsi";
- } else if (extention(filename[secondaryDevice], ".ids")) {
- typeToReplace = ".ids";
- } else if (extention(filename[secondaryDevice], ".srl")) {
- typeToReplace = ".srl";
- } else if (extention(filename[secondaryDevice], ".app")) {
- typeToReplace = ".app";
- }
-
- char *name = argarray.at(0);
- strcpy (filePath + pathLen, name);
- free(argarray.at(0));
- argarray.at(0) = filePath;
-
- dsiWareSrlPath = argarray[0];
- dsiWarePubPath = replaceAll(argarray[0], typeToReplace, ".pub");
- dsiWarePrvPath = replaceAll(argarray[0], typeToReplace, ".prv");
- launchType[secondaryDevice] = (consoleModel>0 ? 1 : 3);
- SaveSettings();
-
- sNDSHeaderExt NDSHeader;
-
- FILE *f_nds_file = fopen(filename[secondaryDevice].c_str(), "rb");
-
- fread(&NDSHeader, 1, sizeof(NDSHeader), f_nds_file);
- fclose(f_nds_file);
-
- whiteScreen = true;
-
- if ((getFileSize(dsiWarePubPath.c_str()) == 0) && (NDSHeader.pubSavSize > 0)) {
- clearText();
- if (memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) == 0) {
- // Display nothing
- } else if (consoleModel >= 2) {
- printSmallCentered(false, 20, "If this takes a while, press HOME,");
- printSmallCentered(false, 34, "then press B.");
- } else {
- printSmallCentered(false, 20, "If this takes a while, close and open");
- printSmallCentered(false, 34, "the console's lid.");
- }
- printSmall(false, 2, 80, "Creating public save file...");
- if (!fadeType) {
- fadeType = true; // Fade in from white
- for (int i = 0; i < 35; i++) swiWaitForVBlank();
- }
-
- static const int BUFFER_SIZE = 4096;
- char buffer[BUFFER_SIZE];
- memset(buffer, 0, sizeof(buffer));
- char savHdrPath[64];
- snprintf(savHdrPath, sizeof(savHdrPath), "nitro:/DSiWareSaveHeaders/%x.savhdr", (unsigned int)NDSHeader.pubSavSize);
- FILE *hdrFile = fopen(savHdrPath, "rb");
- if (hdrFile) fread(buffer, 1, 0x200, hdrFile);
- fclose(hdrFile);
-
- FILE *pFile = fopen(dsiWarePubPath.c_str(), "wb");
- if (pFile) {
- fwrite(buffer, 1, sizeof(buffer), pFile);
- fseek(pFile, NDSHeader.pubSavSize - 1, SEEK_SET);
- fputc('\0', pFile);
- fclose(pFile);
- }
- printSmall(false, 2, 88, "Public save file created!");
- for (int i = 0; i < 60; i++) swiWaitForVBlank();
- }
-
- if ((getFileSize(dsiWarePrvPath.c_str()) == 0) && (NDSHeader.prvSavSize > 0)) {
- clearText();
- if (memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) == 0) {
- // Display nothing
- } else if (consoleModel >= 2) {
- printSmallCentered(false, 20, "If this takes a while, press HOME,");
- printSmallCentered(false, 34, "then press B.");
- } else {
- printSmallCentered(false, 20, "If this takes a while, close and open");
- printSmallCentered(false, 34, "the console's lid.");
- }
- printSmall(false, 2, 80, "Creating private save file...");
- if (!fadeType) {
- fadeType = true; // Fade in from white
- for (int i = 0; i < 35; i++) swiWaitForVBlank();
- }
-
- static const int BUFFER_SIZE = 4096;
- char buffer[BUFFER_SIZE];
- memset(buffer, 0, sizeof(buffer));
- char savHdrPath[64];
- snprintf(savHdrPath, sizeof(savHdrPath), "nitro:/DSiWareSaveHeaders/%x.savhdr", (unsigned int)NDSHeader.prvSavSize);
- FILE *hdrFile = fopen(savHdrPath, "rb");
- if (hdrFile) fread(buffer, 1, 0x200, hdrFile);
- fclose(hdrFile);
-
- FILE *pFile = fopen(dsiWarePrvPath.c_str(), "wb");
- if (pFile) {
- fwrite(buffer, 1, sizeof(buffer), pFile);
- fseek(pFile, NDSHeader.prvSavSize - 1, SEEK_SET);
- fputc('\0', pFile);
- fclose(pFile);
- }
- printSmall(false, 2, 88, "Private save file created!");
- for (int i = 0; i < 60; i++) swiWaitForVBlank();
- }
-
- if (fadeType) {
- fadeType = false; // Fade to white
- for (int i = 0; i < 25; i++) swiWaitForVBlank();
- }
-
- if (dsiWareBooter || consoleModel > 0) {
- // Use nds-bootstrap
- loadPerGameSettings(filename[secondaryDevice]);
-
- bootstrapinipath = "sd:/_nds/nds-bootstrap.ini";
- CIniFile bootstrapini(bootstrapinipath);
- bootstrapini.SetString("NDS-BOOTSTRAP", "NDS_PATH", dsiWareSrlPath);
- bootstrapini.SetString("NDS-BOOTSTRAP", "SAV_PATH", dsiWarePubPath);
- bootstrapini.SetString("NDS-BOOTSTRAP", "AP_FIX_PATH", "");
- bootstrapini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", -1);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", true);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", true);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", true);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "DONOR_SDK_VER", 5);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "GAME_SOFT_RESET", 1);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "PATCH_MPU_REGION", 0);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "PATCH_MPU_SIZE", 0);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", 1);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
- (forceSleepPatch
- || ((flashcard == 1 || flashcard == 3) && !isRegularDS))
- );
- bootstrapini.SaveIniFile(bootstrapinipath);
-
- if (isDSiMode() || !secondaryDevice) {
- SetWidescreen(filename[secondaryDevice].c_str());
- }
- if (!isDSiMode() && !secondaryDevice) {
- ntrStartSdGame();
- }
-
- bool useNightly = (perGameSettings_bootstrapFile == -1 ? bootstrapFile : perGameSettings_bootstrapFile);
-
- char ndsToBoot[256];
- sprintf(ndsToBoot, "sd:/_nds/nds-bootstrap-%s.nds", useNightly ? "nightly" : "release");
- if(access(ndsToBoot, F_OK) != 0) {
- sprintf(ndsToBoot, "fat:/_nds/nds-bootstrap-%s.nds", useNightly ? "nightly" : "release");
- }
-
- argarray.at(0) = (char *)ndsToBoot;
- int err = runNdsFile(argarray[0], argarray.size(), (const char **)&argarray[0], true, true, false, true, true);
- char text[32];
- snprintf (text, sizeof(text), "Start failed. Error %i", err);
- clearText();
- ClearBrightness();
- printSmall(false, 4, 80, text);
- if (err == 1) {
- printSmall(false, 4, 88, useNightly ? "nds-bootstrap (Nightly)" : "nds-bootstrap (Release)");
- printSmall(false, 4, 96, "not found.");
- }
- stop();
- }
-
- if (secondaryDevice) {
- clearText();
- printSmallCentered(false, 20, "If this takes a while, close and open");
- printSmallCentered(false, 34, "the console's lid.");
- printSmallCentered(false, 86, "Now copying data...");
- printSmallCentered(false, 100, "Do not turn off the power.");
- fadeType = true; // Fade in from white
- for (int i = 0; i < 35; i++) swiWaitForVBlank();
- fcopy(dsiWareSrlPath.c_str(), "sd:/_nds/TWiLightMenu/tempDSiWare.dsi");
- if ((access(dsiWarePubPath.c_str(), F_OK) == 0) && (NDSHeader.pubSavSize > 0)) {
- fcopy(dsiWarePubPath.c_str(), "sd:/_nds/TWiLightMenu/tempDSiWare.pub");
- }
- if ((access(dsiWarePrvPath.c_str(), F_OK) == 0) && (NDSHeader.prvSavSize > 0)) {
- fcopy(dsiWarePrvPath.c_str(), "sd:/_nds/TWiLightMenu/tempDSiWare.prv");
- }
- fadeType = false; // Fade to white
- for (int i = 0; i < 25; i++) swiWaitForVBlank();
-
- if ((access(dsiWarePubPath.c_str(), F_OK) == 0 && (NDSHeader.pubSavSize > 0))
- || (access(dsiWarePrvPath.c_str(), F_OK) == 0 && (NDSHeader.prvSavSize > 0))) {
- clearText();
- printSmallCentered(false, 8, "After saving, please re-start");
- printSmallCentered(false, 20, "TWiLight Menu++ to transfer your");
- printSmallCentered(false, 32, "save data back.");
- fadeType = true; // Fade in from white
- for (int i = 0; i < 60*3; i++) swiWaitForVBlank(); // Wait 3 seconds
- fadeType = false; // Fade to white
- for (int i = 0; i < 25; i++) swiWaitForVBlank();
- }
- }
-
- char unlaunchDevicePath[256];
- if (secondaryDevice) {
- snprintf(unlaunchDevicePath, sizeof(unlaunchDevicePath), "sdmc:/_nds/TWiLightMenu/tempDSiWare.dsi");
- } else {
- snprintf(unlaunchDevicePath, sizeof(unlaunchDevicePath), "__%s", dsiWareSrlPath.c_str());
- unlaunchDevicePath[0] = 's';
- unlaunchDevicePath[1] = 'd';
- unlaunchDevicePath[2] = 'm';
- unlaunchDevicePath[3] = 'c';
- }
-
- tonccpy((u8*)0x02000800, unlaunchAutoLoadID, 12);
- *(u16*)(0x0200080C) = 0x3F0; // Unlaunch Length for CRC16 (fixed, must be 3F0h)
- *(u16*)(0x0200080E) = 0; // Unlaunch CRC16 (empty)
- *(u32*)(0x02000810) = 0; // Unlaunch Flags
- *(u32*)(0x02000810) |= BIT(0); // Load the title at 2000838h
- *(u32*)(0x02000810) |= BIT(1); // Use colors 2000814h
- *(u16*)(0x02000814) = 0x7FFF; // Unlaunch Upper screen BG color (0..7FFFh)
- *(u16*)(0x02000816) = 0x7FFF; // Unlaunch Lower screen BG color (0..7FFFh)
- toncset((u8*)0x02000818, 0, 0x20+0x208+0x1C0); // Unlaunch Reserved (zero)
- int i2 = 0;
- for (int i = 0; i < (int)sizeof(unlaunchDevicePath); i++) {
- *(u8*)(0x02000838+i2) = unlaunchDevicePath[i]; // Unlaunch Device:/Path/Filename.ext (16bit Unicode,end by 0000h)
- i2 += 2;
- }
- *(u16*)(0x0200080E) = swiCRC16(0xFFFF, (void*)0x02000810, 0x3F0); // Unlaunch CRC16
-
- fifoSendValue32(FIFO_USER_02, 1); // Reboot into DSiWare title, booted via Launcher
- for (int i = 0; i < 15; i++) swiWaitForVBlank();
- }
-
- // Launch .nds directly or via nds-bootstrap
- if (extention(filename[secondaryDevice], ".nds") || extention(filename[secondaryDevice], ".dsi")
- || extention(filename[secondaryDevice], ".ids") || extention(filename[secondaryDevice], ".srl")
- || extention(filename[secondaryDevice], ".app")) {
- const char *typeToReplace = ".nds";
- if (extention(filename[secondaryDevice], ".dsi")) {
- typeToReplace = ".dsi";
- } else if (extention(filename[secondaryDevice], ".ids")) {
- typeToReplace = ".ids";
- } else if (extention(filename[secondaryDevice], ".srl")) {
- typeToReplace = ".srl";
- } else if (extention(filename[secondaryDevice], ".app")) {
- typeToReplace = ".app";
- }
-
- bool dsModeSwitch = false;
- bool dsModeDSiWare = false;
-
- char game_TID[5];
-
- FILE *f_nds_file = fopen(argarray[0], "rb");
-
- fseek(f_nds_file, offsetof(sNDSHeaderExt, gameCode), SEEK_SET);
- fread(game_TID, 1, 4, f_nds_file);
- fclose(f_nds_file);
- game_TID[4] = 0;
- game_TID[3] = 0;
-
- if (strcmp(game_TID, "HND") == 0 || strcmp(game_TID, "HNE") == 0) {
- dsModeSwitch = true;
- dsModeDSiWare = true;
- useBackend = false; // Bypass nds-bootstrap
- homebrewBootstrap = true;
- } else if (isHomebrew[secondaryDevice]) {
- loadPerGameSettings(filename[secondaryDevice]);
- if (perGameSettings_directBoot || (useBootstrap && secondaryDevice)) {
- useBackend = false; // Bypass nds-bootstrap
- } else {
- useBackend = true;
- }
- if (isDSiMode() && !perGameSettings_dsiMode) {
- dsModeSwitch = true;
- }
- homebrewBootstrap = true;
- } else {
- loadPerGameSettings(filename[secondaryDevice]);
- useBackend = true;
- homebrewBootstrap = false;
- }
-
- char *name = argarray.at(0);
- strcpy (filePath + pathLen, name);
- free(argarray.at(0));
- argarray.at(0) = filePath;
- if(useBackend) {
- if(useBootstrap || !secondaryDevice) {
- std::string path = argarray[0];
- std::string savename = replaceAll(filename[secondaryDevice], typeToReplace, getSavExtension());
- std::string ramdiskname = replaceAll(filename[secondaryDevice], typeToReplace, getImgExtension());
- std::string romFolderNoSlash = romfolder[secondaryDevice];
- RemoveTrailingSlashes(romFolderNoSlash);
- mkdir (isHomebrew[secondaryDevice] ? "ramdisks" : "saves", 0777);
- std::string savepath = romFolderNoSlash+"/saves/"+savename;
- if (sdFound() && secondaryDevice && fcSaveOnSd) {
- savepath = replaceAll(savepath, "fat:/", "sd:/");
- }
- std::string ramdiskpath = romFolderNoSlash+"/ramdisks/"+ramdiskname;
-
- if (!isHomebrew[secondaryDevice] && (strcmp(game_TID, "NTR") != 0)) {
- // Create or expand save if game isn't homebrew
- int orgsavesize = getFileSize(savepath.c_str());
- int savesize = 524288; // 512KB (default size)
-
- for (auto i : saveMap) {
- if (i.second.find(game_TID) != i.second.cend()) {
- savesize = i.first;
- break;
- }
- }
-
- bool saveSizeFixNeeded = false;
-
- // TODO: If the list gets large enough, switch to bsearch().
- for (unsigned int i = 0; i < sizeof(saveSizeFixList) / sizeof(saveSizeFixList[0]); i++) {
- if (memcmp(game_TID, saveSizeFixList[i], 3) == 0) {
- // Found a match.
- saveSizeFixNeeded = true;
- break;
- }
- }
-
- if ((orgsavesize == 0 && savesize > 0) || (orgsavesize < savesize && saveSizeFixNeeded)) {
- clearText();
- ClearBrightness();
- if (isDSiMode() && memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) == 0) {
- // Display nothing
- } else if (REG_SCFG_EXT != 0 && consoleModel >= 2) {
- printSmallCentered(false, 20, "If this takes a while, press HOME,");
- printSmallCentered(false, 34, "then press B.");
- } else {
- printSmallCentered(false, 20, "If this takes a while, close and open");
- printSmallCentered(false, 34, "the console's lid.");
- }
- printSmallCentered(false, 88, (orgsavesize == 0) ? "Creating save file..." : "Expanding save file...");
-
- if (orgsavesize > 0) {
- fsizeincrease(savepath.c_str(), sdFound() ? "sd:/_nds/TWiLightMenu/temp.sav" : "fat:/_nds/TWiLightMenu/temp.sav", savesize);
- } else {
- FILE *pFile = fopen(savepath.c_str(), "wb");
- if (pFile) {
- fseek(pFile, savesize - 1, SEEK_SET);
- fputc('\0', pFile);
- fclose(pFile);
- }
- }
- clearText();
- printSmallCentered(false, 88, (orgsavesize == 0) ? "Save file created!" : "Save file expanded!");
- for (int i = 0; i < 30; i++) swiWaitForVBlank();
- }
- }
-
- int donorSdkVer = SetDonorSDK(argarray[0]);
- SetMPUSettings(argarray[0]);
- SetSpeedBumpExclude(argarray[0]);
-
- bool useWidescreen = (perGameSettings_wideScreen == -1 ? wideScreen : perGameSettings_wideScreen);
-
- bootstrapinipath = ((!secondaryDevice || (isDSiMode() && sdFound())) ? "sd:/_nds/nds-bootstrap.ini" : "fat:/_nds/nds-bootstrap.ini");
- CIniFile bootstrapini( bootstrapinipath );
- bootstrapini.SetString("NDS-BOOTSTRAP", "NDS_PATH", path);
- bootstrapini.SetString("NDS-BOOTSTRAP", "SAV_PATH", savepath);
- if (!isHomebrew[secondaryDevice]) {
- bootstrapini.SetString("NDS-BOOTSTRAP", "AP_FIX_PATH", setApFix(argarray[0]));
- }
- bootstrapini.SetString("NDS-BOOTSTRAP", "HOMEBREW_ARG", (useWidescreen && game_TID[0] == 'W') ? "wide" : "");
- bootstrapini.SetString("NDS-BOOTSTRAP", "RAM_DRIVE_PATH", (perGameSettings_ramDiskNo >= 0 && !secondaryDevice) ? ramdiskpath : "sd:/null.img");
- bootstrapini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", perGameSettings_language == -2 ? gameLanguage : perGameSettings_language);
- if (isDSiMode() || !secondaryDevice) {
- bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", perGameSettings_dsiMode == -1 ? bstrap_dsiMode : perGameSettings_dsiMode);
- }
- if ((REG_SCFG_EXT != 0) || !secondaryDevice) {
- bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", perGameSettings_boostCpu == -1 ? boostCpu : perGameSettings_boostCpu);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", perGameSettings_boostVram == -1 ? boostVram : perGameSettings_boostVram);
- }
- bootstrapini.SetInt("NDS-BOOTSTRAP", "EXTENDED_MEMORY", perGameSettings_expandRomSpace == -1 ? bstrap_extendedMemory : perGameSettings_expandRomSpace);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "DONOR_SDK_VER", donorSdkVer);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "PATCH_MPU_REGION", mpuregion);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "PATCH_MPU_SIZE", mpusize);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", ceCached);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
- (forceSleepPatch
- || ((flashcard == 1 || flashcard == 3) && !isRegularDS))
- );
- bootstrapini.SaveIniFile( bootstrapinipath );
-
- CheatCodelist codelist;
- u32 gameCode,crc32;
-
- if ((isDSiMode() || !secondaryDevice) && !isHomebrew[secondaryDevice]) {
- bool cheatsEnabled = true;
- const char* cheatDataBin = "/_nds/nds-bootstrap/cheatData.bin";
- mkdir("/_nds", 0777);
- mkdir("/_nds/nds-bootstrap", 0777);
- if(codelist.romData(path,gameCode,crc32)) {
- long cheatOffset; size_t cheatSize;
- FILE* dat=fopen(sdFound() ? "sd:/_nds/TWiLightMenu/extras/usrcheat.dat" : "fat:/_nds/TWiLightMenu/extras/usrcheat.dat","rb");
- if (dat) {
- if (codelist.searchCheatData(dat, gameCode,
- crc32, cheatOffset,
- cheatSize)) {
- codelist.parse(path);
- writeCheatsToFile(codelist.getCheats(), cheatDataBin);
- FILE* cheatData=fopen(cheatDataBin,"rb");
- if (cheatData) {
- u32 check[2];
- fread(check, 1, 8, cheatData);
- fclose(cheatData);
- if (check[1] == 0xCF000000
- || getFileSize(cheatDataBin) > 0x8000) {
- cheatsEnabled = false;
- }
- }
- } else {
- cheatsEnabled = false;
- }
- fclose(dat);
- } else {
- cheatsEnabled = false;
- }
- } else {
- cheatsEnabled = false;
- }
- if (!cheatsEnabled) {
- remove(cheatDataBin);
- }
- }
-
- launchType[secondaryDevice] = 1;
- previousUsedDevice = secondaryDevice;
- SaveSettings();
-
- if (isDSiMode() || !secondaryDevice) {
- SetWidescreen(filename[secondaryDevice].c_str());
- }
- if (!isDSiMode() && !secondaryDevice) {
- ntrStartSdGame();
- }
-
- bool useNightly = (perGameSettings_bootstrapFile == -1 ? bootstrapFile : perGameSettings_bootstrapFile);
-
- char ndsToBoot[256];
- sprintf(ndsToBoot, "sd:/_nds/nds-bootstrap-%s%s.nds", homebrewBootstrap ? "hb-" : "", useNightly ? "nightly" : "release");
- if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
- sprintf(ndsToBoot, "fat:/_nds/%s-%s%s.nds", isDSiMode() ? "nds-bootstrap" : "b4ds", homebrewBootstrap ? "hb-" : "", useNightly ? "nightly" : "release");
- }
-
- argarray.at(0) = (char *)ndsToBoot;
- int err = runNdsFile (argarray[0], argarray.size(), (const char **)&argarray[0], (homebrewBootstrap ? false : true), true, false, true, true);
- char text[32];
- snprintf (text, sizeof(text), "Start failed. Error %i", err);
- clearText();
- ClearBrightness();
- printSmall(false, 4, 80, text);
- if (err == 1) {
- printSmall(false, 4, 88, useNightly ? "nds-bootstrap (Nightly)" : "nds-bootstrap (Release)");
- printSmall(false, 4, 96, "not found.");
- }
- stop();
- } else {
- launchType[secondaryDevice] = 1;
- previousUsedDevice = secondaryDevice;
- SaveSettings();
- loadGameOnFlashcard(argarray[0], true);
- }
- } else {
- if (isDSiMode() || !secondaryDevice) {
- SetWidescreen(filename[secondaryDevice].c_str());
- }
- launchType[secondaryDevice] = 2;
- previousUsedDevice = secondaryDevice;
- SaveSettings();
- if (!isDSiMode() && !secondaryDevice) {
- ntrStartSdGame();
- }
-
- bool useWidescreen = (perGameSettings_wideScreen == -1 ? wideScreen : perGameSettings_wideScreen);
-
- if (consoleModel >= 2 && useWidescreen && homebrewHasWide) {
- argarray.push_back((char*)"wide");
- }
-
- bool runNds_boostCpu = false;
- bool runNds_boostVram = false;
- if (REG_SCFG_EXT != 0 && !dsModeDSiWare) {
- loadPerGameSettings(filename[secondaryDevice]);
-
- runNds_boostCpu = perGameSettings_boostCpu == -1 ? boostCpu : perGameSettings_boostCpu;
- runNds_boostVram = perGameSettings_boostVram == -1 ? boostVram : perGameSettings_boostVram;
- }
- //iprintf ("Running %s with %d parameters\n", argarray[0], argarray.size());
- int err = runNdsFile (argarray[0], argarray.size(), (const char **)&argarray[0], true, true, dsModeSwitch, runNds_boostCpu, runNds_boostVram);
- char text[32];
- snprintf (text, sizeof(text), "Start failed. Error %i", err);
- clearText();
- ClearBrightness();
- printSmall(false, 4, 4, text);
- stop();
- }
- } else {
- bool useNDSB = false;
- bool dsModeSwitch = false;
- bool boostCpu = true;
- bool boostVram = false;
-
- std::string romfolderNoSlash = romfolder[secondaryDevice];
- RemoveTrailingSlashes(romfolderNoSlash);
- char ROMpath[256];
- snprintf (ROMpath, sizeof(ROMpath), "%s/%s", romfolderNoSlash.c_str(), filename[secondaryDevice].c_str());
- romPath[secondaryDevice] = ROMpath;
- previousUsedDevice = secondaryDevice;
- homebrewBootstrap = true;
-
- const char *ndsToBoot = "sd:/_nds/nds-bootstrap-release.nds";
- if (extention(filename[secondaryDevice], ".plg")) {
- ndsToBoot = "fat:/_nds/TWiLightMenu/bootplg.srldr";
-
- // Print .plg path without "fat:" at the beginning
- char ROMpathDS2[256];
- if (secondaryDevice) {
- for (int i = 0; i < 252; i++) {
- ROMpathDS2[i] = ROMpath[4+i];
- if (ROMpath[4+i] == '\x00') break;
- }
- } else {
- sprintf(ROMpathDS2, "/_nds/TWiLightMenu/tempPlugin.plg");
- fcopy(ROMpath, "fat:/_nds/TWiLightMenu/tempPlugin.plg");
- }
-
- CIniFile dstwobootini( "fat:/_dstwo/twlm.ini" );
- dstwobootini.SetString("boot_settings", "file", ROMpathDS2);
- dstwobootini.SaveIniFile( "fat:/_dstwo/twlm.ini" );
- } else if (extention(filename[secondaryDevice], ".rvid")) {
- launchType[secondaryDevice] = 7;
-
- ndsToBoot = "sd:/_nds/TWiLightMenu/apps/RocketVideoPlayer.nds";
- if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
- ndsToBoot = "fat:/_nds/TWiLightMenu/apps/RocketVideoPlayer.nds";
- boostVram = true;
- }
- } else if (extention(filename[secondaryDevice], ".mp4")) {
- launchType[secondaryDevice] = 8;
-
- ndsToBoot = "sd:/_nds/TWiLightMenu/apps/MPEG4Player.nds";
- if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
- ndsToBoot = "fat:/_nds/TWiLightMenu/apps/MPEG4Player.nds";
- boostVram = true;
- }
- } else if (extention(filename[secondaryDevice], ".gba")) {
- launchType[secondaryDevice] = 1;
-
- if (secondaryDevice) {
- ndsToBoot = gbar2DldiAccess ? "sd:/_nds/GBARunner2_arm7dldi_ds.nds" : "sd:/_nds/GBARunner2_arm9dldi_ds.nds";
- if (REG_SCFG_EXT != 0) {
- ndsToBoot = consoleModel>0 ? "sd:/_nds/GBARunner2_arm7dldi_3ds.nds" : "sd:/_nds/GBARunner2_arm7dldi_dsi.nds";
- }
- if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
- ndsToBoot = gbar2DldiAccess ? "fat:/_nds/GBARunner2_arm7dldi_ds.nds" : "fat:/_nds/GBARunner2_arm9dldi_ds.nds";
- if (REG_SCFG_EXT != 0) {
- ndsToBoot = consoleModel>0 ? "fat:/_nds/GBARunner2_arm7dldi_3ds.nds" : "fat:/_nds/GBARunner2_arm7dldi_dsi.nds";
- }
- }
- boostVram = false;
- } else {
- useNDSB = true;
-
- const char* gbar2Path = consoleModel>0 ? "sd:/_nds/GBARunner2_arm7dldi_3ds.nds" : "sd:/_nds/GBARunner2_arm7dldi_dsi.nds";
- if (isDSiMode() && arm7SCFGLocked) {
- gbar2Path = consoleModel>0 ? "sd:/_nds/GBARunner2_arm7dldi_nodsp_3ds.nds" : "sd:/_nds/GBARunner2_arm7dldi_nodsp_dsi.nds";
- }
-
- ndsToBoot = (bootstrapFile ? "sd:/_nds/nds-bootstrap-hb-nightly.nds" : "sd:/_nds/nds-bootstrap-hb-release.nds");
- CIniFile bootstrapini("sd:/_nds/nds-bootstrap.ini");
-
- bootstrapini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", gameLanguage);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", 0);
- bootstrapini.SetString("NDS-BOOTSTRAP", "NDS_PATH", gbar2Path);
- bootstrapini.SetString("NDS-BOOTSTRAP", "HOMEBREW_ARG", ROMpath);
- bootstrapini.SetString("NDS-BOOTSTRAP", "RAM_DRIVE_PATH", "");
- bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", 1);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", 0);
-
- bootstrapini.SaveIniFile("sd:/_nds/nds-bootstrap.ini");
- }
- } else if (extention(filename[secondaryDevice], ".a26")) {
- launchType[secondaryDevice] = 9;
-
- ndsToBoot = "sd:/_nds/TWiLightMenu/emulators/StellaDS.nds";
- if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
- ndsToBoot = "fat:/_nds/TWiLightMenu/emulators/StellaDS.nds";
- boostVram = true;
- }
- } else if (extention(filename[secondaryDevice], ".gb") || extention(filename[secondaryDevice], ".sgb") || extention(filename[secondaryDevice], ".gbc")) {
- launchType[secondaryDevice] = 5;
-
- ndsToBoot = "sd:/_nds/TWiLightMenu/emulators/gameyob.nds";
- if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
- ndsToBoot = "fat:/_nds/TWiLightMenu/emulators/gameyob.nds";
- dsModeSwitch = !isDSiMode();
- boostVram = true;
- }
- } else if (extention(filename[secondaryDevice], ".nes") || extention(filename[secondaryDevice], ".fds")) {
- launchType[secondaryDevice] = 4;
-
- ndsToBoot = (secondaryDevice ? "sd:/_nds/TWiLightMenu/emulators/nesds.nds" : "sd:/_nds/TWiLightMenu/emulators/nestwl.nds");
- if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
- ndsToBoot = "fat:/_nds/TWiLightMenu/emulators/nesds.nds";
- boostVram = true;
- }
- } else if (extention(filename[secondaryDevice], ".sms") || extention(filename[secondaryDevice], ".gg")) {
- mkdir(secondaryDevice ? "fat:/data" : "sd:/data", 0777);
- mkdir(secondaryDevice ? "fat:/data/s8ds" : "sd:/data/s8ds", 0777);
-
- if (!secondaryDevice && !arm7SCFGLocked && smsGgInRam) {
- launchType[secondaryDevice] = 1;
-
- useNDSB = true;
-
- ndsToBoot = (bootstrapFile ? "sd:/_nds/nds-bootstrap-hb-nightly.nds" : "sd:/_nds/nds-bootstrap-hb-release.nds");
- CIniFile bootstrapini("sd:/_nds/nds-bootstrap.ini");
-
- bootstrapini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", gameLanguage);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", 0);
- bootstrapini.SetString("NDS-BOOTSTRAP", "NDS_PATH", "sd:/_nds/TWiLightMenu/emulators/S8DS07.nds");
- bootstrapini.SetString("NDS-BOOTSTRAP", "HOMEBREW_ARG", "");
- bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", 1);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", 0);
-
- bootstrapini.SetString("NDS-BOOTSTRAP", "RAM_DRIVE_PATH", ROMpath);
- bootstrapini.SaveIniFile("sd:/_nds/nds-bootstrap.ini");
- } else {
- launchType[secondaryDevice] = 6;
-
- ndsToBoot = "sd:/_nds/TWiLightMenu/emulators/S8DS.nds";
- if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
- ndsToBoot = "fat:/_nds/TWiLightMenu/emulators/S8DS.nds";
- boostVram = true;
- }
- }
- } else if (extention(filename[secondaryDevice], ".gen")) {
- bool usePicoDrive = ((isDSiMode() && sdFound() && arm7SCFGLocked)
- || showMd==2 || (showMd==3 && getFileSize(filename[secondaryDevice].c_str()) > 0x300000));
- launchType[secondaryDevice] = (usePicoDrive ? 10 : 1);
-
- if (usePicoDrive || secondaryDevice) {
- ndsToBoot = usePicoDrive ? "sd:/_nds/TWiLightMenu/emulators/PicoDriveTWL.nds" : "sd:/_nds/TWiLightMenu/emulators/jEnesisDS.nds";
- if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
- ndsToBoot = usePicoDrive ? "fat:/_nds/TWiLightMenu/emulators/PicoDriveTWL.nds" : "fat:/_nds/TWiLightMenu/emulators/jEnesisDS.nds";
- boostVram = true;
- }
- dsModeSwitch = !usePicoDrive;
- } else {
- useNDSB = true;
-
- ndsToBoot = (bootstrapFile ? "sd:/_nds/nds-bootstrap-hb-nightly.nds" : "sd:/_nds/nds-bootstrap-hb-release.nds");
- CIniFile bootstrapini("sd:/_nds/nds-bootstrap.ini");
-
- bootstrapini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", gameLanguage);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", 0);
- bootstrapini.SetString("NDS-BOOTSTRAP", "NDS_PATH", "sd:/_nds/TWiLightMenu/emulators/jEnesisDS.nds");
- bootstrapini.SetString("NDS-BOOTSTRAP", "HOMEBREW_ARG", "fat:/ROM.BIN");
- bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", 1);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", 0);
-
- bootstrapini.SetString("NDS-BOOTSTRAP", "RAM_DRIVE_PATH", ROMpath);
- bootstrapini.SaveIniFile("sd:/_nds/nds-bootstrap.ini");
- }
- } else if (extention(filename[secondaryDevice], ".smc") || extention(filename[secondaryDevice], ".sfc")) {
- launchType[secondaryDevice] = 1;
-
- if (secondaryDevice) {
- ndsToBoot = "sd:/_nds/TWiLightMenu/emulators/SNEmulDS.nds";
- if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
- ndsToBoot = "fat:/_nds/TWiLightMenu/emulators/SNEmulDS.nds";
- boostCpu = false;
- boostVram = true;
- }
- dsModeSwitch = true;
- } else {
- useNDSB = true;
-
- ndsToBoot = (bootstrapFile ? "sd:/_nds/nds-bootstrap-hb-nightly.nds" : "sd:/_nds/nds-bootstrap-hb-release.nds");
- CIniFile bootstrapini("sd:/_nds/nds-bootstrap.ini");
-
- bootstrapini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", gameLanguage);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", 0);
- bootstrapini.SetString("NDS-BOOTSTRAP", "NDS_PATH", "sd:/_nds/TWiLightMenu/emulators/SNEmulDS.nds");
- bootstrapini.SetString("NDS-BOOTSTRAP", "HOMEBREW_ARG", "fat:/snes/ROM.SMC");
- bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", 0);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", 0);
-
- bootstrapini.SetString("NDS-BOOTSTRAP", "RAM_DRIVE_PATH", ROMpath);
- bootstrapini.SaveIniFile("sd:/_nds/nds-bootstrap.ini");
- }
- } else if (extention(filename[secondaryDevice], ".pce")) {
- launchType[secondaryDevice] = 1;
-
- if (secondaryDevice) {
- ndsToBoot = "sd:/_nds/TWiLightMenu/emulators/NitroGrafx.nds";
- if(access(ndsToBoot, F_OK) != 0) {
- ndsToBoot = "/_nds/TWiLightMenu/emulators/NitroGrafx.nds";
- boostVram = true;
- }
- dsModeSwitch = true;
- } else {
- useNDSB = true;
-
- ndsToBoot = (bootstrapFile ? "sd:/_nds/nds-bootstrap-hb-nightly.nds" : "sd:/_nds/nds-bootstrap-hb-release.nds");
- CIniFile bootstrapini("sd:/_nds/nds-bootstrap.ini");
-
- bootstrapini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", gameLanguage);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", 0);
- bootstrapini.SetString("NDS-BOOTSTRAP", "NDS_PATH", "sd:/_nds/TWiLightMenu/emulators/NitroGrafx.nds");
- bootstrapini.SetString("NDS-BOOTSTRAP", "HOMEBREW_ARG", ROMpath);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", 0);
- bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", 0);
-
- bootstrapini.SetString("NDS-BOOTSTRAP", "RAM_DRIVE_PATH", "");
- bootstrapini.SaveIniFile("sd:/_nds/nds-bootstrap.ini");
- }
- }
-
- SaveSettings();
- if (!isDSiMode() && !secondaryDevice && !extention(filename[secondaryDevice], ".plg")) {
- ntrStartSdGame();
- }
- argarray.push_back(ROMpath);
- argarray.at(0) = (char *)ndsToBoot;
-
- int err = runNdsFile (argarray[0], argarray.size(), (const char **)&argarray[0], !useNDSB, true, dsModeSwitch, boostCpu, boostVram); // Pass ROM to emulator as argument
-
- char text[32];
- snprintf (text, sizeof(text), "Start failed. Error %i", err);
- clearText();
- ClearBrightness();
- printLarge(false, 4, 80, text);
- if (err == 1 && useNDSB) {
- printSmall(false, 4, 88, bootstrapFile ? "nds-bootstrap (Nightly)" : "nds-bootstrap (Release)");
- printSmall(false, 4, 96, "not found.");
- }
- stop();
-
- while(argarray.size() !=0 ) {
- free(argarray.at(0));
- argarray.erase(argarray.begin());
- }
- }
- }
- }
-
- return 0;
-}
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include "date.h"
+#include "fileCopy.h"
+#include "nand/nandio.h"
+
+#include "graphics/graphics.h"
+
+#include "common/tonccpy.h"
+#include "common/nitrofs.h"
+#include "read_card.h"
+#include "flashcard.h"
+#include "ndsheaderbanner.h"
+#include "gbaswitch.h"
+#include "nds_loader_arm9.h"
+#include "perGameSettings.h"
+#include "errorScreen.h"
+
+#include "iconTitle.h"
+#include "graphics/fontHandler.h"
+
+#include "common/inifile.h"
+#include "common/dsimenusettings.h"
+#include "tool/stringtool.h"
+
+#include "language.h"
+
+#include "cheat.h"
+#include "crc.h"
+
+#include "soundbank.h"
+#include "soundbank_bin.h"
+
+#include "donorMap.h"
+#include "mpuMap.h"
+#include "speedBumpExcludeMap.h"
+#include "saveMap.h"
+
+#include "sr_data_srllastran.h" // For rebooting into the game
+
+#define gbamodeText "Start GBA game."
+#define featureUnavailableText "This feature is unavailable."
+
+bool useTwlCfg = false;
+
+bool whiteScreen = true;
+bool fadeType = false; // false = out, true = in
+bool fadeSpeed = true; // false = slow (for DSi launch effect), true = fast
+bool controlTopBright = true;
+bool controlBottomBright = true;
+bool widescreenEffects = false;
+int fps = 60;
+int colorMode = 0;
+int blfLevel = 0;
+
+bool cardEjected = false;
+static bool cardRefreshed = false;
+
+extern void ClearBrightness();
+extern int boxArtType[2];
+
+const char* settingsinipath = "sd:/_nds/TWiLightMenu/settings.ini";
+const char* bootstrapinipath = "sd:/_nds/nds-bootstrap.ini";
+
+std::string romPath[2];
+std::string dsiWareSrlPath;
+std::string dsiWarePubPath;
+std::string dsiWarePrvPath;
+
+const char *charUnlaunchBg;
+std::string unlaunchBg = "default.gif";
+bool removeLauncherPatches = true;
+
+const char *unlaunchAutoLoadID = "AutoLoadInfo";
+static char hiyaNdsPath[14] = {'s','d','m','c',':','/','h','i','y','a','.','d','s','i'};
+char unlaunchDevicePath[256];
+
+static char pictochatPath[256];
+static char dlplayPath[256];
+
+bool arm7SCFGLocked = false;
+int consoleModel = 0;
+/* 0 = Nintendo DSi (Retail)
+ 1 = Nintendo DSi (Dev/Panda)
+ 2 = Nintendo 3DS
+ 3 = New Nintendo 3DS */
+bool isRegularDS = true;
+bool isDSLite = false;
+int flashcard = 0;
+
+extern bool showdialogbox;
+
+bool extention(const std::string& filename, const char* ext) {
+ if(strcasecmp(filename.c_str() + filename.size() - strlen(ext), ext)) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+/**
+ * Remove trailing slashes from a pathname, if present.
+ * @param path Pathname to modify.
+ */
+void RemoveTrailingSlashes(std::string& path)
+{
+ while (!path.empty() && path[path.size()-1] == '/') {
+ path.resize(path.size()-1);
+ }
+}
+
+/**
+ * Remove trailing spaces from a cheat code line, if present.
+ * @param path Code line to modify.
+ */
+/*static void RemoveTrailingSpaces(std::string& code)
+{
+ while (!code.empty() && code[code.size()-1] == ' ') {
+ code.resize(code.size()-1);
+ }
+}*/
+
+std::string romfolder[2];
+
+// These are used by flashcard functions and must retain their trailing slash.
+static const std::string slashchar = "/";
+static const std::string woodfat = "fat0:/";
+static const std::string dstwofat = "fat1:/";
+
+int mpuregion = 0;
+int mpusize = 0;
+bool ceCached = true;
+
+bool applaunch = false;
+bool showCursor = true;
+bool startMenu = false;
+bool gotosettings = false;
+
+bool slot1Launched = false;
+int launchType[2] = {0}; // 0 = Slot-1, 1 = SD/Flash card, 2 = SD/Flash card (Direct boot), 3 = DSiWare, 4 = NES, 5 = (S)GB(C), 6 = SMS/GG
+int slot1LaunchMethod = 1; // 0 == Reboot, 1 == Direct, 2 == Unlaunch
+bool useBootstrap = true;
+bool bootstrapFile = false;
+bool homebrewBootstrap = false;
+bool homebrewHasWide = false;
+bool show12hrClock = true;
+//bool snesEmulator = true;
+bool smsGgInRam = false;
+bool fcSaveOnSd = false;
+bool wideScreen = false;
+
+bool pictochatFound = false;
+bool dlplayFound = false;
+bool pictochatReboot = false;
+bool dlplayReboot = false;
+bool sdRemoveDetect = true;
+bool useGbarunner = false;
+bool gbar2DldiAccess = false; // false == ARM9, true == ARM7
+int theme = 0;
+int subtheme = 0;
+int showMd = 3;
+int cursorPosition[2] = {0};
+int startMenu_cursorPosition = 0;
+int pagenum[2] = {0};
+bool showDirectories = true;
+int showBoxArt = 1 + isDSiMode();
+bool animateDsiIcons = false;
+int launcherApp = -1;
+int sysRegion = -1;
+
+int guiLanguage = -1;
+int gameLanguage = -1;
+int titleLanguage = -1;
+bool boostCpu = false; // false == NTR, true == TWL
+bool boostVram = false;
+int bstrap_dsiMode = 0;
+int bstrap_extendedMemory = 0;
+bool forceSleepPatch = false;
+bool dsiWareBooter = false;
+
+void LoadSettings(void) {
+ useBootstrap = isDSiMode();
+
+ // GUI
+ CIniFile settingsini( settingsinipath );
+
+ // UI settings.
+ consoleModel = settingsini.GetInt("SRLOADER", "CONSOLE_MODEL", 0);
+
+ showMd = settingsini.GetInt("SRLOADER", "SHOW_MDGEN", showMd);
+
+ // Customizable UI settings.
+ fps = settingsini.GetInt("SRLOADER", "FRAME_RATE", fps);
+ colorMode = settingsini.GetInt("SRLOADER", "COLOR_MODE", 0);
+ blfLevel = settingsini.GetInt("SRLOADER", "BLUE_LIGHT_FILTER_LEVEL", 0);
+ guiLanguage = settingsini.GetInt("SRLOADER", "LANGUAGE", -1);
+ titleLanguage = settingsini.GetInt("SRLOADER", "TITLELANGUAGE", titleLanguage);
+ sdRemoveDetect = settingsini.GetInt("SRLOADER", "SD_REMOVE_DETECT", 1);
+ useGbarunner = settingsini.GetInt("SRLOADER", "USE_GBARUNNER2", 0);
+ if (!isRegularDS) useGbarunner = true;
+ gbar2DldiAccess = settingsini.GetInt("SRLOADER", "GBAR2_DLDI_ACCESS", gbar2DldiAccess);
+ theme = settingsini.GetInt("SRLOADER", "THEME", 0);
+ subtheme = settingsini.GetInt("SRLOADER", "SUB_THEME", 0);
+ showDirectories = settingsini.GetInt("SRLOADER", "SHOW_DIRECTORIES", 1);
+ showBoxArt = settingsini.GetInt("SRLOADER", "SHOW_BOX_ART", showBoxArt);
+ animateDsiIcons = settingsini.GetInt("SRLOADER", "ANIMATE_DSI_ICONS", 0);
+ if (consoleModel < 2) {
+ launcherApp = settingsini.GetInt("SRLOADER", "LAUNCHER_APP", launcherApp);
+ }
+
+ flashcard = settingsini.GetInt("SRLOADER", "FLASHCARD", flashcard);
+
+ previousUsedDevice = settingsini.GetInt("SRLOADER", "PREVIOUS_USED_DEVICE", previousUsedDevice);
+ secondaryDevice = bothSDandFlashcard() ? settingsini.GetInt("SRLOADER", "SECONDARY_DEVICE", secondaryDevice) : flashcardFound();
+ fcSaveOnSd = settingsini.GetInt("SRLOADER", "FC_SAVE_ON_SD", fcSaveOnSd);
+
+ slot1LaunchMethod = settingsini.GetInt("SRLOADER", "SLOT1_LAUNCHMETHOD", slot1LaunchMethod);
+ useBootstrap = settingsini.GetInt("SRLOADER", "USE_BOOTSTRAP", useBootstrap);
+ bootstrapFile = settingsini.GetInt("SRLOADER", "BOOTSTRAP_FILE", 0);
+ //snesEmulator = settingsini.GetInt("SRLOADER", "SNES_EMULATOR", snesEmulator);
+ smsGgInRam = settingsini.GetInt("SRLOADER", "SMS_GG_IN_RAM", smsGgInRam);
+
+ show12hrClock = settingsini.GetInt("SRLOADER", "SHOW_12H_CLOCK", show12hrClock);
+
+ unlaunchBg = settingsini.GetString("SRLOADER", "UNLAUNCH_BG", unlaunchBg);
+ charUnlaunchBg = unlaunchBg.c_str();
+ removeLauncherPatches = settingsini.GetInt("SRLOADER", "UNLAUNCH_PATCH_REMOVE", removeLauncherPatches);
+
+ // Default nds-bootstrap settings
+ gameLanguage = settingsini.GetInt("NDS-BOOTSTRAP", "LANGUAGE", -1);
+ boostCpu = settingsini.GetInt("NDS-BOOTSTRAP", "BOOST_CPU", 0);
+ boostVram = settingsini.GetInt("NDS-BOOTSTRAP", "BOOST_VRAM", 0);
+ bstrap_dsiMode = settingsini.GetInt("NDS-BOOTSTRAP", "DSI_MODE", 0);
+ bstrap_extendedMemory = settingsini.GetInt("NDS-BOOTSTRAP", "EXTENDED_MEMORY", 0);
+
+ forceSleepPatch = settingsini.GetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH", 0);
+ dsiWareBooter = settingsini.GetInt("SRLOADER", "DSIWARE_BOOTER", dsiWareBooter);
+
+ dsiWareSrlPath = settingsini.GetString("SRLOADER", "DSIWARE_SRL", dsiWareSrlPath);
+ dsiWarePubPath = settingsini.GetString("SRLOADER", "DSIWARE_PUB", dsiWarePubPath);
+ dsiWarePrvPath = settingsini.GetString("SRLOADER", "DSIWARE_PRV", dsiWarePrvPath);
+ launchType[0] = settingsini.GetInt("SRLOADER", "LAUNCH_TYPE", launchType[0]);
+ launchType[1] = settingsini.GetInt("SRLOADER", "SECONDARY_LAUNCH_TYPE", launchType[1]);
+ romPath[0] = settingsini.GetString("SRLOADER", "ROM_PATH", romPath[0]);
+ romPath[1] = settingsini.GetString("SRLOADER", "SECONDARY_ROM_PATH", romPath[1]);
+
+ wideScreen = settingsini.GetInt("SRLOADER", "WIDESCREEN", wideScreen);
+}
+
+void SaveSettings(void) {
+ // GUI
+ CIniFile settingsini( settingsinipath );
+
+ // UI settings.
+ if (!gotosettings) {
+ settingsini.SetString("SRLOADER", "DSIWARE_SRL", dsiWareSrlPath);
+ settingsini.SetString("SRLOADER", "DSIWARE_PUB", dsiWarePubPath);
+ settingsini.SetString("SRLOADER", "DSIWARE_PRV", dsiWarePrvPath);
+ settingsini.SetInt("SRLOADER", "SLOT1_LAUNCHED", slot1Launched);
+ settingsini.SetInt("SRLOADER", "LAUNCH_TYPE", launchType[0]);
+ settingsini.SetInt("SRLOADER", "SECONDARY_LAUNCH_TYPE", launchType[1]);
+ settingsini.SetInt("SRLOADER", "HOMEBREW_BOOTSTRAP", homebrewBootstrap);
+ settingsini.SetInt("SRLOADER", "HOMEBREW_HAS_WIDE", homebrewHasWide);
+ }
+ //settingsini.SetInt("SRLOADER", "THEME", theme);
+ //settingsini.SetInt("SRLOADER", "SUB_THEME", subtheme);
+ settingsini.SaveIniFile(settingsinipath);
+}
+
+bool isDSPhat(void) {
+ return (isRegularDS && !isDSLite);
+}
+
+bool useBackend = false;
+
+using namespace std;
+
+bool showbubble = false;
+bool showSTARTborder = false;
+
+bool titleboxXmoveleft = false;
+bool titleboxXmoveright = false;
+
+bool applaunchprep = false;
+
+int spawnedtitleboxes = 0;
+
+//char usernameRendered[10];
+//bool usernameRenderedDone = false;
+
+touchPosition touch;
+
+//---------------------------------------------------------------------------------
+void stop (void) {
+//---------------------------------------------------------------------------------
+ while (1) {
+ swiWaitForVBlank();
+ }
+}
+
+/**
+ * Set donor SDK version for a specific game.
+ */
+int SetDonorSDK(const char* filename) {
+ FILE *f_nds_file = fopen(filename, "rb");
+
+ char game_TID[5];
+ grabTID(f_nds_file, game_TID);
+ fclose(f_nds_file);
+ game_TID[4] = 0;
+ game_TID[3] = 0;
+
+ for (auto i : donorMap) {
+ if (i.first == 5 && game_TID[0] == 'V')
+ return 5;
+
+ if (i.second.find(game_TID) != i.second.cend())
+ return i.first;
+ }
+
+ return 0;
+}
+
+/**
+ * Set MPU settings for a specific game.
+ */
+void SetMPUSettings(const char* filename) {
+ FILE *f_nds_file = fopen(filename, "rb");
+
+ char game_TID[5];
+ fseek(f_nds_file, offsetof(sNDSHeaderExt, gameCode), SEEK_SET);
+ fread(game_TID, 1, 4, f_nds_file);
+ game_TID[4] = 0;
+ game_TID[3] = 0;
+ fclose(f_nds_file);
+
+ scanKeys();
+ int pressed = keysHeld();
+
+ if (pressed & KEY_B) {
+ mpuregion = 1;
+ } else if (pressed & KEY_X) {
+ mpuregion = 2;
+ } else if (pressed & KEY_Y) {
+ mpuregion = 3;
+ } else {
+ mpuregion = 0;
+ }
+
+ if(pressed & KEY_RIGHT) {
+ mpusize = 3145728;
+ } else if(pressed & KEY_LEFT) {
+ mpusize = 1;
+ } else {
+ mpusize = 0;
+ }
+
+ // Check for games that need an MPU size of 3 MB.
+ // TODO: If the list gets large enough, switch to bsearch().
+ for (unsigned int i = 0; i < sizeof(mpu_3MB_list)/sizeof(mpu_3MB_list[0]); i++) {
+ if (!memcmp(game_TID, mpu_3MB_list[i], 3)) {
+ // Found a match.
+ mpuregion = 1;
+ mpusize = 3145728;
+ break;
+ }
+ }
+}
+
+/**
+ * Move nds-bootstrap's cardEngine_arm9 to cached memory region for some games.
+ */
+void SetSpeedBumpExclude(const char* filename) {
+ if (!isDSiMode() || (perGameSettings_heapShrink >= 0 && perGameSettings_heapShrink < 2)) {
+ ceCached = perGameSettings_heapShrink;
+ return;
+ }
+
+ FILE *f_nds_file = fopen(filename, "rb");
+
+ char game_TID[5];
+ fseek(f_nds_file, offsetof(sNDSHeaderExt, gameCode), SEEK_SET);
+ fread(game_TID, 1, 4, f_nds_file);
+ fclose(f_nds_file);
+
+ // TODO: If the list gets large enough, switch to bsearch().
+ for (unsigned int i = 0; i < sizeof(sbeList2)/sizeof(sbeList2[0]); i++) {
+ if (memcmp(game_TID, sbeList2[i], 3) == 0) {
+ // Found match
+ ceCached = false;
+ }
+ }
+}
+
+/**
+ * Fix AP for some games.
+ */
+std::string setApFix(const char *filename) {
+ remove("fat:/_nds/nds-bootstrap/apFix.ips");
+
+ bool ipsFound = false;
+ char ipsPath[256];
+ snprintf(ipsPath, sizeof(ipsPath), "%s:/_nds/TWiLightMenu/apfix/%s.ips", sdFound() ? "sd" : "fat", filename);
+ ipsFound = (access(ipsPath, F_OK) == 0);
+
+ if (!ipsFound) {
+ FILE *f_nds_file = fopen(filename, "rb");
+
+ char game_TID[5];
+ u16 headerCRC16 = 0;
+ fseek(f_nds_file, offsetof(sNDSHeaderExt, gameCode), SEEK_SET);
+ fread(game_TID, 1, 4, f_nds_file);
+ fseek(f_nds_file, offsetof(sNDSHeaderExt, headerCRC16), SEEK_SET);
+ fread(&headerCRC16, sizeof(u16), 1, f_nds_file);
+ fclose(f_nds_file);
+ game_TID[4] = 0;
+
+ snprintf(ipsPath, sizeof(ipsPath), "%s:/_nds/TWiLightMenu/apfix/%s-%X.ips", sdFound() ? "sd" : "fat", game_TID, headerCRC16);
+ ipsFound = (access(ipsPath, F_OK) == 0);
+ }
+
+ if (ipsFound) {
+ if (secondaryDevice && sdFound()) {
+ mkdir("fat:/_nds", 0777);
+ mkdir("fat:/_nds/nds-bootstrap", 0777);
+ fcopy(ipsPath, "fat:/_nds/nds-bootstrap/apFix.ips");
+ return "fat:/_nds/nds-bootstrap/apFix.ips";
+ }
+ return ipsPath;
+ }
+
+ return "";
+}
+
+/**
+ * Enable widescreen for some games.
+ */
+void SetWidescreen(const char *filename) {
+ remove("/_nds/nds-bootstrap/wideCheatData.bin");
+
+ bool useWidescreen = (perGameSettings_wideScreen == -1 ? wideScreen : perGameSettings_wideScreen);
+
+ if ((isDSiMode() && arm7SCFGLocked) || consoleModel < 2 || !useWidescreen
+ || (access("sd:/luma/sysmodules/TwlBg.cxi", F_OK) != 0)) {
+ homebrewHasWide = false;
+ return;
+ }
+
+ bool wideCheatFound = false;
+ char wideBinPath[256];
+ if (launchType[secondaryDevice] == 1) {
+ snprintf(wideBinPath, sizeof(wideBinPath), "sd:/_nds/TWiLightMenu/widescreen/%s.bin", filename);
+ wideCheatFound = (access(wideBinPath, F_OK) == 0);
+ }
+
+ if (slot1Launched) {
+ // Reset Slot-1 to allow reading card header
+ sysSetCardOwner (BUS_OWNER_ARM9);
+ disableSlot1();
+ for(int i = 0; i < 25; i++) { swiWaitForVBlank(); }
+ enableSlot1();
+ for(int i = 0; i < 15; i++) { swiWaitForVBlank(); }
+
+ cardReadHeader((uint8*)&ndsCardHeader);
+
+ char game_TID[5];
+ tonccpy(game_TID, ndsCardHeader.gameCode, 4);
+ game_TID[4] = 0;
+
+ snprintf(wideBinPath, sizeof(wideBinPath), "sd:/_nds/TWiLightMenu/widescreen/%s-%X.bin", game_TID, ndsCardHeader.headerCRC16);
+ wideCheatFound = (access(wideBinPath, F_OK) == 0);
+ } else if (!wideCheatFound) {
+ FILE *f_nds_file = fopen(filename, "rb");
+
+ char game_TID[5];
+ u16 headerCRC16 = 0;
+ fseek(f_nds_file, offsetof(sNDSHeaderExt, gameCode), SEEK_SET);
+ fread(game_TID, 1, 4, f_nds_file);
+ fseek(f_nds_file, offsetof(sNDSHeaderExt, headerCRC16), SEEK_SET);
+ fread(&headerCRC16, sizeof(u16), 1, f_nds_file);
+ fclose(f_nds_file);
+ game_TID[4] = 0;
+
+ snprintf(wideBinPath, sizeof(wideBinPath), "sd:/_nds/TWiLightMenu/widescreen/%s-%X.bin", game_TID, headerCRC16);
+ wideCheatFound = (access(wideBinPath, F_OK) == 0);
+ }
+
+ if (isHomebrew[secondaryDevice]) {
+ FILE *f_nds_file = fopen(filename, "rb");
+
+ char game_TID[5];
+ u8 romVersion = 0;
+ fseek(f_nds_file, offsetof(sNDSHeaderExt, gameCode), SEEK_SET);
+ fread(game_TID, 1, 4, f_nds_file);
+ fseek(f_nds_file, offsetof(sNDSHeaderExt, romversion), SEEK_SET);
+ fread(&romVersion, sizeof(u8), 1, f_nds_file);
+ fclose(f_nds_file);
+ game_TID[4] = 0;
+
+ homebrewHasWide = (game_TID[0] == 'W' || romVersion == 0x57);
+ return;
+ }
+
+ if (wideCheatFound) {
+ const char* resultText1;
+ const char* resultText2;
+ mkdir("/_nds", 0777);
+ mkdir("/_nds/nds-bootstrap", 0777);
+ if (fcopy(wideBinPath, "/_nds/nds-bootstrap/wideCheatData.bin") == 0) {
+ return;
+ } else {
+ resultText1 = "Failed to copy widescreen";
+ resultText2 = "code for the game.";
+ }
+ remove("/_nds/nds-bootstrap/wideCheatData.bin");
+ int textXpos[2] = {0};
+ textXpos[0] = 72;
+ textXpos[1] = 84;
+ clearText();
+ printSmallCentered(false, textXpos[0], resultText1);
+ printSmallCentered(false, textXpos[1], resultText2);
+ fadeType = true; // Fade in from white
+ for (int i = 0; i < 60 * 3; i++) {
+ swiWaitForVBlank(); // Wait 3 seconds
+ }
+ fadeType = false; // Fade to white
+ for (int i = 0; i < 25; i++) {
+ swiWaitForVBlank();
+ }
+ }
+}
+
+char filePath[PATH_MAX];
+
+//---------------------------------------------------------------------------------
+void doPause() {
+//---------------------------------------------------------------------------------
+ // iprintf("Press start...\n");
+ // printSmall(false, x, y, "Press start...");
+ while(1) {
+ scanKeys();
+ if(keysDown() & KEY_START)
+ break;
+ swiWaitForVBlank();
+ }
+ scanKeys();
+}
+
+mm_sound_effect snd_launch;
+mm_sound_effect snd_select;
+mm_sound_effect snd_stop;
+mm_sound_effect snd_wrong;
+mm_sound_effect snd_back;
+mm_sound_effect snd_switch;
+mm_sound_effect snd_backlight;
+
+void InitSound() {
+ mmInitDefaultMem((mm_addr)soundbank_bin);
+
+ mmLoadEffect( SFX_LAUNCH );
+ mmLoadEffect( SFX_SELECT );
+ mmLoadEffect( SFX_STOP );
+ mmLoadEffect( SFX_WRONG );
+ mmLoadEffect( SFX_BACK );
+ mmLoadEffect( SFX_SWITCH );
+ mmLoadEffect( SFX_BACKLIGHT );
+
+ snd_launch = {
+ { SFX_LAUNCH } , // id
+ (int)(1.0f * (1<<10)), // rate
+ 0, // handle
+ 255, // volume
+ 128, // panning
+ };
+ snd_select = {
+ { SFX_SELECT } , // id
+ (int)(1.0f * (1<<10)), // rate
+ 0, // handle
+ 255, // volume
+ 128, // panning
+ };
+ snd_stop = {
+ { SFX_STOP } , // id
+ (int)(1.0f * (1<<10)), // rate
+ 0, // handle
+ 255, // volume
+ 128, // panning
+ };
+ snd_wrong = {
+ { SFX_WRONG } , // id
+ (int)(1.0f * (1<<10)), // rate
+ 0, // handle
+ 255, // volume
+ 128, // panning
+ };
+ snd_back = {
+ { SFX_BACK } , // id
+ (int)(1.0f * (1<<10)), // rate
+ 0, // handle
+ 255, // volume
+ 128, // panning
+ };
+ snd_switch = {
+ { SFX_SWITCH } , // id
+ (int)(1.0f * (1<<10)), // rate
+ 0, // handle
+ 255, // volume
+ 128, // panning
+ };
+ snd_backlight = {
+ { SFX_BACKLIGHT } , // id
+ (int)(1.0f * (1<<10)), // rate
+ 0, // handle
+ 255, // volume
+ 128, // panning
+ };
+}
+
+void loadGameOnFlashcard (const char* ndsPath, bool dsGame) {
+ bool runNds_boostCpu = false;
+ bool runNds_boostVram = false;
+ std::string filename = ndsPath;
+ const size_t last_slash_idx = filename.find_last_of("/");
+ if (std::string::npos != last_slash_idx) {
+ filename.erase(0, last_slash_idx + 1);
+ }
+
+ loadPerGameSettings(filename);
+
+ if ((REG_SCFG_EXT != 0) && dsGame) {
+ runNds_boostCpu = perGameSettings_boostCpu == -1 ? boostCpu : perGameSettings_boostCpu;
+ runNds_boostVram = perGameSettings_boostVram == -1 ? boostVram : perGameSettings_boostVram;
+ }
+ if (dsGame) {
+ // Move .sav outside of "saves" folder for flashcard kernel usage
+ const char *typeToReplace = ".nds";
+ if (extention(filename, ".dsi")) {
+ typeToReplace = ".dsi";
+ } else if (extention(filename, ".ids")) {
+ typeToReplace = ".ids";
+ } else if (extention(filename, ".srl")) {
+ typeToReplace = ".srl";
+ } else if (extention(filename, ".app")) {
+ typeToReplace = ".app";
+ }
+
+ std::string savename = replaceAll(filename, typeToReplace, getSavExtension());
+ std::string savenameFc = replaceAll(filename, typeToReplace, ".sav");
+ std::string romFolderNoSlash = romfolder[true];
+ RemoveTrailingSlashes(romFolderNoSlash);
+ std::string saveFolder = romFolderNoSlash + "/saves";
+ mkdir(saveFolder.c_str(), 0777);
+ std::string savepath = romFolderNoSlash + "/saves/" + savename;
+ std::string savepathFc = romFolderNoSlash + "/" + savenameFc;
+ rename(savepath.c_str(), savepathFc.c_str());
+ }
+
+ std::string fcPath;
+ int err = 0;
+
+ switch (flashcard) {
+ case 1: {
+ CIniFile fcrompathini("fat:/TTMenu/YSMenu.ini");
+ fcPath = replaceAll(ndsPath, "fat:/", slashchar);
+ fcrompathini.SetString("YSMENU", "AUTO_BOOT", fcPath);
+ fcrompathini.SaveIniFile("fat:/TTMenu/YSMenu.ini");
+ err = runNdsFile("fat:/YSMenu.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ case 6: // Blue card can run wood 1.62 so this should work?
+ case 2: // And clones that can run wood (no N5)
+ case 3: {
+ CIniFile fcrompathini("fat:/_wfwd/lastsave.ini");
+ fcPath = replaceAll(ndsPath, "fat:/", woodfat);
+ fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
+ fcrompathini.SaveIniFile("fat:/_wfwd/lastsave.ini");
+ err = runNdsFile("fat:/Wfwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ case 7: {
+ CIniFile fcrompathini("fat:/_dstwo/autoboot.ini");
+ fcPath = replaceAll(ndsPath, "fat:/", dstwofat);
+ fcrompathini.SetString("Dir Info", "fullName", fcPath);
+ fcrompathini.SaveIniFile("fat:/_dstwo/autoboot.ini");
+ err = runNdsFile("fat:/_dstwo/autoboot.nds", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ case 5: // ?
+ case 4: {
+ CIniFile fcrompathini("fat:/_afwd/lastsave.ini");
+ fcPath = replaceAll(ndsPath, "fat:/", woodfat);
+ fcrompathini.SetString("Save Info", "lastLoaded", fcPath);
+ fcrompathini.SaveIniFile("fat:/_afwd/lastsave.ini");
+ err = runNdsFile("fat:/Afwd.dat", 0, NULL, true, true, true, runNds_boostCpu, runNds_boostVram);
+ break;
+ }
+ default: {
+ err = 1337;
+ return;
+ }
+ }
+
+
+ char text[32];
+ snprintf(text, sizeof(text), "Start failed. Error %i", err);
+ ClearBrightness();
+ printSmall(false, 4, 4, text);
+ if (err == 0) {
+ printSmall(false, 4, 20, "Flashcard may be unsupported.");
+ printSmall(false, 4, 52, "Flashcard name:");
+ printSmall(false, 4, 68, io_dldi_data->friendlyName);
+ }
+ stop();
+}
+
+void loadROMselect()
+{
+ if (!isDSiMode()) {
+ chdir("fat:/");
+ } else if (sdFound()) {
+ chdir("sd:/");
+ }
+ /*if (theme == 3)
+ {
+ runNdsFile("/_nds/TWiLightMenu/akmenu.srldr", 0, NULL, true, false, false, true, true);
+ }
+ else */if (theme == 2 || theme == 6)
+ {
+ runNdsFile("/_nds/TWiLightMenu/r4menu.srldr", 0, NULL, true, false, false, true, true);
+ }
+ else
+ {
+ runNdsFile("/_nds/TWiLightMenu/dsimenu.srldr", 0, NULL, true, false, false, true, true);
+ }
+}
+
+void unlaunchRomBoot(const char* rom) {
+ char unlaunchDevicePath[256] = {0};
+ if (strncmp(rom, "cart:", 5) == 0) {
+ sprintf(unlaunchDevicePath, "cart:");
+ } else {
+ sprintf(unlaunchDevicePath, "__%s", rom);
+ unlaunchDevicePath[0] = 's';
+ unlaunchDevicePath[1] = 'd';
+ unlaunchDevicePath[2] = 'm';
+ unlaunchDevicePath[3] = 'c';
+ }
+
+ tonccpy((u8*)0x02000800, unlaunchAutoLoadID, 12);
+ *(u16*)(0x0200080C) = 0x3F0; // Unlaunch Length for CRC16 (fixed, must be 3F0h)
+ *(u16*)(0x0200080E) = 0; // Unlaunch CRC16 (empty)
+ *(u32*)(0x02000810) = 0; // Unlaunch Flags
+ *(u32*)(0x02000810) |= BIT(0); // Load the title at 2000838h
+ *(u32*)(0x02000810) |= BIT(1); // Use colors 2000814h
+ *(u16*)(0x02000814) = 0x7FFF; // Unlaunch Upper screen BG color (0..7FFFh)
+ *(u16*)(0x02000816) = 0x7FFF; // Unlaunch Lower screen BG color (0..7FFFh)
+ toncset((u8*)0x02000818, 0, 0x20+0x208+0x1C0); // Unlaunch Reserved (zero)
+ int i2 = 0;
+ for (int i = 0; i < (int)sizeof(unlaunchDevicePath); i++) {
+ *(u8*)(0x02000838+i2) = unlaunchDevicePath[i]; // Unlaunch Device:/Path/Filename.ext (16bit Unicode,end by 0000h)
+ i2 += 2;
+ }
+ while (*(u16*)(0x0200080E) == 0) { // Keep running, so that CRC16 isn't 0
+ *(u16*)(0x0200080E) = swiCRC16(0xFFFF, (void*)0x02000810, 0x3F0); // Unlaunch CRC16
+ }
+
+ DC_FlushAll(); // Make reboot not fail
+ fifoSendValue32(FIFO_USER_02, 1); // Reboot into DSiWare title, booted via Unlaunch
+ stop();
+}
+
+void unlaunchSetHiyaBoot(void) {
+ tonccpy((u8*)0x02000800, unlaunchAutoLoadID, 12);
+ *(u16*)(0x0200080C) = 0x3F0; // Unlaunch Length for CRC16 (fixed, must be 3F0h)
+ *(u16*)(0x0200080E) = 0; // Unlaunch CRC16 (empty)
+ *(u32*)(0x02000810) |= BIT(0); // Load the title at 2000838h
+ *(u32*)(0x02000810) |= BIT(1); // Use colors 2000814h
+ *(u16*)(0x02000814) = 0x7FFF; // Unlaunch Upper screen BG color (0..7FFFh)
+ *(u16*)(0x02000816) = 0x7FFF; // Unlaunch Lower screen BG color (0..7FFFh)
+ toncset((u8*)0x02000818, 0, 0x20+0x208+0x1C0); // Unlaunch Reserved (zero)
+ int i2 = 0;
+ for (int i = 0; i < 14; i++) {
+ *(u8*)(0x02000838+i2) = hiyaNdsPath[i]; // Unlaunch Device:/Path/Filename.ext (16bit Unicode,end by 0000h)
+ i2 += 2;
+ }
+ while (*(u16*)(0x0200080E) == 0) { // Keep running, so that CRC16 isn't 0
+ *(u16*)(0x0200080E) = swiCRC16(0xFFFF, (void*)0x02000810, 0x3F0); // Unlaunch CRC16
+ }
+}
+
+/**
+ * Reboot into an SD game when in DS mode.
+ */
+void ntrStartSdGame(void) {
+ if (consoleModel == 0) {
+ unlaunchRomBoot("sd:/_nds/TWiLightMenu/resetgame.srldr");
+ } else {
+ tonccpy((u32 *)0x02000300, sr_data_srllastran, 0x020);
+ DC_FlushAll(); // Make reboot not fail
+ fifoSendValue32(FIFO_USER_02, 1);
+ stop();
+ }
+}
+
+void dsCardLaunch() {
+ *(u32*)(0x02000300) = 0x434E4C54; // Set "CNLT" warmboot flag
+ *(u16*)(0x02000304) = 0x1801;
+ *(u32*)(0x02000308) = 0x43415254; // "CART"
+ *(u32*)(0x0200030C) = 0x00000000;
+ *(u32*)(0x02000310) = 0x43415254; // "CART"
+ *(u32*)(0x02000314) = 0x00000000;
+ *(u32*)(0x02000318) = 0x00000013;
+ *(u32*)(0x0200031C) = 0x00000000;
+ while (*(u16*)(0x02000306) == 0) { // Keep running, so that CRC16 isn't 0
+ *(u16*)(0x02000306) = swiCRC16(0xFFFF, (void*)0x02000308, 0x18);
+ }
+
+ unlaunchSetHiyaBoot();
+
+ DC_FlushAll(); // Make reboot not fail
+ fifoSendValue32(FIFO_USER_02, 1); // Reboot into DSiWare title, booted via Launcher
+ stop();
+}
+
+void directCardLaunch() {
+ /*if (memcmp(ndsCardHeader.gameCode, "ALXX", 4) == 0) {
+ u16 alxxBannerCrc = 0;
+ extern u32 arm9StartSig[4];
+ cardRead(0x75600, &arm9StartSig, 0x10);
+ cardRead(0x174602, &alxxBannerCrc, sizeof(u16));
+ if ((arm9StartSig[0] == 0xE58D0008
+ && arm9StartSig[1] == 0xE1500005
+ && arm9StartSig[2] == 0xBAFFFFC5
+ && arm9StartSig[3] == 0xE59D100C)
+ || alxxBannerCrc != 0xBA52)
+ {
+ if (sdFound()) {
+ chdir("sd:/");
+ }
+ int err = runNdsFile ("/_nds/TWiLightMenu/dstwoLaunch.srldr", 0, NULL, true, true, true, boostCpu, boostVram);
+ char text[32];
+ snprintf(text, sizeof(text), "Start failed. Error %i", err);
+ ClearBrightness();
+ printSmall(false, 4, 4, text);
+ stop();
+ }
+ }*/
+ SetWidescreen(NULL);
+ if (sdFound()) {
+ chdir("sd:/");
+ }
+ int err = runNdsFile ("/_nds/TWiLightMenu/slot1launch.srldr", 0, NULL, true, true, false, true, true);
+ char text[32];
+ snprintf(text, sizeof(text), "Start failed. Error %i", err);
+ ClearBrightness();
+ printSmall(false, 4, 4, text);
+ stop();
+}
+
+void printLastPlayedText(int num) {
+ printSmallCentered(false, 24, iconYpos[num]+BOX_PY+BOX_PY_spacing2, "Last-played game");
+ printSmallCentered(false, 24, iconYpos[num]+BOX_PY+BOX_PY_spacing3, "will appear here.");
+}
+
+void refreshNdsCard() {
+ if (cardRefreshed) return;
+
+ if (arm7SCFGLocked && showBoxArt) {
+ loadBoxArt("nitro:/graphics/boxart_unknown.png");
+ } else if ((cardInit(true) == 0) && showBoxArt) {
+ char game_TID[5] = {0};
+ tonccpy(&game_TID, ndsCardHeader.gameCode, 4);
+
+ char boxArtPath[256];
+ sprintf (boxArtPath, (sdFound() ? "sd:/_nds/TWiLightMenu/boxart/%s.png" : "fat:/_nds/TWiLightMenu/boxart/%s.png"), game_TID);
+ loadBoxArt(boxArtPath); // Load box art
+ } else if (showBoxArt) {
+ loadBoxArt("nitro:/graphics/boxart_unknown.png");
+ }
+
+ getGameInfo(1, false, "slot1");
+ iconUpdate (1, false, "slot1");
+ bnrRomType[1] = 0;
+ boxArtType[1] = 0;
+
+ // Power off after done retrieving info
+ disableSlot1();
+
+ cardRefreshed = true;
+ cardEjected = false;
+}
+
+void printNdsCartBannerText() {
+ if (cardEjected) {
+ printSmallCentered(false, 24, iconYpos[0]+BOX_PY+BOX_PY_spacing2, "There is no Game Card");
+ printSmallCentered(false, 24, iconYpos[0]+BOX_PY+BOX_PY_spacing3, "inserted.");
+ } else if (arm7SCFGLocked) {
+ printSmallCentered(false, 24, iconYpos[0]+BOX_PY+BOX_PY_spacing1, "Start Game Card");
+ } else {
+ titleUpdate(1, false, "slot1");
+ }
+}
+
+void printGbaBannerText() {
+ printSmallCentered(false, 24, iconYpos[3]+BOX_PY+BOX_PY_spacing1, isRegularDS ? gbamodeText : featureUnavailableText);
+}
+
+//---------------------------------------------------------------------------------
+int main(int argc, char **argv) {
+//---------------------------------------------------------------------------------
+
+ defaultExceptionHandler();
+
+ useTwlCfg = (REG_SCFG_EXT!=0 && (*(u8*)0x02000400 & 0x0F) && (*(u8*)0x02000401 == 0) && (*(u8*)0x02000402 == 0) && (*(u8*)0x02000404 == 0) && (*(u8*)0x02000448 != 0));
+
+ extern const DISC_INTERFACE __my_io_dsisd;
+
+ *(u32*)(0x2FFFD0C) = 0x54494D52; // Run reboot timer
+ fatMountSimple("sd", &__my_io_dsisd);
+ fatMountSimple("fat", dldiGetInternal());
+ bool fatInited = (sdFound() || flashcardFound());
+ *(u32*)(0x2FFFD0C) = 0;
+ chdir(sdFound()&&isDSiMode() ? "sd:/" : "fat:/");
+
+ // Read user name
+ /*char *username = (char*)PersonalData->name;
+
+ // text
+ for (int i = 0; i < 10; i++) {
+ if (username[i*2] == 0x00)
+ username[i*2/2] = 0;
+ else
+ username[i*2/2] = username[i*2];
+ }*/
+
+ if (!fatInited) {
+ graphicsInit();
+ fontInit();
+ whiteScreen = true;
+ printSmall(false, 64, 32, "fatinitDefault failed!");
+ fadeType = true;
+ stop();
+ }
+
+ nitroFSInit("/_nds/TWiLightMenu/mainmenu.srldr");
+
+ if (access(settingsinipath, F_OK) != 0 && flashcardFound()) {
+ settingsinipath = "fat:/_nds/TWiLightMenu/settings.ini"; // Fallback to .ini path on flashcard, if not found on SD card, or if SD access is disabled
+ }
+
+ langInit();
+
+ std::string filename[2];
+
+ fifoWaitValue32(FIFO_USER_06);
+ if (fifoGetValue32(FIFO_USER_03) == 0) arm7SCFGLocked = true; // If TWiLight Menu++ is being run from DSiWarehax or flashcard, then arm7 SCFG is locked.
+ u16 arm7_SNDEXCNT = fifoGetValue32(FIFO_USER_07);
+ if (arm7_SNDEXCNT != 0) isRegularDS = false; // If sound frequency setting is found, then the console is not a DS Phat/Lite
+ isDSLite = fifoGetValue32(FIFO_USER_04);
+ fifoSendValue32(FIFO_USER_07, 0);
+
+ LoadSettings();
+ widescreenEffects = (consoleModel >= 2 && wideScreen && access("sd:/luma/sysmodules/TwlBg.cxi", F_OK) == 0);
+
+ snprintf(pictochatPath, sizeof(pictochatPath), "/_nds/pictochat.nds");
+ pictochatFound = (access(pictochatPath, F_OK) == 0);
+
+ if (isDSiMode() && arm7SCFGLocked) {
+ if (consoleModel < 2 && !pictochatFound) {
+ pictochatFound = true;
+ pictochatReboot = true;
+ }
+ dlplayFound = true;
+ dlplayReboot = true;
+ } else {
+ bool nandInited = false;
+ char srcPath[256];
+ u8 regions[3] = {0x41, 0x43, 0x4B};
+
+ if (!pictochatFound && consoleModel == 0) {
+ for (int i = 0; i < 3; i++)
+ {
+ snprintf(pictochatPath, sizeof(pictochatPath), "/title/00030005/484e45%x/content/00000000.app", regions[i]);
+ if (access(pictochatPath, F_OK) == 0)
+ {
+ pictochatFound = true;
+ break;
+ }
+ }
+ }
+ if (!pictochatFound && isDSiMode() && sdFound() && consoleModel == 0) {
+ if (!nandInited) {
+ fatMountSimple("nand", &io_dsi_nand);
+ nandInited = true;
+ }
+ if (access("nand:/", F_OK) == 0) {
+ for (int i = 0; i < 3; i++)
+ {
+ snprintf(srcPath, sizeof(srcPath), "nand:/title/00030005/484e45%x/content/00000000.app", regions[i]);
+ if (access(srcPath, F_OK) == 0)
+ {
+ snprintf(pictochatPath, sizeof(pictochatPath), "/_nds/pictochat.nds");
+ remove(pictochatPath);
+ fcopy(srcPath, pictochatPath); // Copy from NAND
+ pictochatFound = true;
+ break;
+ }
+ }
+ }
+ }
+
+ snprintf(dlplayPath, sizeof(dlplayPath), "/_nds/dlplay.nds");
+ dlplayFound = (access(dlplayPath, F_OK) == 0);
+ if (!dlplayFound && consoleModel == 0) {
+ for (int i = 0; i < 3; i++)
+ {
+ snprintf(dlplayPath, sizeof(dlplayPath), "/title/00030005/484e44%x/content/00000000.app", regions[i]);
+ if (access(dlplayPath, F_OK) == 0) {
+ dlplayFound = true;
+ break;
+ } else if (regions[i] != 0x43 && regions[i] != 0x4B) {
+ snprintf(dlplayPath, sizeof(dlplayPath), "/title/00030005/484e4441/content/00000001.app");
+ if (access(dlplayPath, F_OK) == 0) {
+ dlplayFound = true;
+ break;
+ }
+ }
+ }
+ }
+ if (!dlplayFound && isDSiMode() && sdFound() && consoleModel == 0) {
+ if (!nandInited) {
+ fatMountSimple("nand", &io_dsi_nand);
+ nandInited = true;
+ }
+ if (access("nand:/", F_OK) == 0) {
+ for (int i = 0; i < 3; i++)
+ {
+ snprintf(srcPath, sizeof(srcPath), "nand:/title/00030005/484e44%x/content/00000000.app", regions[i]);
+ if (access(srcPath, F_OK) == 0) {
+ snprintf(dlplayPath, sizeof(dlplayPath), "/_nds/dlplay.nds");
+ remove(dlplayPath);
+ fcopy(srcPath, dlplayPath); // Copy from NAND
+ dlplayFound = true;
+ break;
+ } else if (regions[i] != 0x43 && regions[i] != 0x4B) {
+ snprintf(srcPath, sizeof(srcPath), "nand:/title/00030005/484e4441/content/00000001.app");
+ if (access(srcPath, F_OK) == 0) {
+ snprintf(dlplayPath, sizeof(dlplayPath), "/_nds/dlplay.nds");
+ remove(dlplayPath);
+ fcopy(srcPath, dlplayPath); // Copy from NAND
+ dlplayFound = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (!dlplayFound && consoleModel >= 2) {
+ dlplayFound = true;
+ dlplayReboot = true;
+ }
+ }
+
+ if (isDSiMode() && sdFound() && consoleModel < 2 && launcherApp != -1) {
+ u8 setRegion = 0;
+ if (sysRegion == -1) {
+ // Determine SysNAND region by searching region of System Settings on SDNAND
+ char tmdpath[256];
+ for (u8 i = 0x41; i <= 0x5A; i++)
+ {
+ snprintf(tmdpath, sizeof(tmdpath), "sd:/title/00030015/484e42%x/content/title.tmd", i);
+ if (access(tmdpath, F_OK) == 0)
+ {
+ setRegion = i;
+ break;
+ }
+ }
+ } else {
+ switch(sysRegion) {
+ case 0:
+ default:
+ setRegion = 0x4A; // JAP
+ break;
+ case 1:
+ setRegion = 0x45; // USA
+ break;
+ case 2:
+ setRegion = 0x50; // EUR
+ break;
+ case 3:
+ setRegion = 0x55; // AUS
+ break;
+ case 4:
+ setRegion = 0x43; // CHN
+ break;
+ case 5:
+ setRegion = 0x4B; // KOR
+ break;
+ }
+ }
+
+ snprintf(unlaunchDevicePath, sizeof(unlaunchDevicePath), "nand:/title/00030017/484E41%x/content/0000000%i.app", setRegion, launcherApp);
+ }
+
+ graphicsInit();
+ fontInit();
+
+ iconTitleInit();
+
+ InitSound();
+
+ keysSetRepeat(25,5);
+
+ srand(time(NULL));
+
+ bool menuButtonPressed = false;
+
+ if (flashcardFound()) {
+ // Move .sav back to "saves" folder
+ std::string filename = romPath[true];
+ const size_t last_slash_idx = filename.find_last_of("/");
+ if (std::string::npos != last_slash_idx) {
+ filename.erase(0, last_slash_idx + 1);
+ }
+
+ loadPerGameSettings(filename);
+
+ const char *typeToReplace = ".nds";
+ if (extention(filename, ".dsi")) {
+ typeToReplace = ".dsi";
+ } else if (extention(filename, ".ids")) {
+ typeToReplace = ".ids";
+ } else if (extention(filename, ".srl")) {
+ typeToReplace = ".srl";
+ } else if (extention(filename, ".app")) {
+ typeToReplace = ".app";
+ }
+
+ std::string savename = replaceAll(filename, typeToReplace, getSavExtension());
+ std::string savenameFc = replaceAll(filename, typeToReplace, ".sav");
+ std::string romFolderNoSlash = romfolder[true];
+ RemoveTrailingSlashes(romFolderNoSlash);
+ std::string savepath = romFolderNoSlash + "/saves/" + savename;
+ std::string savepathFc = romFolderNoSlash + "/" + savenameFc;
+ if (access(savepathFc.c_str(), F_OK) == 0) {
+ rename(savepathFc.c_str(), savepath.c_str());
+ }
+ }
+
+ if (consoleModel < 2
+ && previousUsedDevice
+ && bothSDandFlashcard()
+ && launchType[previousUsedDevice] == 3
+ && !dsiWareBooter
+ && (
+ (access(dsiWarePubPath.c_str(), F_OK) == 0 && extention(dsiWarePubPath.c_str(), ".pub"))
+ || (access(dsiWarePrvPath.c_str(), F_OK) == 0 && extention(dsiWarePrvPath.c_str(), ".prv"))
+ )
+ ) {
+ controlTopBright = false;
+ whiteScreen = true;
+ fadeType = true; // Fade in from white
+ printSmallCentered(false, 24, "If this takes a while, close and open");
+ printSmallCentered(false, 38, "the console's lid.");
+ printSmallCentered(false, 86, "Now copying data...");
+ printSmallCentered(false, 100, "Do not turn off the power.");
+ for (int i = 0; i < 30; i++) swiWaitForVBlank();
+ if (access(dsiWarePubPath.c_str(), F_OK) == 0) {
+ fcopy("sd:/_nds/TWiLightMenu/tempDSiWare.pub", dsiWarePubPath.c_str());
+ }
+ if (access(dsiWarePrvPath.c_str(), F_OK) == 0) {
+ fcopy("sd:/_nds/TWiLightMenu/tempDSiWare.prv", dsiWarePrvPath.c_str());
+ }
+ fadeType = false; // Fade to white
+ for (int i = 0; i < 30; i++) swiWaitForVBlank();
+ clearText(false);
+ whiteScreen = false;
+ controlTopBright = true;
+ }
+
+ topBgLoad();
+ bottomBgLoad();
+
+ bool romFound[2] = {false};
+
+ // SD card
+ if (sdFound() && romPath[0] != "" && access(romPath[0].c_str(), F_OK) == 0) {
+ romFound[0] = true;
+
+ romfolder[0] = romPath[0];
+ while (!romfolder[0].empty() && romfolder[0][romfolder[0].size()-1] != '/') {
+ romfolder[0].resize(romfolder[0].size()-1);
+ }
+ chdir(romfolder[0].c_str());
+
+ filename[0] = romPath[0];
+ const size_t last_slash_idx = filename[0].find_last_of("/");
+ if (std::string::npos != last_slash_idx)
+ {
+ filename[0].erase(0, last_slash_idx + 1);
+ }
+
+ if (extention(filename[0], ".nds") || extention(filename[0], ".dsi") || extention(filename[0], ".ids") || extention(filename[0], ".app") || extention(filename[0], ".srl") || extention(filename[0], ".argv")) {
+ getGameInfo(0, false, filename[0].c_str());
+ iconUpdate (0, false, filename[0].c_str());
+ bnrRomType[0] = 0;
+ boxArtType[0] = 0;
+ } else if (extention(filename[0], ".plg") || extention(filename[0], ".rvid") || extention(filename[0], ".mp4") || extention(filename[0], ".a26") || extention(filename[0], ".pce")) {
+ bnrRomType[0] = 9;
+ boxArtType[0] = 0;
+ } else if (extention(filename[0], ".gba")) {
+ bnrRomType[0] = 1;
+ boxArtType[0] = 1;
+ } else if (extention(filename[0], ".gb") || extention(filename[0], ".sgb")) {
+ bnrRomType[0] = 2;
+ boxArtType[0] = 1;
+ } else if (extention(filename[0], ".gbc")) {
+ bnrRomType[0] = 3;
+ boxArtType[0] = 1;
+ } else if (extention(filename[0], ".nes")) {
+ bnrRomType[0] = 4;
+ boxArtType[0] = 2;
+ } else if (extention(filename[0], ".fds")) {
+ bnrRomType[0] = 4;
+ boxArtType[0] = 1;
+ } else if (extention(filename[0], ".sms")) {
+ bnrRomType[0] = 5;
+ boxArtType[0] = 2;
+ } else if (extention(filename[0], ".gg")) {
+ bnrRomType[0] = 6;
+ boxArtType[0] = 2;
+ } else if (extention(filename[0], ".gen")) {
+ bnrRomType[0] = 7;
+ boxArtType[0] = 2;
+ } else if (extention(filename[0], ".smc")) {
+ bnrRomType[0] = 8;
+ boxArtType[0] = 3;
+ } else if (extention(filename[0], ".sfc")) {
+ bnrRomType[0] = 8;
+ boxArtType[0] = 2;
+ }
+ }
+
+ // Flashcard (Secondary device)
+ if (flashcardFound() && romPath[1] != "" && access(romPath[1].c_str(), F_OK) == 0) {
+ romFound[1] = true;
+
+ romfolder[1] = romPath[1];
+ while (!romfolder[1].empty() && romfolder[1][romfolder[1].size()-1] != '/') {
+ romfolder[1].resize(romfolder[1].size()-1);
+ }
+ chdir(romfolder[1].c_str());
+
+ filename[1] = romPath[1];
+ const size_t last_slash_idx = filename[1].find_last_of("/");
+ if (std::string::npos != last_slash_idx)
+ {
+ filename[1].erase(0, last_slash_idx + 1);
+ }
+
+ if (extention(filename[1], ".nds") || extention(filename[1], ".dsi") || extention(filename[1], ".ids") || extention(filename[1], ".app") || extention(filename[1], ".srl") || extention(filename[1], ".argv")) {
+ getGameInfo(1, false, filename[1].c_str());
+ iconUpdate (1, false, filename[1].c_str());
+ bnrRomType[1] = 0;
+ boxArtType[1] = 0;
+ } else if (extention(filename[1], ".plg") || extention(filename[1], ".rvid") || extention(filename[1], ".mp4") || extention(filename[1], ".a26")) {
+ bnrRomType[1] = 9;
+ boxArtType[1] = 0;
+ } else if (extention(filename[1], ".gba")) {
+ bnrRomType[1] = 1;
+ boxArtType[1] = 1;
+ } else if (extention(filename[1], ".gb") || extention(filename[1], ".sgb")) {
+ bnrRomType[1] = 2;
+ boxArtType[1] = 1;
+ } else if (extention(filename[1], ".gbc")) {
+ bnrRomType[1] = 3;
+ boxArtType[1] = 1;
+ } else if (extention(filename[1], ".nes")) {
+ bnrRomType[1] = 4;
+ boxArtType[1] = 2;
+ } else if (extention(filename[1], ".fds")) {
+ bnrRomType[1] = 4;
+ boxArtType[1] = 1;
+ } else if (extention(filename[1], ".sms")) {
+ bnrRomType[1] = 5;
+ boxArtType[1] = 2;
+ } else if (extention(filename[1], ".gg")) {
+ bnrRomType[1] = 6;
+ boxArtType[1] = 2;
+ } else if (extention(filename[1], ".gen")) {
+ bnrRomType[1] = 7;
+ boxArtType[1] = 2;
+ } else if (extention(filename[1], ".smc")) {
+ bnrRomType[1] = 8;
+ boxArtType[1] = 3;
+ } else if (extention(filename[1], ".sfc")) {
+ bnrRomType[1] = 8;
+ boxArtType[1] = 2;
+ }
+
+ if (showBoxArt) {
+ // Store box art path
+ std::string temp_filename = filename[secondaryDevice];
+ char boxArtPath[256];
+ snprintf (boxArtPath, sizeof(boxArtPath), (sdFound() ? "sd:/_nds/TWiLightMenu/boxart/%s.png" : "fat:/_nds/TWiLightMenu/boxart/%s.png"), filename[0].c_str());
+ if ((access(boxArtPath, F_OK) != 0) && (bnrRomType[secondaryDevice] == 0)) {
+ if(extention(filename[0], ".argv")) {
+ vector argarray;
+
+ FILE *argfile = fopen(filename[0].c_str(),"rb");
+ char str[PATH_MAX], *pstr;
+ const char seps[]= "\n\r\t ";
+
+ while( fgets(str, PATH_MAX, argfile) ) {
+ // Find comment and end string there
+ if( (pstr = strchr(str, '#')) )
+ *pstr= '\0';
+
+ // Tokenize arguments
+ pstr= strtok(str, seps);
+
+ while( pstr != NULL ) {
+ argarray.push_back(strdup(pstr));
+ pstr= strtok(NULL, seps);
+ }
+ }
+ fclose(argfile);
+ temp_filename = argarray.at(0);
+ }
+ // Get game's TID
+ FILE *f_nds_file = fopen(temp_filename.c_str(), "rb");
+ char game_TID[5];
+ grabTID(f_nds_file, game_TID);
+ game_TID[4] = 0;
+ fclose(f_nds_file);
+
+ sprintf (boxArtPath, (sdFound() ? "sd:/_nds/TWiLightMenu/boxart/%s.png" : "fat:/_nds/TWiLightMenu/boxart/%s.png"), game_TID);
+ }
+ loadBoxArt(boxArtPath); // Load box art
+ }
+ }
+
+ if (isDSiMode() && !flashcardFound()) {
+ if (REG_SCFG_MC == 0x11) {
+ if (showBoxArt) loadBoxArt("nitro:/graphics/boxart_unknown.png");
+ cardEjected = true;
+ } else {
+ refreshNdsCard();
+ }
+ }
+
+ whiteScreen = false;
+ fadeType = true; // Fade in from white
+ for (int i = 0; i < 30; i++) {
+ swiWaitForVBlank();
+ }
+ topBarLoad();
+ startMenu = true; // Show bottom screen graphics
+ fadeSpeed = false;
+
+ while(1) {
+
+ if (startMenu) {
+ int pressed = 0;
+
+ do {
+ clearText();
+ printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
+ printSmallCentered(false, 112, 6, RetTime().c_str());
+ if (flashcardFound()) {
+ if (romFound[1]) {
+ titleUpdate(1, false, filename[1].c_str());
+ } else {
+ printLastPlayedText(0);
+ }
+ } else if (isDSiMode() && !flashcardFound()) {
+ printNdsCartBannerText();
+ }
+ if (!sdFound()) {
+ printGbaBannerText();
+ } else if (romFound[0]) {
+ titleUpdate(0, false, filename[0].c_str());
+ } else {
+ printLastPlayedText(3);
+ }
+
+ if (isDSiMode() && !flashcardFound()) {
+ if (REG_SCFG_MC == 0x11) {
+ if (cardRefreshed && showBoxArt) {
+ loadBoxArt("nitro:/graphics/boxart_unknown.png");
+ }
+ cardRefreshed = false;
+ cardEjected = true;
+ } else if (cardEjected) {
+ refreshNdsCard();
+ }
+ }
+
+ scanKeys();
+ pressed = keysDownRepeat();
+ touchRead(&touch);
+ checkSdEject();
+ swiWaitForVBlank();
+ } while (!pressed);
+
+ if (pressed & KEY_UP) {
+ if (startMenu_cursorPosition == 2 || startMenu_cursorPosition == 3 || startMenu_cursorPosition == 5) {
+ startMenu_cursorPosition -= 2;
+ mmEffectEx(&snd_select);
+ } else if (startMenu_cursorPosition == 6) {
+ startMenu_cursorPosition -= 3;
+ mmEffectEx(&snd_select);
+ } else {
+ startMenu_cursorPosition--;
+ mmEffectEx(&snd_select);
+ }
+ }
+
+ if (pressed & KEY_DOWN) {
+ if (startMenu_cursorPosition == 1 || startMenu_cursorPosition == 3) {
+ startMenu_cursorPosition += 2;
+ mmEffectEx(&snd_select);
+ } else if (startMenu_cursorPosition >= 0 && startMenu_cursorPosition <= 3) {
+ startMenu_cursorPosition++;
+ mmEffectEx(&snd_select);
+ }
+ }
+
+ if (pressed & KEY_LEFT) {
+ if (startMenu_cursorPosition == 2 || (startMenu_cursorPosition == 5 && isDSiMode() && consoleModel < 2)
+ || startMenu_cursorPosition == 6) {
+ startMenu_cursorPosition--;
+ mmEffectEx(&snd_select);
+ }
+ }
+
+ if (pressed & KEY_RIGHT) {
+ if (startMenu_cursorPosition == 1 || startMenu_cursorPosition == 4 || startMenu_cursorPosition == 5) {
+ startMenu_cursorPosition++;
+ mmEffectEx(&snd_select);
+ }
+ }
+
+ if (pressed & KEY_TOUCH) {
+ if (touch.px >= 33 && touch.px <= 221 && touch.py >= 25 && touch.py <= 69) {
+ startMenu_cursorPosition = 0;
+ menuButtonPressed = true;
+ } else if (touch.px >= 33 && touch.px <= 125 && touch.py >= 73 && touch.py <= 117) {
+ startMenu_cursorPosition = 1;
+ menuButtonPressed = true;
+ } else if (touch.px >= 129 && touch.px <= 221 && touch.py >= 73 && touch.py <= 117) {
+ startMenu_cursorPosition = 2;
+ menuButtonPressed = true;
+ } else if (touch.px >= 33 && touch.px <= 221 && touch.py >= 121 && touch.py <= 165) {
+ startMenu_cursorPosition = 3;
+ menuButtonPressed = true;
+ } else if (touch.px >= 10 && touch.px <= 20 && touch.py >= 175 && touch.py <= 185
+ && isDSiMode() && consoleModel < 2)
+ {
+ startMenu_cursorPosition = 4;
+ menuButtonPressed = true;
+ } else if (touch.px >= 117 && touch.px <= 137 && touch.py >= 170 && touch.py <= 190) {
+ startMenu_cursorPosition = 5;
+ menuButtonPressed = true;
+ } else if (touch.px >= 235 && touch.px <= 244 && touch.py >= 175 && touch.py <= 185) {
+ startMenu_cursorPosition = 6;
+ menuButtonPressed = true;
+ }
+ }
+
+ if (pressed & KEY_A) {
+ menuButtonPressed = true;
+ }
+
+ if (startMenu_cursorPosition < 0) startMenu_cursorPosition = 0;
+ if (startMenu_cursorPosition > 6) startMenu_cursorPosition = 6;
+
+ if (menuButtonPressed) {
+ switch (startMenu_cursorPosition) {
+ case -1:
+ default:
+ break;
+ case 0:
+ if (flashcardFound()) {
+ // Launch last-run ROM (Secondary)
+ if (launchType[1] == 0) {
+ showCursor = false;
+ fadeType = false; // Fade to white
+ mmEffectEx(&snd_launch);
+ for (int i = 0; i < 50; i++) {
+ iconYpos[0] -= 6;
+ clearText();
+ printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
+ printSmallCentered(false, 112, 6, RetTime().c_str());
+ if (romFound[1]) {
+ titleUpdate(1, false, filename[1].c_str());
+ } else {
+ printLastPlayedText(0);
+ }
+ if (!sdFound()) {
+ printGbaBannerText();
+ } else if (romFound[0]) {
+ titleUpdate(0, false, filename[0].c_str());
+ } else {
+ printLastPlayedText(3);
+ }
+ swiWaitForVBlank();
+ }
+ loadROMselect();
+ } else if (launchType[1] > 0) {
+ showCursor = false;
+ fadeType = false; // Fade to white
+ mmEffectEx(&snd_launch);
+ for (int i = 0; i < 50; i++) {
+ iconYpos[0] -= 6;
+ clearText();
+ printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
+ printSmallCentered(false, 112, 6, RetTime().c_str());
+ if (romFound[1]) {
+ titleUpdate(1, false, filename[1].c_str());
+ } else {
+ printLastPlayedText(0);
+ }
+ if (!sdFound()) {
+ printGbaBannerText();
+ } else if (romFound[0]) {
+ titleUpdate(0, false, filename[0].c_str());
+ } else {
+ printLastPlayedText(3);
+ }
+ swiWaitForVBlank();
+ }
+ if (romFound[1]) {
+ applaunch = true;
+ } else {
+ loadROMselect();
+ }
+ }
+ secondaryDevice = true;
+ } else if (!flashcardFound() && REG_SCFG_MC != 0x11) {
+ // Launch Slot-1
+ showCursor = false;
+ fadeType = false; // Fade to white
+ mmEffectEx(&snd_launch);
+ for (int i = 0; i < 50; i++) {
+ iconYpos[0] -= 6;
+ clearText();
+ printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
+ printSmallCentered(false, 112, 6, RetTime().c_str());
+ printNdsCartBannerText();
+ if (romFound[0]) {
+ titleUpdate(0, false, filename[0].c_str());
+ } else {
+ printLastPlayedText(3);
+ }
+ swiWaitForVBlank();
+ }
+ slot1Launched = true;
+ SaveSettings();
+
+ if (slot1LaunchMethod == 0 || arm7SCFGLocked) {
+ dsCardLaunch();
+ } else if (slot1LaunchMethod == 2) {
+ unlaunchRomBoot("cart:");
+ } else {
+ directCardLaunch();
+ }
+ } else {
+ mmEffectEx(&snd_wrong);
+ }
+ break;
+ case 1:
+ if (pictochatFound) {
+ showCursor = false;
+ fadeType = false; // Fade to white
+ mmEffectEx(&snd_launch);
+ for (int i = 0; i < 50; i++) {
+ iconYpos[1] -= 6;
+ clearText();
+ printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
+ printSmallCentered(false, 112, 6, RetTime().c_str());
+ if (!sdFound()) {
+ printGbaBannerText();
+ } else if (romFound[0]) {
+ titleUpdate(0, false, filename[0].c_str());
+ } else {
+ printLastPlayedText(3);
+ }
+ swiWaitForVBlank();
+ }
+
+ // Clear screen with white
+ whiteScreen = true;
+ controlTopBright = false;
+ clearText();
+
+ if (pictochatReboot) {
+ *(u32 *)(0x02000300) = 0x434E4C54; // Set "CNLT" warmboot flag
+ *(u16 *)(0x02000304) = 0x1801;
+
+ switch (sysRegion) {
+ case 4:
+ *(u32 *)(0x02000308) = 0x484E4543;
+ *(u32 *)(0x0200030C) = 0x00030005;
+ *(u32 *)(0x02000310) = 0x484E4543;
+ break;
+ case 5:
+ *(u32 *)(0x02000308) = 0x484E454B;
+ *(u32 *)(0x0200030C) = 0x00030005;
+ *(u32 *)(0x02000310) = 0x484E454B;
+ break;
+ default:
+ *(u32 *)(0x02000308) = 0x484E4541; // "HNEA"
+ *(u32 *)(0x0200030C) = 0x00030005;
+ *(u32 *)(0x02000310) = 0x484E4541; // "HNEA"
+ }
+
+ *(u32 *)(0x02000314) = 0x00030005;
+ *(u32 *)(0x02000318) = 0x00000017;
+ *(u32 *)(0x0200031C) = 0x00000000;
+ while (*(u16 *)(0x02000306) == 0x0000)
+ { // Keep running, so that CRC16 isn't 0
+ *(u16 *)(0x02000306) = swiCRC16(0xFFFF, (void *)0x02000308, 0x18);
+ }
+
+ if (consoleModel < 2) {
+ unlaunchSetHiyaBoot();
+ }
+
+ fifoSendValue32(FIFO_USER_02, 1); // Reboot into DSiWare title, booted via Launcher
+ for (int i = 0; i < 15; i++) swiWaitForVBlank();
+ } else {
+ if (sdFound()) {
+ chdir("sd:/");
+ }
+ int err = runNdsFile (pictochatPath, 0, NULL, true, true, true, false, false);
+ char text[32];
+ snprintf (text, sizeof(text), "Start failed. Error %i", err);
+ clearText();
+ ClearBrightness();
+ printSmall(false, 4, 80, text);
+ stop();
+ }
+ } else {
+ mmEffectEx(&snd_wrong);
+ }
+ break;
+ case 2:
+ if (dlplayFound) {
+ showCursor = false;
+ fadeType = false; // Fade to white
+ mmEffectEx(&snd_launch);
+ for (int i = 0; i < 50; i++) {
+ iconYpos[2] -= 6;
+ clearText();
+ printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
+ printSmallCentered(false, 112, 6, RetTime().c_str());
+ if (!sdFound()) {
+ printGbaBannerText();
+ } else if (romFound[0]) {
+ titleUpdate(0, false, filename[0].c_str());
+ } else {
+ printLastPlayedText(3);
+ }
+ swiWaitForVBlank();
+ }
+
+ // Clear screen with white
+ whiteScreen = true;
+ controlTopBright = false;
+ clearText();
+
+ if (dlplayReboot) {
+ *(u32 *)(0x02000300) = 0x434E4C54; // Set "CNLT" warmboot flag
+ *(u16 *)(0x02000304) = 0x1801;
+
+ switch (sysRegion) {
+ case 4:
+ *(u32 *)(0x02000308) = 0x484E4443;
+ *(u32 *)(0x0200030C) = 0x00030005;
+ *(u32 *)(0x02000310) = 0x484E4443;
+ break;
+ case 5:
+ *(u32 *)(0x02000308) = 0x484E444B;
+ *(u32 *)(0x0200030C) = 0x00030005;
+ *(u32 *)(0x02000310) = 0x484E444B;
+ break;
+ default:
+ *(u32 *)(0x02000308) = 0x484E4441; // "HNDA"
+ *(u32 *)(0x0200030C) = 0x00030005;
+ *(u32 *)(0x02000310) = 0x484E4441; // "HNDA"
+ }
+
+ *(u32 *)(0x02000314) = 0x00030005;
+ *(u32 *)(0x02000318) = 0x00000017;
+ *(u32 *)(0x0200031C) = 0x00000000;
+ while (*(u16 *)(0x02000306) == 0x0000)
+ { // Keep running, so that CRC16 isn't 0
+ *(u16 *)(0x02000306) = swiCRC16(0xFFFF, (void *)0x02000308, 0x18);
+ }
+
+ if (consoleModel < 2) {
+ unlaunchSetHiyaBoot();
+ }
+
+ fifoSendValue32(FIFO_USER_02, 1); // Reboot into DSiWare title, booted via Launcher
+ for (int i = 0; i < 15; i++) swiWaitForVBlank();
+ } else {
+ if (sdFound()) {
+ chdir("sd:/");
+ }
+ int err = runNdsFile (dlplayPath, 0, NULL, true, true, true, false, false);
+ char text[32];
+ snprintf (text, sizeof(text), "Start failed. Error %i", err);
+ clearText();
+ ClearBrightness();
+ printSmall(false, 4, 80, text);
+ stop();
+ }
+ } else {
+ mmEffectEx(&snd_wrong);
+ }
+ break;
+ case 3:
+ if (sdFound()) {
+ // Launch last-run ROM (SD)
+ if (launchType[0] == 0) {
+ showCursor = false;
+ fadeType = false; // Fade to white
+ mmEffectEx(&snd_launch);
+ for (int i = 0; i < 50; i++) {
+ iconYpos[3] -= 6;
+ clearText();
+ printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
+ printSmallCentered(false, 112, 6, RetTime().c_str());
+ if (romFound[0]) {
+ titleUpdate(0, false, filename[0].c_str());
+ } else {
+ printLastPlayedText(3);
+ }
+ swiWaitForVBlank();
+ }
+ loadROMselect();
+ } else if (launchType[0] > 0) {
+ showCursor = false;
+ fadeType = false; // Fade to white
+ mmEffectEx(&snd_launch);
+ for (int i = 0; i < 50; i++) {
+ iconYpos[3] -= 6;
+ clearText();
+ printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
+ printSmallCentered(false, 112, 6, RetTime().c_str());
+ if (romFound[0]) {
+ titleUpdate(0, false, filename[0].c_str());
+ } else {
+ printLastPlayedText(3);
+ }
+ swiWaitForVBlank();
+ }
+ if (romFound[0]) {
+ applaunch = true;
+ } else {
+ loadROMselect();
+ }
+ }
+ secondaryDevice = false;
+ } else if (isRegularDS) {
+ // Switch to GBA mode
+ showCursor = false;
+ fadeType = false; // Fade to white
+ mmEffectEx(&snd_launch);
+ for (int i = 0; i < 50; i++) {
+ iconYpos[3] -= 6;
+ clearText();
+ printSmall(false, 6, 6, "\u2428 Back"); // "(B) Back"
+ printSmallCentered(false, 112, 6, RetTime().c_str());
+ printGbaBannerText();
+ swiWaitForVBlank();
+ }
+ gbaSwitch();
+ } else {
+ mmEffectEx(&snd_wrong);
+ }
+ break;
+ case 4:
+ // Adjust backlight level
+ if (isDSiMode() && consoleModel < 2) {
+ fifoSendValue32(FIFO_USER_04, 1);
+ mmEffectEx(&snd_backlight);
+ }
+ break;
+ case 5:
+ // Launch settings
+ showCursor = false;
+ fadeType = false; // Fade to white
+ mmEffectEx(&snd_launch);
+ for (int i = 0; i < 50; i++) {
+ iconYpos[5] -= 6;
+ swiWaitForVBlank();
+ }
+
+ gotosettings = true;
+ //SaveSettings();
+ if (!isDSiMode()) {
+ chdir("fat:/");
+ } else if (sdFound()) {
+ chdir("sd:/");
+ }
+ int err = runNdsFile ("/_nds/TWiLightMenu/settings.srldr", 0, NULL, true, false, false, true, true);
+ iprintf ("Start failed. Error %i\n", err);
+ break;
+ }
+ if (startMenu_cursorPosition == 6) {
+ // Open manual
+ showCursor = false;
+ fadeType = false; // Fade to white
+ mmEffectEx(&snd_launch);
+ for (int i = 0; i < 50; i++) {
+ iconYpos[6] -= 6;
+ swiWaitForVBlank();
+ }
+ if (!isDSiMode()) {
+ chdir("fat:/");
+ } else if (sdFound()) {
+ chdir("sd:/");
+ }
+ int err = runNdsFile ("/_nds/TWiLightMenu/manual.srldr", 0, NULL, true, false, false, true, true);
+ iprintf ("Start failed. Error %i\n", err);
+ }
+
+ menuButtonPressed = false;
+ }
+
+ if (pressed & KEY_B) {
+ mmEffectEx(&snd_back);
+ fadeType = false; // Fade to white
+ for (int i = 0; i < 50; i++) swiWaitForVBlank();
+ loadROMselect();
+ }
+
+ if ((pressed & KEY_X) && !isRegularDS) {
+ mmEffectEx(&snd_back);
+ fadeType = false; // Fade to white
+ for (int i = 0; i < 50; i++) swiWaitForVBlank();
+ if (!isDSiMode() || launcherApp == -1) {
+ *(u32*)(0x02000300) = 0x434E4C54; // Set "CNLT" warmboot flag
+ *(u16*)(0x02000304) = 0x1801;
+ *(u32*)(0x02000310) = 0x4D454E55; // "MENU"
+ unlaunchSetHiyaBoot();
+ } else {
+ tonccpy((u8*)0x02000800, unlaunchAutoLoadID, 12);
+ *(u16*)(0x0200080C) = 0x3F0; // Unlaunch Length for CRC16 (fixed, must be 3F0h)
+ *(u16*)(0x0200080E) = 0; // Unlaunch CRC16 (empty)
+ *(u32*)(0x02000810) |= BIT(0); // Load the title at 2000838h
+ *(u32*)(0x02000810) |= BIT(1); // Use colors 2000814h
+ *(u16*)(0x02000814) = 0x7FFF; // Unlaunch Upper screen BG color (0..7FFFh)
+ *(u16*)(0x02000816) = 0x7FFF; // Unlaunch Lower screen BG color (0..7FFFh)
+ toncset((u8*)0x02000818, 0, 0x20+0x208+0x1C0); // Unlaunch Reserved (zero)
+ int i2 = 0;
+ for (int i = 0; i < (int)sizeof(unlaunchDevicePath); i++) {
+ *(u8*)(0x02000838+i2) = unlaunchDevicePath[i]; // Unlaunch Device:/Path/Filename.ext (16bit Unicode,end by 0000h)
+ i2 += 2;
+ }
+ while (*(u16*)(0x0200080E) == 0) { // Keep running, so that CRC16 isn't 0
+ *(u16*)(0x0200080E) = swiCRC16(0xFFFF, (void*)0x02000810, 0x3F0); // Unlaunch CRC16
+ }
+ }
+ fifoSendValue32(FIFO_USER_02, 1); // ReturntoDSiMenu
+ }
+
+ }
+
+ ////////////////////////////////////
+ // Launch the item
+
+ if (applaunch) {
+ // Clear screen with white
+ whiteScreen = true;
+ fadeSpeed = true;
+ controlTopBright = false;
+ clearText();
+
+ // Delete previously used DSiWare of flashcard from SD
+ if (!gotosettings && consoleModel < 2 && previousUsedDevice && bothSDandFlashcard()) {
+ if (access("sd:/_nds/TWiLightMenu/tempDSiWare.dsi", F_OK) == 0) {
+ remove("sd:/_nds/TWiLightMenu/tempDSiWare.dsi");
+ }
+ if (access("sd:/_nds/TWiLightMenu/tempDSiWare.pub", F_OK) == 0) {
+ remove("sd:/_nds/TWiLightMenu/tempDSiWare.pub");
+ }
+ if (access("sd:/_nds/TWiLightMenu/tempDSiWare.prv", F_OK) == 0) {
+ remove("sd:/_nds/TWiLightMenu/tempDSiWare.prv");
+ }
+ }
+
+ // Construct a command line
+ getcwd (filePath, PATH_MAX);
+ int pathLen = strlen(filePath);
+ vector argarray;
+
+ if (extention(filename[secondaryDevice], ".argv"))
+ {
+ FILE *argfile = fopen(filename[secondaryDevice].c_str(),"rb");
+ char str[PATH_MAX], *pstr;
+ const char seps[]= "\n\r\t ";
+
+ while( fgets(str, PATH_MAX, argfile) ) {
+ // Find comment and end string there
+ if( (pstr = strchr(str, '#')) )
+ *pstr= '\0';
+
+ // Tokenize arguments
+ pstr= strtok(str, seps);
+
+ while( pstr != NULL ) {
+ argarray.push_back(strdup(pstr));
+ pstr= strtok(NULL, seps);
+ }
+ }
+ fclose(argfile);
+ filename[secondaryDevice] = argarray.at(0);
+ } else {
+ argarray.push_back(strdup(filename[secondaryDevice].c_str()));
+ }
+
+ // Launch DSiWare .nds via Unlaunch
+ if ((isDSiMode() || sdFound()) && isDSiWare[secondaryDevice]) {
+ const char *typeToReplace = ".nds";
+ if (extention(filename[secondaryDevice], ".dsi")) {
+ typeToReplace = ".dsi";
+ } else if (extention(filename[secondaryDevice], ".ids")) {
+ typeToReplace = ".ids";
+ } else if (extention(filename[secondaryDevice], ".srl")) {
+ typeToReplace = ".srl";
+ } else if (extention(filename[secondaryDevice], ".app")) {
+ typeToReplace = ".app";
+ }
+
+ char *name = argarray.at(0);
+ strcpy (filePath + pathLen, name);
+ free(argarray.at(0));
+ argarray.at(0) = filePath;
+
+ dsiWareSrlPath = argarray[0];
+ dsiWarePubPath = replaceAll(argarray[0], typeToReplace, ".pub");
+ dsiWarePrvPath = replaceAll(argarray[0], typeToReplace, ".prv");
+ launchType[secondaryDevice] = (consoleModel>0 ? 1 : 3);
+ SaveSettings();
+
+ sNDSHeaderExt NDSHeader;
+
+ FILE *f_nds_file = fopen(filename[secondaryDevice].c_str(), "rb");
+
+ fread(&NDSHeader, 1, sizeof(NDSHeader), f_nds_file);
+ fclose(f_nds_file);
+
+ whiteScreen = true;
+
+ if ((getFileSize(dsiWarePubPath.c_str()) == 0) && (NDSHeader.pubSavSize > 0)) {
+ clearText();
+ if (flashcard == 8) {
+ // Display nothing
+ } else if (consoleModel >= 2) {
+ printSmallCentered(false, 20, "If this takes a while, press HOME,");
+ printSmallCentered(false, 34, "then press B.");
+ } else {
+ printSmallCentered(false, 20, "If this takes a while, close and open");
+ printSmallCentered(false, 34, "the console's lid.");
+ }
+ printSmall(false, 2, 80, "Creating public save file...");
+ if (!fadeType) {
+ fadeType = true; // Fade in from white
+ for (int i = 0; i < 35; i++) swiWaitForVBlank();
+ }
+
+ static const int BUFFER_SIZE = 4096;
+ char buffer[BUFFER_SIZE];
+ memset(buffer, 0, sizeof(buffer));
+ char savHdrPath[64];
+ snprintf(savHdrPath, sizeof(savHdrPath), "nitro:/DSiWareSaveHeaders/%x.savhdr", (unsigned int)NDSHeader.pubSavSize);
+ FILE *hdrFile = fopen(savHdrPath, "rb");
+ if (hdrFile) fread(buffer, 1, 0x200, hdrFile);
+ fclose(hdrFile);
+
+ FILE *pFile = fopen(dsiWarePubPath.c_str(), "wb");
+ if (pFile) {
+ fwrite(buffer, 1, sizeof(buffer), pFile);
+ fseek(pFile, NDSHeader.pubSavSize - 1, SEEK_SET);
+ fputc('\0', pFile);
+ fclose(pFile);
+ }
+ printSmall(false, 2, 88, "Public save file created!");
+ for (int i = 0; i < 60; i++) swiWaitForVBlank();
+ }
+
+ if ((getFileSize(dsiWarePrvPath.c_str()) == 0) && (NDSHeader.prvSavSize > 0)) {
+ clearText();
+ if (flashcard == 8) {
+ // Display nothing
+ } else if (consoleModel >= 2) {
+ printSmallCentered(false, 20, "If this takes a while, press HOME,");
+ printSmallCentered(false, 34, "then press B.");
+ } else {
+ printSmallCentered(false, 20, "If this takes a while, close and open");
+ printSmallCentered(false, 34, "the console's lid.");
+ }
+ printSmall(false, 2, 80, "Creating private save file...");
+ if (!fadeType) {
+ fadeType = true; // Fade in from white
+ for (int i = 0; i < 35; i++) swiWaitForVBlank();
+ }
+
+ static const int BUFFER_SIZE = 4096;
+ char buffer[BUFFER_SIZE];
+ memset(buffer, 0, sizeof(buffer));
+ char savHdrPath[64];
+ snprintf(savHdrPath, sizeof(savHdrPath), "nitro:/DSiWareSaveHeaders/%x.savhdr", (unsigned int)NDSHeader.prvSavSize);
+ FILE *hdrFile = fopen(savHdrPath, "rb");
+ if (hdrFile) fread(buffer, 1, 0x200, hdrFile);
+ fclose(hdrFile);
+
+ FILE *pFile = fopen(dsiWarePrvPath.c_str(), "wb");
+ if (pFile) {
+ fwrite(buffer, 1, sizeof(buffer), pFile);
+ fseek(pFile, NDSHeader.prvSavSize - 1, SEEK_SET);
+ fputc('\0', pFile);
+ fclose(pFile);
+ }
+ printSmall(false, 2, 88, "Private save file created!");
+ for (int i = 0; i < 60; i++) swiWaitForVBlank();
+ }
+
+ if (fadeType) {
+ fadeType = false; // Fade to white
+ for (int i = 0; i < 25; i++) swiWaitForVBlank();
+ }
+
+ if (dsiWareBooter || consoleModel > 0) {
+ // Use nds-bootstrap
+ loadPerGameSettings(filename[secondaryDevice]);
+
+ bootstrapinipath = "sd:/_nds/nds-bootstrap.ini";
+ CIniFile bootstrapini(bootstrapinipath);
+ bootstrapini.SetString("NDS-BOOTSTRAP", "NDS_PATH", dsiWareSrlPath);
+ bootstrapini.SetString("NDS-BOOTSTRAP", "SAV_PATH", dsiWarePubPath);
+ bootstrapini.SetString("NDS-BOOTSTRAP", "AP_FIX_PATH", "");
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", -1);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", true);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", true);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", true);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "DONOR_SDK_VER", 5);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "GAME_SOFT_RESET", 1);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "PATCH_MPU_REGION", 0);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "PATCH_MPU_SIZE", 0);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", 1);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
+ (forceSleepPatch
+ || ((flashcard == 1 || flashcard == 3) && !isRegularDS))
+ );
+ bootstrapini.SaveIniFile(bootstrapinipath);
+
+ if (isDSiMode() || !secondaryDevice) {
+ SetWidescreen(filename[secondaryDevice].c_str());
+ }
+ if (!isDSiMode() && !secondaryDevice) {
+ ntrStartSdGame();
+ }
+
+ bool useNightly = (perGameSettings_bootstrapFile == -1 ? bootstrapFile : perGameSettings_bootstrapFile);
+
+ char ndsToBoot[256];
+ sprintf(ndsToBoot, "sd:/_nds/nds-bootstrap-%s.nds", useNightly ? "nightly" : "release");
+ if(access(ndsToBoot, F_OK) != 0) {
+ sprintf(ndsToBoot, "fat:/_nds/nds-bootstrap-%s.nds", useNightly ? "nightly" : "release");
+ }
+
+ argarray.at(0) = (char *)ndsToBoot;
+ int err = runNdsFile(argarray[0], argarray.size(), (const char **)&argarray[0], true, true, false, true, true);
+ char text[32];
+ snprintf (text, sizeof(text), "Start failed. Error %i", err);
+ clearText();
+ ClearBrightness();
+ printSmall(false, 4, 80, text);
+ if (err == 1) {
+ printSmall(false, 4, 88, useNightly ? "nds-bootstrap (Nightly)" : "nds-bootstrap (Release)");
+ printSmall(false, 4, 96, "not found.");
+ }
+ stop();
+ }
+
+ if (secondaryDevice) {
+ clearText();
+ printSmallCentered(false, 20, "If this takes a while, close and open");
+ printSmallCentered(false, 34, "the console's lid.");
+ printSmallCentered(false, 86, "Now copying data...");
+ printSmallCentered(false, 100, "Do not turn off the power.");
+ fadeType = true; // Fade in from white
+ for (int i = 0; i < 35; i++) swiWaitForVBlank();
+ fcopy(dsiWareSrlPath.c_str(), "sd:/_nds/TWiLightMenu/tempDSiWare.dsi");
+ if ((access(dsiWarePubPath.c_str(), F_OK) == 0) && (NDSHeader.pubSavSize > 0)) {
+ fcopy(dsiWarePubPath.c_str(), "sd:/_nds/TWiLightMenu/tempDSiWare.pub");
+ }
+ if ((access(dsiWarePrvPath.c_str(), F_OK) == 0) && (NDSHeader.prvSavSize > 0)) {
+ fcopy(dsiWarePrvPath.c_str(), "sd:/_nds/TWiLightMenu/tempDSiWare.prv");
+ }
+ fadeType = false; // Fade to white
+ for (int i = 0; i < 25; i++) swiWaitForVBlank();
+
+ if ((access(dsiWarePubPath.c_str(), F_OK) == 0 && (NDSHeader.pubSavSize > 0))
+ || (access(dsiWarePrvPath.c_str(), F_OK) == 0 && (NDSHeader.prvSavSize > 0))) {
+ clearText();
+ printSmallCentered(false, 8, "After saving, please re-start");
+ printSmallCentered(false, 20, "TWiLight Menu++ to transfer your");
+ printSmallCentered(false, 32, "save data back.");
+ fadeType = true; // Fade in from white
+ for (int i = 0; i < 60*3; i++) swiWaitForVBlank(); // Wait 3 seconds
+ fadeType = false; // Fade to white
+ for (int i = 0; i < 25; i++) swiWaitForVBlank();
+ }
+ }
+
+ char unlaunchDevicePath[256];
+ if (secondaryDevice) {
+ snprintf(unlaunchDevicePath, sizeof(unlaunchDevicePath), "sdmc:/_nds/TWiLightMenu/tempDSiWare.dsi");
+ } else {
+ snprintf(unlaunchDevicePath, sizeof(unlaunchDevicePath), "__%s", dsiWareSrlPath.c_str());
+ unlaunchDevicePath[0] = 's';
+ unlaunchDevicePath[1] = 'd';
+ unlaunchDevicePath[2] = 'm';
+ unlaunchDevicePath[3] = 'c';
+ }
+
+ tonccpy((u8*)0x02000800, unlaunchAutoLoadID, 12);
+ *(u16*)(0x0200080C) = 0x3F0; // Unlaunch Length for CRC16 (fixed, must be 3F0h)
+ *(u16*)(0x0200080E) = 0; // Unlaunch CRC16 (empty)
+ *(u32*)(0x02000810) = 0; // Unlaunch Flags
+ *(u32*)(0x02000810) |= BIT(0); // Load the title at 2000838h
+ *(u32*)(0x02000810) |= BIT(1); // Use colors 2000814h
+ *(u16*)(0x02000814) = 0x7FFF; // Unlaunch Upper screen BG color (0..7FFFh)
+ *(u16*)(0x02000816) = 0x7FFF; // Unlaunch Lower screen BG color (0..7FFFh)
+ toncset((u8*)0x02000818, 0, 0x20+0x208+0x1C0); // Unlaunch Reserved (zero)
+ int i2 = 0;
+ for (int i = 0; i < (int)sizeof(unlaunchDevicePath); i++) {
+ *(u8*)(0x02000838+i2) = unlaunchDevicePath[i]; // Unlaunch Device:/Path/Filename.ext (16bit Unicode,end by 0000h)
+ i2 += 2;
+ }
+ *(u16*)(0x0200080E) = swiCRC16(0xFFFF, (void*)0x02000810, 0x3F0); // Unlaunch CRC16
+
+ fifoSendValue32(FIFO_USER_02, 1); // Reboot into DSiWare title, booted via Launcher
+ for (int i = 0; i < 15; i++) swiWaitForVBlank();
+ }
+
+ // Launch .nds directly or via nds-bootstrap
+ if (extention(filename[secondaryDevice], ".nds") || extention(filename[secondaryDevice], ".dsi")
+ || extention(filename[secondaryDevice], ".ids") || extention(filename[secondaryDevice], ".srl")
+ || extention(filename[secondaryDevice], ".app")) {
+ const char *typeToReplace = ".nds";
+ if (extention(filename[secondaryDevice], ".dsi")) {
+ typeToReplace = ".dsi";
+ } else if (extention(filename[secondaryDevice], ".ids")) {
+ typeToReplace = ".ids";
+ } else if (extention(filename[secondaryDevice], ".srl")) {
+ typeToReplace = ".srl";
+ } else if (extention(filename[secondaryDevice], ".app")) {
+ typeToReplace = ".app";
+ }
+
+ bool dsModeSwitch = false;
+ bool dsModeDSiWare = false;
+
+ char game_TID[5];
+
+ FILE *f_nds_file = fopen(argarray[0], "rb");
+
+ fseek(f_nds_file, offsetof(sNDSHeaderExt, gameCode), SEEK_SET);
+ fread(game_TID, 1, 4, f_nds_file);
+ fclose(f_nds_file);
+ game_TID[4] = 0;
+ game_TID[3] = 0;
+
+ if (strcmp(game_TID, "HND") == 0 || strcmp(game_TID, "HNE") == 0) {
+ dsModeSwitch = true;
+ dsModeDSiWare = true;
+ useBackend = false; // Bypass nds-bootstrap
+ homebrewBootstrap = true;
+ } else if (isHomebrew[secondaryDevice]) {
+ loadPerGameSettings(filename[secondaryDevice]);
+ if (perGameSettings_directBoot || (useBootstrap && secondaryDevice)) {
+ useBackend = false; // Bypass nds-bootstrap
+ } else {
+ useBackend = true;
+ }
+ if (isDSiMode() && !perGameSettings_dsiMode) {
+ dsModeSwitch = true;
+ }
+ homebrewBootstrap = true;
+ } else {
+ loadPerGameSettings(filename[secondaryDevice]);
+ useBackend = true;
+ homebrewBootstrap = false;
+ }
+
+ char *name = argarray.at(0);
+ strcpy (filePath + pathLen, name);
+ free(argarray.at(0));
+ argarray.at(0) = filePath;
+ if(useBackend) {
+ if(useBootstrap || !secondaryDevice) {
+ std::string path = argarray[0];
+ std::string savename = replaceAll(filename[secondaryDevice], typeToReplace, getSavExtension());
+ std::string ramdiskname = replaceAll(filename[secondaryDevice], typeToReplace, getImgExtension());
+ std::string romFolderNoSlash = romfolder[secondaryDevice];
+ RemoveTrailingSlashes(romFolderNoSlash);
+ mkdir (isHomebrew[secondaryDevice] ? "ramdisks" : "saves", 0777);
+ std::string savepath = romFolderNoSlash+"/saves/"+savename;
+ if (sdFound() && secondaryDevice && fcSaveOnSd) {
+ savepath = replaceAll(savepath, "fat:/", "sd:/");
+ }
+ std::string ramdiskpath = romFolderNoSlash+"/ramdisks/"+ramdiskname;
+
+ if (!isHomebrew[secondaryDevice] && (strcmp(game_TID, "NTR") != 0)) {
+ // Create or expand save if game isn't homebrew
+ int orgsavesize = getFileSize(savepath.c_str());
+ int savesize = 524288; // 512KB (default size)
+
+ for (auto i : saveMap) {
+ if (i.second.find(game_TID) != i.second.cend()) {
+ savesize = i.first;
+ break;
+ }
+ }
+
+ bool saveSizeFixNeeded = false;
+
+ // TODO: If the list gets large enough, switch to bsearch().
+ for (unsigned int i = 0; i < sizeof(saveSizeFixList) / sizeof(saveSizeFixList[0]); i++) {
+ if (memcmp(game_TID, saveSizeFixList[i], 3) == 0) {
+ // Found a match.
+ saveSizeFixNeeded = true;
+ break;
+ }
+ }
+
+ if ((orgsavesize == 0 && savesize > 0) || (orgsavesize < savesize && saveSizeFixNeeded)) {
+ clearText();
+ ClearBrightness();
+ if (isDSiMode() && flashcard == 8) {
+ // Display nothing
+ } else if (REG_SCFG_EXT != 0 && consoleModel >= 2) {
+ printSmallCentered(false, 20, "If this takes a while, press HOME,");
+ printSmallCentered(false, 34, "then press B.");
+ } else {
+ printSmallCentered(false, 20, "If this takes a while, close and open");
+ printSmallCentered(false, 34, "the console's lid.");
+ }
+ printSmallCentered(false, 88, (orgsavesize == 0) ? "Creating save file..." : "Expanding save file...");
+
+ if (orgsavesize > 0) {
+ fsizeincrease(savepath.c_str(), sdFound() ? "sd:/_nds/TWiLightMenu/temp.sav" : "fat:/_nds/TWiLightMenu/temp.sav", savesize);
+ } else {
+ FILE *pFile = fopen(savepath.c_str(), "wb");
+ if (pFile) {
+ fseek(pFile, savesize - 1, SEEK_SET);
+ fputc('\0', pFile);
+ fclose(pFile);
+ }
+ }
+ clearText();
+ printSmallCentered(false, 88, (orgsavesize == 0) ? "Save file created!" : "Save file expanded!");
+ for (int i = 0; i < 30; i++) swiWaitForVBlank();
+ }
+ }
+
+ int donorSdkVer = SetDonorSDK(argarray[0]);
+ SetMPUSettings(argarray[0]);
+ SetSpeedBumpExclude(argarray[0]);
+
+ bool useWidescreen = (perGameSettings_wideScreen == -1 ? wideScreen : perGameSettings_wideScreen);
+
+ bootstrapinipath = ((!secondaryDevice || (isDSiMode() && sdFound())) ? "sd:/_nds/nds-bootstrap.ini" : "fat:/_nds/nds-bootstrap.ini");
+ CIniFile bootstrapini( bootstrapinipath );
+ bootstrapini.SetString("NDS-BOOTSTRAP", "NDS_PATH", path);
+ bootstrapini.SetString("NDS-BOOTSTRAP", "SAV_PATH", savepath);
+ if (!isHomebrew[secondaryDevice]) {
+ bootstrapini.SetString("NDS-BOOTSTRAP", "AP_FIX_PATH", setApFix(argarray[0]));
+ }
+ bootstrapini.SetString("NDS-BOOTSTRAP", "HOMEBREW_ARG", (useWidescreen && game_TID[0] == 'W') ? "wide" : "");
+ bootstrapini.SetString("NDS-BOOTSTRAP", "RAM_DRIVE_PATH", (perGameSettings_ramDiskNo >= 0 && !secondaryDevice) ? ramdiskpath : "sd:/null.img");
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", perGameSettings_language == -2 ? gameLanguage : perGameSettings_language);
+ if (isDSiMode() || !secondaryDevice) {
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", perGameSettings_dsiMode == -1 ? bstrap_dsiMode : perGameSettings_dsiMode);
+ }
+ if ((REG_SCFG_EXT != 0) || !secondaryDevice) {
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", perGameSettings_boostCpu == -1 ? boostCpu : perGameSettings_boostCpu);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", perGameSettings_boostVram == -1 ? boostVram : perGameSettings_boostVram);
+ }
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "EXTENDED_MEMORY", perGameSettings_expandRomSpace == -1 ? bstrap_extendedMemory : perGameSettings_expandRomSpace);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "DONOR_SDK_VER", donorSdkVer);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "PATCH_MPU_REGION", mpuregion);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "PATCH_MPU_SIZE", mpusize);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "CARDENGINE_CACHED", ceCached);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "FORCE_SLEEP_PATCH",
+ (forceSleepPatch
+ || ((flashcard == 1 || flashcard == 3) && !isRegularDS))
+ );
+ bootstrapini.SaveIniFile( bootstrapinipath );
+
+ CheatCodelist codelist;
+ u32 gameCode,crc32;
+
+ if ((isDSiMode() || !secondaryDevice) && !isHomebrew[secondaryDevice]) {
+ bool cheatsEnabled = true;
+ const char* cheatDataBin = "/_nds/nds-bootstrap/cheatData.bin";
+ mkdir("/_nds", 0777);
+ mkdir("/_nds/nds-bootstrap", 0777);
+ if(codelist.romData(path,gameCode,crc32)) {
+ long cheatOffset; size_t cheatSize;
+ FILE* dat=fopen(sdFound() ? "sd:/_nds/TWiLightMenu/extras/usrcheat.dat" : "fat:/_nds/TWiLightMenu/extras/usrcheat.dat","rb");
+ if (dat) {
+ if (codelist.searchCheatData(dat, gameCode,
+ crc32, cheatOffset,
+ cheatSize)) {
+ codelist.parse(path);
+ writeCheatsToFile(codelist.getCheats(), cheatDataBin);
+ FILE* cheatData=fopen(cheatDataBin,"rb");
+ if (cheatData) {
+ u32 check[2];
+ fread(check, 1, 8, cheatData);
+ fclose(cheatData);
+ if (check[1] == 0xCF000000
+ || getFileSize(cheatDataBin) > 0x8000) {
+ cheatsEnabled = false;
+ }
+ }
+ } else {
+ cheatsEnabled = false;
+ }
+ fclose(dat);
+ } else {
+ cheatsEnabled = false;
+ }
+ } else {
+ cheatsEnabled = false;
+ }
+ if (!cheatsEnabled) {
+ remove(cheatDataBin);
+ }
+ }
+
+ launchType[secondaryDevice] = 1;
+ previousUsedDevice = secondaryDevice;
+ SaveSettings();
+
+ if (isDSiMode() || !secondaryDevice) {
+ SetWidescreen(filename[secondaryDevice].c_str());
+ }
+ if (!isDSiMode() && !secondaryDevice) {
+ ntrStartSdGame();
+ }
+
+ bool useNightly = (perGameSettings_bootstrapFile == -1 ? bootstrapFile : perGameSettings_bootstrapFile);
+
+ char ndsToBoot[256];
+ sprintf(ndsToBoot, "sd:/_nds/nds-bootstrap-%s%s.nds", homebrewBootstrap ? "hb-" : "", useNightly ? "nightly" : "release");
+ if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
+ sprintf(ndsToBoot, "fat:/_nds/%s-%s%s.nds", isDSiMode() ? "nds-bootstrap" : "b4ds", homebrewBootstrap ? "hb-" : "", useNightly ? "nightly" : "release");
+ }
+
+ argarray.at(0) = (char *)ndsToBoot;
+ int err = runNdsFile (argarray[0], argarray.size(), (const char **)&argarray[0], (homebrewBootstrap ? false : true), true, false, true, true);
+ char text[32];
+ snprintf (text, sizeof(text), "Start failed. Error %i", err);
+ clearText();
+ ClearBrightness();
+ printSmall(false, 4, 80, text);
+ if (err == 1) {
+ printSmall(false, 4, 88, useNightly ? "nds-bootstrap (Nightly)" : "nds-bootstrap (Release)");
+ printSmall(false, 4, 96, "not found.");
+ }
+ stop();
+ } else {
+ launchType[secondaryDevice] = 1;
+ previousUsedDevice = secondaryDevice;
+ SaveSettings();
+ loadGameOnFlashcard(argarray[0], true);
+ }
+ } else {
+ if (isDSiMode() || !secondaryDevice) {
+ SetWidescreen(filename[secondaryDevice].c_str());
+ }
+ launchType[secondaryDevice] = 2;
+ previousUsedDevice = secondaryDevice;
+ SaveSettings();
+ if (!isDSiMode() && !secondaryDevice) {
+ ntrStartSdGame();
+ }
+
+ bool useWidescreen = (perGameSettings_wideScreen == -1 ? wideScreen : perGameSettings_wideScreen);
+
+ if (consoleModel >= 2 && useWidescreen && homebrewHasWide) {
+ argarray.push_back((char*)"wide");
+ }
+
+ bool runNds_boostCpu = false;
+ bool runNds_boostVram = false;
+ if (REG_SCFG_EXT != 0 && !dsModeDSiWare) {
+ loadPerGameSettings(filename[secondaryDevice]);
+
+ runNds_boostCpu = perGameSettings_boostCpu == -1 ? boostCpu : perGameSettings_boostCpu;
+ runNds_boostVram = perGameSettings_boostVram == -1 ? boostVram : perGameSettings_boostVram;
+ }
+ //iprintf ("Running %s with %d parameters\n", argarray[0], argarray.size());
+ int err = runNdsFile (argarray[0], argarray.size(), (const char **)&argarray[0], true, true, dsModeSwitch, runNds_boostCpu, runNds_boostVram);
+ char text[32];
+ snprintf (text, sizeof(text), "Start failed. Error %i", err);
+ clearText();
+ ClearBrightness();
+ printSmall(false, 4, 4, text);
+ stop();
+ }
+ } else {
+ bool useNDSB = false;
+ bool dsModeSwitch = false;
+ bool boostCpu = true;
+ bool boostVram = false;
+
+ std::string romfolderNoSlash = romfolder[secondaryDevice];
+ RemoveTrailingSlashes(romfolderNoSlash);
+ char ROMpath[256];
+ snprintf (ROMpath, sizeof(ROMpath), "%s/%s", romfolderNoSlash.c_str(), filename[secondaryDevice].c_str());
+ romPath[secondaryDevice] = ROMpath;
+ previousUsedDevice = secondaryDevice;
+ homebrewBootstrap = true;
+
+ const char *ndsToBoot = "sd:/_nds/nds-bootstrap-release.nds";
+ if (extention(filename[secondaryDevice], ".plg")) {
+ ndsToBoot = "fat:/_nds/TWiLightMenu/bootplg.srldr";
+
+ // Print .plg path without "fat:" at the beginning
+ char ROMpathDS2[256];
+ if (secondaryDevice) {
+ for (int i = 0; i < 252; i++) {
+ ROMpathDS2[i] = ROMpath[4+i];
+ if (ROMpath[4+i] == '\x00') break;
+ }
+ } else {
+ sprintf(ROMpathDS2, "/_nds/TWiLightMenu/tempPlugin.plg");
+ fcopy(ROMpath, "fat:/_nds/TWiLightMenu/tempPlugin.plg");
+ }
+
+ CIniFile dstwobootini( "fat:/_dstwo/twlm.ini" );
+ dstwobootini.SetString("boot_settings", "file", ROMpathDS2);
+ dstwobootini.SaveIniFile( "fat:/_dstwo/twlm.ini" );
+ } else if (extention(filename[secondaryDevice], ".rvid")) {
+ launchType[secondaryDevice] = 7;
+
+ ndsToBoot = "sd:/_nds/TWiLightMenu/apps/RocketVideoPlayer.nds";
+ if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
+ ndsToBoot = "fat:/_nds/TWiLightMenu/apps/RocketVideoPlayer.nds";
+ boostVram = true;
+ }
+ } else if (extention(filename[secondaryDevice], ".mp4")) {
+ launchType[secondaryDevice] = 8;
+
+ ndsToBoot = "sd:/_nds/TWiLightMenu/apps/MPEG4Player.nds";
+ if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
+ ndsToBoot = "fat:/_nds/TWiLightMenu/apps/MPEG4Player.nds";
+ boostVram = true;
+ }
+ } else if (extention(filename[secondaryDevice], ".gba")) {
+ launchType[secondaryDevice] = 1;
+
+ if (secondaryDevice) {
+ ndsToBoot = gbar2DldiAccess ? "sd:/_nds/GBARunner2_arm7dldi_ds.nds" : "sd:/_nds/GBARunner2_arm9dldi_ds.nds";
+ if (REG_SCFG_EXT != 0) {
+ ndsToBoot = consoleModel>0 ? "sd:/_nds/GBARunner2_arm7dldi_3ds.nds" : "sd:/_nds/GBARunner2_arm7dldi_dsi.nds";
+ }
+ if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
+ ndsToBoot = gbar2DldiAccess ? "fat:/_nds/GBARunner2_arm7dldi_ds.nds" : "fat:/_nds/GBARunner2_arm9dldi_ds.nds";
+ if (REG_SCFG_EXT != 0) {
+ ndsToBoot = consoleModel>0 ? "fat:/_nds/GBARunner2_arm7dldi_3ds.nds" : "fat:/_nds/GBARunner2_arm7dldi_dsi.nds";
+ }
+ }
+ boostVram = false;
+ } else {
+ useNDSB = true;
+
+ const char* gbar2Path = consoleModel>0 ? "sd:/_nds/GBARunner2_arm7dldi_3ds.nds" : "sd:/_nds/GBARunner2_arm7dldi_dsi.nds";
+ if (isDSiMode() && arm7SCFGLocked) {
+ gbar2Path = consoleModel>0 ? "sd:/_nds/GBARunner2_arm7dldi_nodsp_3ds.nds" : "sd:/_nds/GBARunner2_arm7dldi_nodsp_dsi.nds";
+ }
+
+ ndsToBoot = (bootstrapFile ? "sd:/_nds/nds-bootstrap-hb-nightly.nds" : "sd:/_nds/nds-bootstrap-hb-release.nds");
+ CIniFile bootstrapini("sd:/_nds/nds-bootstrap.ini");
+
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", gameLanguage);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", 0);
+ bootstrapini.SetString("NDS-BOOTSTRAP", "NDS_PATH", gbar2Path);
+ bootstrapini.SetString("NDS-BOOTSTRAP", "HOMEBREW_ARG", ROMpath);
+ bootstrapini.SetString("NDS-BOOTSTRAP", "RAM_DRIVE_PATH", "");
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", 1);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", 0);
+
+ bootstrapini.SaveIniFile("sd:/_nds/nds-bootstrap.ini");
+ }
+ } else if (extention(filename[secondaryDevice], ".a26")) {
+ launchType[secondaryDevice] = 9;
+
+ ndsToBoot = "sd:/_nds/TWiLightMenu/emulators/StellaDS.nds";
+ if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
+ ndsToBoot = "fat:/_nds/TWiLightMenu/emulators/StellaDS.nds";
+ boostVram = true;
+ }
+ } else if (extention(filename[secondaryDevice], ".gb") || extention(filename[secondaryDevice], ".sgb") || extention(filename[secondaryDevice], ".gbc")) {
+ launchType[secondaryDevice] = 5;
+
+ ndsToBoot = "sd:/_nds/TWiLightMenu/emulators/gameyob.nds";
+ if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
+ ndsToBoot = "fat:/_nds/TWiLightMenu/emulators/gameyob.nds";
+ dsModeSwitch = !isDSiMode();
+ boostVram = true;
+ }
+ } else if (extention(filename[secondaryDevice], ".nes") || extention(filename[secondaryDevice], ".fds")) {
+ launchType[secondaryDevice] = 4;
+
+ ndsToBoot = (secondaryDevice ? "sd:/_nds/TWiLightMenu/emulators/nesds.nds" : "sd:/_nds/TWiLightMenu/emulators/nestwl.nds");
+ if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
+ ndsToBoot = "fat:/_nds/TWiLightMenu/emulators/nesds.nds";
+ boostVram = true;
+ }
+ } else if (extention(filename[secondaryDevice], ".sms") || extention(filename[secondaryDevice], ".gg")) {
+ mkdir(secondaryDevice ? "fat:/data" : "sd:/data", 0777);
+ mkdir(secondaryDevice ? "fat:/data/s8ds" : "sd:/data/s8ds", 0777);
+
+ if (!secondaryDevice && !arm7SCFGLocked && smsGgInRam) {
+ launchType[secondaryDevice] = 1;
+
+ useNDSB = true;
+
+ ndsToBoot = (bootstrapFile ? "sd:/_nds/nds-bootstrap-hb-nightly.nds" : "sd:/_nds/nds-bootstrap-hb-release.nds");
+ CIniFile bootstrapini("sd:/_nds/nds-bootstrap.ini");
+
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", gameLanguage);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", 0);
+ bootstrapini.SetString("NDS-BOOTSTRAP", "NDS_PATH", "sd:/_nds/TWiLightMenu/emulators/S8DS07.nds");
+ bootstrapini.SetString("NDS-BOOTSTRAP", "HOMEBREW_ARG", "");
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", 1);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", 0);
+
+ bootstrapini.SetString("NDS-BOOTSTRAP", "RAM_DRIVE_PATH", ROMpath);
+ bootstrapini.SaveIniFile("sd:/_nds/nds-bootstrap.ini");
+ } else {
+ launchType[secondaryDevice] = 6;
+
+ ndsToBoot = "sd:/_nds/TWiLightMenu/emulators/S8DS.nds";
+ if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
+ ndsToBoot = "fat:/_nds/TWiLightMenu/emulators/S8DS.nds";
+ boostVram = true;
+ }
+ }
+ } else if (extention(filename[secondaryDevice], ".gen")) {
+ bool usePicoDrive = ((isDSiMode() && sdFound() && arm7SCFGLocked)
+ || showMd==2 || (showMd==3 && getFileSize(filename[secondaryDevice].c_str()) > 0x300000));
+ launchType[secondaryDevice] = (usePicoDrive ? 10 : 1);
+
+ if (usePicoDrive || secondaryDevice) {
+ ndsToBoot = usePicoDrive ? "sd:/_nds/TWiLightMenu/emulators/PicoDriveTWL.nds" : "sd:/_nds/TWiLightMenu/emulators/jEnesisDS.nds";
+ if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
+ ndsToBoot = usePicoDrive ? "fat:/_nds/TWiLightMenu/emulators/PicoDriveTWL.nds" : "fat:/_nds/TWiLightMenu/emulators/jEnesisDS.nds";
+ boostVram = true;
+ }
+ dsModeSwitch = !usePicoDrive;
+ } else {
+ useNDSB = true;
+
+ ndsToBoot = (bootstrapFile ? "sd:/_nds/nds-bootstrap-hb-nightly.nds" : "sd:/_nds/nds-bootstrap-hb-release.nds");
+ CIniFile bootstrapini("sd:/_nds/nds-bootstrap.ini");
+
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", gameLanguage);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", 0);
+ bootstrapini.SetString("NDS-BOOTSTRAP", "NDS_PATH", "sd:/_nds/TWiLightMenu/emulators/jEnesisDS.nds");
+ bootstrapini.SetString("NDS-BOOTSTRAP", "HOMEBREW_ARG", "fat:/ROM.BIN");
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", 1);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", 0);
+
+ bootstrapini.SetString("NDS-BOOTSTRAP", "RAM_DRIVE_PATH", ROMpath);
+ bootstrapini.SaveIniFile("sd:/_nds/nds-bootstrap.ini");
+ }
+ } else if (extention(filename[secondaryDevice], ".smc") || extention(filename[secondaryDevice], ".sfc")) {
+ launchType[secondaryDevice] = 1;
+
+ if (secondaryDevice) {
+ ndsToBoot = "sd:/_nds/TWiLightMenu/emulators/SNEmulDS.nds";
+ if(!isDSiMode() || access(ndsToBoot, F_OK) != 0) {
+ ndsToBoot = "fat:/_nds/TWiLightMenu/emulators/SNEmulDS.nds";
+ boostCpu = false;
+ boostVram = true;
+ }
+ dsModeSwitch = true;
+ } else {
+ useNDSB = true;
+
+ ndsToBoot = (bootstrapFile ? "sd:/_nds/nds-bootstrap-hb-nightly.nds" : "sd:/_nds/nds-bootstrap-hb-release.nds");
+ CIniFile bootstrapini("sd:/_nds/nds-bootstrap.ini");
+
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", gameLanguage);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", 0);
+ bootstrapini.SetString("NDS-BOOTSTRAP", "NDS_PATH", "sd:/_nds/TWiLightMenu/emulators/SNEmulDS.nds");
+ bootstrapini.SetString("NDS-BOOTSTRAP", "HOMEBREW_ARG", "fat:/snes/ROM.SMC");
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", 0);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", 0);
+
+ bootstrapini.SetString("NDS-BOOTSTRAP", "RAM_DRIVE_PATH", ROMpath);
+ bootstrapini.SaveIniFile("sd:/_nds/nds-bootstrap.ini");
+ }
+ } else if (extention(filename[secondaryDevice], ".pce")) {
+ launchType[secondaryDevice] = 1;
+
+ if (secondaryDevice) {
+ ndsToBoot = "sd:/_nds/TWiLightMenu/emulators/NitroGrafx.nds";
+ if(access(ndsToBoot, F_OK) != 0) {
+ ndsToBoot = "/_nds/TWiLightMenu/emulators/NitroGrafx.nds";
+ boostVram = true;
+ }
+ dsModeSwitch = true;
+ } else {
+ useNDSB = true;
+
+ ndsToBoot = (bootstrapFile ? "sd:/_nds/nds-bootstrap-hb-nightly.nds" : "sd:/_nds/nds-bootstrap-hb-release.nds");
+ CIniFile bootstrapini("sd:/_nds/nds-bootstrap.ini");
+
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", gameLanguage);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", 0);
+ bootstrapini.SetString("NDS-BOOTSTRAP", "NDS_PATH", "sd:/_nds/TWiLightMenu/emulators/NitroGrafx.nds");
+ bootstrapini.SetString("NDS-BOOTSTRAP", "HOMEBREW_ARG", ROMpath);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", 0);
+ bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", 0);
+
+ bootstrapini.SetString("NDS-BOOTSTRAP", "RAM_DRIVE_PATH", "");
+ bootstrapini.SaveIniFile("sd:/_nds/nds-bootstrap.ini");
+ }
+ }
+
+ SaveSettings();
+ if (!isDSiMode() && !secondaryDevice && !extention(filename[secondaryDevice], ".plg")) {
+ ntrStartSdGame();
+ }
+ argarray.push_back(ROMpath);
+ argarray.at(0) = (char *)ndsToBoot;
+
+ int err = runNdsFile (argarray[0], argarray.size(), (const char **)&argarray[0], !useNDSB, true, dsModeSwitch, boostCpu, boostVram); // Pass ROM to emulator as argument
+
+ char text[32];
+ snprintf (text, sizeof(text), "Start failed. Error %i", err);
+ clearText();
+ ClearBrightness();
+ printLarge(false, 4, 80, text);
+ if (err == 1 && useNDSB) {
+ printSmall(false, 4, 88, bootstrapFile ? "nds-bootstrap (Nightly)" : "nds-bootstrap (Release)");
+ printSmall(false, 4, 96, "not found.");
+ }
+ stop();
+
+ while(argarray.size() !=0 ) {
+ free(argarray.at(0));
+ argarray.erase(argarray.begin());
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/romsel_aktheme/arm9/source/common/dsimenusettings.h b/romsel_aktheme/arm9/source/common/dsimenusettings.h
index 160b6dd2a7..089a3b5e46 100644
--- a/romsel_aktheme/arm9/source/common/dsimenusettings.h
+++ b/romsel_aktheme/arm9/source/common/dsimenusettings.h
@@ -31,7 +31,7 @@ class TWLSettings
/*
- 0: Unknown
+ 0: Unknown
1: DSTT/R4i Gold/R4i-SDHC/R4 SDHC Dual-Core/R4 SDHC Upgrade/SC DSONE
2: R4DS (Original Non-SDHC version)/ M3 Simply
3: R4iDSN/R4i Gold RTS/R4 Ultra
@@ -39,18 +39,20 @@ class TWLSettings
5: Acekard RPG
6: Ace 3DS+/Gateway Blue Card/R4iTT
7: SuperCard DSTWO
+ 8: CycloDS iEvolution
*/
enum TFlashCard
{
- EFCUnknown = 0,
+ EUnknown = 0,
EDSTTClone = 1,
ER4Original = 2,
ER4iGoldClone = 3,
EAcekard2i = 4,
EAcekardRPG = 5,
EGatewayBlue = 6,
- ESupercardDSTWO = 7
+ ESupercardDSTWO = 7,
+ ECycloDSi = 8
};
// Do not reorder these, just add to the end
diff --git a/romsel_aktheme/arm9/source/dsrom.cpp b/romsel_aktheme/arm9/source/dsrom.cpp
index 4a46d2931d..265c026ef7 100644
--- a/romsel_aktheme/arm9/source/dsrom.cpp
+++ b/romsel_aktheme/arm9/source/dsrom.cpp
@@ -138,7 +138,7 @@ bool DSRomInfo::loadDSRomInfo(const std::string &filename, bool loadBanner)
_hasExtendedBinaries = ETrue;
_requiresDonorRom = 0;
bool usingFlashcard = (!isDSiMode() && ms().secondaryDevice);
- bool hasCycloDSi = (memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) == 0);
+ bool hasCycloDSi = ms().flashcard == 8;
switch (header.arm7binarySize) {
case 0x22B40:
case 0x22BCC:
diff --git a/romsel_dsimenutheme/arm9/source/common/dsimenusettings.h b/romsel_dsimenutheme/arm9/source/common/dsimenusettings.h
index eb59f95577..a34aa34e24 100644
--- a/romsel_dsimenutheme/arm9/source/common/dsimenusettings.h
+++ b/romsel_dsimenutheme/arm9/source/common/dsimenusettings.h
@@ -33,25 +33,28 @@ class TWLSettings
};
/*
- 0: DSTT/R4i Gold/R4i-SDHC/R4 SDHC Dual-Core/R4 SDHC Upgrade/SC DSONE
- 1: R4DS (Original Non-SDHC version)/ M3 Simply
- 2: R4iDSN/R4i Gold RTS/R4 Ultra
- 3: Acekard 2(i)/Galaxy Eagle/M3DS Real
- 4: Acekard RPG
- 5: Ace 3DS+/Gateway Blue Card/R4iTT
- 6: SuperCard DSTWO
+ 0: Unknown
+ 1: DSTT/R4i Gold/R4i-SDHC/R4 SDHC Dual-Core/R4 SDHC Upgrade/SC DSONE
+ 2: R4DS (Original Non-SDHC version)/ M3 Simply
+ 3: R4iDSN/R4i Gold RTS/R4 Ultra
+ 4: Acekard 2(i)/Galaxy Eagle/M3DS Real
+ 5: Acekard RPG
+ 6: Ace 3DS+/Gateway Blue Card/R4iTT
+ 7: SuperCard DSTWO
+ 8: CycloDS iEvolution
*/
enum TFlashCard
{
- EFCUnknown = 0,
+ EUnknown = 0,
EDSTTClone = 1,
ER4Original = 2,
ER4iGoldClone = 3,
EAcekard2i = 4,
EAcekardRPG = 5,
EGatewayBlue = 6,
- ESupercardDSTWO = 7
+ ESupercardDSTWO = 7,
+ ECycloDSi = 8
};
// Do not reorder these, just add to the end
diff --git a/romsel_dsimenutheme/arm9/source/fileBrowse.cpp b/romsel_dsimenutheme/arm9/source/fileBrowse.cpp
index b0ee9821f7..c771e93f41 100644
--- a/romsel_dsimenutheme/arm9/source/fileBrowse.cpp
+++ b/romsel_dsimenutheme/arm9/source/fileBrowse.cpp
@@ -430,7 +430,7 @@ void displayNowLoading(void) {
fadeType = true; // Fade in from white
snd().updateStream();
std::string *msg;
- if (isDSiMode() && memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) == 0) {
+ if (isDSiMode() && ms().flashcard == 8) {
msg = &STR_TAKEWHILE_TURNOFF;
} else if (REG_SCFG_EXT != 0 && ms().consoleModel >= 2) {
msg = &STR_TAKEWHILE_PRESSHOME;
@@ -1268,7 +1268,7 @@ bool selectMenu(void) {
int selCursorPosition = 0;
int assignedOp[5] = {-1};
int selIconYpos = 96;
- if (isDSiMode() && memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) != 0) {
+ if (isDSiMode() && ms().flashcard != 8) {
for (int i = 0; i < 4; i++) {
selIconYpos -= 14;
}
@@ -1321,7 +1321,7 @@ bool selectMenu(void) {
} else {
printSmall(false, 64, textYpos, STR_SWITCH_TO_SLOT_1);
}
- } else if (isDSiMode() && memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) != 0) {
+ } else if (isDSiMode() && ms().flashcard != 8) {
printSmall(false, 64, textYpos, (REG_SCFG_MC == 0x11) ? STR_NO_SLOT_1 : STR_LAUNCH_SLOT_1);
}
} else if (assignedOp[i] == 3) {
diff --git a/romsel_dsimenutheme/arm9/source/graphics/graphics.cpp b/romsel_dsimenutheme/arm9/source/graphics/graphics.cpp
index 44a6d389c8..97c0011792 100644
--- a/romsel_dsimenutheme/arm9/source/graphics/graphics.cpp
+++ b/romsel_dsimenutheme/arm9/source/graphics/graphics.cpp
@@ -1256,15 +1256,10 @@ void vBlankHandler() {
drawIcon(24, ((ms().theme == 4 || ms().theme == 5) ? 0 : dbox_Ypos) + 24, CURPOS);
}
if (dbox_selectMenu) {
+ bool noCycloDSi = isDSiMode() && ms().flashcard != 8;
int selIconYpos = 96;
- if (isDSiMode() && memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) != 0) {
- for (int i = 0; i < 4; i++) {
- selIconYpos -= 14;
- }
- } else {
- for (int i = 0; i < 3; i++) {
- selIconYpos -= 14;
- }
+ for (int i = 0; i < (noCycloDSi ? 4 : 3); i++) {
+ selIconYpos -= 14;
}
if (!sys().isRegularDS()) {
glSprite(32, (ms().theme == 4 ? 0 : dbox_Ypos) + selIconYpos, GL_FLIP_NONE,
@@ -1274,16 +1269,10 @@ void vBlankHandler() {
glSprite(32, (ms().theme == 4 ? 0 : dbox_Ypos) + selIconYpos, GL_FLIP_NONE,
&tex().cornerButtonImage()[0]); // Settings
selIconYpos += 28;
- if (isDSiMode() && memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) != 0) {
- if (ms().secondaryDevice) {
- glSprite(32, (ms().theme == 4 ? 0 : dbox_Ypos) + selIconYpos, GL_FLIP_NONE,
- &tex().smallCartImage()[2]); // SD card
- } else {
- glSprite(
- 32, (ms().theme == 4 ? 0 : dbox_Ypos) + selIconYpos, GL_FLIP_NONE,
- &tex().smallCartImage()[(REG_SCFG_MC == 0x11) ? 1
- : 0]); // Slot-1 card
- }
+ if (noCycloDSi) {
+ glSprite(
+ 32, (ms().theme == 4 ? 0 : dbox_Ypos) + selIconYpos, GL_FLIP_NONE,
+ &tex().smallCartImage()[ms().secondaryDevice ? 2 : (REG_SCFG_MC == 0x11)]);
selIconYpos += 28;
}
if (!ms().useGbarunner && sys().isRegularDS()) {
diff --git a/romsel_dsimenutheme/arm9/source/iconTitle.cpp b/romsel_dsimenutheme/arm9/source/iconTitle.cpp
index 5ecc749248..bdd4d35e06 100644
--- a/romsel_dsimenutheme/arm9/source/iconTitle.cpp
+++ b/romsel_dsimenutheme/arm9/source/iconTitle.cpp
@@ -371,7 +371,7 @@ void getGameInfo(bool isDir, const char *name, int num) {
}
bool usingFlashcard = (!isDSiMode() && ms().secondaryDevice);
- bool hasCycloDSi = (memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) == 0);
+ bool hasCycloDSi = ms().flashcard == 8;
if (num < 40) {
tonccpy(gameTid[num], ndsHeader.gameCode, 4);
diff --git a/romsel_dsimenutheme/arm9/source/main.cpp b/romsel_dsimenutheme/arm9/source/main.cpp
index 15136926fa..34dff5bdd7 100644
--- a/romsel_dsimenutheme/arm9/source/main.cpp
+++ b/romsel_dsimenutheme/arm9/source/main.cpp
@@ -920,7 +920,7 @@ int main(int argc, char **argv) {
if ((getFileSize(ms().dsiWarePubPath.c_str()) == 0) && (NDSHeader.pubSavSize > 0)) {
if (ms().theme == 5) displayGameIcons = false;
clearText();
- if (memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) == 0) {
+ if (ms().flashcard == 8) {
// Display nothing
} else if (ms().consoleModel >= 2) {
printSmall(false, 0, 20, STR_TAKEWHILE_PRESSHOME, Alignment::center);
@@ -966,7 +966,7 @@ int main(int argc, char **argv) {
if ((getFileSize(ms().dsiWarePrvPath.c_str()) == 0) && (NDSHeader.prvSavSize > 0)) {
if (ms().theme == 5) displayGameIcons = false;
clearText();
- if (memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) == 0) {
+ if (ms().flashcard == 8) {
// Display nothing
} else if (ms().consoleModel >= 2) {
printSmall(false, 0, 20, STR_TAKEWHILE_PRESSHOME, Alignment::center);
@@ -1278,7 +1278,7 @@ int main(int argc, char **argv) {
if ((orgsavesize == 0 && savesize > 0) || (orgsavesize < savesize && saveSizeFixNeeded)) {
if (ms().theme == 5) displayGameIcons = false;
- if (isDSiMode() && memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) == 0) {
+ if (isDSiMode() && ms().flashcard == 8) {
// Display nothing
} else if (REG_SCFG_EXT != 0 && ms().consoleModel >= 2) {
printSmall(false, 0, 20, STR_TAKEWHILE_PRESSHOME, Alignment::center);
diff --git a/romsel_dsimenutheme/arm9/source/perGameSettings.cpp b/romsel_dsimenutheme/arm9/source/perGameSettings.cpp
index dad1050eb0..3ae30faca9 100644
--- a/romsel_dsimenutheme/arm9/source/perGameSettings.cpp
+++ b/romsel_dsimenutheme/arm9/source/perGameSettings.cpp
@@ -189,7 +189,7 @@ bool showSetDonorRom(u32 arm7size, u32 SDKVersion) {
if (requiresDonorRom[CURPOS]) return false;
bool usingFlashcard = (!isDSiMode() && ms().secondaryDevice);
- bool hasCycloDSi = (memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) == 0);
+ bool hasCycloDSi = ms().flashcard == 8;
if (((usingFlashcard || hasCycloDSi) && SDKVersion > 0x2000000 && SDKVersion < 0x2008000 // Early SDK2
&& (arm7size==0x25F70
diff --git a/romsel_r4theme/arm9/source/iconTitle.cpp b/romsel_r4theme/arm9/source/iconTitle.cpp
index f4ea194f67..9f50b03163 100644
--- a/romsel_r4theme/arm9/source/iconTitle.cpp
+++ b/romsel_r4theme/arm9/source/iconTitle.cpp
@@ -57,6 +57,8 @@ extern int consoleModel;
extern bool dsiWareBooter;
extern bool secondaryDevice;
+extern int flashcard;
+
extern int theme;
extern int colorMode;
extern bool useGbarunner;
@@ -723,7 +725,7 @@ void getGameInfo(bool isDir, const char* name)
}
bool usingFlashcard = (!isDSiMode() && secondaryDevice);
- bool hasCycloDSi = (memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) == 0);
+ bool hasCycloDSi = flashcard == 8;
romVersion = ndsHeader.romversion;
switch (ndsHeader.arm7binarySize) {
case 0x22B40:
diff --git a/romsel_r4theme/arm9/source/perGameSettings.cpp b/romsel_r4theme/arm9/source/perGameSettings.cpp
index 19c4eb7bdb..75371862ca 100644
--- a/romsel_r4theme/arm9/source/perGameSettings.cpp
+++ b/romsel_r4theme/arm9/source/perGameSettings.cpp
@@ -40,6 +40,8 @@ extern const char *bootstrapinipath;
extern bool isRegularDS;
extern int consoleModel;
+extern int flashcard;
+
extern int bstrap_dsiMode;
extern bool useBootstrap;
extern int theme;
@@ -174,7 +176,7 @@ bool checkIfDSiMode (std::string filename) {
bool showSetDonorRom(u32 arm7size, u32 SDKVersion) {
if (requiresDonorRom) return false;
- bool hasCycloDSi = (memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) == 0);
+ bool hasCycloDSi = flashcard == 8;
if (((!isDSiMode() || hasCycloDSi) && SDKVersion > 0x2000000 && SDKVersion < 0x2008000 // Early SDK2
&& (arm7size==0x25F70
diff --git a/settings/arm9/source/common/dsimenusettings.h b/settings/arm9/source/common/dsimenusettings.h
index 712facc8a8..0bc9f9a190 100644
--- a/settings/arm9/source/common/dsimenusettings.h
+++ b/settings/arm9/source/common/dsimenusettings.h
@@ -30,7 +30,7 @@ class TWLSettings
};
/*
- 0: Unknown
+ 0: Unknown
1: DSTT/R4i Gold/R4i-SDHC/R4 SDHC Dual-Core/R4 SDHC Upgrade/SC DSONE
2: R4DS (Original Non-SDHC version)/ M3 Simply
3: R4iDSN/R4i Gold RTS/R4 Ultra
@@ -38,18 +38,20 @@ class TWLSettings
5: Acekard RPG
6: Ace 3DS+/Gateway Blue Card/R4iTT
7: SuperCard DSTWO
+ 8: CycloDS iEvolution
*/
enum TFlashCard
{
- EFCUnknown = 0,
+ EUnknown = 0,
EDSTTClone = 1,
ER4Original = 2,
ER4iGoldClone = 3,
EAcekard2i = 4,
EAcekardRPG = 5,
EGatewayBlue = 6,
- ESupercardDSTWO = 7
+ ESupercardDSTWO = 7,
+ ECycloDSi = 8
};
// Do not reorder these, just add to the end
diff --git a/title/arm9/source/common/dsimenusettings.h b/title/arm9/source/common/dsimenusettings.h
index 3763a945cf..8923a2dd0f 100644
--- a/title/arm9/source/common/dsimenusettings.h
+++ b/title/arm9/source/common/dsimenusettings.h
@@ -29,25 +29,29 @@ class TWLSettings
EViewInternal = 2
};
- /*0: DSTT/R4i Gold/R4i-SDHC/R4 SDHC Dual-Core/R4 SDHC Upgrade/SC DSONE
- 1: R4DS (Original Non-SDHC version)/ M3 Simply
- 2: R4iDSN/R4i Gold RTS/R4 Ultra
- 3: Acekard 2(i)/Galaxy Eagle/M3DS Real
- 4: Acekard RPG
- 5: Ace 3DS+/Gateway Blue Card/R4iTT
- 6: SuperCard DSTWO
+ /*
+ 0: Unknown
+ 1: DSTT/R4i Gold/R4i-SDHC/R4 SDHC Dual-Core/R4 SDHC Upgrade/SC DSONE
+ 2: R4DS (Original Non-SDHC version)/ M3 Simply
+ 3: R4iDSN/R4i Gold RTS/R4 Ultra
+ 4: Acekard 2(i)/Galaxy Eagle/M3DS Real
+ 5: Acekard RPG
+ 6: Ace 3DS+/Gateway Blue Card/R4iTT
+ 7: SuperCard DSTWO
+ 8: CycloDS iEvolution
*/
enum TFlashCard
{
- EFCUnknown = 0,
+ EUnknown = 0,
EDSTTClone = 1,
ER4Original = 2,
ER4iGoldClone = 3,
EAcekard2i = 4,
EAcekardRPG = 5,
EGatewayBlue = 6,
- ESupercardDSTWO = 7
+ ESupercardDSTWO = 7,
+ ECycloDSi = 8
};
// Do not reorder these, just add to the end
diff --git a/title/arm9/source/common/flashcard.cpp b/title/arm9/source/common/flashcard.cpp
index 50e23d2700..b3a4bd0f93 100644
--- a/title/arm9/source/common/flashcard.cpp
+++ b/title/arm9/source/common/flashcard.cpp
@@ -7,8 +7,11 @@
#include "common/bootstrappaths.h"
#include "common/inifile.h"
#include "common/systemdetails.h"
+#include "common/dsimenusettings.h"
#include "read_card.h"
+using FC = TWLSettings::TFlashCard;
+
bool sdFound(void) {
return (access("sd:/", F_OK) == 0);
}
@@ -99,3 +102,21 @@ void flashcardInit(void) {
twl_flashcardInit();
}
}
+
+void detectFlashcard() {
+ if (!memcmp(io_dldi_data->friendlyName, "TTCARD", 6)
+ || !memcmp(io_dldi_data->friendlyName, "DSTT", 4)
+ || !memcmp(io_dldi_data->friendlyName, "DEMON", 5))
+ ms().flashcard = FC::EDSTTClone;
+ else if (!memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 26)
+ || !memcmp(io_dldi_data->friendlyName, "R4TF", 4))
+ ms().flashcard = FC::ER4Original;
+ else if (!memcmp(io_dldi_data->friendlyName, "R4iDSN", 6))
+ ms().flashcard = FC::ER4iGoldClone;
+ else if (!memcmp(io_dldi_data->friendlyName, "Acekard AK2", 0xB))
+ ms().flashcard = FC::EAcekard2i;
+ else if (!memcmp(io_dldi_data->friendlyName, "DSTWO(Slot-1)", 0xD))
+ ms().flashcard = FC::ESupercardDSTWO;
+ else
+ ms().flashcard = FC::EUnknown;
+}
diff --git a/title/arm9/source/common/flashcard.h b/title/arm9/source/common/flashcard.h
index 4b364b710e..341ced7b97 100644
--- a/title/arm9/source/common/flashcard.h
+++ b/title/arm9/source/common/flashcard.h
@@ -8,5 +8,6 @@ bool sdFound(void);
bool flashcardFound(void);
bool bothSDandFlashcard(void);
void flashcardInit(void);
+void detectFlashcard();
#endif //DSIMENUPP_FLASHCARD_H
diff --git a/title/arm9/source/main.cpp b/title/arm9/source/main.cpp
index da6360e176..aeceaaaf78 100644
--- a/title/arm9/source/main.cpp
+++ b/title/arm9/source/main.cpp
@@ -745,6 +745,8 @@ int main(int argc, char **argv)
if (flashcardFound()) {
mkdir("fat:/_gba", 0777);
mkdir("fat:/_nds/TWiLightMenu/gamesettings", 0777);
+
+ detectFlashcard();
}
runGraphicIrq();
From 226d53303f2c1220fa8bf3abebb78475c424ffef Mon Sep 17 00:00:00 2001
From: unresolvedsymbol <48220091+unresolvedsymbol@users.noreply.github.com>
Date: Mon, 2 Nov 2020 21:32:48 -0600
Subject: [PATCH 6/8] Save
---
title/arm9/source/common/flashcard.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/title/arm9/source/common/flashcard.cpp b/title/arm9/source/common/flashcard.cpp
index b3a4bd0f93..53d7e2fae2 100644
--- a/title/arm9/source/common/flashcard.cpp
+++ b/title/arm9/source/common/flashcard.cpp
@@ -119,4 +119,5 @@ void detectFlashcard() {
ms().flashcard = FC::ESupercardDSTWO;
else
ms().flashcard = FC::EUnknown;
+ ms().saveSettings();
}
From 126b4b62ffd0de5f223e610016e904ae2829a9f1 Mon Sep 17 00:00:00 2001
From: unresolvedsymbol <48220091+unresolvedsymbol@users.noreply.github.com>
Date: Tue, 3 Nov 2020 00:29:20 -0600
Subject: [PATCH 7/8] Fix loading/saving of flashcard type, more
---
.../arm9/source/common/dsimenusettings.cpp | 20 +-
.../arm9/source/common/dsimenusettings.cpp | 3 +-
.../arm9/source/common/dsimenusettings.cpp | 5 +-
settings/arm9/source/common/flashcard.cpp | 3 +
settings/arm9/source/settingsgui.h | 2 +-
title/arm9/source/common/dsimenusettings.cpp | 273 +++++++++---------
title/arm9/source/common/flashcard.cpp | 27 +-
title/arm9/source/common/flashcard.h | 2 +-
title/arm9/source/main.cpp | 33 +--
9 files changed, 188 insertions(+), 180 deletions(-)
diff --git a/quickmenu/arm9/source/common/dsimenusettings.cpp b/quickmenu/arm9/source/common/dsimenusettings.cpp
index 6095ddcb13..e0813790e0 100644
--- a/quickmenu/arm9/source/common/dsimenusettings.cpp
+++ b/quickmenu/arm9/source/common/dsimenusettings.cpp
@@ -18,20 +18,20 @@ TWLSettings::TWLSettings()
wifiLed = true;
sdRemoveDetect = true;
showMicroSd = false;
- gbar2DldiAccess = false;
+ gbar2DldiAccess = false;
showMainMenu = true;
theme = 0;
subtheme = 0;
dsiMusic = 1;
- showNds = true;
- showRvid = true;
- showNes = true;
- showGb = true;
- showSmsGg = true;
- showMd = true;
- showSnes = true;
- updateRecentlyPlayedList = true;
+ showNds = true;
+ showRvid = true;
+ showNes = true;
+ showGb = true;
+ showSmsGg = true;
+ showMd = true;
+ showSnes = true;
+ updateRecentlyPlayedList = true;
sortMethod = 0;
showDirectories = true;
showHidden = false;
@@ -42,7 +42,7 @@ TWLSettings::TWLSettings()
secondaryAccess = false;
previousUsedDevice = false;
secondaryDevice = false;
- fcSaveOnSd = false;
+ fcSaveOnSd = false;
flashcard = 0;
diff --git a/romsel_aktheme/arm9/source/common/dsimenusettings.cpp b/romsel_aktheme/arm9/source/common/dsimenusettings.cpp
index e4325bdb5c..dc08a2738e 100644
--- a/romsel_aktheme/arm9/source/common/dsimenusettings.cpp
+++ b/romsel_aktheme/arm9/source/common/dsimenusettings.cpp
@@ -143,7 +143,7 @@ void TWLSettings::loadSettings()
launcherApp = settingsini.GetInt("SRLOADER", "LAUNCHER_APP", launcherApp);
}
- flashcard = settingsini.GetInt("SRLOADER", "FLASHCARD", flashcard);
+ flashcard = settingsini.GetInt("SRLOADER", "FLASHCARD", flashcard);
slot1LaunchMethod = settingsini.GetInt("SRLOADER", "SLOT1_LAUNCHMETHOD", slot1LaunchMethod);
bootstrapFile = settingsini.GetInt("SRLOADER", "BOOTSTRAP_FILE", bootstrapFile);
@@ -211,6 +211,7 @@ void TWLSettings::saveSettings()
settingsini.SetInt("SRLOADER", "ANIMATE_DSI_ICONS", animateDsiIcons);
settingsini.SetInt("SRLOADER", "SLOT1_LAUNCHMETHOD", slot1LaunchMethod);
+ settingsini.SetInt("SRLOADER", "FLASHCARD", flashcard);
settingsini.SetInt("SRLOADER", "BOOTSTRAP_FILE", bootstrapFile);
if (!isDSiMode()) settingsini.SetInt("SRLOADER", "USE_BOOTSTRAP", useBootstrap);
diff --git a/romsel_dsimenutheme/arm9/source/common/dsimenusettings.cpp b/romsel_dsimenutheme/arm9/source/common/dsimenusettings.cpp
index 8dc6523bb2..52b4583ea5 100644
--- a/romsel_dsimenutheme/arm9/source/common/dsimenusettings.cpp
+++ b/romsel_dsimenutheme/arm9/source/common/dsimenusettings.cpp
@@ -64,7 +64,7 @@ TWLSettings::TWLSettings()
updateRecentlyPlayedList = true;
sortMethod = 0;
- flashcard = 1;
+ flashcard = 0;
slot1LaunchMethod = EDirect;
@@ -128,6 +128,8 @@ void TWLSettings::loadSettings()
startMenu_cursorPosition = settingsini.GetInt("SRLOADER", "STARTMENU_CURSOR_POSITION", startMenu_cursorPosition);
consoleModel = settingsini.GetInt("SRLOADER", "CONSOLE_MODEL", consoleModel);
+ flashcard = settingsini.GetInt("SRLOADER", "FLASHCARD", flashcard);
+
showNds = settingsini.GetInt("SRLOADER", "SHOW_NDS", showNds);
showRvid = settingsini.GetInt("SRLOADER", "SHOW_RVID", showRvid);
showA26 = settingsini.GetInt("SRLOADER", "SHOW_A26", showA26);
@@ -233,6 +235,7 @@ void TWLSettings::saveSettings()
if (bothSDandFlashcard()) {
settingsini.SetInt("SRLOADER", "SECONDARY_DEVICE", secondaryDevice);
}
+ settingsini.SetInt("SRLOADER", "FLASHCARD", flashcard);
if (!gotosettings) {
settingsini.SetInt("SRLOADER", "PREVIOUS_USED_DEVICE", previousUsedDevice);
diff --git a/settings/arm9/source/common/flashcard.cpp b/settings/arm9/source/common/flashcard.cpp
index 50e23d2700..b701f91c3f 100644
--- a/settings/arm9/source/common/flashcard.cpp
+++ b/settings/arm9/source/common/flashcard.cpp
@@ -91,6 +91,9 @@ TWL_CODE void twl_flashcardInit(void) {
io_dldi_data = dldiLoadFromFile("nitro:/dldi/CycloIEvo.dldi");
fatMountSimple("fat", &io_dldi_data->ioInterface);
} */
+ else {
+ disableSlot1();
+ }
}
}
diff --git a/settings/arm9/source/settingsgui.h b/settings/arm9/source/settingsgui.h
index d1ad5e7bf4..3ded0ce4c0 100644
--- a/settings/arm9/source/settingsgui.h
+++ b/settings/arm9/source/settingsgui.h
@@ -235,4 +235,4 @@ class SettingsGUI
typedef singleton settingsGui_s;
inline SettingsGUI &gui() { return settingsGui_s::instance(); }
-#endif
\ No newline at end of file
+#endif
diff --git a/title/arm9/source/common/dsimenusettings.cpp b/title/arm9/source/common/dsimenusettings.cpp
index 96e31c9c16..f8cde861b9 100644
--- a/title/arm9/source/common/dsimenusettings.cpp
+++ b/title/arm9/source/common/dsimenusettings.cpp
@@ -12,65 +12,65 @@ bool removeLauncherPatches = true;
TWLSettings::TWLSettings()
{
- romfolder = "";
- pagenum = 0;
- cursorPosition = 0;
- startMenu_cursorPosition = 0;
- consoleModel = -1;
-
- guiLanguage = ELangDefault;
- colorMode = 0;
- blfLevel = 0;
- dsiWareExploit = 0;
- wifiLed = -1;
- useGbarunner = false;
- showMainMenu = false;
- theme = 0;
- subtheme = 0;
+ romfolder = "";
+ pagenum = 0;
+ cursorPosition = 0;
+ startMenu_cursorPosition = 0;
+ consoleModel = -1;
+
+ guiLanguage = ELangDefault;
+ colorMode = 0;
+ blfLevel = 0;
+ dsiWareExploit = 0;
+ wifiLed = -1;
+ useGbarunner = false;
+ showMainMenu = false;
+ theme = 0;
+ subtheme = 0;
showMd = 3;
- showDirectories = true;
- showBoxArt = 1 + isDSiMode();
- animateDsiIcons = true;
- sysRegion = -1;
- launcherApp = -1;
- secondaryAccess = false;
- previousUsedDevice = false;
- secondaryDevice = false;
+ showDirectories = true;
+ showBoxArt = 1 + isDSiMode();
+ animateDsiIcons = true;
+ sysRegion = -1;
+ launcherApp = -1;
+ secondaryAccess = false;
+ previousUsedDevice = false;
+ secondaryDevice = false;
fcSaveOnSd = false;
- flashcard = 0;
+ flashcard = 0;
- slot1LaunchMethod = EDirect;
+ slot1LaunchMethod = EDirect;
- useBootstrap = true;
- bootstrapFile = EReleaseBootstrap;
+ useBootstrap = true;
+ bootstrapFile = EReleaseBootstrap;
- gameLanguage = ELangDefault;
- boostCpu = false;
- boostVram = false;
- bstrap_dsiMode = false;
- slot1SCFGUnlock = false;
+ gameLanguage = ELangDefault;
+ boostCpu = false;
+ boostVram = false;
+ bstrap_dsiMode = false;
+ slot1SCFGUnlock = false;
- show12hrClock = true;
+ show12hrClock = true;
- ak_viewMode = EViewInternal;
- ak_scrollSpeed = EScrollFast;
- ak_theme = "zelda";
- ak_zoomIcons = true;
+ ak_viewMode = EViewInternal;
+ ak_scrollSpeed = EScrollFast;
+ ak_theme = "zelda";
+ ak_zoomIcons = true;
slot1Launched = false;
- launchType[0] = ENoLaunch;
- launchType[1] = ENoLaunch;
- homebrewBootstrap = EReleaseBootstrap;
- homebrewHasWide = false;
+ launchType[0] = ENoLaunch;
+ launchType[1] = ENoLaunch;
+ homebrewBootstrap = EReleaseBootstrap;
+ homebrewHasWide = false;
- r4_theme = "unused";
- unlaunchBg = "default.gif";
+ r4_theme = "unused";
+ unlaunchBg = "default.gif";
dsiSplash = isDSiMode();
- showlogo = true;
- autorun = false;
+ showlogo = true;
+ autorun = false;
autostartSlot1 = false;
wideScreen = false;
@@ -78,144 +78,147 @@ TWLSettings::TWLSettings()
void TWLSettings::loadSettings()
{
- CIniFile settingsini(settingsinipath);
+ CIniFile settingsini(settingsinipath);
- // UI settings.
- romfolder = settingsini.GetString("SRLOADER", "ROM_FOLDER", romfolder);
+ // UI settings.
+ romfolder = settingsini.GetString("SRLOADER", "ROM_FOLDER", romfolder);
- pagenum = settingsini.GetInt("SRLOADER", "PAGE_NUMBER", pagenum);
- cursorPosition = settingsini.GetInt("SRLOADER", "CURSOR_POSITION", cursorPosition);
- startMenu_cursorPosition = settingsini.GetInt("SRLOADER", "STARTMENU_CURSOR_POSITION", startMenu_cursorPosition);
- consoleModel = settingsini.GetInt("SRLOADER", "CONSOLE_MODEL", consoleModel);
+ pagenum = settingsini.GetInt("SRLOADER", "PAGE_NUMBER", pagenum);
+ cursorPosition = settingsini.GetInt("SRLOADER", "CURSOR_POSITION", cursorPosition);
+ startMenu_cursorPosition = settingsini.GetInt("SRLOADER", "STARTMENU_CURSOR_POSITION", startMenu_cursorPosition);
+ consoleModel = settingsini.GetInt("SRLOADER", "CONSOLE_MODEL", consoleModel);
+
+ flashcard = settingsini.GetInt("SRLOADER", "FLASHCARD", flashcard);
showMd = settingsini.GetInt("SRLOADER", "SHOW_MDGEN", showMd);
- // Customizable UI settings.
+ // Customizable UI settings.
colorMode = settingsini.GetInt("SRLOADER", "COLOR_MODE", colorMode);
blfLevel = settingsini.GetInt("SRLOADER", "BLUE_LIGHT_FILTER_LEVEL", blfLevel);
dsiWareExploit = settingsini.GetInt("SRLOADER", "DSIWARE_EXPLOIT", dsiWareExploit);
wifiLed = settingsini.GetInt("SRLOADER", "WIFI_LED", wifiLed);
- guiLanguage = settingsini.GetInt("SRLOADER", "LANGUAGE", guiLanguage);
- useGbarunner = settingsini.GetInt("SRLOADER", "USE_GBARUNNER2", useGbarunner);
- if (!sys().isRegularDS()) {
- useGbarunner = true;
- }
+ guiLanguage = settingsini.GetInt("SRLOADER", "LANGUAGE", guiLanguage);
+ useGbarunner = settingsini.GetInt("SRLOADER", "USE_GBARUNNER2", useGbarunner);
+ if (!sys().isRegularDS()) {
+ useGbarunner = true;
+ }
- dsiSplash = settingsini.GetInt("SRLOADER", "DSI_SPLASH", dsiSplash);
- showlogo = settingsini.GetInt("SRLOADER", "SHOWLOGO", showlogo);
+ dsiSplash = settingsini.GetInt("SRLOADER", "DSI_SPLASH", dsiSplash);
+ showlogo = settingsini.GetInt("SRLOADER", "SHOWLOGO", showlogo);
secondaryAccess = settingsini.GetInt("SRLOADER", "SECONDARY_ACCESS", secondaryAccess);
previousUsedDevice = settingsini.GetInt("SRLOADER", "PREVIOUS_USED_DEVICE", previousUsedDevice);
- secondaryDevice = settingsini.GetInt("SRLOADER", "SECONDARY_DEVICE", secondaryDevice);
+ secondaryDevice = settingsini.GetInt("SRLOADER", "SECONDARY_DEVICE", secondaryDevice);
fcSaveOnSd = settingsini.GetInt("SRLOADER", "FC_SAVE_ON_SD", fcSaveOnSd);
- romPath[0] = settingsini.GetString("SRLOADER", "ROM_PATH", romPath[0]);
- romPath[1] = settingsini.GetString("SRLOADER", "SECONDARY_ROM_PATH", romPath[1]);
- showMainMenu = settingsini.GetInt("SRLOADER", "SHOW_MAIN_MENU", showMainMenu);
- theme = settingsini.GetInt("SRLOADER", "THEME", theme);
- subtheme = settingsini.GetInt("SRLOADER", "SUB_THEME", subtheme);
- showDirectories = settingsini.GetInt("SRLOADER", "SHOW_DIRECTORIES", showDirectories);
- showBoxArt = settingsini.GetInt("SRLOADER", "SHOW_BOX_ART", showBoxArt);
- animateDsiIcons = settingsini.GetInt("SRLOADER", "ANIMATE_DSI_ICONS", animateDsiIcons);
+ romPath[0] = settingsini.GetString("SRLOADER", "ROM_PATH", romPath[0]);
+ romPath[1] = settingsini.GetString("SRLOADER", "SECONDARY_ROM_PATH", romPath[1]);
+ showMainMenu = settingsini.GetInt("SRLOADER", "SHOW_MAIN_MENU", showMainMenu);
+ theme = settingsini.GetInt("SRLOADER", "THEME", theme);
+ subtheme = settingsini.GetInt("SRLOADER", "SUB_THEME", subtheme);
+ showDirectories = settingsini.GetInt("SRLOADER", "SHOW_DIRECTORIES", showDirectories);
+ showBoxArt = settingsini.GetInt("SRLOADER", "SHOW_BOX_ART", showBoxArt);
+ animateDsiIcons = settingsini.GetInt("SRLOADER", "ANIMATE_DSI_ICONS", animateDsiIcons);
if (consoleModel < 2) {
sysRegion = settingsini.GetInt("SRLOADER", "SYS_REGION", sysRegion);
launcherApp = settingsini.GetInt("SRLOADER", "LAUNCHER_APP", launcherApp);
}
- slot1LaunchMethod = settingsini.GetInt("SRLOADER", "SLOT1_LAUNCHMETHOD", slot1LaunchMethod);
- bootstrapFile = settingsini.GetInt("SRLOADER", "BOOTSTRAP_FILE", bootstrapFile);
- useBootstrap = settingsini.GetInt("SRLOADER", "USE_BOOTSTRAP", useBootstrap);
+ slot1LaunchMethod = settingsini.GetInt("SRLOADER", "SLOT1_LAUNCHMETHOD", slot1LaunchMethod);
+ bootstrapFile = settingsini.GetInt("SRLOADER", "BOOTSTRAP_FILE", bootstrapFile);
+ useBootstrap = settingsini.GetInt("SRLOADER", "USE_BOOTSTRAP", useBootstrap);
- // Default nds-bootstrap settings
- gameLanguage = settingsini.GetInt("NDS-BOOTSTRAP", "LANGUAGE", gameLanguage);
- boostCpu = settingsini.GetInt("NDS-BOOTSTRAP", "BOOST_CPU", boostCpu);
- boostVram = settingsini.GetInt("NDS-BOOTSTRAP", "BOOST_VRAM", boostVram);
- bstrap_dsiMode = settingsini.GetInt("NDS-BOOTSTRAP", "DSI_MODE", bstrap_dsiMode);
+ // Default nds-bootstrap settings
+ gameLanguage = settingsini.GetInt("NDS-BOOTSTRAP", "LANGUAGE", gameLanguage);
+ boostCpu = settingsini.GetInt("NDS-BOOTSTRAP", "BOOST_CPU", boostCpu);
+ boostVram = settingsini.GetInt("NDS-BOOTSTRAP", "BOOST_VRAM", boostVram);
+ bstrap_dsiMode = settingsini.GetInt("NDS-BOOTSTRAP", "DSI_MODE", bstrap_dsiMode);
- ak_viewMode = settingsini.GetInt("SRLOADER", "AK_VIEWMODE", ak_viewMode);
- ak_scrollSpeed = settingsini.GetInt("SRLOADER", "AK_SCROLLSPEED", ak_scrollSpeed);
- ak_theme = settingsini.GetString("SRLOADER", "AK_THEME", ak_theme);
- ak_zoomIcons = settingsini.GetInt("SRLOADER", "AK_ZOOM_ICONS", ak_zoomIcons);
+ ak_viewMode = settingsini.GetInt("SRLOADER", "AK_VIEWMODE", ak_viewMode);
+ ak_scrollSpeed = settingsini.GetInt("SRLOADER", "AK_SCROLLSPEED", ak_scrollSpeed);
+ ak_theme = settingsini.GetString("SRLOADER", "AK_THEME", ak_theme);
+ ak_zoomIcons = settingsini.GetInt("SRLOADER", "AK_ZOOM_ICONS", ak_zoomIcons);
- dsiWareSrlPath = settingsini.GetString("SRLOADER", "DSIWARE_SRL", dsiWareSrlPath);
- dsiWarePubPath = settingsini.GetString("SRLOADER", "DSIWARE_PUB", dsiWarePubPath);
- dsiWarePrvPath = settingsini.GetString("SRLOADER", "DSIWARE_PRV", dsiWarePrvPath);
+ dsiWareSrlPath = settingsini.GetString("SRLOADER", "DSIWARE_SRL", dsiWareSrlPath);
+ dsiWarePubPath = settingsini.GetString("SRLOADER", "DSIWARE_PUB", dsiWarePubPath);
+ dsiWarePrvPath = settingsini.GetString("SRLOADER", "DSIWARE_PRV", dsiWarePrvPath);
slot1Launched = settingsini.GetInt("SRLOADER", "SLOT1_LAUNCHED", slot1Launched);
- launchType[0] = settingsini.GetInt("SRLOADER", "LAUNCH_TYPE", launchType[0]);
- launchType[1] = settingsini.GetInt("SRLOADER", "SECONDARY_LAUNCH_TYPE", launchType[1]);
- homebrewArg[0] = settingsini.GetString("SRLOADER", "HOMEBREW_ARG", homebrewArg[0]);
- homebrewArg[1] = settingsini.GetString("SRLOADER", "SECONDARY_HOMEBREW_ARG", homebrewArg[0]);
- homebrewBootstrap = settingsini.GetInt("SRLOADER", "HOMEBREW_BOOTSTRAP", homebrewBootstrap);
- homebrewHasWide = settingsini.GetInt("SRLOADER", "HOMEBREW_HAS_WIDE", homebrewHasWide);
-
- unlaunchBg = settingsini.GetString("SRLOADER", "UNLAUNCH_BG", unlaunchBg);
+ launchType[0] = settingsini.GetInt("SRLOADER", "LAUNCH_TYPE", launchType[0]);
+ launchType[1] = settingsini.GetInt("SRLOADER", "SECONDARY_LAUNCH_TYPE", launchType[1]);
+ homebrewArg[0] = settingsini.GetString("SRLOADER", "HOMEBREW_ARG", homebrewArg[0]);
+ homebrewArg[1] = settingsini.GetString("SRLOADER", "SECONDARY_HOMEBREW_ARG", homebrewArg[0]);
+ homebrewBootstrap = settingsini.GetInt("SRLOADER", "HOMEBREW_BOOTSTRAP", homebrewBootstrap);
+ homebrewHasWide = settingsini.GetInt("SRLOADER", "HOMEBREW_HAS_WIDE", homebrewHasWide);
+
+ unlaunchBg = settingsini.GetString("SRLOADER", "UNLAUNCH_BG", unlaunchBg);
charUnlaunchBg = unlaunchBg.c_str();
removeLauncherPatches = settingsini.GetInt("SRLOADER", "UNLAUNCH_PATCH_REMOVE", removeLauncherPatches);
- show12hrClock = settingsini.GetInt("SRLOADER", "SHOW_12H_CLOCK", show12hrClock);
+ show12hrClock = settingsini.GetInt("SRLOADER", "SHOW_12H_CLOCK", show12hrClock);
- autorun = settingsini.GetInt("SRLOADER", "AUTORUNGAME", autorun);
- autostartSlot1 = settingsini.GetInt("SRLOADER", "AUTORUNSLOT1", autostartSlot1);
+ autorun = settingsini.GetInt("SRLOADER", "AUTORUNGAME", autorun);
+ autostartSlot1 = settingsini.GetInt("SRLOADER", "AUTORUNSLOT1", autostartSlot1);
- wideScreen = settingsini.GetInt("SRLOADER", "WIDESCREEN", wideScreen);
+ wideScreen = settingsini.GetInt("SRLOADER", "WIDESCREEN", wideScreen);
}
void TWLSettings::saveSettings()
{
- CIniFile settingsini(settingsinipath);
+ CIniFile settingsini(settingsinipath);
- settingsini.SetString("SRLOADER", "ROM_FOLDER", romfolder);
+ settingsini.SetString("SRLOADER", "ROM_FOLDER", romfolder);
- settingsini.SetInt("SRLOADER", "PAGE_NUMBER", pagenum);
- settingsini.SetInt("SRLOADER", "CURSOR_POSITION", cursorPosition);
- settingsini.SetInt("SRLOADER", "STARTMENU_CURSOR_POSITION", startMenu_cursorPosition);
- settingsini.SetInt("SRLOADER", "CONSOLE_MODEL", consoleModel);
- settingsini.SetInt("SRLOADER", "AUTORUNGAME", autorun);
+ settingsini.SetInt("SRLOADER", "PAGE_NUMBER", pagenum);
+ settingsini.SetInt("SRLOADER", "CURSOR_POSITION", cursorPosition);
+ settingsini.SetInt("SRLOADER", "STARTMENU_CURSOR_POSITION", startMenu_cursorPosition);
+ settingsini.SetInt("SRLOADER", "CONSOLE_MODEL", consoleModel);
+ settingsini.SetInt("SRLOADER", "FLASHCARD", flashcard);
+ settingsini.SetInt("SRLOADER", "AUTORUNGAME", autorun);
settingsini.SetInt("SRLOADER", "WIFI_LED", wifiLed);
- // Customizable UI settings.
- settingsini.SetInt("SRLOADER", "LANGUAGE", guiLanguage);
- settingsini.SetInt("SRLOADER", "USE_GBARUNNER2", useGbarunner);
-
- settingsini.SetInt("SRLOADER", "SHOWLOGO", showlogo);
-
- settingsini.SetInt("SRLOADER", "SECONDARY_ACCESS", secondaryAccess);
- settingsini.SetInt("SRLOADER", "SHOW_MAIN_MENU", showMainMenu);
- settingsini.SetInt("SRLOADER", "THEME", theme);
- settingsini.SetInt("SRLOADER", "SUB_THEME", subtheme);
- settingsini.SetInt("SRLOADER", "SHOW_DIRECTORIES", showDirectories);
- settingsini.SetInt("SRLOADER", "SHOW_BOX_ART", showBoxArt);
- settingsini.SetInt("SRLOADER", "ANIMATE_DSI_ICONS", animateDsiIcons);
+ // Customizable UI settings.
+ settingsini.SetInt("SRLOADER", "LANGUAGE", guiLanguage);
+ settingsini.SetInt("SRLOADER", "USE_GBARUNNER2", useGbarunner);
+
+ settingsini.SetInt("SRLOADER", "SHOWLOGO", showlogo);
+
+ settingsini.SetInt("SRLOADER", "SECONDARY_ACCESS", secondaryAccess);
+ settingsini.SetInt("SRLOADER", "SHOW_MAIN_MENU", showMainMenu);
+ settingsini.SetInt("SRLOADER", "THEME", theme);
+ settingsini.SetInt("SRLOADER", "SUB_THEME", subtheme);
+ settingsini.SetInt("SRLOADER", "SHOW_DIRECTORIES", showDirectories);
+ settingsini.SetInt("SRLOADER", "SHOW_BOX_ART", showBoxArt);
+ settingsini.SetInt("SRLOADER", "ANIMATE_DSI_ICONS", animateDsiIcons);
if (consoleModel < 2) {
settingsini.SetInt("SRLOADER", "SYS_REGION", sysRegion);
settingsini.SetInt("SRLOADER", "LAUNCHER_APP", launcherApp);
}
- settingsini.SetInt("SRLOADER", "SLOT1_LAUNCHMETHOD", slot1LaunchMethod);
- settingsini.SetInt("SRLOADER", "BOOTSTRAP_FILE", bootstrapFile);
- settingsini.SetInt("SRLOADER", "USE_BOOTSTRAP", useBootstrap);
+ settingsini.SetInt("SRLOADER", "SLOT1_LAUNCHMETHOD", slot1LaunchMethod);
+ settingsini.SetInt("SRLOADER", "BOOTSTRAP_FILE", bootstrapFile);
+ settingsini.SetInt("SRLOADER", "USE_BOOTSTRAP", useBootstrap);
- // Default nds-bootstrap settings
- settingsini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", gameLanguage);
- settingsini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", boostCpu);
- settingsini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", boostVram);
- settingsini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", bstrap_dsiMode);
+ // Default nds-bootstrap settings
+ settingsini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", gameLanguage);
+ settingsini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", boostCpu);
+ settingsini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", boostVram);
+ settingsini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", bstrap_dsiMode);
- settingsini.SetInt("SRLOADER", "AK_VIEWMODE", ak_viewMode);
- settingsini.SetInt("SRLOADER", "AK_SCROLLSPEED", ak_scrollSpeed);
- settingsini.SetString("SRLOADER", "AK_THEME", ak_theme);
- settingsini.SetInt("SRLOADER", "AK_ZOOM_ICONS", ak_zoomIcons);
+ settingsini.SetInt("SRLOADER", "AK_VIEWMODE", ak_viewMode);
+ settingsini.SetInt("SRLOADER", "AK_SCROLLSPEED", ak_scrollSpeed);
+ settingsini.SetString("SRLOADER", "AK_THEME", ak_theme);
+ settingsini.SetInt("SRLOADER", "AK_ZOOM_ICONS", ak_zoomIcons);
- settingsini.SetInt("SRLOADER", "SHOW_12H_CLOCK", show12hrClock);
+ settingsini.SetInt("SRLOADER", "SHOW_12H_CLOCK", show12hrClock);
- settingsini.SaveIniFile(settingsinipath);
+ settingsini.SaveIniFile(settingsinipath);
}
TWLSettings::TLanguage TWLSettings::getGuiLanguage()
{
- if (guiLanguage == ELangDefault)
- {
+ if (guiLanguage == ELangDefault)
+ {
extern bool useTwlCfg;
- return (TLanguage)(useTwlCfg ? *(u8*)0x02000406 : PersonalData->language);
- }
- return (TLanguage)guiLanguage;
+ return (TLanguage)(useTwlCfg ? *(u8*)0x02000406 : PersonalData->language);
+ }
+ return (TLanguage)guiLanguage;
}
diff --git a/title/arm9/source/common/flashcard.cpp b/title/arm9/source/common/flashcard.cpp
index 53d7e2fae2..e22b4a4ef0 100644
--- a/title/arm9/source/common/flashcard.cpp
+++ b/title/arm9/source/common/flashcard.cpp
@@ -94,6 +94,9 @@ TWL_CODE void twl_flashcardInit(void) {
io_dldi_data = dldiLoadFromFile("nitro:/dldi/CycloIEvo.dldi");
fatMountSimple("fat", &io_dldi_data->ioInterface);
} */
+ else {
+ disableSlot1();
+ }
}
}
@@ -103,21 +106,19 @@ void flashcardInit(void) {
}
}
-void detectFlashcard() {
+int detectFlashcard() {
if (!memcmp(io_dldi_data->friendlyName, "TTCARD", 6)
|| !memcmp(io_dldi_data->friendlyName, "DSTT", 4)
|| !memcmp(io_dldi_data->friendlyName, "DEMON", 5))
- ms().flashcard = FC::EDSTTClone;
- else if (!memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 26)
+ return FC::EDSTTClone;
+ if (!memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 26)
|| !memcmp(io_dldi_data->friendlyName, "R4TF", 4))
- ms().flashcard = FC::ER4Original;
- else if (!memcmp(io_dldi_data->friendlyName, "R4iDSN", 6))
- ms().flashcard = FC::ER4iGoldClone;
- else if (!memcmp(io_dldi_data->friendlyName, "Acekard AK2", 0xB))
- ms().flashcard = FC::EAcekard2i;
- else if (!memcmp(io_dldi_data->friendlyName, "DSTWO(Slot-1)", 0xD))
- ms().flashcard = FC::ESupercardDSTWO;
- else
- ms().flashcard = FC::EUnknown;
- ms().saveSettings();
+ return FC::ER4Original;
+ if (!memcmp(io_dldi_data->friendlyName, "R4iDSN", 6))
+ return FC::ER4iGoldClone;
+ if (!memcmp(io_dldi_data->friendlyName, "Acekard AK2", 0xB))
+ return FC::EAcekard2i;
+ if (!memcmp(io_dldi_data->friendlyName, "DSTWO(Slot-1)", 0xD))
+ return FC::ESupercardDSTWO;
+ return FC::EUnknown;
}
diff --git a/title/arm9/source/common/flashcard.h b/title/arm9/source/common/flashcard.h
index 341ced7b97..30be6c9946 100644
--- a/title/arm9/source/common/flashcard.h
+++ b/title/arm9/source/common/flashcard.h
@@ -8,6 +8,6 @@ bool sdFound(void);
bool flashcardFound(void);
bool bothSDandFlashcard(void);
void flashcardInit(void);
-void detectFlashcard();
+int detectFlashcard(void);
#endif //DSIMENUPP_FLASHCARD_H
diff --git a/title/arm9/source/main.cpp b/title/arm9/source/main.cpp
index aeceaaaf78..65f79aa311 100644
--- a/title/arm9/source/main.cpp
+++ b/title/arm9/source/main.cpp
@@ -34,16 +34,7 @@ extern bool controlBottomBright;
//bool soundfreqsettingChanged = false;
bool hiyaAutobootFound = false;
-//static int flashcard;
-/* Flashcard value
- 0: DSTT/R4i Gold/R4i-SDHC/R4 SDHC Dual-Core/R4 SDHC Upgrade/SC DSONE
- 1: R4DS (Original Non-SDHC version)/ M3 Simply
- 2: R4iDSN/R4i Gold RTS/R4 Ultra
- 3: Acekard 2(i)/Galaxy Eagle/M3DS Real
- 4: Acekard RPG
- 5: Ace 3DS+/Gateway Blue Card/R4iTT
- 6: SuperCard DSTWO
-*/
+int flashcard = 0;
const char *hiyacfwinipath = "sd:/hiya/settings.ini";
const char *settingsinipath = DSIMENUPP_INI;
@@ -93,8 +84,8 @@ void stop(void)
char filePath[PATH_MAX];
-/*//---------------------------------------------------------------------------------
-void doPause(void)
+//---------------------------------------------------------------------------------
+/*void doPause(void)
{
//---------------------------------------------------------------------------------
printf("Press start...\n");
@@ -721,6 +712,7 @@ int main(int argc, char **argv)
ms().loadSettings();
bs().loadSettings();
+
if (isDSiMode() && ms().consoleModel < 2) {
if (ms().wifiLed == -1) {
if (*(u8*)(0x023FFD01) == 0x13) {
@@ -745,8 +737,6 @@ int main(int argc, char **argv)
if (flashcardFound()) {
mkdir("fat:/_gba", 0777);
mkdir("fat:/_nds/TWiLightMenu/gamesettings", 0777);
-
- detectFlashcard();
}
runGraphicIrq();
@@ -860,6 +850,17 @@ int main(int argc, char **argv)
scanKeys();
+ // If in DSi mode with SCFG access attempt to cut slot1 power to save battery
+ if (isDSiMode() && !sys().arm7SCFGLocked() && !ms().autostartSlot1) {
+ disableSlot1();
+ } else {
+ const int flashcard = detectFlashcard();
+ ms().flashcard = flashcard;
+ ms().flashcard = flashcard;
+ ms().saveSettings();
+ ms().saveSettings();
+ }
+
if (softResetParamsFound
|| (ms().autorun && !(keysHeld() & KEY_B))
|| (!ms().autorun && (keysHeld() & KEY_B)))
@@ -868,10 +869,6 @@ int main(int argc, char **argv)
lastRunROM();
}
- // If in DSi mode with SCFG access attempt to cut slot1 power to save battery
- if (isDSiMode() && !sys().arm7SCFGLocked() && !ms().autostartSlot1) {
- disableSlot1();
- }
if (!softResetParamsFound && ms().autostartSlot1 && isDSiMode() && REG_SCFG_MC != 0x11 && !flashcardFound() && !(keysHeld() & KEY_SELECT)) {
if (ms().slot1LaunchMethod==0 || sys().arm7SCFGLocked()) {
From 4a3ed2389258444d02ffc5629f635e715dc7aa42 Mon Sep 17 00:00:00 2001
From: unresolvedsymbol <48220091+unresolvedsymbol@users.noreply.github.com>
Date: Tue, 3 Nov 2020 16:13:57 -0600
Subject: [PATCH 8/8] Update flashcards
---
title/arm9/source/common/flashcard.cpp | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/title/arm9/source/common/flashcard.cpp b/title/arm9/source/common/flashcard.cpp
index e22b4a4ef0..41f8385468 100644
--- a/title/arm9/source/common/flashcard.cpp
+++ b/title/arm9/source/common/flashcard.cpp
@@ -86,6 +86,7 @@ TWL_CODE void twl_flashcardInit(void) {
fatMountSimple("fat", &io_dldi_data->ioInterface);
} else if (!memcmp(ndsCardHeader.gameCode, "ACEK", 4) || !memcmp(ndsCardHeader.gameCode, "YCEP", 4) || !memcmp(ndsCardHeader.gameCode, "AHZH", 4) || !memcmp(ndsCardHeader.gameCode, "CHPJ", 4) || !memcmp(ndsCardHeader.gameCode, "ADLP", 4)) {
io_dldi_data = dldiLoadFromFile("nitro:/dldi/ak2_sd.dldi");
+ //io_dldi_data = dldiLoadFromFile("nitro:/dldi/r4idsn_sd.dldi");
fatMountSimple("fat", &io_dldi_data->ioInterface);
} /*else if (!memcmp(ndsCardHeader.gameCode, "ALXX", 4)) {
io_dldi_data = dldiLoadFromFile("nitro:/dldi/dstwo.dldi");
@@ -111,14 +112,18 @@ int detectFlashcard() {
|| !memcmp(io_dldi_data->friendlyName, "DSTT", 4)
|| !memcmp(io_dldi_data->friendlyName, "DEMON", 5))
return FC::EDSTTClone;
- if (!memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 26)
+ if (!memcmp(io_dldi_data->friendlyName, "R4(DS) - Revolution for DS", 0x1A)
|| !memcmp(io_dldi_data->friendlyName, "R4TF", 4))
return FC::ER4Original;
if (!memcmp(io_dldi_data->friendlyName, "R4iDSN", 6))
- return FC::ER4iGoldClone;
+ return FC::ER4iGoldClone;
if (!memcmp(io_dldi_data->friendlyName, "Acekard AK2", 0xB))
return FC::EAcekard2i;
+ if (!memcmp(io_dldi_data->friendlyName, "Acekard RPG", 0xB))
+ return FC::EAcekardRPG;
if (!memcmp(io_dldi_data->friendlyName, "DSTWO(Slot-1)", 0xD))
return FC::ESupercardDSTWO;
+ if (!memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 0x12))
+ return FC::ECycloDSi;
return FC::EUnknown;
}