Skip to content

Commit

Permalink
Add per-game settings menu (ahezard#4)
Browse files Browse the repository at this point in the history
* Add per-game settings menu

* Actually save per-game settings

* Hold Y to open per-game settings instead of X or SELECT

For consistency with TWLMenu++

Co-authored-by: RocketRobz <[email protected]>
  • Loading branch information
Epicpkmn11 and RocketRobz authored Nov 5, 2021
1 parent d0f2a12 commit 225f062
Show file tree
Hide file tree
Showing 3 changed files with 248 additions and 12 deletions.
34 changes: 22 additions & 12 deletions SD Card/sd/arm9/source/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "inifile.h"
#include "fileCopy.h"
#include "perGameSettings.h"

#include "twlClockExcludeMap.h"
#include "dmaExcludeMap.h"
Expand Down Expand Up @@ -321,6 +322,8 @@ int main(int argc, char **argv) {
// Cut slot1 power to save battery
disableSlot1();

keysSetRepeat(25, 5);

*(vu32*)0x0DFFFE0C = 0x4652544E;
bool debugRam = (*(vu32*)0x0DFFFE0C == 0x4652544E);

Expand Down Expand Up @@ -366,6 +369,12 @@ int main(int argc, char **argv) {
filename.erase(0, last_slash_idx + 1);
}

GameSettings gameSettings(filename);
scanKeys();
if(keysHeld() & KEY_Y) {
gameSettings.menu();
}

FILE *f_nds_file = fopen(filename.c_str(), "rb");
bool dsiBinariesFound = checkDsiBinaries(f_nds_file);
int isHomebrew = checkIfHomebrew(f_nds_file);
Expand Down Expand Up @@ -423,7 +432,10 @@ int main(int argc, char **argv) {
typeToReplace = ".app";
}

savename = ReplaceAll(filename, typeToReplace, ".sav");
char savExtension[16] = ".sav";
if(gameSettings.saveNo > 0)
snprintf(savExtension, sizeof(savExtension), ".sav%d", gameSettings.saveNo);
savename = ReplaceAll(filename, typeToReplace, savExtension);
romFolderNoSlash = romfolder;
RemoveTrailingSlashes(romFolderNoSlash);
savepath = romFolderNoSlash+"/saves/"+savename;
Expand Down Expand Up @@ -590,22 +602,20 @@ int main(int argc, char **argv) {
bootstrapini.SetString("NDS-BOOTSTRAP", "AP_FIX_PATH", isDSiWare ? "" : setApFix(filename.c_str()));
}
bootstrapini.SetString("NDS-BOOTSTRAP", "HOMEBREW_ARG", "");
bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", setClockSpeed(filename.c_str()));
//bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", boostVram);
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARD_READ_DMA", setCardReadDMA(filename.c_str()));
bootstrapini.SetInt("NDS-BOOTSTRAP", "ASYNC_CARD_READ", setAsyncCardRead(filename.c_str()));
if (dsModeForced || ndsHeader.unitCode == 0) {
bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", 0);
} else {
bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", 1);
}
bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_CPU", gameSettings.boostCpu == -1 ? setClockSpeed(filename.c_str()) : gameSettings.boostCpu);
bootstrapini.SetInt("NDS-BOOTSTRAP", "BOOST_VRAM", gameSettings.boostVram == -1 ? boostVram : gameSettings.boostVram);
bootstrapini.SetInt("NDS-BOOTSTRAP", "CARD_READ_DMA", gameSettings.cardReadDMA == -1 ? setCardReadDMA(filename.c_str()) : gameSettings.cardReadDMA);
bootstrapini.SetInt("NDS-BOOTSTRAP", "ASYNC_CARD_READ", gameSettings.asyncCardRead == -1 ? setAsyncCardRead(filename.c_str()) : gameSettings.asyncCardRead);
bootstrapini.SetInt("NDS-BOOTSTRAP", "DSI_MODE", dsModeForced ? 0 : (gameSettings.dsiMode == -1 ? dsiMode : gameSettings.dsiMode));
bootstrapini.SetInt("NDS-BOOTSTRAP", "SWI_HALT_HOOK", gameSettings.swiHaltHook == -1 ? true : gameSettings.swiHaltHook);
bootstrapini.SetInt("NDS-BOOTSTRAP", "EXTENDED_MEMORY", gameSettings.expandRomSpace == -1 ? false : gameSettings.expandRomSpace);
//bootstrapini.SetInt("NDS-BOOTSTRAP", "CACHE_FAT_TABLE", cacheFatTable);
bootstrapini.SetInt("NDS-BOOTSTRAP", "DONOR_SDK_VER", donorSdkVer);
bootstrapini.SetInt("NDS-BOOTSTRAP", "PATCH_MPU_REGION", 0);
bootstrapini.SetInt("NDS-BOOTSTRAP", "PATCH_MPU_SIZE", 0);
bootstrapini.SetInt("NDS-BOOTSTRAP", "CONSOLE_MODEL", consoleModel);
bootstrapini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", language);
bootstrapini.SetInt("NDS-BOOTSTRAP", "REGION", region);
bootstrapini.SetInt("NDS-BOOTSTRAP", "LANGUAGE", gameSettings.language == -2 ? language : gameSettings.language);
bootstrapini.SetInt("NDS-BOOTSTRAP", "REGION", gameSettings.region == -3 ? region : gameSettings.region);
bootstrapini.SaveIniFile( "sd:/_nds/nds-bootstrap.ini" );

if (isHomebrew == 1) {
Expand Down
193 changes: 193 additions & 0 deletions SD Card/sd/arm9/source/perGameSettings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
#include "perGameSettings.h"

#include <nds.h>
#include <dirent.h>

constexpr std::array<const char *, 3> offOnLabels = {"Default", "Off", "On"};
constexpr std::array<const char *, 10> languageLabels = {"Default", "System", "Japanese", "English", "French", "German", "Italian", "Spanish", "Chinese", "Korean"};
constexpr std::array<const char *, 9> regionLabels = {"Default", "Per-game", "System", "Japan", "USA", "Europe", "Australia", "China", "Korea"};
constexpr std::array<const char *, 4> runInLabels = {"Default", "DS Mode", "Auto", "DSi Mode"};
constexpr std::array<const char *, 3> cpuLabels = {"Default", "67 MHz (NTR)", "133 MHz (TWL)"};
constexpr std::array<const char *, 3> vramLabels = {"Default", "DS Mode", "DSi Mode"};
constexpr std::array<const char *, 4> expandLabels = {"Default", "No", "Yes", "Yes+512 KB"};
constexpr std::array<const char *, 3> bootstrapLabels = {"Default", "Release", "Nightly"};

GameSettings::GameSettings(const std::string &filename) : filepath("sd:/_nds/ntr-forwarder/gamesettings/" + filename + ".ini"), ini(filepath) {
language = ini.GetInt("GAMESETTINGS", "LANGUAGE", language);
region = ini.GetInt("GAMESETTINGS", "REGION", region);
saveNo = ini.GetInt("GAMESETTINGS", "SAVE_NUMBER", saveNo);
dsiMode = ini.GetInt("GAMESETTINGS", "DSI_MODE", dsiMode);
boostCpu = ini.GetInt("GAMESETTINGS", "BOOST_CPU", boostCpu);
boostVram = ini.GetInt("GAMESETTINGS", "BOOST_VRAM", boostVram);
cardReadDMA = ini.GetInt("GAMESETTINGS", "CARD_READ_DMA", cardReadDMA);
asyncCardRead = ini.GetInt("GAMESETTINGS", "ASYNC_CARD_READ", asyncCardRead);
swiHaltHook = ini.GetInt("GAMESETTINGS", "SWI_HALT_HOOK", swiHaltHook);
expandRomSpace = ini.GetInt("GAMESETTINGS", "EXTENDED_MEMORY", expandRomSpace);
bootstrapFile = ini.GetInt("GAMESETTINGS", "BOOTSTRAP_FILE", bootstrapFile);
}

void GameSettings::save() {
ini.SetInt("GAMESETTINGS", "LANGUAGE", language);
ini.SetInt("GAMESETTINGS", "REGION", region);
ini.SetInt("GAMESETTINGS", "SAVE_NUMBER", saveNo);
ini.SetInt("GAMESETTINGS", "DSI_MODE", dsiMode);
ini.SetInt("GAMESETTINGS", "BOOST_CPU", boostCpu);
ini.SetInt("GAMESETTINGS", "BOOST_VRAM", boostVram);
ini.SetInt("GAMESETTINGS", "CARD_READ_DMA", cardReadDMA);
ini.SetInt("GAMESETTINGS", "ASYNC_CARD_READ", asyncCardRead);
ini.SetInt("GAMESETTINGS", "SWI_HALT_HOOK", swiHaltHook);
ini.SetInt("GAMESETTINGS", "EXTENDED_MEMORY", expandRomSpace);
ini.SetInt("GAMESETTINGS", "BOOTSTRAP_FILE", bootstrapFile);

// Ensure the folder exists
if(access("sd:/_nds", F_OK) != 0)
mkdir("sd:/_nds", 0777);
if(access("sd:/_nds/ntr-forwarder", F_OK) != 0)
mkdir("sd:/_nds/ntr-forwarder", 0777);
if(access("sd:/_nds/ntr-forwarder/gamesettings", F_OK) != 0)
mkdir("sd:/_nds/ntr-forwarder/gamesettings", 0777);

ini.SaveIniFile(filepath);
}

void GameSettings::menu() {
consoleDemoInit();

u16 held;
int cursorPosition = 0;
while(1) {
consoleClear();
iprintf("ntr-forwarder\n\n");
iprintf(" Language: %s\n", languageLabels[language + 2]);
iprintf(" Region: %s\n", regionLabels[region + 3]);
iprintf(" Save Number: %d\n", saveNo);
iprintf(" Run in: %s\n", runInLabels[dsiMode + 1]);
iprintf(" ARM9 CPU Speed: %s\n", cpuLabels[boostCpu + 1]);
iprintf(" VRAM Mode: %s\n", vramLabels[boostVram + 1]);
iprintf(" Card Read DMA: %s\n", offOnLabels[cardReadDMA + 1]);
iprintf(" Async Card Read: %s\n", offOnLabels[asyncCardRead + 1]);
iprintf(" SWI Halt Hook: %s\n", offOnLabels[swiHaltHook + 1]);
iprintf(" Expand ROM in RAM: %s\n", expandLabels[expandRomSpace + 1]);
iprintf(" Bootstrap File: %s\n", bootstrapLabels[bootstrapFile + 1]);
iprintf("\nPress <B> to cancel,\n<START> to save\n");

// Print cursor
iprintf("\x1b[%d;0H>", 2 + cursorPosition);

do {
scanKeys();
held = keysDownRepeat();

swiWaitForVBlank();
} while(!held);

if(held & KEY_UP) {
cursorPosition--;
if(cursorPosition < 0)
cursorPosition = 10;
} else if(held & KEY_DOWN) {
cursorPosition++;
if(cursorPosition > 10)
cursorPosition = 0;
} else if(held & (KEY_LEFT | KEY_A)) {
switch(cursorPosition) {
case 0:
language--;
if(language < -2) language = 7;
break;
case 1:
region--;
if(region < -3) region = 5;
break;
case 2:
saveNo--;
if(saveNo < 0) saveNo = 9;
break;
case 3:
dsiMode--;
if(dsiMode < -1) dsiMode = 2;
break;
case 4:
boostCpu--;
if(boostCpu < -1) boostCpu = 1;
break;
case 5:
boostVram--;
if(boostVram < -1) boostVram = 1;
break;
case 6:
cardReadDMA--;
if(cardReadDMA < -1) cardReadDMA = 1;
break;
case 7:
asyncCardRead--;
if(asyncCardRead < -1) asyncCardRead = 1;
break;
case 8:
swiHaltHook--;
if(swiHaltHook < -1) swiHaltHook = 1;
break;
case 9:
expandRomSpace--;
if(expandRomSpace < -1) expandRomSpace = 2;
break;
case 10:
bootstrapFile--;
if(bootstrapFile < -1) bootstrapFile = 1;
break;
}
} else if(held & KEY_RIGHT) {
switch(cursorPosition) {
case 0:
language++;
if(language > 7) language = -2;
break;
case 1:
region++;
if(region > 5) region = -3;
break;
case 2:
saveNo++;
if(saveNo > 9) saveNo = 0;
break;
case 3:
dsiMode++;
if(dsiMode > 2) dsiMode = -1;
break;
case 4:
boostCpu++;
if(boostCpu > 1) boostCpu = -1;
break;
case 5:
boostVram++;
if(boostVram > 1) boostVram = -1;
break;
case 6:
cardReadDMA++;
if(cardReadDMA > 1) cardReadDMA = -1;
break;
case 7:
asyncCardRead++;
if(asyncCardRead > 1) asyncCardRead = -1;
break;
case 8:
swiHaltHook++;
if(swiHaltHook > 1) swiHaltHook = -1;
break;
case 9:
expandRomSpace++;
if(expandRomSpace > 2) expandRomSpace = -1;
break;
case 10:
bootstrapFile++;
if(bootstrapFile > 1) bootstrapFile = -1;
break;
}
} else if(held & KEY_B) {
return;
} else if(held & KEY_START) {
save();
return;
}
}
}
33 changes: 33 additions & 0 deletions SD Card/sd/arm9/source/perGameSettings.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef PER_GAME_SETTINGS_H
#define PER_GAME_SETTINGS_H

#include <string>

#include "inifile.h"

class GameSettings {
std::string filepath;
CIniFile ini;

public:
GameSettings(const std::string &filename);

int language = -2;
int region = -3;
int saveNo = 0;
int dsiMode = -1;
int boostCpu = -1;
int boostVram = -1;
int cardReadDMA = -1;
int asyncCardRead = -1;
int swiHaltHook = -1;
int expandRomSpace = -1;
int bootstrapFile = -1;

void save(void);

void menu(void);

};

#endif // PER_GAME_SETTINGS_H

0 comments on commit 225f062

Please sign in to comment.