VRAM Fix, System Dir change and saves folder support

- VRAM Fix in nds-bootloader, should fix garbled graphics in Giana Sisters DS
- System Dir changed from _nds to _nds/akmenunext, this is a breaking change. Its intended so users using TWL++ alongside have less clutter.
- Added support for "saves" folders now. Its a setting that can be toggled.
This commit is contained in:
Kei 2025-01-25 23:29:52 +00:00
parent e0552ca296
commit e682a4252e
13 changed files with 72 additions and 24 deletions

View File

@ -47,6 +47,12 @@
"stdexcept": "cpp", "stdexcept": "cpp",
"streambuf": "cpp", "streambuf": "cpp",
"cinttypes": "cpp", "cinttypes": "cpp",
"typeinfo": "cpp" "typeinfo": "cpp",
"charconv": "cpp",
"ctime": "cpp",
"format": "cpp",
"span": "cpp",
"text_encoding": "cpp",
"variant": "cpp"
} }
} }

View File

@ -30,6 +30,7 @@ include $(DEVKITARM)/ds_rules
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
all: nds-bootloader checkarm7 checkarm9 checkarm9_dsi \ all: nds-bootloader checkarm7 checkarm9 checkarm9_dsi \
$(TARGET).nds $(TARGET).dsi $(TARGET).nds $(TARGET).dsi
@$(MAKE) organize_files
data: data:
@mkdir -p data @mkdir -p data
@ -74,11 +75,19 @@ arm9/$(TARGET).elf: nds-bootloader
arm9_dsi/$(TARGET).elf: arm9_dsi/$(TARGET).elf:
$(MAKE) -C arm9_dsi $(MAKE) -C arm9_dsi
#---------------------------------------------------------------------------------
organize_files:
@mkdir -p build
@mv -f $(TARGET).nds $(TARGET).dsi build/
@cd build && \
cp $(TARGET).nds launcher_$(TARGET).nds && \
cp $(TARGET).dsi launcher_$(TARGET).dsi
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
clean: clean:
$(MAKE) -C arm9 clean $(MAKE) -C arm9 clean
$(MAKE) -C arm9_dsi clean $(MAKE) -C arm9_dsi clean
$(MAKE) -C nds-bootloader clean $(MAKE) -C nds-bootloader clean
$(MAKE) -C arm7 clean $(MAKE) -C arm7 clean
rm -rf data rm -rf data build
rm -f *.nds *.dsi rm -f *.nds *.dsi

View File

@ -9,10 +9,10 @@ Requires devkitarm to be installed with the `nds-dev` package. Simply build the
### Configuration ### Configuration
* The system directory is `_nds` where the akmenu system files should be placed, along with a copy of nds-bootstrap as `nds-bootstrap-release.nds`. * The system directory is `_nds/akmenunext` where the akmenu system files should be placed, along with a copy of nds-bootstrap in the `_nds` folder as `nds-bootstrap-release.nds`.
* The binary of akmenu-next additionally needs to be in the `_nds` folder as `launcher.nds` for theme & language reboots. * The binary of akmenu-next additionally needs to be in the `_nds/akmenunext` folder as `launcher.nds` for theme & language reboots.
* Cheats should be placed as `usrcheat.dat` into the `_nds/cheats` folder. * Cheats should be placed as `usrcheat.dat` into the `_nds/akmenu/cheats` folder.
* Themes go into `_nds/ui`. Acekard & Wood R4 themes are supported. * Themes go into `_nds/akmenunext/ui`. Acekard & Wood R4 themes are supported.
## License ## License

View File

@ -38,6 +38,7 @@ cGlobalSettings::cGlobalSettings() {
cheatDB = false; cheatDB = false;
slot2mode = ESlot2Ask; slot2mode = ESlot2Ask;
saveExt = true; saveExt = true;
saveDir = false;
safeMode = false; safeMode = false;
show12hrClock = false; show12hrClock = false;
autorunWithLastRom = false; autorunWithLastRom = false;
@ -66,6 +67,7 @@ void cGlobalSettings::loadSettings() {
Animation = ini.GetInt("system", "Animation", Animation); Animation = ini.GetInt("system", "Animation", Animation);
cheats = ini.GetInt("system", "cheats", cheats); cheats = ini.GetInt("system", "cheats", cheats);
softreset = ini.GetInt("system", "softreset", softreset); softreset = ini.GetInt("system", "softreset", softreset);
saveDir = ini.GetInt("system", "savedir", saveDir);
dma = ini.GetInt("system", "dma", dma); dma = ini.GetInt("system", "dma", dma);
sdsave = ini.GetInt("system", "sdsave", sdsave); sdsave = ini.GetInt("system", "sdsave", sdsave);
safeMode = ini.GetInt("system", "safemode", safeMode); safeMode = ini.GetInt("system", "safemode", safeMode);
@ -117,6 +119,7 @@ void cGlobalSettings::saveSettings() {
ini.SetInt("system", "dma", dma); ini.SetInt("system", "dma", dma);
ini.SetInt("system", "sdsave", sdsave); ini.SetInt("system", "sdsave", sdsave);
ini.SetInt("system", "safemode", safeMode); ini.SetInt("system", "safemode", safeMode);
ini.SetInt("system", "savedir", saveDir);
ini.SetInt("system", "Show12hrClock", show12hrClock); ini.SetInt("system", "Show12hrClock", show12hrClock);
ini.SetInt("system", "homebrewreset", homebrewreset); ini.SetInt("system", "homebrewreset", homebrewreset);

View File

@ -58,6 +58,7 @@ class cGlobalSettings {
bool cheatDB; bool cheatDB;
int slot2mode; int slot2mode;
bool saveExt; bool saveExt;
bool saveDir;
bool safeMode; bool safeMode;
bool show12hrClock; bool show12hrClock;
bool autorunWithLastRom; bool autorunWithLastRom;

View File

@ -8,6 +8,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "flags.h"
#include "HomebrewLauncher.h" #include "HomebrewLauncher.h"
#include "ILauncher.h" #include "ILauncher.h"
#include "nds_loader_arm9.h" #include "nds_loader_arm9.h"

View File

@ -14,7 +14,7 @@
bool PassMeLauncher::launchRom(std::string romPath, std::string savePath, u32 flags, bool PassMeLauncher::launchRom(std::string romPath, std::string savePath, u32 flags,
u32 cheatOffset, u32 cheatSize) { u32 cheatOffset, u32 cheatSize) {
const char passMeLoaderPath[] = "fat:/_nds/PassMeLoader.nds"; const char passMeLoaderPath[] = "fat:/_nds/akmenunext/PassMeLoader.nds";
if (access(passMeLoaderPath, F_OK) != 0) { if (access(passMeLoaderPath, F_OK) != 0) {
printLoaderNotFound(passMeLoaderPath); printLoaderNotFound(passMeLoaderPath);

View File

@ -281,6 +281,8 @@ eRunNdsRetCode runNds (const void* loader, u32 loaderSize, u32 cluster, bool ini
// Direct CPU access to VRAM bank C // Direct CPU access to VRAM bank C
VRAM_C_CR = VRAM_ENABLE | VRAM_C_LCD; VRAM_C_CR = VRAM_ENABLE | VRAM_C_LCD;
//Fix VRAM because for some reason some homebrew screws up without it
memset (LCDC_BANK_C, 0x00, 128 * 1024);
// Load the loader/patcher into the correct address // Load the loader/patcher into the correct address
vramcpy (LCDC_BANK_C, loader, loaderSize); vramcpy (LCDC_BANK_C, loader, loaderSize);

View File

@ -381,6 +381,11 @@ void cMainWnd::onKeyAPressed() {
void cMainWnd::launchSelected() { void cMainWnd::launchSelected() {
std::string fullPath = _mainList->getSelectedFullPath(); std::string fullPath = _mainList->getSelectedFullPath();
std::string romName = _mainList->getSelectedShowName(); std::string romName = _mainList->getSelectedShowName();
size_t lastSlashPos = fullPath.find_last_of("/\\");
std::string directory = fullPath.substr(0, lastSlashPos + 1);
// Create the new path by appending "saves/"
std::string savesPath = directory + "saves/" + romName;
if (fullPath[fullPath.size() - 1] == '/') { if (fullPath[fullPath.size() - 1] == '/') {
_mainList->enterDir(fullPath); _mainList->enterDir(fullPath);
@ -408,7 +413,7 @@ void cMainWnd::launchSelected() {
progressWnd().show(); progressWnd().show();
progressWnd().setPercent(0); progressWnd().setPercent(0);
switch (launchRom(fullPath, rominfo, switch (launchRom(fullPath, rominfo,
rominfo.isHomebrew() && "BOOT.NDS" == _mainList->getSelectedShowName())) { rominfo.isHomebrew() && "BOOT.NDS" == _mainList->getSelectedShowName(), savesPath)) {
case ELaunchNoFreeSpace: case ELaunchNoFreeSpace:
title = LANG("no free space", "title"); title = LANG("no free space", "title");
text = LANG("no free space", "text"); text = LANG("no free space", "text");
@ -531,6 +536,10 @@ void cMainWnd::setParam(void) {
_values.push_back(".nds.sav"); _values.push_back(".nds.sav");
_values.push_back(".sav"); _values.push_back(".sav");
settingWnd.addSettingItem(LANG("file settings", "save extension"), _values, gs().saveExt); settingWnd.addSettingItem(LANG("file settings", "save extension"), _values, gs().saveExt);
_values.clear();
_values.push_back("no");
_values.push_back("yes");
settingWnd.addSettingItem(LANG("file settings", "use saves folder"), _values, gs().saveDir);
// page 4: patches // page 4: patches
settingWnd.addSettingTab(LANG("setting window", "patches")); settingWnd.addSettingTab(LANG("setting window", "patches"));
@ -538,8 +547,6 @@ void cMainWnd::setParam(void) {
_values.push_back(LANG("switches", "Disable")); _values.push_back(LANG("switches", "Disable"));
_values.push_back(LANG("switches", "Enable")); _values.push_back(LANG("switches", "Enable"));
settingWnd.addSettingItem(LANG("patches", "cheating system"), _values, gs().cheats); settingWnd.addSettingItem(LANG("patches", "cheating system"), _values, gs().cheats);
settingWnd.addSettingItem(LANG("patches", "reset in game"), _values, gs().softreset);
settingWnd.addSettingItem(LANG("patches", "homebrew reset"), _values, gs().homebrewreset);
#ifdef __KERNEL_LAUNCHER_SUPPORT__ #ifdef __KERNEL_LAUNCHER_SUPPORT__
_values.clear(); _values.clear();
_values.push_back("Kernel"); _values.push_back("Kernel");
@ -589,6 +596,7 @@ void cMainWnd::setParam(void) {
gs().showHiddenFiles = settingWnd.getItemSelection(2, 0); gs().showHiddenFiles = settingWnd.getItemSelection(2, 0);
gs().romTrim = settingWnd.getItemSelection(2, 1); gs().romTrim = settingWnd.getItemSelection(2, 1);
gs().saveExt = settingWnd.getItemSelection(2, 2); gs().saveExt = settingWnd.getItemSelection(2, 2);
gs().saveDir = settingWnd.getItemSelection(2, 3);
// page 4: patches // page 4: patches
gs().cheats = settingWnd.getItemSelection(3, 0); gs().cheats = settingWnd.getItemSelection(3, 0);
@ -609,9 +617,9 @@ void cMainWnd::setParam(void) {
gs().langDirectory = langNames[langIndexAfter]; gs().langDirectory = langNames[langIndexAfter];
gs().saveSettings(); gs().saveSettings();
#ifdef __DSIMODE__ #ifdef __DSIMODE__
HomebrewLauncher().launchRom("sd:/_nds/launcher.nds", "", 0, 0, 0); HomebrewLauncher().launchRom("sd:/_nds/akmenunext/launcher.nds", "", 0, 0, 0);
#else #else
HomebrewLauncher().launchRom("fat:/_nds/launcher.nds", "", 0, 0, 0); HomebrewLauncher().launchRom("fat:/_nds/akmenunext/launcher.nds", "", 0, 0, 0);
#endif #endif
} }
} }
@ -623,9 +631,9 @@ void cMainWnd::setParam(void) {
gs().langDirectory = langNames[langIndexAfter]; gs().langDirectory = langNames[langIndexAfter];
gs().saveSettings(); gs().saveSettings();
#ifdef __DSIMODE__ #ifdef __DSIMODE__
HomebrewLauncher().launchRom("sd:/_nds/launcher.nds", "", 0, 0, 0); HomebrewLauncher().launchRom("sd:/_nds/akmenunext/launcher.nds", "", 0, 0, 0);
#else #else
HomebrewLauncher().launchRom("fat:/_nds/launcher.nds", "", 0, 0, 0); HomebrewLauncher().launchRom("fat:/_nds/akmenunext/launcher.nds", "", 0, 0, 0);
#endif #endif
} }
} }

View File

@ -5,6 +5,7 @@
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#include <sys/stat.h>
#include "romlauncher.h" #include "romlauncher.h"
#include "cheatwnd.h" #include "cheatwnd.h"
#include "exptools.h" #include "exptools.h"
@ -132,11 +133,12 @@ static u32 SaveSize(SAVE_TYPE st) {
return result; return result;
} }
TLaunchResult launchRom(const std::string& aFullPath, DSRomInfo& aRomInfo, bool aMenu) { TLaunchResult launchRom(const std::string& aFullPath, DSRomInfo& aRomInfo, bool aMenu, const std::string& savesPath) {
u32 flags = 0; u32 flags = 0;
long cheatOffset = 0; long cheatOffset = 0;
size_t cheatSize = 0; size_t cheatSize = 0;
std::string saveName; std::string saveName;
std::string useSavesPath;
ILauncher* launcher = nullptr; ILauncher* launcher = nullptr;
if (!aRomInfo.isHomebrew()) { if (!aRomInfo.isHomebrew()) {
u32 gameCode; u32 gameCode;
@ -170,11 +172,27 @@ TLaunchResult launchRom(const std::string& aFullPath, DSRomInfo& aRomInfo, bool
} }
} }
saveName = cSaveManager::generateSaveName(aFullPath, aRomInfo.saveInfo().getSlot()); std::string savesFolderPath = aFullPath;
//if saveDir is set to true, use saves dir
if (gs().saveDir) {
useSavesPath = savesPath;
savesFolderPath.insert(aFullPath.find_last_of("/\\") + 1, "saves/");
size_t lastSlashPos = savesFolderPath.find_last_of("/\\");
std::string directory = savesFolderPath.substr(0, lastSlashPos + 1);
// Create the saves folder if it doesn't exist
std::string cleanPath = (directory.find("fat:") == 0) ? directory.substr(4) : directory;
cleanPath.pop_back();
if (access(cleanPath.c_str(), F_OK) != 0) {
mkdir(cleanPath.c_str(), 0777);
}
}
else useSavesPath = aFullPath;
saveName = cSaveManager::generateSaveName(savesFolderPath, aRomInfo.saveInfo().getSlot());
// restore save data only for offical programs
if (isBigSave) { if (isBigSave) {
isBigSave = cSaveManager::initializeSaveFile(aFullPath, aRomInfo.saveInfo().getSlot(), isBigSave = cSaveManager::initializeSaveFile(useSavesPath, aRomInfo.saveInfo().getSlot(),
bigSaveSize); bigSaveSize);
if (!isBigSave) return ELaunchNoFreeSpace; if (!isBigSave) return ELaunchNoFreeSpace;
flags |= PATCH_SD_SAVE | (bigSaveMask << PATCH_SAVE_SHIFT); flags |= PATCH_SD_SAVE | (bigSaveMask << PATCH_SAVE_SHIFT);
@ -191,7 +209,7 @@ TLaunchResult launchRom(const std::string& aFullPath, DSRomInfo& aRomInfo, bool
saveManager().updateCustomSaveList(aRomInfo.saveInfo()); saveManager().updateCustomSaveList(aRomInfo.saveInfo());
} }
} }
if (cSaveManager::initializeSaveFile(aFullPath, aRomInfo.saveInfo().getSlot(), if (cSaveManager::initializeSaveFile(useSavesPath, aRomInfo.saveInfo().getSlot(),
SaveSize(st))) { SaveSize(st))) {
flags |= PATCH_SD_SAVE | (SaveMask(st) << PATCH_SAVE_SHIFT); flags |= PATCH_SD_SAVE | (SaveMask(st) << PATCH_SAVE_SHIFT);
saveManager().saveLastInfo(aFullPath); saveManager().saveLastInfo(aFullPath);
@ -258,5 +276,5 @@ TLaunchResult launchRom(const std::string& aFullPath, DSRomInfo& aRomInfo, bool
void autoLaunchRom(const std::string& aFullPath) { void autoLaunchRom(const std::string& aFullPath) {
DSRomInfo rominfo; DSRomInfo rominfo;
rominfo.MayBeDSRom(aFullPath); rominfo.MayBeDSRom(aFullPath);
if (rominfo.isDSRom()) launchRom(aFullPath, rominfo, false); if (rominfo.isDSRom()) launchRom(aFullPath, rominfo, false, NULL);
} }

View File

@ -17,5 +17,5 @@ enum TLaunchResult {
ELaunchNoFreeSpace ELaunchNoFreeSpace
}; };
TLaunchResult launchRom(const std::string& aFullPath, DSRomInfo& aRomInfo, bool aMenu); TLaunchResult launchRom(const std::string& aFullPath, DSRomInfo& aRomInfo, bool aMenu, const std::string& savesPath);
void autoLaunchRom(const std::string& aFullPath); void autoLaunchRom(const std::string& aFullPath);

View File

@ -10,9 +10,9 @@
#pragma once #pragma once
#ifndef __DSIMODE__ #ifndef __DSIMODE__
#define SFN_SYSTEM_DIR "fat:/_nds/" #define SFN_SYSTEM_DIR "fat:/_nds/akmenunext/"
#else #else
#define SFN_SYSTEM_DIR "sd:/_nds/" #define SFN_SYSTEM_DIR "sd:/_nds/akmenunext/"
#endif #endif
#define SFN_OFFICIAL_SAVELIST SFN_SYSTEM_DIR "savelist.bin" #define SFN_OFFICIAL_SAVELIST SFN_SYSTEM_DIR "savelist.bin"
#define SFN_CUSTOM_SAVELIST SFN_SYSTEM_DIR "gamedata.bin" #define SFN_CUSTOM_SAVELIST SFN_SYSTEM_DIR "gamedata.bin"

View File

@ -8,7 +8,7 @@
*/ */
#define AKMENU_VERSION_MAIN "1" #define AKMENU_VERSION_MAIN "1"
#define AKMENU_VERSION_SUB "2" #define AKMENU_VERSION_SUB "3"
#ifndef __KERNEL_LAUNCHER_SUPPORT__ #ifndef __KERNEL_LAUNCHER_SUPPORT__
#define AKMENU_LOADER_NAME "nds-bootstrap" #define AKMENU_LOADER_NAME "nds-bootstrap"