diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bfa545b..9f3d986 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,8 @@ on: jobs: build: runs-on: ubuntu-latest - container: devkitpro/devkitarm + # Something something old releases being hostile and damaging, boo hoo dkp. Maybe don't make extremely breaking changes. + container: devkitpro/devkitarm:20241104 name: Build with Docker using devkitARM steps: - name: Checkout repo diff --git a/arm9/Makefile b/arm9/Makefile index 0c7ce9a..1637712 100644 --- a/arm9/Makefile +++ b/arm9/Makefile @@ -13,6 +13,7 @@ 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 +BUILD_DATE := $(shell date +'%Y%m%d') # Ensure version.h exists ifeq (,$(wildcard include/version.h)) @@ -27,7 +28,7 @@ endif # Print new version if changed ifeq (,$(findstring $(GIT_VER), $(shell cat include/version.h))) $(shell echo -n $(GIT_VER) > ../../nitrofiles/version_twlnandtool) -$(shell printf "#ifndef VERSION_H\n#define VERSION_H\n\n#define VERSION \"$(GIT_VER)\"\n\n#endif // VERSION_H\n" > include/version.h) +$(shell printf "#ifndef VERSION_H\n#define VERSION_H\n\n#define VERSION \"$(GIT_VER)\"\n#define BUILD_DATE \"$(BUILD_DATE)\"\n\n#endif // VERSION_H\n" > include/version.h) endif #--------------------------------------------------------------------------------- @@ -41,8 +42,7 @@ BUILD := build SOURCES := src src/nand src/nand/polarssl src/nand/twltool INCLUDES := include src/nand DATA := ../data -GRAPHICS := ../gfx - +GRAPHICS := fonts #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- @@ -81,11 +81,14 @@ export ARM9ELF := $(CURDIR)/$(TARGET).elf export DEPSDIR := $(CURDIR)/$(BUILD) export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ - $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ + $(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir)) CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BMPFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.bmp))) +PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png))) BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) #--------------------------------------------------------------------------------- @@ -105,7 +108,9 @@ endif export OFILES := $(addsuffix .o,$(BINFILES)) \ $(BMPFILES:.bmp=.o) \ $(PNGFILES:.png=.o) \ - $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) \ + +export HFILES := $(BMPFILES:.bmp=.h) $(PNGFILES:.png=.h) $(addsuffix .h,$(subst .,_,$(BINFILES))) export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ @@ -139,7 +144,7 @@ $(ARM9ELF) : $(OFILES) #--------------------------------------------------------------------------------- # you need a rule like this for each extension you use as binary data #--------------------------------------------------------------------------------- -%.bin.o : %.bin +%.bin.o %_bin.h : %.bin #--------------------------------------------------------------------------------- @echo $(notdir $<) @$(bin2o) @@ -155,7 +160,7 @@ $(ARM9ELF) : $(OFILES) grit $< -fts -o$* #--------------------------------------------------------------------------------- -%.s %.h : %.png %.grit +%.s %.h : %.png %.grit #--------------------------------------------------------------------------------- grit $< -fts -o$* diff --git a/arm9/fonts/font.bmp b/arm9/fonts/font.bmp new file mode 100644 index 0000000..a7b8d54 Binary files /dev/null and b/arm9/fonts/font.bmp differ diff --git a/arm9/fonts/font.grit b/arm9/fonts/font.grit new file mode 100644 index 0000000..c0af58e --- /dev/null +++ b/arm9/fonts/font.grit @@ -0,0 +1,25 @@ +#------------------------------------------------------- +# graphics in tile format +#------------------------------------------------------- +-gt + +#------------------------------------------------------- +# output first 16 colors of the palette +#------------------------------------------------------- +-pw16 + +#------------------------------------------------------- +# no tile reduction +#------------------------------------------------------- +-mR! + +#------------------------------------------------------- +# no map output +#------------------------------------------------------- +-m! + +#------------------------------------------------------- +# graphics bit depth is 4 (16 color) +#------------------------------------------------------- +-gB4 + diff --git a/arm9/src/main.c b/arm9/src/main.c index 259df88..0abf51f 100644 --- a/arm9/src/main.c +++ b/arm9/src/main.c @@ -10,14 +10,14 @@ #include "nand/nandfirm.h" #include "video.h" #include "nitrofs.h" +#include "font.h" #include #include /* TODO: - - Write good NAND I/O routine - - Import NandFirm + - Write good NAND read routine - Detect debugger vs dev - Create FAT @@ -35,7 +35,7 @@ }; Pad to 0x200b and make sure to have 0x55AA (CRINGE I HATE MBR I HATE MBR I HATE MBR) <-- I don't even remember writing this. - Now fill 0x200*688b (total 0x171000) afterwards with zerobytes. + Now fill 0x200*B88b (total 0x171000) afterwards with zerobytes. Congrats. This is a formatted file system. Please don't hurt me. @@ -74,6 +74,7 @@ u8 batteryLevel = 0; u8 region = 0; u32 consoleSign; char consoleSignName[9]; +char consoleType[9]; PrintConsole topScreen; PrintConsole bottomScreen; @@ -81,34 +82,34 @@ PrintConsole bottomScreen; typedef enum { MENUSTATE_FS_MENU, MENUSTATE_NF_MENU, + MENUSTATE_NULL, MENUSTATE_TEST, + MENUSTATE_TEST2, MENUSTATE_EXIT } MenuState; static int _mainMenu(int cursor) { - //top screen - clearScreen(cMAIN); - - printf("\n\x1B[40mTwlNandTool Ver%s", VERSION); - printf("\nRun on: %s (%02lX)", consoleSignName, consoleSign); - printf("\n\nNAND repair tool by RMC/RVTR"); - printf("\n\nMode: Main Menu"); + clearScreen(cSUB); + clearScreen(cMAIN); //menu Menu* m = newMenu(); setMenuHeader(m, "TwlNandTool"); + setListHeader(m, "START MENU"); char modeStr[32]; - addMenuItem(m, "FileSystem Menu", NULL, 0); - addMenuItem(m, "NandFirm menu", NULL, 0); - addMenuItem(m, "Debug1", NULL, 0); - addMenuItem(m, "Exit", NULL, 0); + addMenuItem(m, "FileSystem Menu", NULL, 0, "Options such as repairing MBR\n and formatting twl_main/photo."); + addMenuItem(m, "NandFirm menu", NULL, 0, "NandFirm (stage2) installers\n and version testing."); + addMenuItem(m, "---------------", NULL, 0, ""); + addMenuItem(m, "Debug1", NULL, 0, "Testing area"); + addMenuItem(m, "Debug2", NULL, 0, "Testing area"); + addMenuItem(m, "Exit", NULL, 0, "Leave the program."); - m->cursor = cursor; + m->cursor = (cursor); //bottom screen - printMenu(m); + printMenu(m, 0); while (!programEnd) { @@ -116,7 +117,7 @@ static int _mainMenu(int cursor) scanKeys(); if (moveCursor(m)) - printMenu(m); + printMenu(m, 0); if (keysDown() & KEY_A) break; @@ -155,8 +156,22 @@ int main(int argc, char **argv) strcpy(consoleSignName, "dev"); } + if (consoleSign == 0x00) { + strcpy(consoleType, "Retail"); + } else if (consoleSign == 0x02) { + strcpy(consoleType, "Panda"); + }/* + + Do some check here to determine retail, panda, and debugger. + Then block debuggers due to different FW and a higher chance of messing stuff up without an easy fix. + + else if (consoleSign == 0x02 || ) { + strcpy consoleType, "Debugger" + } + */ + videoInit(); - + srand(time(0)); keysSetRepeat(25, 5); //_setupScreens(); @@ -172,7 +187,7 @@ int main(int argc, char **argv) //setup sd card access if (!fatInitDefault()) { - messageBox("fatInitDefault()...\x1B[31mFailed\n\x1B[40m\n\nSome features will not work."); + messageBox("fatInitDefault()...\x1B[31mFailed\n\x1B[30m\n\nSome features will not work."); //return 0; } @@ -189,7 +204,7 @@ int main(int argc, char **argv) if (keysDown() & KEY_SELECT ) break; } - messageBox("nitroFSInit()...\x1B[31mFailed\n\x1B[40m\nSome features will not work.\n\nTry placing the SRL for your DSion your SD card root like this:\n\nSDMC:/TwlNandTool.prod.srl\nSDMC:/TwlNandTool.dev.srl\nSDMC:/ntrboot.nds\n"); + messageBox("nitroFSInit()...\x1B[31mFailed\n\x1B[30m\nSome features will not work.\n\nTry placing the SRL for your DSion your SD card root like this:\n\nSDMC:/TwlNandTool.prod.srl\nSDMC:/TwlNandTool.dev.srl\nSDMC:/ntrboot.nds\n"); } } } @@ -197,9 +212,12 @@ int main(int argc, char **argv) //setup nand access if (!fatMountSimple("nand", &io_dsi_nand)) { - messageBox("nand init \x1B[31mfailed\n\x1B[40m\n\nNAND must be repaired."); + messageBox("nand init \x1B[31mfailed\n\x1B[30m\n\nNAND must be repaired."); } + clearScreen(cSUB); + clearScreen(cMAIN); + int cursor = 0; while (!programEnd) @@ -217,10 +235,17 @@ int main(int argc, char **argv) nfMain(); break; + case MENUSTATE_NULL: + break; + case MENUSTATE_TEST: debug1(); break; + case MENUSTATE_TEST2: + debug2(); + break; + case MENUSTATE_EXIT: programEnd = true; break; @@ -246,23 +271,73 @@ int debug1(void) { clearScreen(cSUB); iprintf("\n>> Debug1"); - iprintf("\n NandFirm write "); + iprintf("\n Show font "); iprintf("\n--------------------------------"); - printf("Opening NandFirm...\n"); - - FILE *file = fopen("nitro:/import/prod/menu-launcher.nand", "r"); - if(file) { - // First 0x200 of NandFirm is reserved for MBR - fseek(file, 0, SEEK_END); - int file_length = ftell(file); - fseek(file, 0x200, SEEK_SET); - printf("Importing...\n"); - good_nandio_write_file(0x200, file_length - ftell(file), file, false); - printf("Done!\n"); - fclose(file); + for (int i = 0; i <= 200; i++) { + printf("%c ", (char)i); } + iprintf("\n\n Please Push Select To Return "); + + while (true) + { + swiWaitForVBlank(); + scanKeys(); + + if (keysDown() & KEY_SELECT ) + break; + } +} + +int debug2(void) { + + clearScreen(cSUB); + + iprintf("\n>> Debug1"); + iprintf("\n Stupid AES-CTR BS "); + iprintf("\n--------------------------------"); + + nand_ReadSectors(877, 1, sector_buf); + dsi_nand_crypt(sector_buf, sector_buf, 877, SECTOR_SIZE / AES_BLOCK_SIZE); + + printf("\n "); + for (int i = 452; i < SECTOR_SIZE; i++) { + printf("%02X", sector_buf[i]); + if ((i + 1) % 2 == 0) { + printf(" "); + } + if ((i - 443) % 8 == 0 && i != 444) { + printf("\n "); + } + } + + iprintf("\n\n Read in"); + + while (true) + { + swiWaitForVBlank(); + scanKeys(); + + if (keysDown() & KEY_SELECT ) + break; + } + + dsi_nand_crypt(sector_buf, sector_buf, 877, SECTOR_SIZE / AES_BLOCK_SIZE); + + printf("\n "); + for (int i = 444; i < SECTOR_SIZE; i++) { + printf("%02X", sector_buf[i]); + if ((i + 1) % 2 == 0) { + printf(" "); + } + if ((i - 443) % 8 == 0 && i != 444) { + printf("\n "); + } + } + + iprintf("\n\n Read out"); + while (true) { swiWaitForVBlank(); diff --git a/arm9/src/main.h b/arm9/src/main.h index e1c4fbf..05e3958 100644 --- a/arm9/src/main.h +++ b/arm9/src/main.h @@ -19,12 +19,14 @@ extern u8 batteryLevel; extern u8 region; extern u32 consoleSign; extern char consoleSignName[9]; +extern char consoleType[9]; void installMenu(); void titleMenu(); void backupMenu(); void testMenu(); int debug1(); +int debug2(); extern PrintConsole topScreen; extern PrintConsole bottomScreen; diff --git a/arm9/src/menu.c b/arm9/src/menu.c index 37f9346..ad8df74 100644 --- a/arm9/src/menu.c +++ b/arm9/src/menu.c @@ -1,6 +1,8 @@ #include "menu.h" #include "main.h" #include "video.h" +#include "version.h" +#include "nand/nandio.h" Menu* newMenu() { @@ -12,12 +14,14 @@ Menu* newMenu() m->nextPage = false; m->changePage = 0; m->header[0] = '\0'; + m->lheader[0] = '\0'; for (int i = 0; i < ITEMS_PER_PAGE; i++) { m->items[i].directory = false; m->items[i].label = NULL; m->items[i].value = NULL; + m->items[i].help = NULL; } return m; @@ -33,7 +37,7 @@ void freeMenu(Menu* m) m = NULL; } -void addMenuItem(Menu* m, char const* label, char const* value, bool directory) +void addMenuItem(Menu* m, char const* label, char const* value, bool directory, char const* help) { if (!m) return; @@ -54,6 +58,12 @@ void addMenuItem(Menu* m, char const* label, char const* value, bool directory) sprintf(m->items[i].value, "%s", value); } + if (help) + { + m->items[i].help = (char*)malloc(200); + sprintf(m->items[i].help, "%s", help); + } + m->itemCount += 1; } @@ -93,6 +103,25 @@ void setMenuHeader(Menu* m, char* str) sprintf(m->header, "%.30s", strPtr); } + +void setListHeader(Menu* m, char* str) +{ + if (!m) return; + + if (!str) + { + m->lheader[0] = '\0'; + return; + } + + char* strPtr = str; + + if (strlen(strPtr) > 30) + strPtr = str + (strlen(strPtr) - 30); + + sprintf(m->lheader, "%.30s", strPtr); +} + void resetMenu(Menu* m) { m->cursor = 0; @@ -123,39 +152,122 @@ void clearMenu(Menu* m) m->itemCount = 0; } -void printMenu(Menu* m) +void clearHelpMenu(Menu* m) { - clearScreen(cSUB); + consoleSet(cMAIN); + iprintf("\x1B[40m\x1b[0;0H\x1B[40m%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%cHelp%c%c%c%c%c", (char)138, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)134, (char)135, (char)136, (char)136, (char)136, (char)140); + iprintf("\x1b[1;0H\x1b[K"); + iprintf("\x1b[2;0H\x1b[K"); + iprintf("\x1b[3;0H\x1b[K"); + iprintf("\x1b[4;0H\x1b[K"); + iprintf("\x1b[5;0H\x1b[K"); + iprintf("\x1b[6;0H\x1b[K"); + iprintf("\x1b[7;0H\x1b[K"); + iprintf("\x1b[8;0H\x1b[K"); + iprintf("\x1b[9;0H%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", (char)139, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)141); + iprintf("\x1b[10;0H\x1b[K"); + iprintf("\x1b[11;0H\x1B[40m%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%cInfo%c%c%c%c%c", (char)138, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)134, (char)135, (char)136, (char)136, (char)136, (char)140); + iprintf("\x1B[30m\x1b[12;0H\x1b[K %s %s", m->header, VERSION); + iprintf("\x1b[13;0H\x1b[K Built on: %s", BUILD_DATE); + iprintf("\x1b[14;0H\x1b[K Made by: RMC/RVTR"); + iprintf("\x1b[15;0H\x1b[K"); + iprintf("\x1b[16;0H\x1b[K"); + iprintf("\x1b[17;0H\x1b[K Run on: %s\x1B[40m", consoleType); + iprintf("\x1b[18;0H%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\x1B[30m", (char)139, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)136, (char)141); +} + +void printHelpMenu(Menu* m) +{ + if (!m) return; + iprintf("\x1B[30m\x1b[1;0H %s", m->items[m->cursor].help); +} + +void printMenu(Menu* m, int level) +{ + + clearHelpMenu(m); + printHelpMenu(m); + consoleSet(cSUB); if (!m) return; - //header - iprintf("\x1B[42m"); //green - iprintf("%.30s\n\n", m->header); - iprintf("\x1B[40m"); //white - if (m->itemCount <= 0) { iprintf("Back - [B]\n"); return; } + int longestLength = 0; + + for (int i = 0; i < m->itemCount; i++) { + if (m->items[i].label) { + int currentLength = strlen(m->items[i].label); + if (currentLength > longestLength) { + longestLength = currentLength; + } + } + } + +/* + +(char)134 = lbracket +(char)135 = rbracket + + Double line borders: +(char)130 = top lcorner +(char)128 = hpipe +(char)132 = top rcorner +(char)129 = vpipe +(char)131 = bot lcorner +(char)133 = bot rcorner + + Single line borders: + +(char)138 = top lcorner +(char)136 = hpipe +(char)140 = top rcorner +(char)137 = vpipe +(char)139 = bot lcorner +(char)141 = bot rcorner +*/ + +iprintf("\x1B[30m\x1b[%d;%dH%c%c%c%s%c", 1 + level, level + 1, (char)138, (char)136, (char)134, m->lheader, (char)135); +for (int j = 0; j < longestLength - 3 - strlen(m->lheader); j++) { + printf("%c", (char)136); +} +printf("%c\n", (char)140); //items for (int i = 0; i < m->itemCount; i++) { if (m->items[i].label) { - if (m->items[i].directory) - iprintf(" [%.28s]\n", m->items[i].label); - else - iprintf(" %.30s\n", m->items[i].label); + if (m->items[i].directory) { + iprintf("\x1b[%d;%dH%c[%.28s]", i + 2 + level, level + 1, (char)137, m->items[i].label); + for (int j = strlen(m->items[i].label); j < longestLength; j++) { + printf(" "); + } + printf("%c\n", (char)137); + } else { + iprintf("\x1b[%d;%dH%c%.30s", i + 2 + level, level + 1, (char)137, m->items[i].label); + for (int j = strlen(m->items[i].label); j < longestLength; j++) { + printf(" "); + } + printf("%c\n", (char)137); + } } - else + else { iprintf(" \n"); + } } +iprintf("\x1b[%d;%dH%c", m->itemCount + 2 + level, level + 1, (char)139); +for (int j = 0; j < longestLength; j++) { + printf("%c", (char)136); +} +printf("%c\n", (char)141); + //cursor - iprintf("\x1b[%d;0H>", 2 + m->cursor); + iprintf("\x1b[%d;%dH%c\x1B[41m%s\x1B[30m\x1b[%dC%c", m->cursor + 2 + level, level + 1, (char)137, m->items[m->cursor].label, longestLength - strlen(m->items[m->cursor].label), (char)137); //scroll arrows if (m->page > 0) @@ -225,4 +337,12 @@ bool moveCursor(Menu* m) } return !(lastCursor == m->cursor); +} + +char downloadPlayLoading(int number) { + char pictoload[] = {(char)142, (char)143, (char)144, (char)145, (char)146, (char)147, (char)148, (char)149}; + static int counter = 0; + + counter = (counter % 7) + 1; + return pictoload[counter]; } \ No newline at end of file diff --git a/arm9/src/menu.h b/arm9/src/menu.h index ea0ebc5..cd6f2ac 100644 --- a/arm9/src/menu.h +++ b/arm9/src/menu.h @@ -9,6 +9,7 @@ typedef struct { bool directory; char* label; char* value; + char* help; } Item; typedef struct { @@ -18,20 +19,26 @@ typedef struct { bool nextPage; int changePage; char header[32]; + char lheader[32]; Item items[ITEMS_PER_PAGE]; } Menu; Menu* newMenu(); void freeMenu(Menu* m); -void addMenuItem(Menu* m, char const* label, char const* value, bool directory); +void addMenuItem(Menu* m, char const* label, char const* value, bool directory, char const* help); void sortMenuItems(Menu* m); void setMenuHeader(Menu* m, char* str); +void setListHeader(Menu* m, char* str); void resetMenu(Menu* m); void clearMenu(Menu* m); -void printMenu(Menu* m); +void clearHelpMenu(Menu* m); +void printHelpMenu(Menu* m); +void printMenu(Menu* m, int level); bool moveCursor(Menu* m); +char downloadPlayLoading(int number); + #endif \ No newline at end of file diff --git a/arm9/src/message.c b/arm9/src/message.c index 85cd9d2..2c7454f 100644 --- a/arm9/src/message.c +++ b/arm9/src/message.c @@ -23,7 +23,7 @@ bool choiceBox(char* message) iprintf("\x1B[33m"); //yellow iprintf("%s\n", message); - iprintf("\x1B[40m"); //white + iprintf("\x1B[30m"); //white iprintf("\x1b[%d;0H\tYes\n\tNo\n", choiceRow); while (!programEnd) @@ -60,7 +60,7 @@ bool choicePrint(char* message) iprintf("\x1B[34m"); //yellow iprintf("\n%s\n", message); - iprintf("\x1B[40m"); //white + iprintf("\x1B[30m"); //white iprintf("Yes - [A]\nNo - [B]\n"); while (!programEnd) @@ -103,7 +103,7 @@ bool randomConfirmBox(char* message) iprintf("\x1B[43m"); //yellow iprintf("%s\n", message); - iprintf("\x1B[40m"); //white + iprintf("\x1B[30m"); //white iprintf("\n cancel\n"); while (!programEnd && sequencePosition < sizeof(sequence)) diff --git a/arm9/src/nand/filesystem.c b/arm9/src/nand/filesystem.c index 940a44a..5b7788a 100644 --- a/arm9/src/nand/filesystem.c +++ b/arm9/src/nand/filesystem.c @@ -50,6 +50,46 @@ u8 vbrPhoto[54] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; +// File tables for /sys/ folder and HWInfo secure +// Why? HWInfo is always at one of 3 set offsets. I use those offsets for HWInfo recovery. +// We will copy over these file tables to ensure the offsets stay the same. + +// No idea what this is but I need it lol +u8 fileTable1[16] = { + 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00, 0x00 +}; + +// File table for /sys/ folder +u8 fileTable2[64] = { + 0x41, 0x73, 0x00, 0x79, 0x00, 0x73, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x0F, + 0x00, 0x54, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x53, 0x59, 0x53, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x21, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +// File table for HWInfo +u8 fileTable3[192] = { + 0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0x00, 0x00, 0x00, 0x00, 0x75, 0x02, + 0x64, 0x59, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x2E, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x21, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE5, 0x6C, 0x00, 0x6F, 0x00, 0x67, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE5, 0x4F, 0x47, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x01, 0x00, 0x21, 0x28, 0x64, 0x59, 0x00, 0x00, 0x01, 0x00, + 0x21, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x48, 0x00, 0x57, + 0x00, 0x49, 0x00, 0x4E, 0x00, 0x46, 0x00, 0x0F, 0x00, 0x9C, 0x4F, 0x00, + 0x5F, 0x00, 0x53, 0x00, 0x2E, 0x00, 0x64, 0x00, 0x61, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x48, 0x57, 0x49, 0x4E, 0x46, 0x4F, 0x5F, 0x53, + 0x44, 0x41, 0x54, 0x20, 0x00, 0x00, 0x01, 0x00, 0x21, 0x28, 0x64, 0x59, + 0x00, 0x00, 0x50, 0x02, 0x64, 0x59, 0x06, 0x00, 0x00, 0x40, 0x00, 0x00 +}; + static size_t i; enum { @@ -62,28 +102,22 @@ enum { static int _fsMenu(int cursor) { - //top screen - clearScreen(cMAIN); - printf("\n\x1B[40mTwlNandTool Ver0.0"); - printf("\n\nNAND repair tool by RMC/RVTR"); - printf("\n\nMode: FileSystem"); - - //menu - Menu* m = newMenu(); - setMenuHeader(m, "TwlNandTool"); + Menu* m = newMenu(); + setMenuHeader(m, "TwlNandTool"); + setListHeader(m, "FileSystem"); char modeStr[32]; - addMenuItem(m, "Read MBR", NULL, 0); - addMenuItem(m, "Repair MBR", NULL, 0); - addMenuItem(m, "Format TWL_MAIN", NULL, 0); - addMenuItem(m, "Format TWL_PHOTO", NULL, 0); - addMenuItem(m, "Back", NULL, 0); + addMenuItem(m, "Read MBR", NULL, 0, "Test the Master Boot Record."); + addMenuItem(m, "Repair MBR", NULL, 0, "Repair the Master Boot Record."); + addMenuItem(m, "Format TWL_MAIN", NULL, 0, "Format the partition where the\n firmware, apps, and saves are\n installed.\n\n THIS WILL ERASE EVERYTHING."); + addMenuItem(m, "Format TWL_PHOTO", NULL, 0, "Format the partition where\n photos are stored.\n\n THIS WILL ERASE EVERYTHING."); + addMenuItem(m, "Back", NULL, 0, "Leave the FileSystem menu."); m->cursor = cursor; //bottom screen - printMenu(m); + printMenu(m, 1); while (!programEnd) { @@ -91,7 +125,7 @@ static int _fsMenu(int cursor) scanKeys(); if (moveCursor(m)) - printMenu(m); + printMenu(m, 1); if (keysDown() & KEY_A) break; @@ -128,7 +162,7 @@ int fsMain(void) break; case FORMAT_PHOTO: - repairMbr(); + formatPhoto(); break; case BACK: @@ -162,7 +196,7 @@ int readMbr(void) { } } if(parse_mbr(sector_buf, is3DS)) { - iprintf("\n\n \x1B[31mERROR!\x1B[40m MBR is corrupted."); + iprintf("\n\n \x1B[31mERROR!\x1B[30m MBR is corrupted."); } iprintf("\n\n Please Push Select To Return "); @@ -213,11 +247,11 @@ int repairMbr(void) { dsi_nand_crypt(sector_buf, sector_buf, 0, SECTOR_SIZE / AES_BLOCK_SIZE); if(parse_mbr(sector_buf, is3DS)) { - iprintf("\n\n \x1B[31mERROR!\x1B[40m Failed to fix MBR."); + iprintf("\n\n \x1B[31mERROR!\x1B[30m Failed to fix MBR."); + } else { + iprintf("\n\x1B[32mThe new MBR passed!\x1B[30m"); } - iprintf("\n\x1B[32mThe new MBR passed!\x1B[40m"); - iprintf("\n\n Please Push Select To Return "); while (true) @@ -233,18 +267,69 @@ int repairMbr(void) { int formatMain(void) { clearScreen(cSUB); - iprintf("\n>> Write TWL_MAIN VBR "); + iprintf("\n>> Format TWL_MAIN "); iprintf("\n--------------------------------"); + iprintf("\n\nWriting VBR..."); memset(file_buf, 0, 0x200); // Write the first 54 bytes, then pad to 0x1FE. Finally write 0x55AA memcpy(file_buf, vbrMain, sizeof(vbrMain)); memset(file_buf + sizeof(vbrMain), 0, (BUFFER_SIZE - sizeof(vbrMain) - 2)); memset(file_buf + SECTOR_SIZE - 2, 0x55, 1); memset(file_buf + SECTOR_SIZE - 1, 0xAA, 1); - good_nandio_write(0x10EE00, 0x200, file_buf, false); + good_nandio_write(0x10EE00, 0x200, file_buf, true); + iprintf("\nClearing file tables..."); + memset(file_buf, 0, 0x600); + for (i = 0; i < 0x3d8; i++) { + good_nandio_write(0x10EE00 + 0x200 + (0x600 * i), 0x600, file_buf, true); + } + iprintf("\nMaking new file tables..."); + memset(file_buf, 0, 0x200); + memcpy(file_buf, fileTable1, sizeof(fileTable1)); + good_nandio_write(0x115800, sizeof(fileTable1), file_buf, true); + memset(file_buf, 0, 0x200); + memcpy(file_buf, fileTable2, sizeof(fileTable2)); + good_nandio_write(0x11C000, sizeof(fileTable2), file_buf, true); + memset(file_buf, 0, 0x200); + memcpy(file_buf, fileTable3, sizeof(fileTable3)); + good_nandio_write(0x120000, sizeof(fileTable3), file_buf, true); + + iprintf("\nAll done!"); + + iprintf("\n\n Please Push Select To Return "); + + while (true) + { + swiWaitForVBlank(); + scanKeys(); + + if (keysDown() & KEY_SELECT ) + break; + } +} + +int formatPhoto(void) { + clearScreen(cSUB); + + iprintf("\n>> Format TWL_PHOTO "); + iprintf("\n--------------------------------"); + + iprintf("\n\nWriting VBR..."); + memset(file_buf, 0, 0x200); + // Write the first 54 bytes, then pad to 0x1FE. Finally write 0x55AA + memcpy(file_buf, vbrPhoto, sizeof(vbrPhoto)); + memset(file_buf + sizeof(vbrPhoto), 0, (BUFFER_SIZE - sizeof(vbrPhoto) - 2)); + memset(file_buf + SECTOR_SIZE - 2, 0x55, 1); + memset(file_buf + SECTOR_SIZE - 1, 0xAA, 1); + good_nandio_write(0xCF09A00, 0x200, file_buf, true); + iprintf("\nClearing file tables..."); + memset(file_buf, 0, 0x200); + for (i = 0; i < 0x13A; i++) { + good_nandio_write(0xCF09A00 + 0x200 + (0x200 * i), 0x200, file_buf, true); + } + + iprintf("\nAll done!"); - iprintf("\n\nDone! Please confirm VBR is correct."); iprintf("\n\n Please Push Select To Return "); while (true) diff --git a/arm9/src/nand/filesystem.h b/arm9/src/nand/filesystem.h index 4ac79d9..2bff151 100644 --- a/arm9/src/nand/filesystem.h +++ b/arm9/src/nand/filesystem.h @@ -18,4 +18,5 @@ int fsMain(void); int readMbr(void); int repairMbr(void); -int formatMain(void); \ No newline at end of file +int formatMain(void); +int formatPhoto(void); \ No newline at end of file diff --git a/arm9/src/nand/nandfirm.c b/arm9/src/nand/nandfirm.c index 9893849..0e5c7f7 100644 --- a/arm9/src/nand/nandfirm.c +++ b/arm9/src/nand/nandfirm.c @@ -14,7 +14,7 @@ #include "../main.h" #include "../video.h" -u32 done=0; +bool success = true; void death(char *message, u8 *buffer){ iprintf("\n%s\n", message); @@ -34,28 +34,22 @@ enum { static int _nfMenu(int cursor) { - //top screen - clearScreen(cMAIN); - printf("\n\x1B[40mTwlNandTool Ver0.0"); - printf("\n\nNAND repair tool by RMC/RVTR"); - printf("\n\nMode: NandFirm"); - - //menu - Menu* m = newMenu(); - setMenuHeader(m, "TwlNandTool"); + Menu* m = newMenu(); + setMenuHeader(m, "TwlNandTool"); + setListHeader(m, "NandFirm"); char modeStr[32]; - addMenuItem(m, "Check NandFirm", NULL, 0); - addMenuItem(m, "Import NandFirm", NULL, 0); - addMenuItem(m, "Import NandFirm (SDMC)", NULL, 0); - addMenuItem(m, "CID Info", NULL, 0); - addMenuItem(m, "Back", NULL, 0); + addMenuItem(m, "Check NandFirm", NULL, 0, "Check the stage2 (bootloader)\n version and type."); + addMenuItem(m, "Import NandFirm", NULL, 0, "Install the standard stage2\n (bootloader).\n\n This stage2 works normally,\n but it is an updated version:\n - v2265-9336 (prod)\n - v2725-9336 (dev)"); + addMenuItem(m, "Import NandFirm (SDMC)", NULL, 0, "Install the SDMC Launcher\n stage2 (bootloader).\n\n SDMC will remove access to\n the firmware and SHOULD NOT\n BE USED unless otherwise\n told to do so."); + addMenuItem(m, "CID Info", NULL, 0, "Get NAND chip information."); + addMenuItem(m, "Back", NULL, 0, "Leave the NandFirm menu."); m->cursor = cursor; //bottom screen - printMenu(m); + printMenu(m, 1); while (!programEnd) { @@ -63,7 +57,7 @@ static int _nfMenu(int cursor) scanKeys(); if (moveCursor(m)) - printMenu(m); + printMenu(m, 1); if (keysDown() & KEY_A) break; @@ -130,10 +124,12 @@ int nandFirmRead(void) { } printf("\n Ver: "); - for (i = 0; i < 9; i++) { + for (i = 0; i < 10; i++) { if (sector_buf[i] == 0x0A) { printf("-"); + } else if (sector_buf[i] == 0x0D) { + printf(""); } else { printf("%c", sector_buf[i]); } @@ -151,14 +147,14 @@ int nandFirmRead(void) { if (keysDown() & KEY_SELECT ) break; } + return success; } -int nandFirmImport(bool sdmc) { +bool nandFirmImport(bool sdmc) { clearScreen(cSUB); - iprintf("\n>> Debug1"); - iprintf("\n NandFirm write "); + iprintf("\n>> Import NandFirm (%s) ", sdmc ? "sdmc" : "menu"); iprintf("\n--------------------------------"); printf("Opening NandFirm...\n"); @@ -167,7 +163,7 @@ int nandFirmImport(bool sdmc) { snprintf(file_path, 100, "nitro:/import/%s/%s-launcher.nand", consoleSignName, sdmc ? "sdmc" : "menu"); FILE *file = fopen(file_path, "r"); - printf("%s\n", file_path); + printf("\n%s\n\n", file_path); if(file) { // First 0x200 of NandFirm is reserved for MBR @@ -178,8 +174,13 @@ int nandFirmImport(bool sdmc) { good_nandio_write_file(0x200, file_length - ftell(file), file, false); printf("Done!\n"); fclose(file); + } else { + success = false; + iprintf("\nNandFirm import failed!"); } + iprintf("\n\n Please Push Select To Return "); + while (true) { swiWaitForVBlank(); @@ -188,6 +189,7 @@ int nandFirmImport(bool sdmc) { if (keysDown() & KEY_SELECT ) break; } + return success; } int nandPrintInfo(void) { @@ -224,4 +226,5 @@ int nandPrintInfo(void) { if (keysDown() & KEY_SELECT ) break; } + return success; } \ No newline at end of file diff --git a/arm9/src/nand/nandfirm.h b/arm9/src/nand/nandfirm.h index 192a7b1..e0503c3 100644 --- a/arm9/src/nand/nandfirm.h +++ b/arm9/src/nand/nandfirm.h @@ -20,5 +20,5 @@ void death(char *message, u8 *buffer); int nfMain(void); int nandFirmRead(void); -int nandFirmImport(bool sdmc); +bool nandFirmImport(bool sdmc); int nandPrintInfo(void); \ No newline at end of file diff --git a/arm9/src/nand/nandio.c b/arm9/src/nand/nandio.c index 0aebd17..0eb2033 100644 --- a/arm9/src/nand/nandio.c +++ b/arm9/src/nand/nandio.c @@ -7,6 +7,7 @@ #include "sector0.h" #include "f_xy.h" #include "nandio.h" +#include "../menu.h" #include "u128_math.h" /************************ Function Protoypes **********************************/ @@ -50,6 +51,8 @@ static u32 fat_sig_fix_offset = 0; static u32 sector_buf32[SECTOR_SIZE/sizeof(u32)]; extern u8 *sector_buf = (u8*)sector_buf32; +static u32 sector_buf232[SECTOR_SIZE/sizeof(u32)]; +extern u8 *sector_buf2 = (u8*)sector_buf232; static u32 file_buf32[BUFFER_SIZE/sizeof(u32)]; extern u8 *file_buf = (u8*)file_buf32; @@ -253,18 +256,23 @@ bool good_nandio_write(int inputAddress, int inputLength, u8 *buffer, bool crypt int byteEndOffset = (inputAddress+inputLength) % SECTOR_SIZE; int sectorEndNum = (inputAddress+inputLength) / SECTOR_SIZE; int i; - if (inputLength <= 0x200) { + if (inputLength <= SECTOR_SIZE) { // Handle a single sector write differently since it is unpredictable nand_ReadSectors(sectorNum, 1, sector_buf); memcpy(sector_buf, buffer, inputLength); if (crypt == true) { - dsi_nand_crypt(sector_buf, sector_buf, 0, SECTOR_SIZE / AES_BLOCK_SIZE); + dsi_nand_crypt(sector_buf, sector_buf, sectorNum * SECTOR_SIZE / AES_BLOCK_SIZE, SECTOR_SIZE / AES_BLOCK_SIZE); } nand_WriteSectors(sectorNum, 1, sector_buf); //iprintf("\n%02X to %02X of %02X", byteOffset, inputLength, sectorNum); //iprintf("\n%02X to %02X of buffer", 0, inputLength); } else { + iprintf("\n "); for (i = sectorNum; i < sectorEndNum + 1;) { + char currentPicto = downloadPlayLoading(i); + if (i % (sectorEndNum / 15) == 0) { + printf("\b%c", currentPicto); + } // Back up sector nand_ReadSectors(i, 1, sector_buf); if (i == sectorNum) { @@ -286,12 +294,17 @@ bool good_nandio_write(int inputAddress, int inputLength, u8 *buffer, bool crypt // I need to do a cmp here t0 save NAND writes // Write sector if (crypt == true) { - dsi_nand_crypt(buffer, buffer, 0, SECTOR_SIZE / AES_BLOCK_SIZE); + // offset * SECTOR_SIZE / AES_BLOCK_SIZE + dsi_crypt_init((const u8*)consoleIDfixed, (const u8*)0x2FFD7BC, is3DS); + dsi_nand_crypt(sector_buf, sector_buf, i * SECTOR_SIZE / AES_BLOCK_SIZE, SECTOR_SIZE / AES_BLOCK_SIZE); + // Okay so the below one encrypted every other sector, failing the 1st, 3rd, 5th, etc. + //dsi_nand_crypt(sector_buf, sector_buf, inputAddress * SECTOR_SIZE / AES_BLOCK_SIZE, SECTOR_SIZE / AES_BLOCK_SIZE); } nand_WriteSectors(i, 1, sector_buf); i++; // Do some check to make sure it is not outside of NAND range. } + iprintf("\b\x1B[1A"); } return true; } @@ -303,17 +316,22 @@ bool good_nandio_write_file(int inputAddress, int inputLength, FILE *fp, bool cr int sectorEndNum = (inputAddress+inputLength) / SECTOR_SIZE; int i; u8 buffer[SECTOR_SIZE]; - if (inputLength <= 0x200) { + if (inputLength <= SECTOR_SIZE) { // Handle a single sector write differently since it is unpredictable nand_ReadSectors(sectorNum, 1, sector_buf); fread(buffer, 1, inputLength, fp); memcpy(sector_buf, buffer, inputLength); if (crypt == true) { - dsi_nand_crypt(sector_buf, sector_buf, 0, SECTOR_SIZE / AES_BLOCK_SIZE); + dsi_nand_crypt(sector_buf, sector_buf, sectorNum * SECTOR_SIZE / AES_BLOCK_SIZE, SECTOR_SIZE / AES_BLOCK_SIZE); } nand_WriteSectors(sectorNum, 1, sector_buf); } else { + iprintf("\n "); for (i = sectorNum; i < sectorEndNum + 1;) { + char currentPicto = downloadPlayLoading(i); + if (i % (sectorEndNum / 15) == 0) { + printf("\b%c", currentPicto); + } // Back up sector nand_ReadSectors(i, 1, sector_buf); @@ -333,12 +351,13 @@ bool good_nandio_write_file(int inputAddress, int inputLength, FILE *fp, bool cr // I need to do a cmp here t0 save NAND writes // Write sector if (crypt == true) { - dsi_nand_crypt(buffer, buffer, 0, SECTOR_SIZE / AES_BLOCK_SIZE); + dsi_nand_crypt(sector_buf, sector_buf, i * SECTOR_SIZE / AES_BLOCK_SIZE, SECTOR_SIZE / AES_BLOCK_SIZE); } nand_WriteSectors(i, 1, sector_buf); i++; // Do some check to make sure it is not outside of NAND range. } + iprintf("\b\x1B[1A"); } return true; } diff --git a/arm9/src/storage.c b/arm9/src/storage.c index 87c403b..8b72189 100644 --- a/arm9/src/storage.c +++ b/arm9/src/storage.c @@ -38,7 +38,7 @@ void printProgressBar(float percent) { consoleSet(cMAIN); - iprintf("\x1B[42m"); //green + iprintf("\x1B[32m"); //green //Print frame if (lastBars <= 0) @@ -291,7 +291,7 @@ bool copyDir(char const* src, char const* dst) } else { - iprintf("\x1B[42m"); //green + iprintf("\x1B[32m"); //green iprintf("Done\n"); iprintf("\x1B[47m"); //white } @@ -357,7 +357,7 @@ bool deleteDir(char const* path) } else { - iprintf("\x1B[42m"); + iprintf("\x1B[32m"); iprintf("Done\n"); iprintf("\x1B[47m"); } @@ -377,7 +377,7 @@ bool deleteDir(char const* path) } else { - iprintf("\x1B[42m"); + iprintf("\x1B[32m"); iprintf("Done\n"); iprintf("\x1B[47m"); } diff --git a/arm9/src/video.c b/arm9/src/video.c index 4c57555..b55ce58 100755 --- a/arm9/src/video.c +++ b/arm9/src/video.c @@ -4,6 +4,7 @@ // From https://code.google.com/archive/p/sundevos/ // common headers #include "video.h" +#include "font.h" #define SUB ((u16 *)BG_BMP_RAM_SUB(2)) #define MAIN ((u16 *)BG_BMP_RAM(2)) @@ -17,89 +18,31 @@ PrintConsole console, consoleSub; */ void videoInit() { - consoleDebugInit(DebugDevice_CONSOLE); // debug to console - videoSetMode(MODE_5_3D); - vramSetBankA(VRAM_A_MAIN_BG_0x06000000); // allocate 128Ko at 0x06000000 + videoSetMode(MODE_0_2D); + videoSetModeSub(MODE_0_2D); + vramSetBankA (VRAM_A_MAIN_BG); + vramSetBankC (VRAM_C_SUB_BG); - // <-- console (debug console for binaries loaded) - consoleInit( - &console, // the console to be initted - 1, // bgLayer - BgType_Text4bpp, // bg type - BgSize_T_256x256, // bg size - 4, // map base - 0, // tile base - true, // main display - true // load graphics - ); - iprintf("\x1b[32;1m"); // Set the color to green - // --> <-- 2D (96Ko at 0x06008000) - bgInit( - 3, // bg layer - BgType_Bmp16, // bg type - BgSize_B16_256x256, // bg size - 2, // map base (here it's the bmp base) - 0 // tile base (here it's useless) - ); - screenFill(MAIN, RGB15(31, 31, 31)|BIT(15)); - // --> <-- 3D - /* <-- old - glInit(); - glClearColor(0,0,0,0); // make the BG transparent - glClearDepth(0x7FFF); - glViewport(0,0,255,191); // Set our viewport to be the same size as the screen - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(70, 256.0 / 192.0, 0.1, 100); - --> */ + bgInit(3, BgType_Bmp8, BgSize_B8_256x256, 1, 0); + bgInitSub(3, BgType_Bmp8, BgSize_B8_256x256, 1, 0); - #define MIN_X (0.0f) - #define MAX_X (4.0f) - #define MIN_Y (0.0f) - #define MAX_Y (3.0f) - glInit(); - glClearColor(0,0,0,0); // BG must be opaque for AA to work - //glClearPolyID(63); // BG must have a unique polygon ID for AA to work - glClearDepth(0x7FFF); - glViewport(0,0,255,191); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrthof32(floattof32(MIN_X), floattof32(MAX_X), floattof32(MIN_Y), floattof32(MAX_Y), floattof32(0.1), floattof32(10)); - glMatrixMode(GL_MODELVIEW); - glMaterialf(GL_AMBIENT, RGB15(31,31,31)); - glMaterialf(GL_DIFFUSE, RGB15(31,31,31)); - glMaterialf(GL_SPECULAR, BIT(15) | RGB15(31,31,31)); - glMaterialf(GL_EMISSION, RGB15(31,31,31)); - glMaterialShinyness(); - glMatrixMode(GL_MODELVIEW); - // --> + consoleInit(&consoleSub, 3, BgType_Text4bpp, BgSize_T_256x256, 20, 0, false, false); + consoleInit(&console, 3, BgType_Text4bpp, BgSize_T_256x256, 20, 0, true, false); - videoSetModeSub(MODE_5_2D); - vramSetBankC(VRAM_C_SUB_BG_0x06200000); // allocate 128Ko at 0x06200000 + ConsoleFont font; + font.gfx = (u16*)fontTiles; + font.pal = (u16*)fontPal; + font.numChars = 200; + font.numColors = fontPalLen / 2; + font.bpp = 4; + font.asciiOffset = 32; + font.convertSingleColor = true; + consoleSetFont(&console, &font); + consoleSetFont(&consoleSub, &font); - // <-- console (debug console for SunOS) - consoleInit( - &consoleSub, // the console to be initted - 1, // bgLayer - BgType_Text4bpp, // bg type - BgSize_T_256x256, // bg size - 4, // map base - 0, // tile base - false, // main display - true // load graphics - ); - iprintf("\x1b[31;1m"); // Set the color to red - // --> <-- 2D (96Ko at 0x06208000) - bgInitSub( - 3, // bg layer - BgType_Bmp16, // bg type - BgSize_B16_256x256, // bg size - 2, // map base (here it's the bmp base) - 0 // tile base (here it's useless) - ); - screenFill(SUB, RGB15(31, 31, 31)|BIT(15)); - // --> + setBackdropColor(0xFFFF); + setBackdropColorSub(0xFFFF); lcdMainOnBottom(); consoleSet(cSUB); diff --git a/nitrofiles/import/dev/sdmc-launcher.nand b/nitrofiles/import/dev/sdmc-launcher.nand index d1eab97..bf232a6 100644 Binary files a/nitrofiles/import/dev/sdmc-launcher.nand and b/nitrofiles/import/dev/sdmc-launcher.nand differ diff --git a/nitrofiles/import/prod/sdmc-launcher.nand b/nitrofiles/import/prod/sdmc-launcher.nand index 4964f7c..8dec675 100644 Binary files a/nitrofiles/import/prod/sdmc-launcher.nand and b/nitrofiles/import/prod/sdmc-launcher.nand differ