Initial Commit

This commit is contained in:
2026-03-05 20:18:29 +01:00
commit 5a4d3ee8e0
901 changed files with 296682 additions and 0 deletions

View File

@@ -0,0 +1,191 @@
#include "fscopy.h"
#include <libs/fatfs/ff.h>
#include <utils/btn.h>
#include "../tegraexplorer/tconf.h"
#include "../gfx/gfx.h"
#include <mem/heap.h>
#include <string.h>
#include "../gfx/gfxutils.h"
#include "fsutils.h"
#include "readers/folderReader.h"
ErrCode_t FileCopy(const char *locin, const char *locout, u8 options){
FIL in, out;
FILINFO in_info;
u64 sizeRemaining, toCopy;
u8 *buff;
u32 x, y;
ErrCode_t err = newErrCode(0);
int res = 0;
gfx_con_getpos(&x, &y);
if (!strcmp(locin, locout)){
return newErrCode(TE_ERR_SAME_LOC);
}
if ((res = f_open(&in, locin, FA_READ | FA_OPEN_EXISTING))){
return newErrCode(res);
}
if ((res = f_stat(locin, &in_info))){
return newErrCode(res);
}
if ((res = f_open(&out, locout, FA_CREATE_ALWAYS | FA_WRITE))){
return newErrCode(res);
}
if (options & COPY_MODE_PRINT){
gfx_printf("[ 0%%]");
x += 16;
}
buff = malloc(TConf.FSBuffSize);
sizeRemaining = f_size(&in);
const u64 totalsize = sizeRemaining;
while (sizeRemaining > 0){
toCopy = MIN(sizeRemaining, TConf.FSBuffSize);
if ((res = f_read(&in, buff, toCopy, NULL))){
err = newErrCode(res);
break;
}
if ((res = f_write(&out, buff, toCopy, NULL))){
err = newErrCode(res);
break;
}
sizeRemaining -= toCopy;
if (options & COPY_MODE_PRINT){
gfx_con_setpos(x, y);
gfx_printf("%3d%%", (u32)(((totalsize - sizeRemaining) * 100) / totalsize));
}
if (options & COPY_MODE_CANCEL && btn_read() & (BTN_VOL_DOWN | BTN_VOL_UP)){
f_unlink(locout);
break;
}
}
f_close(&in);
f_close(&out);
free(buff);
f_chmod(locout, in_info.fattrib, 0x3A);
if (options & COPY_MODE_PRINT){
gfx_con_setpos(x - 16, y);
}
//f_stat(locin, &in_info); //somehow stops fatfs from being weird
return err;
}
void BoxRestOfScreen(){
u32 tempX, tempY;
gfx_con_getpos(&tempX, &tempY);
gfx_boxGrey(tempX, tempY, YLEFT, tempY + 16, 0x1B);
}
ErrCode_t FolderCopy(const char *locin, const char *locout){
if (TConf.explorerCopyMode >= CMODE_CopyFolder){
if (strstr(locout, locin) != NULL)
return newErrCode(TE_ERR_PATH_IN_PATH);
}
if (!strcmp(locin, locout)){
return newErrCode(TE_ERR_SAME_LOC);
}
char *dstPath = CombinePaths(locout, strrchr(locin, '/') + 1);
int res = 0;
ErrCode_t ret = newErrCode(0);
u32 x, y;
gfx_con_getpos(&x, &y);
Vector_t fileVec = ReadFolder(locin, &res);
if (res){
ret = newErrCode(res);
}
else {
vecDefArray(FSEntry_t *, fs, fileVec);
f_mkdir(dstPath);
for (int i = 0; i < fileVec.count && !ret.err; i++){
char *temp = CombinePaths(locin, fs[i].name);
if (fs[i].isDir){
ret = FolderCopy(temp, dstPath);
}
else {
gfx_puts_limit(fs[i].name, (YLEFT - x) / 16 - 10);
BoxRestOfScreen();
char *tempDst = CombinePaths(dstPath, fs[i].name);
ret = FileCopy(temp, tempDst, COPY_MODE_PRINT);
free(tempDst);
gfx_con_setpos(x, y);
}
free(temp);
}
}
FILINFO fno;
if (!ret.err){
res = f_stat(locin, &fno);
if (res)
ret = newErrCode(res);
else
ret = newErrCode(f_chmod(dstPath, fno.fattrib, 0x3A));
}
free(dstPath);
clearFileVector(&fileVec);
return ret;
}
ErrCode_t FolderDelete(const char *path){
int res = 0;
ErrCode_t ret = newErrCode(0);
u32 x, y;
gfx_con_getpos(&x, &y);
Vector_t fileVec = ReadFolder(path, &res);
if (res){
ret = newErrCode(res);
}
else {
vecDefArray(FSEntry_t *, fs, fileVec);
for (int i = 0; i < fileVec.count && !ret.err; i++){
char *temp = CombinePaths(path, fs[i].name);
if (fs[i].isDir){
ret = FolderDelete(temp);
}
else {
gfx_puts_limit(fs[i].name, (YLEFT - x) / 16 - 10);
BoxRestOfScreen();
res = f_unlink(temp);
if (res){
ret = newErrCode(res);
}
gfx_con_setpos(x, y);
}
free(temp);
}
}
if (!ret.err){
res = f_unlink(path);
if (res)
ret = newErrCode(res);
}
clearFileVector(&fileVec);
return ret;
}

View File

@@ -0,0 +1,10 @@
#pragma once
#include <utils/types.h>
#include "../err.h"
#define COPY_MODE_CANCEL BIT(0)
#define COPY_MODE_PRINT BIT(1)
ErrCode_t FileCopy(const char *locin, const char *locout, u8 options);
ErrCode_t FolderDelete(const char *path);
ErrCode_t FolderCopy(const char *locin, const char *locout);

View File

@@ -0,0 +1,27 @@
#pragma once
#include <utils/types.h>
typedef struct {
char *name;
union {
struct {
u8 readOnly:1;
u8 hidden:1;
u8 system:1;
u8 volume:1;
u8 isDir:1;
u8 archive:1;
};
u8 optionUnion;
};
union {
struct {
u16 size:12;
u16 showSize:1;
u16 sizeDef:3;
};
u16 sizeUnion;
};
} FSEntry_t;
#define newFSEntry(filename) (FSEntry_t) {.name = filename}

View File

@@ -0,0 +1,58 @@
#include <mem/heap.h>
#include <string.h>
#include "fsutils.h"
#include "../utils/utils.h"
#include <utils/sprintf.h>
#include <libs/fatfs/ff.h>
#include "readers/folderReader.h"
char *CombinePaths(const char *current, const char *add){
char *ret;
size_t size = strlen(current) + strlen(add) + 2;
ret = (char*) malloc (size);
s_printf(ret, (current[strlen(current) - 1] == '/') ? "%s%s" : "%s/%s", current, add);
return ret;
}
char *EscapeFolder(const char *current){
char *ret;
char *temp;
ret = CpyStr(current);
temp = strrchr(ret, '/');
if (*(temp - 1) == ':')
temp++;
*temp = '\0';
return ret;
}
FSEntry_t GetFileInfo(const char *path){
FILINFO fno;
f_stat(path, &fno);
FSEntry_t entry = {.optionUnion = fno.fattrib, .name = strrchr(path, '/') + 1};
if (!(*entry.name))
entry.name = "Root";
return entry;
}
char *GetFileAttribs(FSEntry_t entry){
char *ret = CpyStr("RHSVDA");
MaskIn(ret, entry.optionUnion, '-');
return ret;
}
// Returns 1 if a file exists, 0 if it does not
bool FileExists(const char* path){
FRESULT fr;
FILINFO fno;
fr = f_stat(path, &fno);
return !(fr & FR_NO_FILE);
}

View File

@@ -0,0 +1,9 @@
#pragma once
#include <utils/types.h>
#include "fstypes.h"
FSEntry_t GetFileInfo(const char *path);
char *EscapeFolder(const char *current);
char *CombinePaths(const char *current, const char *add);
char *GetFileAttribs(FSEntry_t entry);
bool FileExists(const char* path);

View File

@@ -0,0 +1,148 @@
#include "explorer.h"
#include "../../utils/vector.h"
#include "../readers/folderReader.h"
#include "../../gfx/menu.h"
#include "../fsutils.h"
#include "../../gfx/gfx.h"
#include "../../gfx/gfxutils.h"
#include "../../utils/utils.h"
#include "filemenu.h"
#include <string.h>
#include <mem/heap.h>
#include "../../tegraexplorer/tconf.h"
#include "../../err.h"
#include "../fscopy.h"
#include <libs/fatfs/ff.h>
#include "../../hid/hid.h"
#include "foldermenu.h"
MenuEntry_t topEntries[] = {
{.optionUnion = COLORTORGB(COLOR_GREEN) | SKIPBIT},
{.optionUnion = COLORTORGB(COLOR_ORANGE)},
{.optionUnion = COLORTORGB(COLOR_GREY) | SKIPBIT, .name = "Clipboard -> Current folder"},
{.optionUnion = COLORTORGB(COLOR_ORANGE), .name = "Current folder options"}
};
MenuEntry_t MakeMenuOutFSEntry(FSEntry_t entry){
MenuEntry_t out = {.name = entry.name, .sizeUnion = entry.sizeUnion};
out.optionUnion = (entry.isDir) ? COLORTORGB(COLOR_WHITE) : COLORTORGB(COLOR_VIOLET);
out.icon = (entry.isDir) ? 127 : 128;
return out;
}
void FileExplorer(char *path){
char *storedPath = CpyStr(path);
int res = 0;
if (TConf.explorerCopyMode == CMODE_Move || TConf.explorerCopyMode == CMODE_MoveFolder)
ResetCopyParams();
while (1){
topEntries[2].optionUnion = (TConf.explorerCopyMode != CMODE_None) ? (COLORTORGB(COLOR_ORANGE)) : (COLORTORGB(COLOR_GREY) | SKIPBIT);
topEntries[1].name = (!strcmp(storedPath, path)) ? "<- Exit explorer" : "<- Folder back";
gfx_clearscreen();
gfx_printf("Loading...\r");
int readRes = 0;
Vector_t fileVec = ReadFolder(storedPath, &readRes);
if (readRes){
clearFileVector(&fileVec);
DrawError(newErrCode(readRes));
return;
}
vecDefArray(FSEntry_t*, fsEntries, fileVec);
topEntries[0].name = storedPath;
Vector_t entries = newVec(sizeof(MenuEntry_t), fileVec.count + ARR_LEN(topEntries));
entries.count = ARR_LEN(topEntries);
memcpy(entries.data, topEntries, sizeof(MenuEntry_t) * ARR_LEN(topEntries));
for (int i = 0; i < fileVec.count; i++){
MenuEntry_t a = MakeMenuOutFSEntry(fsEntries[i]);
vecAddElem(&entries, a);
}
gfx_con_setpos(144, 24);
gfx_boxGrey(0, 16, 160, 31, 0x1B);
if (res >= fileVec.count + ARR_LEN(topEntries))
res = 0;
res = newMenu(&entries, res, 60, 42, ENABLEB | ENABLEPAGECOUNT, (int)fileVec.count);
vecFree(entries);
char *oldPath = storedPath;
if (res == 2){
ErrCode_t err = {0};
char *filename = CpyStr(strrchr(TConf.srcCopy, '/') + 1);
char *dst = CombinePaths(storedPath, filename);
if (!strcmp(TConf.srcCopy, dst))
err = newErrCode(TE_ERR_SAME_LOC);
if (!err.err && TConf.explorerCopyMode >= CMODE_CopyFolder){
if (strstr(dst, TConf.srcCopy) != NULL)
err = newErrCode(TE_ERR_PATH_IN_PATH);
}
if (!err.err){
if (TConf.explorerCopyMode == CMODE_Move || TConf.explorerCopyMode == CMODE_MoveFolder){
if ((err.err = f_rename(TConf.srcCopy, dst)))
err = newErrCode(err.err);
}
else if (TConf.explorerCopyMode == CMODE_Copy) {
gfx_clearscreen();
RESETCOLOR;
gfx_printf("Hold vol+/- to cancel\nCopying %s... ", filename);
err = FileCopy(TConf.srcCopy, dst, COPY_MODE_CANCEL | COPY_MODE_PRINT);
}
else {
gfx_clearscreen();
RESETCOLOR;
gfx_printf("\nCopying folder... ");
err = FolderCopy(TConf.srcCopy, storedPath);
}
}
DrawError(err);
free(dst);
free(filename);
ResetCopyParams();
}
else if (res == 3){
if (FolderMenu(storedPath)){
storedPath = EscapeFolder(oldPath);
free(oldPath);
res = 0;
}
}
else if (res < ARR_LEN(topEntries)) {
if (!strcmp(storedPath, path)){
clearFileVector(&fileVec);
free(storedPath);
return;
}
storedPath = EscapeFolder(oldPath);
free(oldPath);
res = 0;
}
else if (fsEntries[res - ARR_LEN(topEntries)].isDir) {
storedPath = CombinePaths(storedPath, fsEntries[res - ARR_LEN(topEntries)].name);
free(oldPath);
res = 0;
}
else {
FileMenu(storedPath, fsEntries[res - ARR_LEN(topEntries)]);
}
clearFileVector(&fileVec);
}
}

View File

@@ -0,0 +1,7 @@
#pragma once
#include "../../utils/vector.h"
#include "../../gfx/menu.h"
#include "../fstypes.h"
void FileExplorer(char *path);
MenuEntry_t MakeMenuOutFSEntry(FSEntry_t entry);

View File

@@ -0,0 +1,216 @@
#include "filemenu.h"
#include "../../err.h"
#include "../../gfx/menu.h"
#include "../../gfx/gfxutils.h"
#include "../fsutils.h"
#include <mem/heap.h>
#include <string.h>
#include <utils/sprintf.h>
#include "../../tegraexplorer/tconf.h"
#include "../../hid/hid.h"
#include <libs/fatfs/ff.h>
#include "../../utils/utils.h"
#include "../../keys/nca.h"
#include <storage/nx_sd.h>
#include "../../storage/emummc.h"
#include "../../script/eval.h"
#include "../../script/parser.h"
#include "../../script/garbageCollector.h"
MenuEntry_t FileMenuEntries[] = {
{.optionUnion = COLORTORGB(COLOR_WHITE) | SKIPBIT, .name = "-- File menu --"},
{.optionUnion = COLORTORGB(COLOR_GREEN) | SKIPBIT}, // For the file name and size
{.optionUnion = COLORTORGB(COLOR_VIOLET) | SKIPBIT}, // For the file Attribs
{.optionUnion = HIDEBIT},
{.optionUnion = COLORTORGB(COLOR_WHITE), .name = "<- Back"},
{.optionUnion = COLORTORGB(COLOR_BLUE), .name = "\nCopy to clipboard"},
{.optionUnion = COLORTORGB(COLOR_BLUE), .name = "Move to clipboard"},
{.optionUnion = COLORTORGB(COLOR_BLUE), .name = "Rename file\n"},
{.optionUnion = COLORTORGB(COLOR_RED), .name = "Delete file"},
{.optionUnion = COLORTORGB(COLOR_GREEN), .name = "View hex"},
{.optionUnion = COLORTORGB(COLOR_ORANGE), .name = "Launch Payload"},
{.optionUnion = COLORTORGB(COLOR_YELLOW), .name = "Launch Script"},
};
void UnimplementedException(char *path, FSEntry_t entry){
DrawError(newErrCode(TE_ERR_UNIMPLEMENTED));
}
extern int launch_payload(char *path);
void LaunchPayload(char *path, FSEntry_t entry){
launch_payload(CombinePaths(path, entry.name));
}
void CopyClipboard(char *path, FSEntry_t entry){
char *thing = CombinePaths(path, entry.name);
SetCopyParams(thing, CMODE_Copy);
free(thing);
}
void MoveClipboard(char *path, FSEntry_t entry){
char *thing = CombinePaths(path, entry.name);
SetCopyParams(thing, CMODE_Move);
free(thing);
}
void DeleteFile(char *path, FSEntry_t entry){
gfx_con_setpos(384 + 16, 200 + 16 + 10 * 16);
SETCOLOR(COLOR_RED, COLOR_DARKGREY);
gfx_printf("Are you sure? ");
WaitFor(500);
if (!MakeYesNoHorzMenu(3, COLOR_DARKGREY))
return;
char *thing = CombinePaths(path, entry.name);
int res = f_unlink(thing);
if (res)
DrawError(newErrCode(res));
free(thing);
}
void RunScriptString(char *str, u32 size){
TConf.scriptCWD = "sd:/";
gfx_clearscreen();
ParserRet_t ret = parseScript(str, size);
setStaticVars(&ret.staticVarHolder);
initRuntimeVars();
eval(ret.main.operations.data, ret.main.operations.count, 0);
exitRuntimeVars();
exitStaticVars(&ret.staticVarHolder);
exitFunction(ret.main.operations.data, ret.main.operations.count);
vecFree(ret.staticVarHolder);
vecFree(ret.main.operations);
}
void RunScript(char *path, FSEntry_t entry){
char *thing = CombinePaths(path, entry.name);
u32 size;
char *script = sd_file_read(thing, &size);
free(thing);
TConf.scriptCWD = path;
if (!script)
return;
if (((entry.size >= 16 && entry.sizeDef == 1) || entry.sizeDef >= 2) && !TConf.minervaEnabled)
return;
gfx_clearscreen();
ParserRet_t ret = parseScript(script, size);
free(script);
setStaticVars(&ret.staticVarHolder);
initRuntimeVars();
Variable_t* res = eval(ret.main.operations.data, ret.main.operations.count, 1);
exitRuntimeVars();
exitStaticVars(&ret.staticVarHolder);
exitFunction(ret.main.operations.data, ret.main.operations.count);
vecFree(ret.staticVarHolder);
vecFree(ret.main.operations);
}
void RenameFile(char *path, FSEntry_t entry){
gfx_clearscreen();
char *renameTo = ShowKeyboard(entry.name, false);
if (renameTo == NULL || !(*renameTo)) // smol memory leak but eh
return;
char *src = CombinePaths(path, entry.name);
char *dst = CombinePaths(path, renameTo);
int res = f_rename(src, dst);
if (res){
DrawError(newErrCode(res));
}
free(src);
free(dst);
free(renameTo);
}
// This is from the original TE and it's bad but uhh i'm too lazy to fix it
void HexView(char *path, FSEntry_t entry){
char *filePath = CombinePaths(path, entry.name);
FIL in;
u8 *print;
u32 size;
QWORD offset = 0;
int res;
Input_t *input = hidRead();
while (input->buttons & (BtnPow | JoyB))
hidRead();
gfx_clearscreen();
print = calloc(2048, 1);
if ((res = f_open(&in, filePath, FA_READ | FA_OPEN_EXISTING))){
DrawError(newErrCode(res));
return;
}
while (1){
f_lseek(&in, offset * 32);
if ((res = f_read(&in, print, 2048, &size))){
DrawError(newErrCode(res));
return;
}
gfx_con_setpos(0, 31);
gfx_hexdump(offset * 32, print, ((size + 31) / 32) * 32);
input = hidRead();
if (!(input->buttons))
input = hidWait();
if (input->down && 2048 == size)
offset += 2;
if (input->up && offset > 0)
offset -= 2;
if (input->buttons & (BtnPow | JoyB))
break;
}
f_close(&in);
free(print);
free(filePath);
}
fileMenuPath FileMenuPaths[] = {
CopyClipboard,
MoveClipboard,
RenameFile,
DeleteFile,
HexView,
LaunchPayload,
RunScript
};
void FileMenu(char *path, FSEntry_t entry){
FileMenuEntries[1].name = entry.name;
FileMenuEntries[0].sizeUnion = entry.sizeUnion;
char attribs[16];
char *attribList = GetFileAttribs(entry);
s_printf(attribs, "Attribs:%s\n", attribList);
free(attribList);
FileMenuEntries[2].name = attribs;
FileMenuEntries[10].hide = !StrEndsWith(entry.name, ".bin");
FileMenuEntries[11].hide = !StrEndsWith(entry.name, ".te");
Vector_t ent = vecFromArray(FileMenuEntries, ARR_LEN(FileMenuEntries), sizeof(MenuEntry_t));
gfx_boxGrey(384, 200, 384 + 512, 200 + 320, 0x33);
gfx_con_setpos(384 + 16, 200 + 16);
int res = newMenu(&ent, 0, 30, 19, ENABLEB | ALWAYSREDRAW | USELIGHTGREY, ent.count);
if (res <= 4)
return;
FileMenuPaths[res - 5](path, entry);
}

View File

@@ -0,0 +1,8 @@
#pragma once
#include "../fstypes.h"
typedef void (*fileMenuPath)(char *path, FSEntry_t entry);
void FileMenu(char *path, FSEntry_t entry);
void RunScript(char *path, FSEntry_t entry);
void RunScriptString(char *str, u32 size);

View File

@@ -0,0 +1,134 @@
#include "foldermenu.h"
#include "../../err.h"
#include "../../gfx/menu.h"
#include "../../gfx/gfxutils.h"
#include "../fsutils.h"
#include <mem/heap.h>
#include <string.h>
#include <utils/sprintf.h>
#include "../../tegraexplorer/tconf.h"
#include "../../hid/hid.h"
#include <libs/fatfs/ff.h>
#include "../../utils/utils.h"
#include "../../keys/nca.h"
#include <storage/nx_sd.h>
#include "../fscopy.h"
MenuEntry_t FolderMenuEntries[] = {
{.optionUnion = COLORTORGB(COLOR_WHITE) | SKIPBIT, .name = "-- Folder menu --"},
{.optionUnion = COLORTORGB(COLOR_GREEN) | SKIPBIT}, // For the file name and size
{.optionUnion = COLORTORGB(COLOR_VIOLET) | SKIPBIT}, // For the file Attribs
{.optionUnion = HIDEBIT},
{.optionUnion = COLORTORGB(COLOR_WHITE), .name = "<- Back"},
{.optionUnion = COLORTORGB(COLOR_BLUE), .name = "\nCopy to clipboard"},
{.optionUnion = COLORTORGB(COLOR_BLUE), .name = "Move to clipboard"},
{.optionUnion = COLORTORGB(COLOR_BLUE), .name = "Rename current folder\n"},
{.optionUnion = COLORTORGB(COLOR_RED), .name = "Delete current folder"},
{.optionUnion = COLORTORGB(COLOR_GREEN), .name = "\nCreate folder"}
};
int UnimplementedFolderException(const char *path){
DrawError(newErrCode(TE_ERR_UNIMPLEMENTED));
return 0;
}
int FolderCopyClipboard(const char *path){
SetCopyParams(path, CMODE_CopyFolder);
return 0;
}
int FolderMoveClipboard(const char *path){
SetCopyParams(path, CMODE_MoveFolder);
return 0;
}
int DeleteFolder(const char *path){
gfx_con_setpos(384 + 16, 200 + 16 + 10 * 16);
SETCOLOR(COLOR_RED, COLOR_DARKGREY);
gfx_printf("Are you sure? ");
WaitFor(1000);
if (MakeYesNoHorzMenu(3, COLOR_DARKGREY)){
gfx_clearscreen();
SETCOLOR(COLOR_RED, COLOR_DEFAULT);
gfx_printf("\nDeleting... ");
ErrCode_t err = FolderDelete(path);
if (err.err){
DrawError(err);
}
else return 1;
}
return 0;
}
int RenameFolder(const char *path){
char *prev = EscapeFolder(path);
gfx_clearscreen();
char *renameTo = ShowKeyboard(strrchr(path, '/') + 1, false);
if (renameTo == NULL || !(*renameTo)) // smol memory leak but eh
return 0;
char *dst = CombinePaths(prev, renameTo);
int res = f_rename(path, dst);
if (res){
DrawError(newErrCode(res));
}
free(prev);
free(dst);
free(renameTo);
return 1;
}
int CreateFolder(const char *path){
gfx_clearscreen();
char *create = ShowKeyboard("New Folder", true);
if (create == NULL || !(*create)) // smol memory leak but eh
return 0;
char *dst = CombinePaths(path, create);
f_mkdir(dst);
free(dst);
free(create);
return 0;
}
folderMenuPath FolderMenuPaths[] = {
FolderCopyClipboard,
FolderMoveClipboard,
RenameFolder,
DeleteFolder,
CreateFolder
};
int FolderMenu(const char *path){
FSEntry_t file = GetFileInfo(path);
FolderMenuEntries[1].name = file.name;
char attribs[16];
char *attribList = GetFileAttribs(file);
s_printf(attribs, "Attribs:%s\n", attribList);
free(attribList);
FolderMenuEntries[2].name = attribs;
// If root, disable all options other than create folder!
int isRoot = !strcmp(file.name, "Root");
FolderMenuEntries[2].hide = isRoot;
for (int i = 5; i <= 8; i++)
FolderMenuEntries[i].hide = isRoot;
Vector_t ent = vecFromArray(FolderMenuEntries, ARR_LEN(FolderMenuEntries), sizeof(MenuEntry_t));
gfx_boxGrey(384, 200, 384 + 512, 200 + 320, 0x33);
gfx_con_setpos(384 + 16, 200 + 16);
int res = newMenu(&ent, 0, 30, 19, ENABLEB | ALWAYSREDRAW | USELIGHTGREY, ent.count);
if (res <= 4)
return 0;
return FolderMenuPaths[res - 5](path);
}

View File

@@ -0,0 +1,4 @@
#pragma once
typedef int (*folderMenuPath)(const char *path);
int FolderMenu(const char *path);

View File

@@ -0,0 +1,48 @@
#include "folderReader.h"
#include <libs/fatfs/ff.h>
#include "../../utils/utils.h"
#include <mem/heap.h>
void clearFileVector(Vector_t *v){
vecPDefArray(FSEntry_t*, entries, v);
for (int i = 0; i < v->count; i++)
free(entries[i].name);
free(v->data);
}
Vector_t /* of type FSEntry_t */ ReadFolder(const char *path, int *res){
Vector_t out = newVec(sizeof(FSEntry_t), 16); // we may want to prealloc with the same size as the folder
DIR dir;
FILINFO fno;
if ((*res = f_opendir(&dir, path))){
// Err!
return out;
}
while (!(*res = f_readdir(&dir, &fno)) && fno.fname[0]) {
FSEntry_t newEntry = {.optionUnion = fno.fattrib, .name = CpyStr(fno.fname)};
if (!newEntry.isDir){
u64 total = fno.fsize;
u8 type = 0;
while (total > 1024){
total /= 1024;
type++;
}
if (type > 3)
type = 3;
newEntry.showSize = 1;
newEntry.size = total;
newEntry.sizeDef = type;
}
vecAddElem(&out, newEntry);
}
f_closedir(&dir);
return out;
}

View File

@@ -0,0 +1,7 @@
#pragma once
#include <utils/types.h>
#include "../../utils/vector.h"
#include "../fstypes.h"
void clearFileVector(Vector_t *v);
Vector_t /* of type FSEntry_t */ ReadFolder(const char *path, int *res);