From e682a4252e7457781146616bfba005aea35f93c2 Mon Sep 17 00:00:00 2001 From: Kei <7037851+coderkei@users.noreply.github.com> Date: Sat, 25 Jan 2025 23:29:52 +0000 Subject: [PATCH] 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. --- .vscode/settings.json | 8 +++++- Makefile | 11 ++++++++- README.md | 8 +++--- arm9/source/globalsettings.cpp | 3 +++ arm9/source/globalsettings.h | 1 + arm9/source/launcher/HomebrewLauncher.cpp | 1 + arm9/source/launcher/PassMeLauncher.cpp | 2 +- arm9/source/launcher/nds_loader_arm9.c | 2 ++ arm9/source/mainwnd.cpp | 22 +++++++++++------ arm9/source/romlauncher.cpp | 30 ++++++++++++++++++----- arm9/source/romlauncher.h | 2 +- arm9/source/systemfilenames.h | 4 +-- arm9/source/version.h | 2 +- 13 files changed, 72 insertions(+), 24 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 31c5044..95ad162 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -47,6 +47,12 @@ "stdexcept": "cpp", "streambuf": "cpp", "cinttypes": "cpp", - "typeinfo": "cpp" + "typeinfo": "cpp", + "charconv": "cpp", + "ctime": "cpp", + "format": "cpp", + "span": "cpp", + "text_encoding": "cpp", + "variant": "cpp" } } \ No newline at end of file diff --git a/Makefile b/Makefile index e4af773..19380d5 100644 --- a/Makefile +++ b/Makefile @@ -30,6 +30,7 @@ include $(DEVKITARM)/ds_rules #--------------------------------------------------------------------------------- all: nds-bootloader checkarm7 checkarm9 checkarm9_dsi \ $(TARGET).nds $(TARGET).dsi + @$(MAKE) organize_files data: @mkdir -p data @@ -74,11 +75,19 @@ arm9/$(TARGET).elf: nds-bootloader arm9_dsi/$(TARGET).elf: $(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: $(MAKE) -C arm9 clean $(MAKE) -C arm9_dsi clean $(MAKE) -C nds-bootloader clean $(MAKE) -C arm7 clean - rm -rf data + rm -rf data build rm -f *.nds *.dsi diff --git a/README.md b/README.md index 04c5109..20eeebd 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@ Requires devkitarm to be installed with the `nds-dev` package. Simply build the ### 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 binary of akmenu-next additionally needs to be in the `_nds` folder as `launcher.nds` for theme & language reboots. -* Cheats should be placed as `usrcheat.dat` into the `_nds/cheats` folder. -* Themes go into `_nds/ui`. Acekard & Wood R4 themes are supported. +* 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/akmenunext` folder as `launcher.nds` for theme & language reboots. +* Cheats should be placed as `usrcheat.dat` into the `_nds/akmenu/cheats` folder. +* Themes go into `_nds/akmenunext/ui`. Acekard & Wood R4 themes are supported. ## License diff --git a/arm9/source/globalsettings.cpp b/arm9/source/globalsettings.cpp index 8f48b59..d2faa53 100644 --- a/arm9/source/globalsettings.cpp +++ b/arm9/source/globalsettings.cpp @@ -38,6 +38,7 @@ cGlobalSettings::cGlobalSettings() { cheatDB = false; slot2mode = ESlot2Ask; saveExt = true; + saveDir = false; safeMode = false; show12hrClock = false; autorunWithLastRom = false; @@ -66,6 +67,7 @@ void cGlobalSettings::loadSettings() { Animation = ini.GetInt("system", "Animation", Animation); cheats = ini.GetInt("system", "cheats", cheats); softreset = ini.GetInt("system", "softreset", softreset); + saveDir = ini.GetInt("system", "savedir", saveDir); dma = ini.GetInt("system", "dma", dma); sdsave = ini.GetInt("system", "sdsave", sdsave); safeMode = ini.GetInt("system", "safemode", safeMode); @@ -117,6 +119,7 @@ void cGlobalSettings::saveSettings() { ini.SetInt("system", "dma", dma); ini.SetInt("system", "sdsave", sdsave); ini.SetInt("system", "safemode", safeMode); + ini.SetInt("system", "savedir", saveDir); ini.SetInt("system", "Show12hrClock", show12hrClock); ini.SetInt("system", "homebrewreset", homebrewreset); diff --git a/arm9/source/globalsettings.h b/arm9/source/globalsettings.h index 64fb1dd..995da17 100644 --- a/arm9/source/globalsettings.h +++ b/arm9/source/globalsettings.h @@ -58,6 +58,7 @@ class cGlobalSettings { bool cheatDB; int slot2mode; bool saveExt; + bool saveDir; bool safeMode; bool show12hrClock; bool autorunWithLastRom; diff --git a/arm9/source/launcher/HomebrewLauncher.cpp b/arm9/source/launcher/HomebrewLauncher.cpp index ea5ab79..1e8dbc2 100644 --- a/arm9/source/launcher/HomebrewLauncher.cpp +++ b/arm9/source/launcher/HomebrewLauncher.cpp @@ -8,6 +8,7 @@ #include #include +#include "flags.h" #include "HomebrewLauncher.h" #include "ILauncher.h" #include "nds_loader_arm9.h" diff --git a/arm9/source/launcher/PassMeLauncher.cpp b/arm9/source/launcher/PassMeLauncher.cpp index e31c6b9..6e8c898 100644 --- a/arm9/source/launcher/PassMeLauncher.cpp +++ b/arm9/source/launcher/PassMeLauncher.cpp @@ -14,7 +14,7 @@ bool PassMeLauncher::launchRom(std::string romPath, std::string savePath, u32 flags, 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) { printLoaderNotFound(passMeLoaderPath); diff --git a/arm9/source/launcher/nds_loader_arm9.c b/arm9/source/launcher/nds_loader_arm9.c index de933ba..613262f 100644 --- a/arm9/source/launcher/nds_loader_arm9.c +++ b/arm9/source/launcher/nds_loader_arm9.c @@ -281,6 +281,8 @@ eRunNdsRetCode runNds (const void* loader, u32 loaderSize, u32 cluster, bool ini // Direct CPU access to VRAM bank C 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 vramcpy (LCDC_BANK_C, loader, loaderSize); diff --git a/arm9/source/mainwnd.cpp b/arm9/source/mainwnd.cpp index ee1f3d2..c3ae07b 100644 --- a/arm9/source/mainwnd.cpp +++ b/arm9/source/mainwnd.cpp @@ -381,6 +381,11 @@ void cMainWnd::onKeyAPressed() { void cMainWnd::launchSelected() { std::string fullPath = _mainList->getSelectedFullPath(); 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] == '/') { _mainList->enterDir(fullPath); @@ -408,7 +413,7 @@ void cMainWnd::launchSelected() { progressWnd().show(); progressWnd().setPercent(0); switch (launchRom(fullPath, rominfo, - rominfo.isHomebrew() && "BOOT.NDS" == _mainList->getSelectedShowName())) { + rominfo.isHomebrew() && "BOOT.NDS" == _mainList->getSelectedShowName(), savesPath)) { case ELaunchNoFreeSpace: title = LANG("no free space", "title"); text = LANG("no free space", "text"); @@ -531,6 +536,10 @@ void cMainWnd::setParam(void) { _values.push_back(".nds.sav"); _values.push_back(".sav"); 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 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", "Enable")); 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__ _values.clear(); _values.push_back("Kernel"); @@ -589,6 +596,7 @@ void cMainWnd::setParam(void) { gs().showHiddenFiles = settingWnd.getItemSelection(2, 0); gs().romTrim = settingWnd.getItemSelection(2, 1); gs().saveExt = settingWnd.getItemSelection(2, 2); + gs().saveDir = settingWnd.getItemSelection(2, 3); // page 4: patches gs().cheats = settingWnd.getItemSelection(3, 0); @@ -609,9 +617,9 @@ void cMainWnd::setParam(void) { gs().langDirectory = langNames[langIndexAfter]; gs().saveSettings(); #ifdef __DSIMODE__ - HomebrewLauncher().launchRom("sd:/_nds/launcher.nds", "", 0, 0, 0); + HomebrewLauncher().launchRom("sd:/_nds/akmenunext/launcher.nds", "", 0, 0, 0); #else - HomebrewLauncher().launchRom("fat:/_nds/launcher.nds", "", 0, 0, 0); + HomebrewLauncher().launchRom("fat:/_nds/akmenunext/launcher.nds", "", 0, 0, 0); #endif } } @@ -623,9 +631,9 @@ void cMainWnd::setParam(void) { gs().langDirectory = langNames[langIndexAfter]; gs().saveSettings(); #ifdef __DSIMODE__ - HomebrewLauncher().launchRom("sd:/_nds/launcher.nds", "", 0, 0, 0); + HomebrewLauncher().launchRom("sd:/_nds/akmenunext/launcher.nds", "", 0, 0, 0); #else - HomebrewLauncher().launchRom("fat:/_nds/launcher.nds", "", 0, 0, 0); + HomebrewLauncher().launchRom("fat:/_nds/akmenunext/launcher.nds", "", 0, 0, 0); #endif } } diff --git a/arm9/source/romlauncher.cpp b/arm9/source/romlauncher.cpp index 4868fcf..10e36cc 100644 --- a/arm9/source/romlauncher.cpp +++ b/arm9/source/romlauncher.cpp @@ -5,6 +5,7 @@ SPDX-License-Identifier: GPL-3.0-or-later */ +#include #include "romlauncher.h" #include "cheatwnd.h" #include "exptools.h" @@ -132,11 +133,12 @@ static u32 SaveSize(SAVE_TYPE st) { 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; long cheatOffset = 0; size_t cheatSize = 0; std::string saveName; + std::string useSavesPath; ILauncher* launcher = nullptr; if (!aRomInfo.isHomebrew()) { 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) { - isBigSave = cSaveManager::initializeSaveFile(aFullPath, aRomInfo.saveInfo().getSlot(), + isBigSave = cSaveManager::initializeSaveFile(useSavesPath, aRomInfo.saveInfo().getSlot(), bigSaveSize); if (!isBigSave) return ELaunchNoFreeSpace; 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()); } } - if (cSaveManager::initializeSaveFile(aFullPath, aRomInfo.saveInfo().getSlot(), + if (cSaveManager::initializeSaveFile(useSavesPath, aRomInfo.saveInfo().getSlot(), SaveSize(st))) { flags |= PATCH_SD_SAVE | (SaveMask(st) << PATCH_SAVE_SHIFT); saveManager().saveLastInfo(aFullPath); @@ -258,5 +276,5 @@ TLaunchResult launchRom(const std::string& aFullPath, DSRomInfo& aRomInfo, bool void autoLaunchRom(const std::string& aFullPath) { DSRomInfo rominfo; rominfo.MayBeDSRom(aFullPath); - if (rominfo.isDSRom()) launchRom(aFullPath, rominfo, false); + if (rominfo.isDSRom()) launchRom(aFullPath, rominfo, false, NULL); } diff --git a/arm9/source/romlauncher.h b/arm9/source/romlauncher.h index d06a594..d7ef438 100644 --- a/arm9/source/romlauncher.h +++ b/arm9/source/romlauncher.h @@ -17,5 +17,5 @@ enum TLaunchResult { 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); diff --git a/arm9/source/systemfilenames.h b/arm9/source/systemfilenames.h index e27505e..5932f53 100644 --- a/arm9/source/systemfilenames.h +++ b/arm9/source/systemfilenames.h @@ -10,9 +10,9 @@ #pragma once #ifndef __DSIMODE__ -#define SFN_SYSTEM_DIR "fat:/_nds/" +#define SFN_SYSTEM_DIR "fat:/_nds/akmenunext/" #else -#define SFN_SYSTEM_DIR "sd:/_nds/" +#define SFN_SYSTEM_DIR "sd:/_nds/akmenunext/" #endif #define SFN_OFFICIAL_SAVELIST SFN_SYSTEM_DIR "savelist.bin" #define SFN_CUSTOM_SAVELIST SFN_SYSTEM_DIR "gamedata.bin" diff --git a/arm9/source/version.h b/arm9/source/version.h index b65c28a..10f903a 100644 --- a/arm9/source/version.h +++ b/arm9/source/version.h @@ -8,7 +8,7 @@ */ #define AKMENU_VERSION_MAIN "1" -#define AKMENU_VERSION_SUB "2" +#define AKMENU_VERSION_SUB "3" #ifndef __KERNEL_LAUNCHER_SUPPORT__ #define AKMENU_LOADER_NAME "nds-bootstrap"