akmenu-next/arm9/source/launcher/NdsBootstrapLauncher.cpp
lifehackerhansol 1a76345468
Add nds-bootstrap interface
- Rework savemngr to use melonDS ROM list for save type
- Use nds-bootstrap in place of akloader for retail game launching
2024-10-13 02:23:15 -07:00

111 lines
3.1 KiB
C++

/*
Copyright (C) 2024 lifehackerhansol
SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <sys/stat.h>
#include <unistd.h>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <nds/ndstypes.h>
#include "../cheatwnd.h"
#include "../dsrom.h"
#include "../flags.h"
#include "../inifile.h"
#include "ILauncher.h"
#include "NdsBootstrapLauncher.h"
#include "nds_loader_arm9.h"
bool NdsBootstrapLauncher::prepareCheats() {
u32 gameCode, crc32;
if (cCheatWnd::romData(mRomPath, gameCode, crc32)) {
FILE* cheatDb = fopen("/__rpg/cheats/usrcheat.dat", "rb");
if (!cheatDb) goto cheat_failed;
long cheatOffset;
size_t cheatSize;
if (cCheatWnd::searchCheatData(cheatDb, gameCode, crc32, cheatOffset, cheatSize)) {
cCheatWnd chtwnd((256) / 2, (192) / 2, 100, 100, NULL, mRomPath);
chtwnd.parse(mRomPath);
chtwnd.writeCheatsToFile("/_nds/nds-bootstrap/cheatData.bin");
FILE* cheatData = fopen("/_nds/nds-bootstrap/cheatData.bin", "rb");
if (cheatData) {
u32 check[2];
fread(check, 1, 8, cheatData);
fclose(cheatData);
// TODO: Delete file, if above 0x8000 bytes
if (check[1] == 0xCF000000) goto cheat_failed;
}
} else {
fclose(cheatDb);
goto cheat_failed;
}
fclose(cheatDb);
}
return true;
cheat_failed:
// Remove cheat bin if exists
if (access("/_nds/nds-bootstrap/cheatData.bin", F_OK) == 0) {
remove("/_nds/nds-bootstrap/cheatData.bin");
}
return false;
}
bool NdsBootstrapLauncher::prepareIni() {
CIniFile ini;
ini.SetString("NDS-BOOTSTRAP", "NDS_PATH", mRomPath);
ini.SetString("NDS-BOOTSTRAP", "SAV_PATH", mSavePath);
ini.SaveIniFile("/_nds/nds-bootstrap.ini");
return true;
}
bool NdsBootstrapLauncher::launchRom(std::string romPath, std::string savePath, u32 flags,
u32 cheatOffset, u32 cheatSize) {
std::string ndsBootstrapPath = "/_nds/nds-bootstrap-release.nds";
std::vector<const char*> argv;
mRomPath = romPath;
mSavePath = savePath;
mFlags = flags;
// mRomPath *should* have the drive name set
// If it doesn't for some reason, default to `fat:/`, because most people are probably using
// this on flashcart
if (mRomPath.find("sd:/", 0) == std::string::npos)
ndsBootstrapPath = "fat:" + ndsBootstrapPath;
else
ndsBootstrapPath = "sd:" + ndsBootstrapPath;
// Create the nds-bootstrap directory if it doesn't exist
if (access("/_nds/nds-bootstrap/", F_OK) != 0) {
mkdir("/_nds/nds-bootstrap/", 0777);
}
// Setup argv to launch nds-bootstrap
argv.push_back(ndsBootstrapPath.c_str());
// Prepare cheat codes if enabled
if (flags & PATCH_CHEATS) {
if (!prepareCheats()) return false;
}
// Setup nds-bootstrap INI parameters
if (!prepareIni()) return false;
// Launch
eRunNdsRetCode rc = runNdsFile(argv[0], argv.size(), &argv[0]);
if (rc == RUN_NDS_OK) return true;
return false;
}