Revamp CTRNAND support, add proper support for hiding options in config menu

This commit is contained in:
Aurora 2016-10-08 01:46:41 +02:00
parent f005da4d12
commit 37030621ac
19 changed files with 150 additions and 100 deletions

View File

@ -77,7 +77,7 @@ static void loadCustomVerString(u16 *out, u32 *verStringSize, u32 currentNand)
IFile file;
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, paths[currentNand], FS_OPEN_READ)))
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, paths[currentNand], FS_OPEN_READ)) || R_SUCCEEDED(fileOpen(&file, ARCHIVE_NAND_RW, paths[currentNand], FS_OPEN_READ)))
{
u64 fileSize;
@ -135,7 +135,7 @@ static void loadTitleCodeSection(u64 progId, u8 *code, u32 size)
IFile file;
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ)))
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ)) || R_SUCCEEDED(fileOpen(&file, ARCHIVE_NAND_RW, path, FS_OPEN_READ)))
{
u64 fileSize;
@ -159,7 +159,7 @@ static void loadTitleLocaleConfig(u64 progId, u8 *regionId, u8 *languageId)
IFile file;
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ)))
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ)) || R_SUCCEEDED(fileOpen(&file, ARCHIVE_NAND_RW, path, FS_OPEN_READ)))
{
u64 fileSize;

View File

@ -29,18 +29,17 @@
#include "buttons.h"
#include "pin.h"
bool readConfig(bool isSdMounted)
bool readConfig(void)
{
bool ret;
if(!isSdMounted ||
fileRead(&configData, CONFIG_PATH, sizeof(CfgData)) != sizeof(CfgData) ||
if(fileRead(&configData, CONFIG_PATH, sizeof(CfgData)) != sizeof(CfgData) ||
memcmp(configData.magic, "CONF", 4) != 0 ||
configData.formatVersionMajor != CONFIG_VERSIONMAJOR ||
configData.formatVersionMinor != CONFIG_VERSIONMINOR)
{
configData.config = 0;
ret = !isSdMounted;
ret = false;
}
else ret = true;
@ -68,7 +67,7 @@ void writeConfig(ConfigurationStatus needConfig, u32 configTemp)
}
}
void configMenu(bool oldPinStatus, u32 oldPinMode)
void configMenu(Fs fsStatus, bool oldPinStatus, u32 oldPinMode)
{
const char *multiOptionsText[] = { "Default EmuNAND: 1( ) 2( ) 3( ) 4( )",
"Screen brightness: 4( ) 3( ) 2( ) 1( )",
@ -80,7 +79,7 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
const char *singleOptionsText[] = { "( ) Autoboot SysNAND",
"( ) Use SysNAND FIRM if booting with R (A9LH)",
"( ) Enable FIRMs and modules loading from SD",
"( ) Enable loading external FIRMs and modules",
"( ) Use custom path",
"( ) Enable region/language emu. and ext. .code",
"( ) Show NAND or user string in System Settings",
@ -148,8 +147,8 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
"1/2/3/4), also add A if you have\n"
"a matching payload.",
"Enable loading FIRMs and\n"
"system modules from the SD card.\n\n"
"Enable loading external FIRMs and\n"
"system modules.\n\n"
"This isn't needed in most cases.\n\n"
"Refer to the wiki for instructions.",
@ -193,25 +192,37 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
u32 posXs[4];
u32 posY;
u32 enabled;
bool visible;
} multiOptions[] = {
{ .posXs = {19, 24, 29, 34} },
{ .posXs = {21, 26, 31, 36} },
{ .posXs = {12, 22, 31, 0} },
{ .posXs = {14, 19, 24, 29} },
{ .posXs = {17, 26, 32, 44} },
{ .posXs = {19, 30, 42, 0} }
{ .posXs = {19, 24, 29, 34}, .visible = fsStatus == SD_CARD },
{ .posXs = {21, 26, 31, 36}, .visible = true },
{ .posXs = {12, 22, 31, 0}, .visible = true },
{ .posXs = {14, 19, 24, 29}, .visible = true },
{ .posXs = {17, 26, 32, 44}, .visible = isN3DS },
{ .posXs = {19, 30, 42, 0}, .visible = true }
};
//Calculate the amount of the various kinds of options and pre-select the first single one
u32 multiOptionsAmount = sizeof(multiOptions) / sizeof(struct multiOption),
singleOptionsAmount = sizeof(singleOptionsText) / sizeof(char *),
totalIndexes = multiOptionsAmount + singleOptionsAmount - 1,
selectedOption = multiOptionsAmount;
struct singleOption {
u32 posY;
bool enabled;
} singleOptions[singleOptionsAmount];
bool visible;
} singleOptions[] = {
{ .visible = fsStatus == SD_CARD },
{ .visible = fsStatus == SD_CARD },
{ .visible = true },
{ .visible = fsStatus == SD_CARD },
{ .visible = true },
{ .visible = true },
{ .visible = true },
{ .visible = true }
};
//Calculate the amount of the various kinds of options and pre-select the first single one
u32 multiOptionsAmount = sizeof(multiOptions) / sizeof(struct multiOption),
singleOptionsAmount = sizeof(singleOptions) / sizeof(struct singleOption),
totalIndexes = multiOptionsAmount + singleOptionsAmount - 1,
selectedOption = multiOptionsAmount;
while(!singleOptions[selectedOption - multiOptionsAmount].visible) selectedOption++;
//Parse the existing options
for(u32 i = 0; i < multiOptionsAmount; i++)
@ -232,7 +243,7 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
//Display all the multiple choice options in white
for(u32 i = 0; i < multiOptionsAmount; i++)
{
if(!(i == NEWCPU && !isN3DS))
if(multiOptions[i].visible)
{
multiOptions[i].posY = endPos + SPACING_Y;
endPos = drawString(multiOptionsText[i], true, 10, multiOptions[i].posY, COLOR_WHITE);
@ -246,10 +257,13 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
//Display all the normal options in white except for the first one
for(u32 i = 0; i < singleOptionsAmount; i++)
{
singleOptions[i].posY = endPos + SPACING_Y;
endPos = drawString(singleOptionsText[i], true, 10, singleOptions[i].posY, color);
if(singleOptions[i].enabled) drawCharacter(selected, true, 10 + SPACING_X, singleOptions[i].posY, color);
color = COLOR_WHITE;
if(singleOptions[i].visible)
{
singleOptions[i].posY = endPos + SPACING_Y;
endPos = drawString(singleOptionsText[i], true, 10, singleOptions[i].posY, color);
if(singleOptions[i].enabled) drawCharacter(selected, true, 10 + SPACING_X, singleOptions[i].posY, color);
color = COLOR_WHITE;
}
}
drawString(optionsDescription[selectedOption], false, 10, 10, COLOR_WHITE);
@ -270,24 +284,31 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
//Remember the previously selected option
u32 oldSelectedOption = selectedOption;
switch(pressed)
while(true)
{
case BUTTON_UP:
if(!selectedOption) selectedOption = totalIndexes;
else selectedOption = (selectedOption == NEWCPU + 1 && !isN3DS) ? selectedOption - 2 : selectedOption - 1;
break;
case BUTTON_DOWN:
if(selectedOption == totalIndexes) selectedOption = 0;
else selectedOption = (selectedOption == NEWCPU - 1 && !isN3DS) ? selectedOption + 2 : selectedOption + 1;
break;
case BUTTON_LEFT:
selectedOption = 0;
break;
case BUTTON_RIGHT:
selectedOption = totalIndexes;
break;
default:
continue;
switch(pressed)
{
case BUTTON_UP:
selectedOption = !selectedOption ? totalIndexes : selectedOption - 1;
break;
case BUTTON_DOWN:
selectedOption = selectedOption == totalIndexes ? 0 : selectedOption + 1;
break;
case BUTTON_LEFT:
pressed = BUTTON_DOWN;
selectedOption = 0;
break;
case BUTTON_RIGHT:
pressed = BUTTON_UP;
selectedOption = totalIndexes;
break;
}
if(selectedOption < multiOptionsAmount)
{
if(multiOptions[selectedOption].visible) break;
}
else if(singleOptions[selectedOption - multiOptionsAmount].visible) break;
}
if(selectedOption == oldSelectedOption) continue;

View File

@ -28,7 +28,7 @@
#define MULTICONFIG(a) ((configData.config >> (a * 2 + 9)) & 3)
#define BOOTCONFIG(a, b) ((configData.config >> a) & b)
#define CONFIG_PATH "/luma/config.bin"
#define CONFIG_PATH "luma/config.bin"
#define CONFIG_VERSIONMAJOR 1
#define CONFIG_VERSIONMINOR 6
@ -78,6 +78,6 @@ typedef enum ConfigurationStatus
extern CfgData configData;
extern bool isN3DS;
bool readConfig(bool isSdMounted);
bool readConfig(void);
void writeConfig(ConfigurationStatus needConfig, u32 configTemp);
void configMenu(bool oldPinStatus, u32 oldPinMode);
void configMenu(Fs fsStatus, bool oldPinStatus, u32 oldPinMode);

View File

@ -347,6 +347,20 @@ int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf)
return result;
}
int ctrNandWrite(u32 sector, u32 sectorCount, u8 *inbuf)
{
u8 __attribute__((aligned(4))) tmpCtr[sizeof(nandCtr)];
memcpy(tmpCtr, nandCtr, sizeof(nandCtr));
aes_advctr(tmpCtr, ((sector + fatStart) * 0x200) / AES_BLOCK_SIZE, AES_INPUT_BE | AES_INPUT_NORMAL);
//Encrypt
aes_use_keyslot(nandSlot);
aes(inbuf, inbuf, sectorCount * 0x200 / AES_BLOCK_SIZE, tmpCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
//Write
return sdmmc_nand_writesectors(sector + fatStart, sectorCount, inbuf);
}
void set6x7xKeys(void)
{
const u8 __attribute__((aligned(4))) keyX0x25[AES_BLOCK_SIZE] = {0xCE, 0xE7, 0xD8, 0xAB, 0x30, 0xC0, 0x0D, 0xAE, 0x85, 0x0E, 0xF5, 0xE3, 0x82, 0xAC, 0x5A, 0xF3};

View File

@ -107,6 +107,7 @@ extern FirmwareSource firmSource;
void ctrNandInit(void);
int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf);
int ctrNandWrite(u32 sector, u32 sectorCount, u8 *inbuf);
void set6x7xKeys(void);
void decryptExeFs(u8 *inbuf);
void decryptNusFirm(const u8 *inbuf, u8 *outbuf, u32 ncchSize);

View File

@ -34,8 +34,8 @@
bool loadSplash(void)
{
const char topSplashPath[] = "/luma/splash.bin",
bottomSplashPath[] = "/luma/splashbottom.bin";
const char topSplashPath[] = "luma/splash.bin",
bottomSplashPath[] = "luma/splashbottom.bin";
bool isTopSplashValid = getFileSize(topSplashPath) == SCREEN_TOP_FBSIZE,
isBottomSplashValid = getFileSize(bottomSplashPath) == SCREEN_BOTTOM_FBSIZE;

View File

@ -172,9 +172,9 @@ void detectAndProcessExceptionDumps(void)
}
}
char path[42];
char path[41];
char fileName[] = "crash_dump_00000000.dmp";
const char *pathFolder = dumpHeader->processor == 9 ? "/luma/dumps/arm9" : "/luma/dumps/arm11";
const char *pathFolder = dumpHeader->processor == 9 ? "luma/dumps/arm9" : "luma/dumps/arm11";
findDumpFile(pathFolder, fileName);
memcpy(path, pathFolder, strlen(pathFolder) + 1);

View File

@ -87,7 +87,8 @@ DRESULT disk_write (
UINT count /* Number of sectors to write */
)
{
return (pdrv == SDCARD && !sdmmc_sdcard_writesectors(sector, count, (BYTE *)buff)) ? RES_OK : RES_PARERR;
return ((pdrv == SDCARD && !sdmmc_sdcard_writesectors(sector, count, (BYTE *)buff)) ||
(pdrv == CTRNAND && !ctrNandWrite(sector, count, (BYTE *)buff))) ? RES_OK : RES_PARERR;
}
#endif

View File

@ -134,7 +134,7 @@
/ This option has no effect when _LFN_UNICODE == 0. */
#define _FS_RPATH 0
#define _FS_RPATH 1
/* This option configures support of relative path.
/
/ 0: Disable relative path and remove related functions.

View File

@ -244,7 +244,6 @@ int __attribute__((noinline)) sdmmc_nand_readsectors(u32 sector_no, u32 numsecto
return geterror(&handleNAND);
}
/*
int __attribute__((noinline)) sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, const u8 *in) //experimental
{
if(handleNAND.isSDHC == 0) sector_no <<= 9;
@ -259,7 +258,6 @@ int __attribute__((noinline)) sdmmc_nand_writesectors(u32 sector_no, u32 numsect
inittarget(&handleSD);
return geterror(&handleNAND);
}
*/
static u32 calcSDSize(u8 *csd, int type)
{

View File

@ -95,6 +95,6 @@ u32 sdmmc_sdcard_init();
int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, u8 *out);
int sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, const u8 *in);
int sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, u8 *out);
//int sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, const u8 *in);
int sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, const u8 *in);
void sdmmc_get_cid(bool isNand, u32 *info);
mmcdevice *getMMCDevice(int drive);

View File

@ -64,11 +64,17 @@ void main(void)
//Detect dev units
isDevUnit = CFG_UNITINFO != 0;
//Mount SD
bool isSdMounted = mountFs(true);
//Mount SD or CTRNAND
Fs fsStatus;
if(mountFs(true)) fsStatus = SD_CARD;
else
{
firmSource = FIRMWARE_SYSNAND;
fsStatus = (mountFs(false) && switchToCtrNand()) ? CTRNAND : NONE;
}
//Attempt to read the configuration file
needConfig = readConfig(isSdMounted) ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION;
needConfig = readConfig() ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION;
u32 devMode = MULTICONFIG(DEVOPTIONS);
@ -94,6 +100,8 @@ void main(void)
//Determine if booting with A9LH
isA9lh = !PDN_SPI_CNT;
if(fsStatus == NONE) error("Error mounting SD and CTRNAND.");
if(devMode != 0 && isA9lh) detectAndProcessExceptionDumps();
//Get pressed buttons
@ -102,15 +110,8 @@ void main(void)
//Save old options and begin saving the new boot configuration
configTemp = (configData.config & 0xFFFFFE00) | ((u32)isA9lh << 6);
if(!isSdMounted)
{
nandType = FIRMWARE_SYSNAND;
firmSource = FIRMWARE_SYSNAND;
needConfig = DONT_CONFIGURE;
}
//If it's a MCU reboot, try to force boot options
else if(isA9lh && CFG_BOOTENV)
if(isA9lh && CFG_BOOTENV)
{
//Always force a sysNAND boot when quitting AGB_FIRM
if(CFG_BOOTENV == 7)
@ -149,7 +150,7 @@ void main(void)
if(shouldLoadConfigMenu)
{
configMenu(pinExists, pinMode);
configMenu(fsStatus, pinExists, pinMode);
//Update pressed buttons
pressed = HID_PAD;
@ -189,12 +190,14 @@ void main(void)
if(splashMode == 2) loadSplash();
//Determine if the user chose to use the SysNAND FIRM as default for a R boot
bool useSysAsDefault = isA9lh ? CONFIG(USESYSFIRM) : false;
if(fsStatus == CTRNAND) nandType = FIRMWARE_SYSNAND;
//If R is pressed, boot the non-updated NAND with the FIRM of the opposite one
if(pressed & BUTTON_R1)
else if(pressed & BUTTON_R1)
{
//Determine if the user chose to use the SysNAND FIRM as default for a R boot
bool useSysAsDefault = isA9lh ? CONFIG(USESYSFIRM) : false;
nandType = useSysAsDefault ? FIRMWARE_EMUNAND : FIRMWARE_SYSNAND;
firmSource = useSysAsDefault ? FIRMWARE_SYSNAND : FIRMWARE_EMUNAND;
}
@ -248,14 +251,14 @@ void main(void)
else if(firmSource != FIRMWARE_SYSNAND)
locateEmuNand(&emuHeader, &firmSource);
if(isSdMounted && !isFirmlaunch)
if(!isFirmlaunch)
{
configTemp |= (u32)nandType | ((u32)firmSource << 3);
writeConfig(needConfig, configTemp);
}
bool loadFromSd = CONFIG(LOADSDFIRMSANDMODULES);
u32 firmVersion = loadFirm(&firmType, firmSource, loadFromSd, isSdMounted);
u32 firmVersion = loadFirm(&firmType, firmSource, loadFromSd, fsStatus);
switch(firmType)
{
@ -274,24 +277,24 @@ void main(void)
launchFirm(firmType, loadFromSd);
}
static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bool loadFromSd, bool isSdMounted)
static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bool loadFromSd, Fs fsStatus)
{
section = firm->section;
const char *firmwareFiles[] = {
"/luma/firmware.bin",
"/luma/firmware_twl.bin",
"/luma/firmware_agb.bin",
"/luma/firmware_safe.bin"
"luma/firmware.bin",
"luma/firmware_twl.bin",
"luma/firmware_agb.bin",
"luma/firmware_safe.bin"
},
*cetkFiles[] = {
"/luma/cetk",
"/luma/cetk_twl",
"/luma/cetk_agb",
"/luma/cetk_safe"
"luma/cetk",
"luma/cetk_twl",
"luma/cetk_agb",
"luma/cetk_safe"
};
if(!mountFs(false)) error("Error mounting CTRNAND.");
if(fsStatus == SD_CARD && !mountFs(false)) error("Error mounting CTRNAND.");
//Load FIRM from CTRNAND
u32 firmVersion = firmRead(firm, (u32)*firmType);
@ -308,7 +311,7 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bo
if(firmSource != FIRMWARE_SYSNAND)
error("An old unsupported EmuNAND has been detected.\nLuma3DS is unable to boot it.");
if(HID_PAD == SAFE_MODE) error("SAFE_MODE is not supported on 1.x/2.x FIRM.");
if(BOOTCFG_SAFEMODE != 0) error("SAFE_MODE is not supported on 1.x/2.x FIRM.");
*firmType = NATIVE_FIRM1X2X;
}
@ -317,7 +320,7 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bo
else if(firmVersion < 0x25) mustLoadFromSd = true;
}
if(isSdMounted && (loadFromSd || mustLoadFromSd))
if(loadFromSd || mustLoadFromSd)
{
u32 firmSize = fileRead(firm, *firmType == NATIVE_FIRM1X2X ? firmwareFiles[0] : firmwareFiles[(u32)*firmType], 0x400000);
@ -329,12 +332,12 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bo
if(fileRead(cetk, *firmType == NATIVE_FIRM1X2X ? cetkFiles[0] : cetkFiles[(u32)*firmType], sizeof(cetk)) == sizeof(cetk))
decryptNusFirm(cetk, (u8 *)firm, firmSize);
else error("The firmware.bin in /luma is encrypted\nor corrupted.");
else error("The firmware.bin in luma is encrypted\nor corrupted.");
}
//Check that the SD FIRM is right for the console from the ARM9 section address
if((section[3].offset ? section[3].address : section[2].address) != (isN3DS ? (u8 *)0x8006000 : (u8 *)0x8006800))
error("The firmware.bin in /luma is not valid for this\nconsole.");
error("The firmware.bin in luma is not valid for this\nconsole.");
firmVersion = 0xFFFFFFFF;
}
@ -342,7 +345,7 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bo
if(firmVersion != 0xFFFFFFFF)
{
if(mustLoadFromSd) error("An old unsupported FIRM has been detected.\nCopy a firmware.bin in /luma to boot.");
if(mustLoadFromSd) error("An old unsupported FIRM has been detected.\nCopy a firmware.bin in luma to boot.");
decryptExeFs((u8 *)firm);
}
@ -485,7 +488,7 @@ static inline void copySection0AndInjectSystemModules(FirmwareType firmType, boo
if(loadFromSd)
{
char fileName[30] = "/luma/sysmodules/";
char fileName[30] = "luma/sysmodules/";
const char *ext = ".cxi";
//Read modules from files if they exist

View File

@ -47,7 +47,7 @@ typedef struct firmHeader {
firmSectionHeader section[4];
} firmHeader;
static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bool loadFromSd, bool isSdMounted);
static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bool loadFromSd, Fs fsStatus);
static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, u32 devMode);
static inline void patchLegacyFirm(FirmwareType firmType, u32 firmVersion, u32 devMode);
static inline void patch1x2xNativeAndSafeFirm(u32 devMode);

View File

@ -38,6 +38,11 @@ bool mountFs(bool isSd)
return isSd ? f_mount(&sdFs, "0:", 1) == FR_OK : f_mount(&nandFs, "1:", 1) == FR_OK;
}
bool switchToCtrNand(void)
{
return f_chdrive("1:") == FR_OK && f_chdir("/rw") == FR_OK;
}
u32 fileRead(void *dest, const char *path, u32 maxSize)
{
FIL file;
@ -84,11 +89,10 @@ bool fileWrite(const void *buffer, const char *path, u32 size)
char folder[i + 1];
memcpy(folder, path, i);
folder[i] = 0;
ret = f_mkdir(folder) == FR_OK;
if(!ret) break;
f_mkdir(folder);
}
if(ret) ret = fileWrite(buffer, path, size);
ret = fileWrite(buffer, path, size);
}
else ret = false;
@ -118,7 +122,7 @@ void loadPayload(u32 pressed)
DIR dir;
FILINFO info;
char path[28] = "/luma/payloads";
char path[27] = "luma/payloads";
FRESULT result = f_findfirst(&dir, &info, path, pattern);

View File

@ -29,6 +29,7 @@
extern bool isN3DS, isA9lh;
bool mountFs(bool isSd);
bool switchToCtrNand(void);
u32 fileRead(void *dest, const char *path, u32 maxSize);
u32 getFileSize(const char *path);
bool fileWrite(const void *buffer, const char *path, u32 size);

View File

@ -93,7 +93,7 @@ void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr)
if(CONFIG(USECUSTOMPATH))
{
const char pathPath[] = "/luma/path.txt";
const char pathPath[] = "luma/path.txt";
u32 pathSize = getFileSize(pathPath);

View File

@ -132,7 +132,7 @@ bool verifyPin(u32 pinMode)
u8 cnt = 0;
u32 charDrawPos = 16 * SPACING_X;
const char messagePath[] = "/luma/pinmessage.txt";
const char messagePath[] = "luma/pinmessage.txt";
u32 messageSize = getFileSize(messagePath);

View File

@ -28,7 +28,7 @@
#include "types.h"
#define PIN_PATH "/luma/pin.bin"
#define PIN_PATH "luma/pin.bin"
#define PIN_VERSIONMAJOR 1
#define PIN_VERSIONMINOR 3

View File

@ -55,4 +55,11 @@ typedef enum FirmwareType
AGB_FIRM,
SAFE_FIRM,
NATIVE_FIRM1X2X
} FirmwareType;
} FirmwareType;
typedef enum Fs
{
SD_CARD = 0,
CTRNAND,
NONE
} Fs;