Misc bugfixes + non working copy / delete features

This commit is contained in:
d0k3 2016-03-02 14:01:20 +01:00
parent dbc7015d2a
commit 7ab86c87a3
4 changed files with 84 additions and 29 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);
} }

View File

@ -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