diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e6b97c3..c81a6c1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Build TMFN +name: Build Universal Title Manager on: push: @@ -20,7 +20,7 @@ jobs: steps: - name: Checkout repo uses: actions/checkout@v1 - - name: Build TMFN + - name: Build Universal Title Manager run: make - name: Publish build to GH Actions uses: actions/upload-artifact@v2 diff --git a/.gitignore b/.gitignore index 2104960..05b2a6d 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ *.vscode *.DS_Store *._* + +arm9/include/version.h diff --git a/Makefile b/Makefile index 4316ba0..d2fa834 100644 --- a/Makefile +++ b/Makefile @@ -13,12 +13,11 @@ export TOPDIR := $(CURDIR) NITRO_FILES := # These set the information text in the nds file -GAME_TITLE := TMFN -GAME_SUBTITLE1 := Title Manager for NAND -GAME_SUBTITLE2 := JeffRuLz, Pk11 +GAME_TITLE := Universal Title Manager +GAME_SUBTITLE1 := JeffRuLz, Pk11 -GAME_CODE := TMFN -GAME_LABEL := TITLEMANFN +GAME_CODE := HTMA +GAME_LABEL := TITLEMAN include $(DEVKITARM)/ds_rules @@ -52,7 +51,7 @@ $(TARGET).dsi : $(NITRO_FILES) arm7/$(TARGET).elf arm9/$(TARGET).elf ndstool -c $(TARGET).dsi -7 arm7/$(TARGET).elf -9 arm9/$(TARGET).elf \ -u "00030004" \ -g "$(GAME_CODE)" "00" "$(GAME_LABEL)" \ - -b $(GAME_ICON) "$(GAME_TITLE);$(GAME_SUBTITLE1);$(GAME_SUBTITLE2)" \ + -b $(GAME_ICON) "$(GAME_TITLE);$(GAME_SUBTITLE1)" \ $(_ADDFILES) #--------------------------------------------------------------------------------- diff --git a/README.md b/README.md index 80190f3..20193fe 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ -# Title Manager for NAND -A basic title manager for DSi NAND, modified from JeffRuLz's Title Manager for HiyaCFW. +# Universal Title Manager +A basic title manager for DSi supporting both hiyaCFW and SysNAND, modified from JeffRuLz's Title Manager for HiyaCFW. ## WARNING -This modifies your internal system NAND! There is *always* a risk of **bricking**, albeit small, when you modify NAND. Please proceed with caution. +This can modify your internal system NAND! There is *always* a risk of **bricking**, albeit small, when you modify NAND. Please proceed with caution. This has *barely* been tested and should be used with *extreme caution*. Please always use with Unlaunch installed, homebrew installed to the DSi Menu won't work without it and I'm not even sure if DSiWare installed by this will. ## Features -- Install DSiWare and homebrew onto your SysNAND home menu. +- Install DSiWare and homebrew onto your hiyaCFW SDNAND and SysNAND DSi Menus. - Delete system titles and others hidden from Data Management. diff --git a/arm9/Makefile b/arm9/Makefile index 16fba63..1ffbbaf 100644 --- a/arm9/Makefile +++ b/arm9/Makefile @@ -7,6 +7,24 @@ endif include $(DEVKITARM)/ds_rules +# If on a tagged commit, use just tag +ifneq ($(shell echo $(shell git tag -l --points-at HEAD) | head -c 1),) +GIT_VER := $(shell git tag -l --points-at HEAD) +else +GIT_VER := $(shell git describe --abbrev=0 --tags)-$(shell git rev-parse --short=7 HEAD) +endif + +# Ensure version.h exists +ifeq (,$(wildcard include/version.h)) +$(shell mkdir -p include) +$(shell touch include/version.h) +endif + +# Print new version if changed +ifeq (,$(findstring $(GIT_VER), $(shell cat include/version.h))) +$(shell printf "#ifndef VERSION_H\n#define VERSION_H\n\n#define VERSION \"$(GIT_VER)\"\n\n#endif // VERSION_H\n" > include/version.h) +endif + #--------------------------------------------------------------------------------- # BUILD is the directory where object files & intermediate files will be placed # SOURCES is a list of directories containing source code diff --git a/arm9/src/backupmenu.c b/arm9/src/backupmenu.c index a960df2..9fc4704 100644 --- a/arm9/src/backupmenu.c +++ b/arm9/src/backupmenu.c @@ -191,12 +191,12 @@ static void restore(Menu* m) } else { - if(!nandio_unlock_writing()) + if(!sdnandMode && !nandio_unlock_writing()) return; clearScreen(&bottomScreen); - if (!copyDir(fpath, "nand:/title")) + if (!copyDir(fpath, sdnandMode ? "sd:/title" : "nand:/title")) { messagePrint("\x1B[31m\nFailed to restore backup.\n\x1B[47m"); } @@ -205,7 +205,8 @@ static void restore(Menu* m) messagePrint("\x1B[42m\nBackup restored.\n\x1B[47m"); } - nandio_lock_writing(); + if(!sdnandMode) + nandio_lock_writing(); } } } diff --git a/arm9/src/install.c b/arm9/src/install.c index 0aa7136..9014052 100644 --- a/arm9/src/install.c +++ b/arm9/src/install.c @@ -14,7 +14,7 @@ static bool _titleIsUsed(tDSiHeader* h) if (!h) return false; char path[64]; - sprintf(path, "nand:/title/%08x/%08x/", (unsigned int)h->tid_high, (unsigned int)h->tid_low); + sprintf(path, "%s:/title/%08x/%08x/", sdnandMode ? "sd" : "nand", (unsigned int)h->tid_high, (unsigned int)h->tid_low); return dirExists(path); } @@ -298,8 +298,8 @@ bool install(char* fpath, bool systemTitle) return false; } - if(!nandio_unlock_writing()) - return false; + if(!sdnandMode && !nandio_unlock_writing()) + return false; //start installation clearScreen(&bottomScreen); @@ -349,8 +349,8 @@ bool install(char* fpath, bool systemTitle) printBytes(installSize); iprintf("\n"); - // if (!_checkSdSpace(installSize)) - // goto error; + if (sdnandMode && !_checkSdSpace(installSize)) + goto error; //system title patch if (systemTitle) @@ -386,14 +386,14 @@ bool install(char* fpath, bool systemTitle) if (_iqueHack(h)) fixHeader = true; - //create title directory nand:/title/XXXXXXXX/XXXXXXXX + //create title directory /title/XXXXXXXX/XXXXXXXX char dirPath[32]; - mkdir("nand:/title", 0777); + mkdir(sdnandMode ? "sd:/title" : "nand:/title", 0777); - sprintf(dirPath, "nand:/title/%08x", (unsigned int)h->tid_high); + sprintf(dirPath, "%s:/title/%08x", sdnandMode ? "sd" : "nand", (unsigned int)h->tid_high); mkdir(dirPath, 0777); - sprintf(dirPath, "nand:/title/%08x/%08x", (unsigned int)h->tid_high, (unsigned int)h->tid_low); + sprintf(dirPath, "%s:/title/%08x/%08x", sdnandMode ? "sd" : "nand", (unsigned int)h->tid_high, (unsigned int)h->tid_low); //check if title is free if (_titleIsUsed(h)) @@ -417,7 +417,7 @@ bool install(char* fpath, bool systemTitle) mkdir(dirPath, 0777); - //content folder nand:/title/XXXXXXXX/XXXXXXXXX/content + //content folder /title/XXXXXXXX/XXXXXXXXX/content { char contentPath[64]; sprintf(contentPath, "%s/content", dirPath); @@ -557,7 +557,8 @@ error: complete: free(h); - nandio_lock_writing(); + if(!sdnandMode) + nandio_lock_writing(); return result; } \ No newline at end of file diff --git a/arm9/src/main.c b/arm9/src/main.c index f30e394..486c8c5 100644 --- a/arm9/src/main.c +++ b/arm9/src/main.c @@ -2,16 +2,17 @@ #include "menu.h" #include "message.h" #include "nand/nandio.h" +#include "version.h" #include -#define VERSION "0.7.1" - bool programEnd = false; +bool sdnandMode = true; PrintConsole topScreen; PrintConsole bottomScreen; enum { + MAIN_MENU_MODE, MAIN_MENU_INSTALL, MAIN_MENU_TITLES, MAIN_MENU_BACKUP, @@ -44,11 +45,11 @@ static int _mainMenu(int cursor) //top screen clearScreen(&topScreen); - iprintf("\t Title Manager for NAND\n"); + iprintf("\t Universal Title Manager\n"); iprintf("\t\t\tmodified from\n"); iprintf("\tTitle Manager for HiyaCFW\n"); iprintf("\nversion %s\n", VERSION); - iprintf("\n\n\x1B[41mWARNING:\x1B[47m This tool writes to\nyour internal NAND!\n\nThis always has a risk, albeit\nlow, of \x1B[41mbricking\x1B[47m your system\nand should be done with caution!\n"); + iprintf("\n\n\x1B[41mWARNING:\x1B[47m This tool can write to\nyour internal NAND!\n\nThis always has a risk, albeit\nlow, of \x1B[41mbricking\x1B[47m your system\nand should be done with caution!\n"); iprintf("\nDo not exit by holding POWER,\ntap it or choose \"Shut Down\".\n"); iprintf("\x1b[22;0HJeff - 2018-2019"); iprintf("\x1b[23;0HPk11 - 2022"); @@ -57,6 +58,9 @@ static int _mainMenu(int cursor) Menu* m = newMenu(); setMenuHeader(m, "MAIN MENU"); + char modeStr[32]; + sprintf(modeStr, "Mode: %s", sdnandMode ? "SDNAND" : "\x1B[41mSysNAND\x1B[47m"); + addMenuItem(m, modeStr, NULL, 0); addMenuItem(m, "Install", NULL, 0); addMenuItem(m, "Titles", NULL, 0); addMenuItem(m, "Restore", NULL, 0); @@ -118,8 +122,8 @@ int main(int argc, char **argv) return 0; } - messageBox("\x1B[41mWARNING:\x1B[47m This tool writes to\nyour internal NAND!\n\nThis always has a risk, albeit\nlow, of \x1B[41mbricking\x1B[47m your system\nand should be done with caution!\n"); - messageBox("Do not exit by holding POWER,\ntap it or choose \"Shut Down\".\n"); + messageBox("\x1B[41mWARNING:\x1B[47m This tool can write to\nyour internal NAND!\n\nThis always has a risk, albeit\nlow, of \x1B[41mbricking\x1B[47m your system\nand should be done with caution!"); + messageBox("Do not exit by holding POWER,\ntap it or choose \"Shut Down\"."); //main menu int cursor = 0; @@ -132,6 +136,10 @@ int main(int argc, char **argv) switch (cursor) { + case MAIN_MENU_MODE: + sdnandMode = !sdnandMode; + break; + case MAIN_MENU_INSTALL: installMenu(); break; diff --git a/arm9/src/main.h b/arm9/src/main.h index 08f0915..7981596 100644 --- a/arm9/src/main.h +++ b/arm9/src/main.h @@ -6,6 +6,7 @@ #include extern bool programEnd; +extern bool sdnandMode; void installMenu(); void titleMenu(); diff --git a/arm9/src/storage.c b/arm9/src/storage.c index 9e3fd78..6444a5d 100644 --- a/arm9/src/storage.c +++ b/arm9/src/storage.c @@ -447,7 +447,7 @@ int getMenuSlotsFree() for (int i = 0; i < NUM_OF_DIRS; i++) { char path[256]; - sprintf(path, "nand:/title/%s", dirs[i]); + sprintf(path, "%s:/title/%s", sdnandMode ? "sd" : "nand", dirs[i]); dir = opendir(path); diff --git a/arm9/src/titlemenu.c b/arm9/src/titlemenu.c index ad4437f..ad7cd9b 100644 --- a/arm9/src/titlemenu.c +++ b/arm9/src/titlemenu.c @@ -95,11 +95,11 @@ static void generateList(Menu* m) bool done = false; int count = 0; //used to skip to the right page - //search each category directory nand:/title/XXXXXXXX + //search each category directory /title/XXXXXXXX for (int i = 0; i < NUM_OF_DIRS && done == false; i++) { char* dirPath = (char*)malloc(strlen(dirs[i])+15); - sprintf(dirPath, "nand:/title/%s", dirs[i]); + sprintf(dirPath, "%s:/title/%s", sdnandMode ? "sd" : "nand", dirs[i]); struct dirent* ent; DIR* dir = opendir(dirPath); @@ -113,7 +113,7 @@ static void generateList(Menu* m) if (ent->d_type == DT_DIR) { - //scan content folder nand:/title/XXXXXXXX/content + //scan content folder /title/XXXXXXXX/content char* contentPath = (char*)malloc(strlen(dirPath) + strlen(ent->d_name) + 20); sprintf(contentPath, "%s/%s/content", dirPath, ent->d_name); @@ -270,7 +270,7 @@ static void backup(Menu* m) getTitleId(h, &tid_low, &tid_high); char* srcpath = (char*)malloc(strlen("nand:/title/") + 32); - sprintf(srcpath, "nand:/title/%08x/%08x", (unsigned int)tid_high, (unsigned int)tid_low); + sprintf(srcpath, "%s:/title/%08x/%08x", sdnandMode ? "sd" : "nand", (unsigned int)tid_high, (unsigned int)tid_low); if (getSDCardFree() < getDirSize(srcpath)) { @@ -348,7 +348,8 @@ static bool delete(Menu* m) else { char dirPath[64]; - sprintf(dirPath, "%.29s", fpath); + sprintf(dirPath, "%.*s", sdnandMode ? 27 : 29, fpath); + nocashMessage(dirPath); if (!dirExists(dirPath)) { @@ -356,7 +357,7 @@ static bool delete(Menu* m) } else { - if(!nandio_unlock_writing()) + if(!sdnandMode && !nandio_unlock_writing()) return false; clearScreen(&bottomScreen); @@ -371,7 +372,8 @@ static bool delete(Menu* m) messagePrint("\nTitle could not be deleted.\n"); } - nandio_lock_writing(); + if(!sdnandMode) + nandio_lock_writing(); } } }