diff --git a/source/gfx/gfx.c b/source/gfx/gfx.c index 4ff71bd..cd19510 100644 --- a/source/gfx/gfx.c +++ b/source/gfx/gfx.c @@ -227,6 +227,11 @@ void gfx_putc(char c) if (gfx_con.y > gfx_ctxt.height - 16) gfx_con.y = 0; } + else if (c == '\e') + gfx_con.x = 672; + else if (c == '\a') + gfx_con.x = 608; + break; case 8: default: @@ -261,6 +266,7 @@ void gfx_putc(char c) if (gfx_con.y > gfx_ctxt.height - 8) gfx_con.y = 0; } + break; } } diff --git a/source/tegraexplorer/fs.c b/source/tegraexplorer/fs.c new file mode 100644 index 0000000..ebd2d58 --- /dev/null +++ b/source/tegraexplorer/fs.c @@ -0,0 +1,85 @@ +#include +#include +#include "gfx.h" +#include "fs.h" +#include "../utils/types.h" +#include "../libs/fatfs/ff.h" +#include "../utils/sprintf.h" +#include "../utils/btn.h" +#include "../gfx/gfx.h" + +fs_entry fileobjects[500]; +char rootpath[10] = ""; +char currentpath[255] = ""; + +char *getnextloc(char *current, char *add){ + char *ret; + size_t size = strlen(current) + strlen(add) + 1; + ret = (char*) malloc (size); + if (!strcmp(rootpath, current)) + sprintf(ret, "%s%s", current, add); + else + sprintf(ret, "%s/%s", current, add); + + return ret; +} + +void addobject(char* name, int spot, bool isfol, bool isarc){ + size_t size = strlen(name) + 1; + fileobjects[spot].property = 0; + + fileobjects[spot].name = (char*) malloc (size); + strlcpy(fileobjects[spot].name, name, size); + + if (isfol) + fileobjects[spot].property |= (ISDIR); + else { + unsigned long size = 0; + int sizes = 0; + FILINFO fno; + f_stat(getnextloc(currentpath, name), &fno); + size = fno.fsize; + + while (size > 1024){ + size /= 1024; + sizes++; + } + + if (sizes > 3) + sizes = 0; + + fileobjects[spot].property |= (1 << (4 + sizes)); + fileobjects[spot].size = size; + } + + if (isarc) + fileobjects[spot].property |= (ISARC); +} + +int readfolder(const char *path){ + DIR dir; + FILINFO fno; + int folderamount = 0, res; + + if (res = f_opendir(&dir, path)){ + char errmes[50] = ""; + sprintf(errmes, "Error during f_opendir: %d", res); + message(errmes, COLOR_RED); + } + + while (!f_readdir(&dir, &fno) && fno.fname[0]){ + addobject(fno.fname, folderamount++, (fno.fattrib & AM_DIR), (fno.fattrib & AM_ARC)); + } + + f_closedir(&dir); + return folderamount; +} + +void filemenu(const char *startpath){ + int amount; + strcpy(rootpath, startpath); + strcpy(currentpath, startpath); + + amount = readfolder(currentpath); + makefilemenu(fileobjects, amount, currentpath); +} \ No newline at end of file diff --git a/source/tegraexplorer/fs.h b/source/tegraexplorer/fs.h new file mode 100644 index 0000000..36bcdc4 --- /dev/null +++ b/source/tegraexplorer/fs.h @@ -0,0 +1,28 @@ +#pragma once +#include "../utils/types.h" + +#define ISDIR (1 << 0) +#define ISARC (1 << 1) + +#define ISGB (1 << 7) +#define ISMB (1 << 6) +#define ISKB (1 << 5) +#define ISB (1 << 4) + +/* Bit table for property: +0000 0001: Directory bit +0000 0010: Archive bit +0001 0000: Size component is a Byte +0010 0000: Size component is a KiloByte +0100 0000: Size component is a MegaByte +1000 0000: Size component is a GigaByte : note that this won't surpass gigabytes, but i don't expect people to have a single file that's a terrabyte big +*/ + +typedef struct _fs_entry { + char* name; + u16 size; + u8 property; +} fs_entry; + +int readfolder(const char *path); +void filemenu(); \ No newline at end of file diff --git a/source/tegraexplorer/gfx.c b/source/tegraexplorer/gfx.c index 2abdd8c..970a616 100644 --- a/source/tegraexplorer/gfx.c +++ b/source/tegraexplorer/gfx.c @@ -1,7 +1,22 @@ #include "../gfx/gfx.h" #include "te.h" #include "../utils/btn.h" +#include "../utils/util.h" #include "gfx.h" +#include "fs.h" + +const char fixedoptions[3][50] = { + "Folder -> previous folder", + "Clipboard -> Current folder", + "Folder options" +}; + +const char sizevalues[4][3] = { + " B", + "KB", + "MB", + "GB" +}; void clearscreen(){ gfx_clear_grey(0x1B); @@ -59,4 +74,62 @@ int makemenu(menu_item menu[], int menuamount){ else if (res & BTN_POWER) return menu[currentpos - 1].internal_function; } +} + +void printfsentry(fs_entry file, bool highlight){ + int size = 0; + + if (highlight) + gfx_printf("%K%k", COLOR_WHITE, COLOR_DEFAULT); + else + gfx_printf("%K%k", COLOR_DEFAULT, COLOR_WHITE); + + if (file.property & ISDIR) + gfx_printf("%s\n", file.name); + else { + for (size = 4; size < 8; size++) + if ((file.property & (1 << size))) + break; + + gfx_printf("%k%s%K\a%d\e%s", COLOR_VIOLET, file.name, COLOR_DEFAULT, file.size, sizevalues[size - 4]); + } +} + +int makefilemenu(fs_entry *files, int amount, char *path){ + int currentpos = 1, i, res = 0, offset = 0, quickoffset = 300; + clearscreen(); + gfx_con_setpos(544, 0); + gfx_printf("%K%k%d / 500\n%K%k%s%k\n\n", COLOR_WHITE, COLOR_DEFAULT, amount, COLOR_DEFAULT, COLOR_GREEN, path, COLOR_DEFAULT); + while (1){ + gfx_con_setpos(0, 47); + for (i = -3 + offset; i < amount; i++){ + if (i < 0){ + if (i == currentpos - 1) + gfx_printf("%k%K%s%K\n", COLOR_ORANGE, COLOR_WHITE, fixedoptions[i + 3], COLOR_DEFAULT); + else + gfx_printf("%k%s\n", COLOR_ORANGE, fixedoptions[i + 3]); + } + else + printfsentry(files[i], (i == currentpos - 1)); + } + + if (quickoffset == 300) + res = btn_wait(); + else { + msleep(quickoffset); + res = btn_read(); + } + + if (res == 0) + quickoffset = 300; + else if (quickoffset > 50) + quickoffset -= 50; + + if ((res & BTN_VOL_UP) && currentpos > -2) + currentpos--; + if ((res & BTN_VOL_DOWN) && currentpos < amount) + currentpos++; + if (res & BTN_POWER) + return currentpos; + } } \ No newline at end of file diff --git a/source/tegraexplorer/gfx.h b/source/tegraexplorer/gfx.h index 32fecab..cf9806c 100644 --- a/source/tegraexplorer/gfx.h +++ b/source/tegraexplorer/gfx.h @@ -1,6 +1,8 @@ #pragma once #include "te.h" +#include "fs.h" int makemenu(menu_item menu[], int menuamount); int message(char* message, u32 color); -void clearscreen(); \ No newline at end of file +void clearscreen(); +int makefilemenu(fs_entry *files, int amount, char *path); \ No newline at end of file diff --git a/source/tegraexplorer/te.c b/source/tegraexplorer/te.c index d4b210c..ee54ba2 100644 --- a/source/tegraexplorer/te.c +++ b/source/tegraexplorer/te.c @@ -4,10 +4,11 @@ #include "gfx.h" #include "../utils/util.h" #include "tools.h" +#include "fs.h" extern bool sd_mount(); extern void sd_unmount(); -bool sd_mounted = false; +bool sd_mounted; menu_item mainmenu[MAINMENU_AMOUNT] = { {"[SD:/] SD CARD", COLOR_GREEN, SD_CARD, 1}, @@ -68,6 +69,7 @@ void te_main(){ switch(res){ case SD_CARD: + filemenu("SD:/"); break; case EMMC: break; @@ -96,44 +98,18 @@ void te_main(){ case EXIT: res = makemenu(shutdownmenu, 5); - if (res == REBOOT_RCM) - reboot_rcm(); - else if (res == REBOOT_NORMAL) - reboot_normal(); - else if (res == POWER_OFF) - power_off(); //todo declock bpmp + switch(res){ + case REBOOT_RCM: + reboot_rcm(); + + case REBOOT_NORMAL: + reboot_normal(); + + case POWER_OFF: + power_off(); + } //todo declock bpmp break; } - /* - if (res == 3){ - if (sd_mounted){ - sd_mounted = false; - sd_unmount(); - } - else - sd_mounted = sd_mount(); - } - - if (res == 4){ - res = makemenu(toolsmenu, 3); - - if (res == 2) - displayinfo(); - } - - if (res == 5) - message(CREDITS_MESSAGE, COLOR_WHITE); - - if (res == 6){ - res = makemenu(shutdownmenu, 5); - if (res == 2) - reboot_rcm(); - else if (res == 3) - reboot_normal(); - else if (res == 4) - power_off(); //todo declock bpmp - } - */ } } \ No newline at end of file