mirror of
https://github.com/rvtr/TwlNandTool.git
synced 2025-10-31 06:01:08 -04:00
Fixed FAT formatting and improved UI
This commit is contained in:
parent
b09e376e67
commit
e6c617fea5
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
@ -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
|
||||
|
||||
@ -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$*
|
||||
|
||||
|
||||
BIN
arm9/fonts/font.bmp
Normal file
BIN
arm9/fonts/font.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
25
arm9/fonts/font.grit
Normal file
25
arm9/fonts/font.grit
Normal file
@ -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
|
||||
|
||||
143
arm9/src/main.c
143
arm9/src/main.c
@ -10,14 +10,14 @@
|
||||
#include "nand/nandfirm.h"
|
||||
#include "video.h"
|
||||
#include "nitrofs.h"
|
||||
#include "font.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
|
||||
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();
|
||||
|
||||
@ -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;
|
||||
|
||||
148
arm9/src/menu.c
148
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];
|
||||
}
|
||||
@ -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
|
||||
@ -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<START> cancel\n");
|
||||
|
||||
while (!programEnd && sequencePosition < sizeof(sequence))
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -18,4 +18,5 @@
|
||||
int fsMain(void);
|
||||
int readMbr(void);
|
||||
int repairMbr(void);
|
||||
int formatMain(void);
|
||||
int formatMain(void);
|
||||
int formatPhoto(void);
|
||||
@ -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;
|
||||
}
|
||||
@ -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);
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user