mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 05:32: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 width = 0;
|
||||
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;
|
||||
old_lf = lf;
|
||||
}
|
||||
if (old_lf == str)
|
||||
width = strnlen(str, 256);
|
||||
if (str_end - old_lf > width)
|
||||
width = str_end - old_lf;
|
||||
width *= 8;
|
||||
return width;
|
||||
}
|
||||
@ -170,6 +171,7 @@ bool ShowPrompt(bool ask, const char *format, ...)
|
||||
{
|
||||
u32 str_width, str_height;
|
||||
u32 x, y;
|
||||
bool ret = true;
|
||||
|
||||
char str[512] = {}; // 512 should be more than enough
|
||||
va_list va;
|
||||
@ -180,6 +182,7 @@ bool ShowPrompt(bool ask, const char *format, ...)
|
||||
|
||||
str_width = GetDrawStringWidth(str);
|
||||
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;
|
||||
y = (str_height >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - str_height) / 2;
|
||||
|
||||
@ -190,12 +193,15 @@ bool ShowPrompt(bool ask, const char *format, ...)
|
||||
while (true) {
|
||||
u32 pad_state = InputWait();
|
||||
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);
|
||||
|
||||
return true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ShowUnlockSequence(u32 seqlvl, const char *format, ...) {
|
||||
@ -227,6 +233,7 @@ bool ShowUnlockSequence(u32 seqlvl, const char *format, ...) {
|
||||
|
||||
str_width = GetDrawStringWidth(str);
|
||||
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;
|
||||
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 */
|
||||
)
|
||||
{
|
||||
if ((pdrv > 0) && mode_n3ds) // is this really set at this point?
|
||||
if ((pdrv > 0) && mode_n3ds)
|
||||
pdrv += 6;
|
||||
|
||||
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
|
||||
static u8* main_buffer = (u8*)0x21100000;
|
||||
// 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
|
||||
static u32 write_permission_level = 1;
|
||||
@ -46,7 +46,7 @@ void DeinitFS() {
|
||||
}
|
||||
|
||||
bool CheckWritePermissions(const char* path) {
|
||||
u32 pdrv = *path - '0';
|
||||
u32 pdrv = (*path) - '0';
|
||||
|
||||
if ((pdrv > 6) || (*(path+1) != ':')) {
|
||||
ShowPrompt(false, "Invalid path");
|
||||
@ -144,18 +144,18 @@ bool PathCopyWorker(char* dest, char* orig) {
|
||||
DIR pdir;
|
||||
char* fname = orig + strnlen(orig, 256);
|
||||
|
||||
*(fname++) = '/';
|
||||
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)
|
||||
if ((f_stat(dest, NULL) != FR_OK) && (f_mkdir(dest) != FR_OK))
|
||||
return false;
|
||||
|
||||
if (f_opendir(&pdir, orig) != FR_OK)
|
||||
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) {
|
||||
ShowPrompt(false, "Trying:\n%s\n%s", orig, dest);
|
||||
if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0))
|
||||
continue; // filter out virtual entries
|
||||
if (fname[0] == 0)
|
||||
@ -164,6 +164,7 @@ bool PathCopyWorker(char* dest, char* orig) {
|
||||
ret = true;
|
||||
break;
|
||||
} else if (!PathCopyWorker(dest, orig)) {
|
||||
ShowPrompt(false, "Failed:\n%s\n%s", orig, dest);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -185,6 +186,7 @@ bool PathCopyWorker(char* dest, char* orig) {
|
||||
f_lseek(&ofile, 0);
|
||||
f_sync(&ofile);
|
||||
|
||||
ret = true;
|
||||
for (size_t pos = 0; pos < fsize; pos += main_buffer_size) {
|
||||
UINT bytes_read = 0;
|
||||
UINT bytes_written = 0;
|
||||
@ -196,6 +198,7 @@ bool PathCopyWorker(char* dest, char* orig) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ShowProgress(1, 1, orig, false);
|
||||
|
||||
f_close(&ofile);
|
||||
f_close(&dfile);
|
||||
@ -219,16 +222,16 @@ bool PathDeleteWorker(char* fpath) {
|
||||
|
||||
// the deletion process takes place here
|
||||
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;
|
||||
char* fname = fpath + strnlen(fpath, 256);
|
||||
|
||||
if (f_opendir(&pdir, fpath) != FR_OK)
|
||||
return false;
|
||||
*(fname++) = '/';
|
||||
fno.lfname = fname;
|
||||
fno.lfsize = 256 - (fname - fpath);
|
||||
|
||||
if (f_opendir(&pdir, fpath) != FR_OK)
|
||||
return false;
|
||||
while (f_readdir(&pdir, &fno) == FR_OK) {
|
||||
if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0))
|
||||
continue; // filter out virtual entries
|
||||
@ -241,6 +244,7 @@ bool PathDeleteWorker(char* fpath) {
|
||||
}
|
||||
}
|
||||
f_closedir(&pdir);
|
||||
*(--fname) = '\0';
|
||||
} else { // processing files...
|
||||
ret = (f_unlink(fpath) == FR_OK);
|
||||
}
|
||||
|
@ -69,14 +69,16 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, DirStruct* c
|
||||
|
||||
// bottom: inctruction block
|
||||
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
|
||||
(*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" :
|
||||
(GetWritePermissions() <= 1) ? "X - Unlock EmuNAND writing\nY - Unlock SysNAND writing\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" :
|
||||
"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" :
|
||||
"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\nSTART - Reboot / [+\x1B] Poweroff"); // generic end part
|
||||
"X - Relock EmuNAND writing\nY - Relock SysNAND writing\n"),
|
||||
"R+L - Make a Screenshot\n",
|
||||
(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);
|
||||
}
|
||||
|
||||
@ -135,6 +137,7 @@ u32 GodMode() {
|
||||
char current_path[256] = { 0x00 };
|
||||
|
||||
int mark_setting = -1;
|
||||
u32 last_clipboard_size = 0;
|
||||
bool switched = false;
|
||||
u32 cursor = 0;
|
||||
|
||||
@ -143,7 +146,7 @@ u32 GodMode() {
|
||||
|
||||
GetDirContents(current_dir, "");
|
||||
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);
|
||||
DrawDirContents(current_dir, cursor);
|
||||
u32 pad_state = InputWait();
|
||||
@ -163,7 +166,7 @@ u32 GodMode() {
|
||||
else *current_path = '\0';
|
||||
GetDirContents(current_dir, current_path);
|
||||
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++;
|
||||
} else if ((pad_state & BUTTON_UP) && cursor) { // cursor down
|
||||
cursor--;
|
||||
@ -189,8 +192,8 @@ u32 GodMode() {
|
||||
current_dir->entry[cursor].marked ^= 0x1;
|
||||
mark_setting = current_dir->entry[cursor].marked;
|
||||
}
|
||||
} else if ((pad_state & BUTTON_SELECT) && (clipboard->n_entries > 0)) { // clear clipboard
|
||||
clipboard->n_entries = 0;
|
||||
} else if (pad_state & BUTTON_SELECT) { // clear/restore clipboard
|
||||
clipboard->n_entries = (clipboard->n_entries > 0) ? 0 : last_clipboard_size;
|
||||
}
|
||||
|
||||
// highly specific commands
|
||||
@ -202,7 +205,26 @@ u32 GodMode() {
|
||||
}
|
||||
} else if (!switched) { // standard unswitched command set
|
||||
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
|
||||
for (u32 c = 0; c < current_dir->n_entries; c++) {
|
||||
if (current_dir->entry[c].marked) {
|
||||
@ -215,6 +237,28 @@ u32 GodMode() {
|
||||
DirEntryCpy(&(clipboard->entry[0]), &(current_dir->entry[cursor]));
|
||||
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
|
||||
// not implemented yet
|
||||
|
Loading…
x
Reference in New Issue
Block a user