mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
Misc bugfixes + non working copy / delete features
This commit is contained in:
parent
dbc7015d2a
commit
7ab86c87a3
@ -118,12 +118,13 @@ u32 GetDrawStringHeight(const char* str) {
|
|||||||
u32 GetDrawStringWidth(char* str) {
|
u32 GetDrawStringWidth(char* str) {
|
||||||
u32 width = 0;
|
u32 width = 0;
|
||||||
char* old_lf = str;
|
char* old_lf = str;
|
||||||
for (char* lf = strchr(str, '\n'); (lf != NULL); lf = strchr(lf + 1, '\n')) {
|
char* str_end = str + strnlen(str, 512);
|
||||||
|
for (char* lf = strchr(str, '\n'); lf != NULL; lf = strchr(lf + 1, '\n')) {
|
||||||
if ((lf - old_lf) > width) width = lf - old_lf;
|
if ((lf - old_lf) > width) width = lf - old_lf;
|
||||||
old_lf = lf;
|
old_lf = lf;
|
||||||
}
|
}
|
||||||
if (old_lf == str)
|
if (str_end - old_lf > width)
|
||||||
width = strnlen(str, 256);
|
width = str_end - old_lf;
|
||||||
width *= 8;
|
width *= 8;
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
@ -170,6 +171,7 @@ bool ShowPrompt(bool ask, const char *format, ...)
|
|||||||
{
|
{
|
||||||
u32 str_width, str_height;
|
u32 str_width, str_height;
|
||||||
u32 x, y;
|
u32 x, y;
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
char str[512] = {}; // 512 should be more than enough
|
char str[512] = {}; // 512 should be more than enough
|
||||||
va_list va;
|
va_list va;
|
||||||
@ -180,6 +182,7 @@ bool ShowPrompt(bool ask, const char *format, ...)
|
|||||||
|
|
||||||
str_width = GetDrawStringWidth(str);
|
str_width = GetDrawStringWidth(str);
|
||||||
str_height = GetDrawStringHeight(str) + (2 * 10);
|
str_height = GetDrawStringHeight(str) + (2 * 10);
|
||||||
|
if (str_width < 18*8) str_width = 18 * 8;
|
||||||
x = (str_width >= SCREEN_WIDTH_TOP) ? 0 : (SCREEN_WIDTH_TOP - str_width) / 2;
|
x = (str_width >= SCREEN_WIDTH_TOP) ? 0 : (SCREEN_WIDTH_TOP - str_width) / 2;
|
||||||
y = (str_height >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - str_height) / 2;
|
y = (str_height >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - str_height) / 2;
|
||||||
|
|
||||||
@ -190,12 +193,15 @@ bool ShowPrompt(bool ask, const char *format, ...)
|
|||||||
while (true) {
|
while (true) {
|
||||||
u32 pad_state = InputWait();
|
u32 pad_state = InputWait();
|
||||||
if (pad_state & BUTTON_A) break;
|
if (pad_state & BUTTON_A) break;
|
||||||
else if (ask && (pad_state & BUTTON_B)) return false;
|
else if (ask && (pad_state & BUTTON_B)) {
|
||||||
|
ret = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearScreenF(true, false, COLOR_STD_BG);
|
ClearScreenF(true, false, COLOR_STD_BG);
|
||||||
|
|
||||||
return true;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShowUnlockSequence(u32 seqlvl, const char *format, ...) {
|
bool ShowUnlockSequence(u32 seqlvl, const char *format, ...) {
|
||||||
@ -227,6 +233,7 @@ bool ShowUnlockSequence(u32 seqlvl, const char *format, ...) {
|
|||||||
|
|
||||||
str_width = GetDrawStringWidth(str);
|
str_width = GetDrawStringWidth(str);
|
||||||
str_height = GetDrawStringHeight(str) + (3*10);
|
str_height = GetDrawStringHeight(str) + (3*10);
|
||||||
|
if (str_width < 24) str_width = 24;
|
||||||
x = (str_width >= SCREEN_WIDTH_TOP) ? 0 : (SCREEN_WIDTH_TOP - str_width) / 2;
|
x = (str_width >= SCREEN_WIDTH_TOP) ? 0 : (SCREEN_WIDTH_TOP - str_width) / 2;
|
||||||
y = (str_height >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - (str_height)) / 2;
|
y = (str_height >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - (str_height)) / 2;
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ DRESULT disk_read (
|
|||||||
UINT count /* Number of sectors to read */
|
UINT count /* Number of sectors to read */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if ((pdrv > 0) && mode_n3ds) // is this really set at this point?
|
if ((pdrv > 0) && mode_n3ds)
|
||||||
pdrv += 6;
|
pdrv += 6;
|
||||||
|
|
||||||
BYTE type = DriveInfo[pdrv].type;
|
BYTE type = DriveInfo[pdrv].type;
|
||||||
|
28
source/fs.c
28
source/fs.c
@ -8,7 +8,7 @@ static FATFS* fs = (FATFS*)0x20316000;
|
|||||||
// this is the main buffer
|
// this is the main buffer
|
||||||
static u8* main_buffer = (u8*)0x21100000;
|
static u8* main_buffer = (u8*)0x21100000;
|
||||||
// this is the main buffer size
|
// this is the main buffer size
|
||||||
static size_t main_buffer_size = 4 * 1024 * 1024;
|
static size_t main_buffer_size = 128 * 1024;
|
||||||
|
|
||||||
// write permission level - careful with this
|
// write permission level - careful with this
|
||||||
static u32 write_permission_level = 1;
|
static u32 write_permission_level = 1;
|
||||||
@ -46,7 +46,7 @@ void DeinitFS() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool CheckWritePermissions(const char* path) {
|
bool CheckWritePermissions(const char* path) {
|
||||||
u32 pdrv = *path - '0';
|
u32 pdrv = (*path) - '0';
|
||||||
|
|
||||||
if ((pdrv > 6) || (*(path+1) != ':')) {
|
if ((pdrv > 6) || (*(path+1) != ':')) {
|
||||||
ShowPrompt(false, "Invalid path");
|
ShowPrompt(false, "Invalid path");
|
||||||
@ -144,18 +144,18 @@ bool PathCopyWorker(char* dest, char* orig) {
|
|||||||
DIR pdir;
|
DIR pdir;
|
||||||
char* fname = orig + strnlen(orig, 256);
|
char* fname = orig + strnlen(orig, 256);
|
||||||
|
|
||||||
*(fname++) = '/';
|
if ((f_stat(dest, NULL) != FR_OK) && (f_mkdir(dest) != FR_OK))
|
||||||
fno.lfname = fname;
|
|
||||||
fno.lfsize = 256 - (fname - orig);
|
|
||||||
|
|
||||||
if (f_stat(dest, NULL) != FR_OK)
|
|
||||||
f_mkdir(dest);
|
|
||||||
if (f_stat(dest, NULL) != FR_OK)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (f_opendir(&pdir, orig) != FR_OK)
|
if (f_opendir(&pdir, orig) != FR_OK)
|
||||||
return false;
|
return false;
|
||||||
|
*(fname++) = '/';
|
||||||
|
fno.lfname = fname;
|
||||||
|
fno.lfsize = 256 - (fname - orig);
|
||||||
|
|
||||||
|
ShowPrompt(false, "Made:\n%s\n%s", orig, dest);
|
||||||
while (f_readdir(&pdir, &fno) == FR_OK) {
|
while (f_readdir(&pdir, &fno) == FR_OK) {
|
||||||
|
ShowPrompt(false, "Trying:\n%s\n%s", orig, dest);
|
||||||
if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0))
|
if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0))
|
||||||
continue; // filter out virtual entries
|
continue; // filter out virtual entries
|
||||||
if (fname[0] == 0)
|
if (fname[0] == 0)
|
||||||
@ -164,6 +164,7 @@ bool PathCopyWorker(char* dest, char* orig) {
|
|||||||
ret = true;
|
ret = true;
|
||||||
break;
|
break;
|
||||||
} else if (!PathCopyWorker(dest, orig)) {
|
} else if (!PathCopyWorker(dest, orig)) {
|
||||||
|
ShowPrompt(false, "Failed:\n%s\n%s", orig, dest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,6 +186,7 @@ bool PathCopyWorker(char* dest, char* orig) {
|
|||||||
f_lseek(&ofile, 0);
|
f_lseek(&ofile, 0);
|
||||||
f_sync(&ofile);
|
f_sync(&ofile);
|
||||||
|
|
||||||
|
ret = true;
|
||||||
for (size_t pos = 0; pos < fsize; pos += main_buffer_size) {
|
for (size_t pos = 0; pos < fsize; pos += main_buffer_size) {
|
||||||
UINT bytes_read = 0;
|
UINT bytes_read = 0;
|
||||||
UINT bytes_written = 0;
|
UINT bytes_written = 0;
|
||||||
@ -196,6 +198,7 @@ bool PathCopyWorker(char* dest, char* orig) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ShowProgress(1, 1, orig, false);
|
||||||
|
|
||||||
f_close(&ofile);
|
f_close(&ofile);
|
||||||
f_close(&dfile);
|
f_close(&dfile);
|
||||||
@ -219,16 +222,16 @@ bool PathDeleteWorker(char* fpath) {
|
|||||||
|
|
||||||
// the deletion process takes place here
|
// the deletion process takes place here
|
||||||
if (f_stat(fpath, &fno) != FR_OK) return false; // fpath does not exist
|
if (f_stat(fpath, &fno) != FR_OK) return false; // fpath does not exist
|
||||||
if (fno.fattrib & AM_DIR) { // processing folders...
|
if (fno.fattrib & AM_DIR) { // process folder contents
|
||||||
DIR pdir;
|
DIR pdir;
|
||||||
char* fname = fpath + strnlen(fpath, 256);
|
char* fname = fpath + strnlen(fpath, 256);
|
||||||
|
|
||||||
|
if (f_opendir(&pdir, fpath) != FR_OK)
|
||||||
|
return false;
|
||||||
*(fname++) = '/';
|
*(fname++) = '/';
|
||||||
fno.lfname = fname;
|
fno.lfname = fname;
|
||||||
fno.lfsize = 256 - (fname - fpath);
|
fno.lfsize = 256 - (fname - fpath);
|
||||||
|
|
||||||
if (f_opendir(&pdir, fpath) != FR_OK)
|
|
||||||
return false;
|
|
||||||
while (f_readdir(&pdir, &fno) == FR_OK) {
|
while (f_readdir(&pdir, &fno) == FR_OK) {
|
||||||
if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0))
|
if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0))
|
||||||
continue; // filter out virtual entries
|
continue; // filter out virtual entries
|
||||||
@ -241,6 +244,7 @@ bool PathDeleteWorker(char* fpath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
f_closedir(&pdir);
|
f_closedir(&pdir);
|
||||||
|
*(--fname) = '\0';
|
||||||
} else { // processing files...
|
} else { // processing files...
|
||||||
ret = (f_unlink(fpath) == FR_OK);
|
ret = (f_unlink(fpath) == FR_OK);
|
||||||
}
|
}
|
||||||
|
@ -69,14 +69,16 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, DirStruct* c
|
|||||||
|
|
||||||
// bottom: inctruction block
|
// bottom: inctruction block
|
||||||
char instr[256];
|
char instr[256];
|
||||||
snprintf(instr, 256, "%s%s%s%s",
|
snprintf(instr, 256, "%s%s%s%s%s",
|
||||||
"GodMode9 File Explorer v0.0.4\n", // generic start part
|
"GodMode9 File Explorer v0.0.4\n", // generic start part
|
||||||
(*curr_path) ? "L - MARK files (use with \x18\x19\x1A\x1B)\nX - DELETE / [+R] RENAME file(s)\nY - COPY file(s) / [+R] CREATE dir\n" :
|
(*curr_path) ? ((clipboard->n_entries == 0) ? "L - MARK files (use with \x18\x19\x1A\x1B)\nX - DELETE / [+R] RENAME file(s)\nY - COPY file(s) / [+R] CREATE dir\n" :
|
||||||
(GetWritePermissions() <= 1) ? "X - Unlock EmuNAND writing\nY - Unlock SysNAND writing\n" :
|
"L - MARK files (use with \x18\x19\x1A\x1B)\nX - DELETE / [+R] RENAME file(s)\nY - PASTE file(s) / [+R] CREATE dir\n") :
|
||||||
|
((GetWritePermissions() <= 1) ? "X - Unlock EmuNAND writing\nY - Unlock SysNAND writing\n" :
|
||||||
(GetWritePermissions() == 2) ? "X - Relock EmuNAND writing\nY - Unlock SysNAND writing\n" :
|
(GetWritePermissions() == 2) ? "X - Relock EmuNAND writing\nY - Unlock SysNAND writing\n" :
|
||||||
"X - Relock EmuNAND writing\nY - Relock SysNAND writing\n",
|
"X - Relock EmuNAND writing\nY - Relock SysNAND writing\n"),
|
||||||
(clipboard->n_entries) ? "SELECT - Clear Clipboard\n" : "", // only if clipboard is full
|
"R+L - Make a Screenshot\n",
|
||||||
"R+L - Make a SCREENSHOT\nSTART - Reboot / [+\x1B] Poweroff"); // generic end part
|
(clipboard->n_entries) ? "SELECT - Clear Clipboard\n" : "SELECT - Restore Clipboard\n", // only if clipboard is full
|
||||||
|
"START - Reboot / [+\x1B] Poweroff"); // generic end part
|
||||||
DrawStringF(true, (SCREEN_WIDTH_TOP - GetDrawStringWidth(instr)) / 2, SCREEN_HEIGHT - 4 - GetDrawStringHeight(instr), COLOR_STD_FONT, COLOR_STD_BG, instr);
|
DrawStringF(true, (SCREEN_WIDTH_TOP - GetDrawStringWidth(instr)) / 2, SCREEN_HEIGHT - 4 - GetDrawStringHeight(instr), COLOR_STD_FONT, COLOR_STD_BG, instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,6 +137,7 @@ u32 GodMode() {
|
|||||||
char current_path[256] = { 0x00 };
|
char current_path[256] = { 0x00 };
|
||||||
|
|
||||||
int mark_setting = -1;
|
int mark_setting = -1;
|
||||||
|
u32 last_clipboard_size = 0;
|
||||||
bool switched = false;
|
bool switched = false;
|
||||||
u32 cursor = 0;
|
u32 cursor = 0;
|
||||||
|
|
||||||
@ -143,7 +146,7 @@ u32 GodMode() {
|
|||||||
|
|
||||||
GetDirContents(current_dir, "");
|
GetDirContents(current_dir, "");
|
||||||
clipboard->n_entries = 0;
|
clipboard->n_entries = 0;
|
||||||
while (true) { // this is the main loop
|
while (true) { // this is the main loop !!! EMPTY DIRS
|
||||||
DrawUserInterface(current_path, &(current_dir->entry[cursor]), clipboard);
|
DrawUserInterface(current_path, &(current_dir->entry[cursor]), clipboard);
|
||||||
DrawDirContents(current_dir, cursor);
|
DrawDirContents(current_dir, cursor);
|
||||||
u32 pad_state = InputWait();
|
u32 pad_state = InputWait();
|
||||||
@ -163,7 +166,7 @@ u32 GodMode() {
|
|||||||
else *current_path = '\0';
|
else *current_path = '\0';
|
||||||
GetDirContents(current_dir, current_path);
|
GetDirContents(current_dir, current_path);
|
||||||
cursor = 0;
|
cursor = 0;
|
||||||
} else if ((pad_state & BUTTON_DOWN) && (cursor < current_dir->n_entries - 1)) { // cursor up
|
} else if ((pad_state & BUTTON_DOWN) && (cursor + 1 < current_dir->n_entries)) { // cursor up
|
||||||
cursor++;
|
cursor++;
|
||||||
} else if ((pad_state & BUTTON_UP) && cursor) { // cursor down
|
} else if ((pad_state & BUTTON_UP) && cursor) { // cursor down
|
||||||
cursor--;
|
cursor--;
|
||||||
@ -189,8 +192,8 @@ u32 GodMode() {
|
|||||||
current_dir->entry[cursor].marked ^= 0x1;
|
current_dir->entry[cursor].marked ^= 0x1;
|
||||||
mark_setting = current_dir->entry[cursor].marked;
|
mark_setting = current_dir->entry[cursor].marked;
|
||||||
}
|
}
|
||||||
} else if ((pad_state & BUTTON_SELECT) && (clipboard->n_entries > 0)) { // clear clipboard
|
} else if (pad_state & BUTTON_SELECT) { // clear/restore clipboard
|
||||||
clipboard->n_entries = 0;
|
clipboard->n_entries = (clipboard->n_entries > 0) ? 0 : last_clipboard_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// highly specific commands
|
// highly specific commands
|
||||||
@ -202,7 +205,26 @@ u32 GodMode() {
|
|||||||
}
|
}
|
||||||
} else if (!switched) { // standard unswitched command set
|
} else if (!switched) { // standard unswitched command set
|
||||||
if (pad_state & BUTTON_X) { // delete a file
|
if (pad_state & BUTTON_X) { // delete a file
|
||||||
// not implemented yet
|
u32 n_marked = 0;
|
||||||
|
for (u32 c = 0; c < current_dir->n_entries; c++)
|
||||||
|
if (current_dir->entry[c].marked) n_marked++;
|
||||||
|
if (n_marked) {
|
||||||
|
if (ShowPrompt(true, "Delete %u path(s)?", n_marked)) {
|
||||||
|
u32 n_errors = 0;
|
||||||
|
for (u32 c = 0; c < current_dir->n_entries; c++)
|
||||||
|
if (current_dir->entry[c].marked && !PathDelete(current_dir->entry[c].path))
|
||||||
|
n_errors++;
|
||||||
|
if (n_errors) ShowPrompt(false, "Failed deleting %u/%u path(s)", n_errors, n_marked);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
char namestr[20+1];
|
||||||
|
TruncateString(namestr, current_dir->entry[cursor].name, 20, 12);
|
||||||
|
if ((ShowPrompt(true, "Delete \"%s\"?", namestr)) && !PathDelete(current_dir->entry[cursor].path))
|
||||||
|
ShowPrompt(false, "Failed deleting \"%s\"", namestr);
|
||||||
|
}
|
||||||
|
GetDirContents(current_dir, current_path);
|
||||||
|
if (cursor >= current_dir->n_entries)
|
||||||
|
cursor = current_dir->n_entries - 1;
|
||||||
} else if ((pad_state & BUTTON_Y) && (clipboard->n_entries == 0)) { // fill clipboard
|
} else if ((pad_state & BUTTON_Y) && (clipboard->n_entries == 0)) { // fill clipboard
|
||||||
for (u32 c = 0; c < current_dir->n_entries; c++) {
|
for (u32 c = 0; c < current_dir->n_entries; c++) {
|
||||||
if (current_dir->entry[c].marked) {
|
if (current_dir->entry[c].marked) {
|
||||||
@ -215,6 +237,28 @@ u32 GodMode() {
|
|||||||
DirEntryCpy(&(clipboard->entry[0]), &(current_dir->entry[cursor]));
|
DirEntryCpy(&(clipboard->entry[0]), &(current_dir->entry[cursor]));
|
||||||
clipboard->n_entries = 1;
|
clipboard->n_entries = 1;
|
||||||
}
|
}
|
||||||
|
last_clipboard_size = clipboard->n_entries;
|
||||||
|
} else if (pad_state & BUTTON_Y) { // paste files
|
||||||
|
char promptstr[64];
|
||||||
|
if (clipboard->n_entries == 1) {
|
||||||
|
char namestr[20+1];
|
||||||
|
TruncateString(namestr, clipboard->entry[0].name, 20, 12);
|
||||||
|
snprintf(promptstr, 64, "Copy \"%s\" here?", namestr);
|
||||||
|
} else snprintf(promptstr, 64, "Copy %lu path(s) here?", clipboard->n_entries);
|
||||||
|
if (ShowPrompt(true, promptstr)) {
|
||||||
|
for (u32 c = 0; c < clipboard->n_entries; c++) {
|
||||||
|
if (!PathCopy(current_path, clipboard->entry[c].path)) {
|
||||||
|
char namestr[20+1];
|
||||||
|
TruncateString(namestr, clipboard->entry[c].name, 20, 12);
|
||||||
|
if (c + 1 < clipboard->n_entries) {
|
||||||
|
if (!ShowPrompt(true, "Failed copying \"%s\"\nContinue?", namestr)) break;
|
||||||
|
} else ShowPrompt(false, "Failed copying \"%s\"\n", namestr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clipboard->n_entries = 0;
|
||||||
|
GetDirContents(current_dir, current_path);
|
||||||
|
ClearScreenF(true, false, COLOR_STD_BG);
|
||||||
}
|
}
|
||||||
} else { // switched command set
|
} else { // switched command set
|
||||||
// not implemented yet
|
// not implemented yet
|
||||||
|
Loading…
x
Reference in New Issue
Block a user