diff --git a/source/draw.c b/source/draw.c index fed337e..ca2b83d 100644 --- a/source/draw.c +++ b/source/draw.c @@ -9,12 +9,7 @@ #include "font.h" #include "draw.h" -#include "fs.h" -#ifdef USE_THEME -#include "theme.h" -#endif - -static char debugstr[DBG_N_CHARS_X * DBG_N_CHARS_Y] = { 0 }; +// #include "fs.h" void ClearScreen(u8* screen, int width, int color) { @@ -26,15 +21,15 @@ void ClearScreen(u8* screen, int width, int color) } } -void ClearScreenFull(bool clear_top, bool clear_bottom) +void ClearScreenFull(bool clear_top, bool clear_bottom, int color) { if (clear_top) { - ClearScreen(TOP_SCREEN0, SCREEN_WIDTH_TOP, STD_COLOR_BG); - ClearScreen(TOP_SCREEN1, SCREEN_WIDTH_TOP, STD_COLOR_BG); + ClearScreen(TOP_SCREEN0, SCREEN_WIDTH_TOP, color); + ClearScreen(TOP_SCREEN1, SCREEN_WIDTH_TOP, color); } if (clear_bottom) { - ClearScreen(BOT_SCREEN0, SCREEN_WIDTH_BOT, STD_COLOR_BG); - ClearScreen(BOT_SCREEN1, SCREEN_WIDTH_BOT, STD_COLOR_BG); + ClearScreen(BOT_SCREEN0, SCREEN_WIDTH_BOT, color); + ClearScreen(BOT_SCREEN1, SCREEN_WIDTH_BOT, color); } } @@ -67,7 +62,7 @@ void DrawString(u8* screen, const char *str, int x, int y, int color, int bgcolo DrawCharacter(screen, str[i], x + i * 8, y, color, bgcolor); } -void DrawStringF(int x, int y, bool use_top, const char *format, ...) +void DrawStringF(bool use_top, int x, int y, int color, int bgcolor, const char *format, ...) { char str[512] = {}; // 512 should be more than enough va_list va; @@ -78,16 +73,16 @@ void DrawStringF(int x, int y, bool use_top, const char *format, ...) for (char* text = strtok(str, "\n"); text != NULL; text = strtok(NULL, "\n"), y += 10) { if (use_top) { - DrawString(TOP_SCREEN0, text, x, y, STD_COLOR_FONT, STD_COLOR_BG); - DrawString(TOP_SCREEN1, text, x, y, STD_COLOR_FONT, STD_COLOR_BG); + DrawString(TOP_SCREEN0, text, x, y, color, bgcolor); + DrawString(TOP_SCREEN1, text, x, y, color, bgcolor); } else { - DrawString(BOT_SCREEN0, text, x, y, STD_COLOR_FONT, STD_COLOR_BG); - DrawString(BOT_SCREEN1, text, x, y, STD_COLOR_FONT, STD_COLOR_BG); + DrawString(BOT_SCREEN0, text, x, y, color, bgcolor); + DrawString(BOT_SCREEN1, text, x, y, color, bgcolor); } } } -void Screenshot(const char* path) +/*void Screenshot(const char* path) { u8* buffer = (u8*) 0x21000000; // careful, this area is used by other functions in Decrypt9 u8* buffer_t = buffer + (400 * 240 * 3); @@ -125,66 +120,22 @@ void Screenshot(const char* path) FileWrite(bmp_header, 54, 0); FileWrite(buffer, 400 * 240 * 3 * 2, 54); FileClose(); -} +}*/ -void DebugClear() +void ShowError(const char *format, ...) { - memset(debugstr, 0x00, DBG_N_CHARS_X * DBG_N_CHARS_Y); - ClearScreen(TOP_SCREEN0, SCREEN_WIDTH_TOP, DBG_COLOR_BG); - ClearScreen(TOP_SCREEN1, SCREEN_WIDTH_TOP, DBG_COLOR_BG); - #if defined USE_THEME && defined GFX_DEBUG_BG - LoadThemeGfx(GFX_DEBUG_BG, true); - #endif - LogWrite(""); - LogWrite(NULL); -} - -void DebugSet(const char **strs) -{ - if (strs != NULL) for (int y = 0; y < DBG_N_CHARS_Y; y++) { - int pos_dbgstr = DBG_N_CHARS_X * (DBG_N_CHARS_Y - 1 - y); - snprintf(debugstr + pos_dbgstr, DBG_N_CHARS_X, "%-*.*s", DBG_N_CHARS_X - 1, DBG_N_CHARS_X - 1, strs[y]); - } - - int pos_y = DBG_START_Y; - for (char* str = debugstr + (DBG_N_CHARS_X * (DBG_N_CHARS_Y - 1)); str >= debugstr; str -= DBG_N_CHARS_X) { - if (str[0] != '\0') { - DrawString(TOP_SCREEN0, str, DBG_START_X, pos_y, DBG_COLOR_FONT, DBG_COLOR_BG); - DrawString(TOP_SCREEN1, str, DBG_START_X, pos_y, DBG_COLOR_FONT, DBG_COLOR_BG); - pos_y += DBG_STEP_Y; - } - } -} - -void Debug(const char *format, ...) -{ - static bool adv_output = true; - char tempstr[128] = { 0 }; // 128 instead of DBG_N_CHARS_X for log file + char str[128] = {}; // 128 should be more than enough va_list va; - + va_start(va, format); - vsnprintf(tempstr, 128, format, va); + vsnprintf(str, 128, format, va); va_end(va); - if (adv_output) { - memmove(debugstr + DBG_N_CHARS_X, debugstr, DBG_N_CHARS_X * (DBG_N_CHARS_Y - 1)); - } else { - adv_output = true; - } - - if (*tempstr != '\r') { // not a good way of doing this - improve this later - snprintf(debugstr, DBG_N_CHARS_X, "%-*.*s", DBG_N_CHARS_X - 1, DBG_N_CHARS_X - 1, tempstr); - LogWrite(tempstr); - } else { - snprintf(debugstr, DBG_N_CHARS_X, "%-*.*s", DBG_N_CHARS_X - 1, DBG_N_CHARS_X - 1, tempstr + 1); - adv_output = false; - } - - DebugSet(NULL); + ClearScreenFull(true, false, COLOR_BLACK); + DrawStringF(true, 80, 80, COLOR_WHITE, COLOR_BLACK, str); } -#if !defined(USE_THEME) || !defined(ALT_PROGRESS) -void ShowProgress(u64 current, u64 total) +/*void ShowProgress(u64 current, u64 total) { const u32 progX = SCREEN_WIDTH_TOP - 40; const u32 progY = SCREEN_HEIGHT - 20; @@ -198,5 +149,4 @@ void ShowProgress(u64 current, u64 total) DrawString(TOP_SCREEN0, " ", progX, progY, DBG_COLOR_FONT, DBG_COLOR_BG); DrawString(TOP_SCREEN1, " ", progX, progY, DBG_COLOR_FONT, DBG_COLOR_BG); } -} -#endif +}*/ diff --git a/source/draw.h b/source/draw.h index 5d25819..2094f98 100644 --- a/source/draw.h +++ b/source/draw.h @@ -17,23 +17,6 @@ #define COLOR_WHITE RGB(0xFF, 0xFF, 0xFF) #define COLOR_TRANSPARENT RGB(0xFF, 0x00, 0xEF) // otherwise known as 'super fuchsia' -#ifndef USE_THEME -#define STD_COLOR_BG COLOR_BLACK -#define STD_COLOR_FONT COLOR_WHITE - -#define DBG_COLOR_BG COLOR_BLACK -#define DBG_COLOR_FONT COLOR_WHITE - -#define DBG_START_Y 10 -#define DBG_END_Y (SCREEN_HEIGHT - 10) -#define DBG_START_X 10 -#define DBG_END_X (SCREEN_WIDTH_TOP - 10) -#define DBG_STEP_Y 10 -#endif - -#define DBG_N_CHARS_Y ((DBG_END_Y - DBG_START_Y) / DBG_STEP_Y) -#define DBG_N_CHARS_X (((DBG_END_X - DBG_START_X) / 8) + 1) - #ifdef EXEC_GATEWAY #define TOP_SCREEN0 (u8*)(*(u32*)((uint32_t)0x080FFFC0 + 4 * (*(u32*)0x080FFFD8 & 1))) #define BOT_SCREEN0 (u8*)(*(u32*)((uint32_t)0x080FFFD0 + 4 * (*(u32*)0x080FFFDC & 1))) @@ -49,15 +32,13 @@ #endif void ClearScreen(unsigned char *screen, int width, int color); -void ClearScreenFull(bool clear_top, bool clear_bottom); +void ClearScreenFull(bool clear_top, bool clear_bottom, int color); void DrawCharacter(unsigned char *screen, int character, int x, int y, int color, int bgcolor); void DrawString(unsigned char *screen, const char *str, int x, int y, int color, int bgcolor); -void DrawStringF(int x, int y, bool use_top, const char *format, ...); +void DrawStringF(bool use_top, int x, int y, int color, int bgcolor, const char *format, ...); void Screenshot(const char* path); -void DebugClear(); -void DebugSet(const char **strs); -void Debug(const char *format, ...); +void ShowError(const char *format, ...); void ShowProgress(u64 current, u64 total); diff --git a/source/fatfs/diskio.c b/source/fatfs/diskio.c index 5711845..c8c219c 100644 --- a/source/fatfs/diskio.c +++ b/source/fatfs/diskio.c @@ -10,7 +10,7 @@ #include "diskio.h" /* FatFs lower layer API */ #include "platform.h" #include "sdmmc.h" -#include "3dsnand.h" +#include "nandio.h" #define TYPE_SDCARD 0 #define TYPE_SYSNAND 1 @@ -53,6 +53,7 @@ FATpartition DriveInfo[28] = { { 0xC00000, TYPE_EMUNAND, P_TWLP } // 27 - EMUNAND3 N3DS TWLP }; +static bool mode_n3ds = false; /*-----------------------------------------------------------------------*/ @@ -78,6 +79,7 @@ DSTATUS disk_initialize ( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { + mode_n3ds = (GetUnitPlatform() == PLATFORM_N3DS); sdmmc_sdcard_init(); return RES_OK; } @@ -96,6 +98,9 @@ DRESULT disk_read ( UINT count /* Number of sectors to read */ ) { + if ((pdrv >= 4) && mode_n3ds) + pdrv += 12; + if (DriveInfo[pdrv].type == TYPE_SDCARD) { if (sdmmc_sdcard_readsectors(sector, count, buff)) { return RES_PARERR; @@ -127,6 +132,9 @@ DRESULT disk_write ( UINT count /* Number of sectors to write */ ) { + if ((pdrv >= 4) && mode_n3ds) + pdrv += 12; + if (DriveInfo[pdrv].type == TYPE_SDCARD) { if (sdmmc_sdcard_writesectors(sector, count, (BYTE *)buff)) { return RES_PARERR; @@ -161,6 +169,9 @@ DRESULT disk_ioctl ( void *buff /* Buffer to send/receive control data */ ) { + if ((pdrv >= 4) && mode_n3ds) + pdrv += 12; + switch (cmd) { case GET_SECTOR_SIZE: *((DWORD*) buff) = 0x200; diff --git a/source/fatfs/3dsnand.c b/source/fatfs/nandio.c similarity index 95% rename from source/fatfs/3dsnand.c rename to source/fatfs/nandio.c index 665d8be..b3bb101 100644 --- a/source/fatfs/3dsnand.c +++ b/source/fatfs/nandio.c @@ -1,6 +1,6 @@ #include "platform.h" #include "fatfs/aes.h" -#include "fatfs/3dsnand.h" +#include "fatfs/nandio.h" #include "fatfs/sdmmc.h" // see: http://3dbrew.org/wiki/Flash_Filesystem @@ -20,25 +20,25 @@ static u32 emunand_offset = 0; u32 CheckEmuNand(void) { - u8* buffer = BUFFER_ADDRESS; + u8 header[0x200]; u32 nand_size_sectors = getMMCDevice(0)->total_size; u32 multi_sectors = (GetUnitPlatform() == PLATFORM_3DS) ? EMUNAND_MULTI_OFFSET_O3DS : EMUNAND_MULTI_OFFSET_N3DS; u32 ret = EMUNAND_NOT_READY; // check the MBR for presence of a hidden partition - sdmmc_sdcard_readsectors(0, 1, buffer); - u32 hidden_sectors = getle32(buffer + 0x1BE + 0x8); + sdmmc_sdcard_readsectors(0, 1, header); + u32 hidden_sectors = getle32(header + 0x1BE + 0x8); for (u32 offset_sector = 0; offset_sector + nand_size_sectors < hidden_sectors; offset_sector += multi_sectors) { // check for Gateway type EmuNAND - sdmmc_sdcard_readsectors(offset_sector + nand_size_sectors, 1, buffer); - if (memcmp(buffer + 0x100, "NCSD", 4) == 0) { + sdmmc_sdcard_readsectors(offset_sector + nand_size_sectors, 1, header); + if (memcmp(header + 0x100, "NCSD", 4) == 0) { ret |= EMUNAND_GATEWAY << (2 * (offset_sector / multi_sectors)); continue; } // check for RedNAND type EmuNAND - sdmmc_sdcard_readsectors(offset_sector + 1, 1, buffer); - if (memcmp(buffer + 0x100, "NCSD", 4) == 0) { + sdmmc_sdcard_readsectors(offset_sector + 1, 1, header); + if (memcmp(header + 0x100, "NCSD", 4) == 0) { ret |= EMUNAND_REDNAND << (2 * (offset_sector / multi_sectors)); continue; } diff --git a/source/fatfs/3dsnand.h b/source/fatfs/nandio.h similarity index 100% rename from source/fatfs/3dsnand.h rename to source/fatfs/nandio.h diff --git a/source/fs.c b/source/fs.c index f7aeadc..73864e6 100644 --- a/source/fs.c +++ b/source/fs.c @@ -1,226 +1,74 @@ -#include "fs.h" #include "draw.h" - +#include "fs.h" #include "fatfs/ff.h" +#include "fatfs/nandio.h" -static FATFS fs; -static FIL file; -static DIR dir; +// don't use this area for anything else! +static FATFS* fs = (FATFS*) 0x20316000; +// reserve one MB for this, just to be safe +static DirStruct* curdir_contents = (DirStruct*)0x21000000; +// this is the main buffer +// static u8* main_buffer = (u8*)0x21100000; +// number of currently open file systems +static u32 numfs = 0; bool InitFS() { -#ifndef EXEC_GATEWAY + #ifndef EXEC_GATEWAY // TODO: Magic? *(u32*)0x10000020 = 0; *(u32*)0x10000020 = 0x340; -#endif - bool ret = (f_mount(&fs, "0:", 0) == FR_OK); -#ifdef WORK_DIR - f_chdir(WORK_DIR); -#endif - return ret; + #endif + u32 emunand_state = CheckEmuNand(); + for (numfs = 0; numfs < 16; numfs++) { + char fsname[8]; + snprintf(fsname, 7, "%lu:", numfs); + if ((numfs >= 4) && (emunand_state >> (2*((numfs-4)/3)) != EMUNAND_GATEWAY)) + break; + if (f_mount(fs, fsname, 0) != FR_OK) { + ShowError("Initialising failed! (%lu/%s)", numfs, fsname); + DeinitFS(); + return false; + } + } + return true; } void DeinitFS() { - LogWrite(NULL); - f_mount(NULL, "0:", 1); + for (u32 i = 0; i < numfs; i++) { + char fsname[8]; + snprintf(fsname, 7, "%lu:", numfs); + f_mount(NULL, fsname, 1); + } + numfs = 0; } -bool FileOpen(const char* path) +bool GetRootDirContentsWorker(DirStruct* contents) { - unsigned flags = FA_READ | FA_WRITE | FA_OPEN_EXISTING; - if (*path == '/') - path++; - bool ret = (f_open(&file, path, flags) == FR_OK); - #ifdef WORK_DIR - f_chdir("/"); // temporarily change the current directory - if (!ret) ret = (f_open(&file, path, flags) == FR_OK); - f_chdir(WORK_DIR); - #endif - f_lseek(&file, 0); - f_sync(&file); - return ret; -} - -bool DebugFileOpen(const char* path) -{ - Debug("Opening %s ...", path); - if (!FileOpen(path)) { - Debug("Could not open %s!", path); - return false; + static const char* drvname[16] = { + "sdcard", + "sysctrn", "systwln", "systwlp", + "emu0ctrn", "emu0twln", "emu0twlp", + "emu1ctrn", "emu1twln", "emu1twlp", + "emu2ctrn", "emu2twln", "emu2twlp", + "emu3ctrn", "emu3twln", "emu3twlp" + }; + + for (u32 pdrv = 0; (pdrv < numfs) && (pdrv < MAX_ENTRIES); pdrv++) { + memset(contents->entry[pdrv].path, 0x00, 16); + snprintf(contents->entry[pdrv].path + 0, 4, "%lu:", pdrv); + snprintf(contents->entry[pdrv].path + 4, 4, "%s", drvname[pdrv]); + contents->entry[pdrv].name = contents->entry[pdrv].path + 4; + contents->entry[pdrv].size = 0; + contents->entry[pdrv].type = T_FAT_ROOT; + contents->n_entries = pdrv; } - return true; + return contents->n_entries; } -bool FileCreate(const char* path, bool truncate) -{ - unsigned flags = FA_READ | FA_WRITE; - flags |= truncate ? FA_CREATE_ALWAYS : FA_OPEN_ALWAYS; - if (*path == '/') - path++; - bool ret = (f_open(&file, path, flags) == FR_OK); - f_lseek(&file, 0); - f_sync(&file); - return ret; -} - -bool DebugFileCreate(const char* path, bool truncate) { - Debug("Creating %s ...", path); - if (!FileCreate(path, truncate)) { - Debug("Could not create %s!", path); - return false; - } - - return true; -} - -size_t FileCopyTo(const char* dest, void* buf, size_t bufsize) -{ - unsigned flags = FA_READ | FA_WRITE | FA_CREATE_ALWAYS; - size_t fsize = f_size(&file); - size_t result = fsize; - FIL dfile; - // make sure the containing folder exists - char tmp[256] = { 0 }; - strncpy(tmp, dest, sizeof(tmp) - 1); - for (char* p = tmp + 1; *p; p++) { - if (*p == '/') { - char s = *p; - *p = 0; - f_mkdir(tmp); - *p = s; - } - } - // do the actual copying - if (f_open(&dfile, dest, flags) != FR_OK) - return 0; - f_lseek(&dfile, 0); - f_sync(&dfile); - f_lseek(&file, 0); - f_sync(&file); - for (size_t pos = 0; pos < fsize; pos += bufsize) { - UINT bytes_read = 0; - UINT bytes_written = 0; - ShowProgress(pos, fsize); - f_read(&file, buf, bufsize, &bytes_read); - f_write(&dfile, buf, bytes_read, &bytes_written); - if (bytes_read != bytes_written) { - result = 0; - } - } - ShowProgress(0, 0); - f_close(&dfile); - return result; -} - -size_t FileRead(void* buf, size_t size, size_t foffset) -{ - UINT bytes_read = 0; - f_lseek(&file, foffset); - f_read(&file, buf, size, &bytes_read); - return bytes_read; -} - -bool DebugFileRead(void* buf, size_t size, size_t foffset) { - size_t bytesRead = FileRead(buf, size, foffset); - if(bytesRead != size) { - Debug("ERROR, file is too small!"); - return false; - } - - return true; -} - -size_t FileWrite(void* buf, size_t size, size_t foffset) -{ - UINT bytes_written = 0; - f_lseek(&file, foffset); - f_write(&file, buf, size, &bytes_written); - f_sync(&file); - return bytes_written; -} - -bool DebugFileWrite(void* buf, size_t size, size_t foffset) -{ - size_t bytesWritten = FileWrite(buf, size, foffset); - if(bytesWritten != size) { - Debug("ERROR, SD card may be full!"); - return false; - } - - return true; -} - -size_t FileGetSize() -{ - return f_size(&file); -} - -void FileClose() -{ - f_close(&file); -} - -bool DirMake(const char* path) -{ - FRESULT res = f_mkdir(path); - bool ret = (res == FR_OK) || (res == FR_EXIST); - return ret; -} - -bool DebugDirMake(const char* path) -{ - Debug("Creating dir %s ...", path); - if (!DirMake(path)) { - Debug("Could not create %s!", path); - return false; - } - - return true; -} - -bool DirOpen(const char* path) -{ - return (f_opendir(&dir, path) == FR_OK); -} - -bool DebugDirOpen(const char* path) -{ - Debug("Opening %s ...", path); - if (!DirOpen(path)) { - Debug("Could not open %s!", path); - return false; - } - - return true; -} - -bool DirRead(char* fname, int fsize) -{ - FILINFO fno; - fno.lfname = fname; - fno.lfsize = fsize; - bool ret = false; - while (f_readdir(&dir, &fno) == FR_OK) { - if (fno.fname[0] == 0) break; - if ((fno.fname[0] != '.') && !(fno.fattrib & AM_DIR)) { - if (fname[0] == 0) - strcpy(fname, fno.fname); - ret = true; - break; - } - } - return ret; -} - -void DirClose() -{ - f_closedir(&dir); -} - -bool GetFileListWorker(char** list, int* lsize, char* fpath, int fsize, bool recursive, bool inc_files, bool inc_dirs) +bool GetDirContentsWorker(DirStruct* contents, char* fpath, int fsize, bool recursive) { DIR pdir; FILINFO fno; @@ -241,13 +89,23 @@ bool GetFileListWorker(char** list, int* lsize, char* fpath, int fsize, bool rec if (fno.fname[0] == 0) { ret = true; break; - } else if ((inc_files && !(fno.fattrib & AM_DIR)) || (inc_dirs && (fno.fattrib & AM_DIR))) { - snprintf(*list, *lsize, "%s\n", fpath); - for(;(*list)[0] != '\0' && (*lsize) > 1; (*list)++, (*lsize)--); - if ((*lsize) <= 1) break; + } else { + DirEntry* entry = &(contents->entry[contents->n_entries]); + snprintf(entry->path, 256, "%s", fpath); + entry->name = entry->path + (fpath - fname); + if (fno.fattrib & AM_DIR) { + entry->type = T_FAT_DIR; + entry->size = 0; + } else { + entry->type = T_FAT_FILE; + entry->size = fno.fsize; + } + contents->n_entries++; + if (contents->n_entries >= MAX_ENTRIES) + break; } if (recursive && (fno.fattrib & AM_DIR)) { - if (!GetFileListWorker(list, lsize, fpath, fsize, recursive, inc_files, inc_dirs)) + if (!GetDirContentsWorker(contents, fpath, fsize, recursive)) break; } } @@ -256,53 +114,23 @@ bool GetFileListWorker(char** list, int* lsize, char* fpath, int fsize, bool rec return ret; } -bool GetFileList(const char* path, char* list, int lsize, bool recursive, bool inc_files, bool inc_dirs) +DirStruct* GetDirContents(const char* path) { - char fpath[256]; // 256 is the maximum length of a full path - strncpy(fpath, path, 256); - return GetFileListWorker(&list, &lsize, fpath, 256, recursive, inc_files, inc_dirs); -} - -size_t LogWrite(const char* text) -{ - #ifdef LOG_FILE - static FIL lfile; - static bool lready = false; - static size_t lstart = 0; - - if ((text == NULL) && lready) { - f_sync(&lfile); - f_close(&lfile); - lready = false; - return lstart; // return the current log start - } else if (text == NULL) { - return 0; + curdir_contents->n_entries = 0; + if (strncmp(path, "", 256) == 0) { // root directory + if (!GetRootDirContentsWorker(curdir_contents)) + curdir_contents->n_entries = 0; // not required, but so what? + } else { + char fpath[256]; // 256 is the maximum length of a full path + strncpy(fpath, path, 256); + if (!GetDirContentsWorker(curdir_contents, fpath, 256, false)) + curdir_contents->n_entries = 0; } - if (!lready) { - unsigned flags = FA_READ | FA_WRITE | FA_OPEN_ALWAYS; - lready = (f_open(&lfile, LOG_FILE, flags) == FR_OK); - if (!lready) return 0; - lstart = f_size(&lfile); - f_lseek(&lfile, lstart); - f_sync(&lfile); - } - - const char newline = '\n'; - UINT bytes_written; - UINT tlen = strnlen(text, 128); - f_write(&lfile, text, tlen, &bytes_written); - if (bytes_written != tlen) return 0; - f_write(&lfile, &newline, 1, &bytes_written); - if (bytes_written != 1) return 0; - - return f_size(&lfile); // return the current position - #else - return 0; - #endif + return curdir_contents; } -static uint64_t ClustersToBytes(FATFS* fs, DWORD clusters) +/*static uint64_t ClustersToBytes(FATFS* fs, DWORD clusters) { uint64_t sectors = clusters * fs->csize; #if _MAX_SS != _MIN_SS @@ -326,4 +154,4 @@ uint64_t RemainingStorageSpace() uint64_t TotalStorageSpace() { return ClustersToBytes(&fs, fs.n_fatent - 2); -} +}*/ diff --git a/source/fs.h b/source/fs.h index baf766e..fa92060 100644 --- a/source/fs.h +++ b/source/fs.h @@ -3,71 +3,35 @@ #include "common.h" typedef enum { - T_NAND_BASE, - T_NONFAT_ROOT, + T_NAND_BASE, // might not be needed + T_NONFAT_ROOT, // might not be needed T_FAT_ROOT, T_FAT_FILE, T_FAT_DIR } EntryType; +#define MAX_ENTRIES 1024 + typedef struct { char* name; // should point to the correct portion of the path char path[256]; u32 size; - u32 offset; - EntryType entryType; + EntryType type; } DirEntry; +typedef struct { + u32 n_entries; + DirEntry entry[MAX_ENTRIES]; +} DirStruct; + bool InitFS(); void DeinitFS(); -/** Opens existing files */ -bool FileOpen(const char* path); -bool DebugFileOpen(const char* path); - -/** Opens new files (and creates them if they don't already exist) */ -bool FileCreate(const char* path, bool truncate); -bool DebugFileCreate(const char* path, bool truncate); - -/** Copies currently opened file to destination (must provide buffer) */ -size_t FileCopyTo(const char* dest, void* buf, size_t bufsize); - -/** Reads contents of the opened file */ -size_t FileRead(void* buf, size_t size, size_t foffset); -bool DebugFileRead(void* buf, size_t size, size_t foffset); - -/** Writes to the opened file */ -size_t FileWrite(void* buf, size_t size, size_t foffset); -bool DebugFileWrite(void* buf, size_t size, size_t foffset); - -/** Gets the size of the opened file */ -size_t FileGetSize(); - -/** Creates a directory */ -bool DirMake(const char* path); -bool DebugDirMake(const char* path); - -/** Opens an existing directory */ -bool DirOpen(const char* path); -bool DebugDirOpen(const char* path); - -/** Reads next file name to fname from opened directory, - returns false if all files in directory are processed. - fname needs to be allocated to fsize bytes minimum. */ -bool DirRead(char* fname, int fsize); - -/** Get list of files under a given path **/ -bool GetFileList(const char* path, char* list, int lsize, bool recursive, bool inc_files, bool inc_dirs); - -/** Writes text to a constantly open log file **/ -size_t LogWrite(const char* text); +/** Get directory content under a given path **/ +DirStruct* GetDirContents(const char* path); /** Gets remaining space on SD card in bytes */ uint64_t RemainingStorageSpace(); /** Gets total space on SD card in bytes */ uint64_t TotalStorageSpace(); - -void FileClose(); - -void DirClose(); diff --git a/source/godmode.c b/source/godmode.c new file mode 100644 index 0000000..32bd239 --- /dev/null +++ b/source/godmode.c @@ -0,0 +1,49 @@ +#include "godmode.h" +#include "draw.h" +#include "hid.h" +#include "fs.h" + +void DrawDirContents(DirStruct* contents, u32 offset, u32 cursor) { + const int str_width = 38; + const u32 stp_y = 10; + const u32 pos_x = 10; + u32 pos_y = 10; + + for (u32 i = 0; pos_y < SCREEN_HEIGHT; i++) { + char tempstr[str_width + 1]; + u32 offset_i = offset + i; + u32 color_font; + u32 color_bg; + if (offset_i < contents->n_entries) { + color_font = COLOR_WHITE; + color_bg = COLOR_BLACK; + snprintf(tempstr, str_width + 1, "%-*.*s", str_width, str_width, contents->entry[offset_i].name); + } else { + color_font = COLOR_BLACK; + color_bg = COLOR_WHITE; + snprintf(tempstr, str_width + 1, "%-*.*s", str_width, str_width, ""); + } + DrawStringF(false, pos_x, pos_y, color_font, color_bg, tempstr); + pos_y += stp_y; + } +} + +u32 GodMode() { + u32 exit_mode = GODMODE_EXIT_REBOOT; + DirStruct* contents; + + ClearScreenFull(true, true, COLOR_BLACK); + if (!InitFS()) { + // ShowError("Could not initialize fs!"); + InputWait(); + return exit_mode; + } + + contents = GetDirContents(""); + DrawDirContents(contents, 0, 0); + InputWait(); + + DeinitFS(); + + return exit_mode; +} diff --git a/source/godmode.h b/source/godmode.h new file mode 100644 index 0000000..cca5140 --- /dev/null +++ b/source/godmode.h @@ -0,0 +1,8 @@ +#pragma once + +#include "common.h" + +#define GODMODE_EXIT_REBOOT 0 +#define GODMODE_EXIT_POWEROFF 1 + +u32 GodMode(); diff --git a/source/main.c b/source/main.c index 7a2917a..d278b13 100644 --- a/source/main.c +++ b/source/main.c @@ -1,4 +1,5 @@ #include "common.h" +#include "godmode.h" #include "draw.h" #include "fs.h" #include "i2c.h" @@ -19,12 +20,6 @@ void PowerOff() int main() { - ClearScreenFull(true, true); - InitFS(); - - u32 godmode_exit = 0; - - DeinitFS(); - (godmode_exit == 0) ? Reboot() : PowerOff(); + (GodMode() == GODMODE_EXIT_REBOOT) ? Reboot() : PowerOff(); return 0; }