mirror of
https://github.com/coderkei/akmenu-next.git
synced 2025-06-18 08:55:46 -04:00
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
This commit is contained in:
parent
1a88151eee
commit
1a76345468
@ -16,7 +16,7 @@ include $(DEVKITARM)/ds_rules
|
||||
# all directories are relative to this makefile
|
||||
#---------------------------------------------------------------------------------
|
||||
BUILD := build
|
||||
SOURCES := source source/ui source/font source/launcher
|
||||
SOURCES := source source/ui source/font source/launcher source/saves
|
||||
INCLUDES := include ../share $(SOURCES)
|
||||
DATA := data
|
||||
GRAPHICS :=
|
||||
|
110
arm9/source/launcher/NdsBootstrapLauncher.cpp
Normal file
110
arm9/source/launcher/NdsBootstrapLauncher.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
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;
|
||||
}
|
25
arm9/source/launcher/NdsBootstrapLauncher.h
Normal file
25
arm9/source/launcher/NdsBootstrapLauncher.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright (C) 2024 lifehackerhansol
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
#include "../dsrom.h"
|
||||
#include "ILauncher.h"
|
||||
|
||||
class NdsBootstrapLauncher : public ILauncher {
|
||||
public:
|
||||
bool launchRom(std::string romPath, std::string savePath, u32 flags, u32 cheatOffset,
|
||||
u32 cheatSize) override;
|
||||
|
||||
private:
|
||||
bool prepareCheats(void);
|
||||
bool prepareIni(void);
|
||||
std::string mRomPath;
|
||||
std::string mSavePath;
|
||||
u32 mFlags;
|
||||
};
|
@ -36,6 +36,7 @@
|
||||
#include <sys/iosupport.h>
|
||||
|
||||
#include "launcher/HomebrewLauncher.h"
|
||||
#include "launcher/NdsBootstrapLauncher.h"
|
||||
|
||||
using namespace akui;
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "launcher/HomebrewLauncher.h"
|
||||
#include "launcher/ILauncher.h"
|
||||
#include "launcher/NdsBootstrapLauncher.h"
|
||||
|
||||
static SAVE_TYPE PrefillGame(u32 aGameCode) {
|
||||
if (0x45444759 == aGameCode) // YGDE: 2209 - Diary Girl (USA)
|
||||
@ -135,7 +136,6 @@ TLaunchResult launchRom(const std::string& aFullPath, DSRomInfo& aRomInfo, bool
|
||||
size_t cheatSize = 0;
|
||||
std::string saveName;
|
||||
ILauncher* launcher = nullptr;
|
||||
#if 0
|
||||
if (!aRomInfo.isHomebrew()) {
|
||||
u32 gameCode;
|
||||
memcpy(&gameCode, aRomInfo.saveInfo().gameCode, sizeof(gameCode)); // because alignment
|
||||
@ -167,6 +167,8 @@ TLaunchResult launchRom(const std::string& aFullPath, DSRomInfo& aRomInfo, bool
|
||||
}
|
||||
|
||||
saveName = cSaveManager::generateSaveName(aFullPath, aRomInfo.saveInfo().getSlot());
|
||||
|
||||
// restore save data only for offical programs
|
||||
if (isBigSave) {
|
||||
isBigSave = cSaveManager::initializeSaveFile(aFullPath, aRomInfo.saveInfo().getSlot(),
|
||||
bigSaveSize);
|
||||
@ -174,7 +176,6 @@ TLaunchResult launchRom(const std::string& aFullPath, DSRomInfo& aRomInfo, bool
|
||||
flags |= PATCH_SD_SAVE | (bigSaveMask << PATCH_SAVE_SHIFT);
|
||||
saveManager().saveLastInfo(aFullPath);
|
||||
} else {
|
||||
// restore save data only for offical programs
|
||||
SAVE_TYPE st = (SAVE_TYPE)aRomInfo.saveInfo().saveType;
|
||||
if (ST_UNKNOWN == st) st = ST_AUTO;
|
||||
SAVE_TYPE st_new = PrefillGame(gameCode);
|
||||
@ -232,12 +233,9 @@ TLaunchResult launchRom(const std::string& aFullPath, DSRomInfo& aRomInfo, bool
|
||||
|
||||
launcher = new NdsBootstrapLauncher();
|
||||
} else {
|
||||
#endif
|
||||
if (!aMenu) saveManager().saveLastInfo(aFullPath);
|
||||
launcher = new HomebrewLauncher();
|
||||
#if 0
|
||||
if (!aMenu) saveManager().saveLastInfo(aFullPath);
|
||||
launcher = new HomebrewLauncher();
|
||||
}
|
||||
#endif
|
||||
launcher->launchRom(aFullPath, saveName, flags, cheatOffset, cheatSize);
|
||||
return ELaunchRomOk;
|
||||
}
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "systemfilenames.h"
|
||||
#include "ui.h"
|
||||
|
||||
#include "saves/ROMList.h"
|
||||
|
||||
using namespace akui;
|
||||
|
||||
cSaveManager::cSaveManager() {}
|
||||
@ -221,6 +223,9 @@ SAVE_TYPE cSaveManager::getSaveTypeByFile(const std::string& romFilename) {
|
||||
return ST_UNKNOWN;
|
||||
}
|
||||
|
||||
SAVE_TYPE MelonDSROMListToSaveType[] = {ST_NOSAVE, ST_4K, ST_64K, ST_512K, ST_1M, ST_2M,
|
||||
ST_4M, ST_8M, ST_16M, ST_32M, ST_64M};
|
||||
|
||||
void cSaveManager::updateSaveInfoByInfo(SAVE_INFO_EX& gameInfo) {
|
||||
size_t saveCount = _customSaveList.size();
|
||||
for (size_t i = 0; i < saveCount; ++i) {
|
||||
@ -231,13 +236,17 @@ void cSaveManager::updateSaveInfoByInfo(SAVE_INFO_EX& gameInfo) {
|
||||
}
|
||||
|
||||
gameInfo.defaults();
|
||||
saveCount = _saveList.size();
|
||||
for (size_t ii = 0; ii < saveCount; ii++) {
|
||||
if (0 == memcmp(&gameInfo, &_saveList[ii], SAVE_INFO_EX_COMPARE_SIZE)) {
|
||||
u8 saveType = _saveList[ii].saveType;
|
||||
if (saveType > ST_UNKNOWN && saveType <= ST_8M)
|
||||
gameInfo.saveType = _saveList[ii].saveType;
|
||||
return;
|
||||
u32 gameCode;
|
||||
memcpy(&gameCode, gameInfo.gameCode, sizeof(gameCode)); // because alignment
|
||||
|
||||
for (size_t i = 0; i < ROMListEntryCount; i++) {
|
||||
const ROMListEntry* entry = &ROMList[i];
|
||||
if (gameCode == entry->GameCode) {
|
||||
if (entry->SaveMemType == 0xFFFFFFFF)
|
||||
gameInfo.saveType = ST_AUTO;
|
||||
else
|
||||
gameInfo.saveType = MelonDSROMListToSaveType[entry->SaveMemType];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
6805
arm9/source/saves/ROMList.cpp
Normal file
6805
arm9/source/saves/ROMList.cpp
Normal file
File diff suppressed because it is too large
Load Diff
41
arm9/source/saves/ROMList.h
Normal file
41
arm9/source/saves/ROMList.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright 2016-2024 melonDS team
|
||||
|
||||
This file is part of melonDS.
|
||||
|
||||
melonDS 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.
|
||||
|
||||
melonDS 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 melonDS. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#ifndef ROMLIST_H
|
||||
#define ROMLIST_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
struct ROMListEntry
|
||||
{
|
||||
u32 GameCode;
|
||||
u32 ROMSize;
|
||||
u32 SaveMemType;
|
||||
};
|
||||
|
||||
|
||||
extern const ROMListEntry ROMList[];
|
||||
|
||||
/// The number of elements in \c ROMList.
|
||||
extern const size_t ROMListEntryCount;
|
||||
|
||||
#endif // ROMLIST_H
|
@ -2,6 +2,8 @@ This program is originally based on the akmenu project by the Acekard team, who
|
||||
|
||||
This program is further developed by yellow wood goblin, who released the source under the GPL-3.0-or-later license. See GPL3.txt for more info.
|
||||
|
||||
This provided source integrates ROM list code from the melonDS project, which is licensed under the GPL-3.0-or-later license. See GPL3.txt for more info.
|
||||
|
||||
This provided source integrates devkitPro's bootloader, which is licensed under the GPL-2.0-or-later license. See GPL2.txt for more info.
|
||||
|
||||
This provided source is collectively licensed under the GPL-3.0-or-later license.
|
||||
|
Loading…
Reference in New Issue
Block a user