diff --git a/source/fs.c b/source/fs.c index 729664d..cd9d1d9 100644 --- a/source/fs.c +++ b/source/fs.c @@ -425,7 +425,7 @@ bool PathCopyVirtual(const char* destdir, const char* orig) { char* dname = strrchr(dest, '/'); if (dname == NULL) return false; dname++; - if (!ShowInputPrompt(dname, 255 - (dname - dest), "Choose new destination name")) + if (!ShowStringPrompt(dname, 255 - (dname - dest), "Choose new destination name")) return false; } while (f_stat(dest, NULL) == FR_OK); } else if (user_select != 2) return (user_select == 3); @@ -487,7 +487,7 @@ bool PathCopyWorker(char* dest, char* orig, bool overwrite, bool move) { // check if destination is part of or equal origin while (strncmp(dest, orig, 255) == 0) { - if (!ShowInputPrompt(dname, 255 - (dname - dest), "Destination is equal to origin\nChoose another name?")) + if (!ShowStringPrompt(dname, 255 - (dname - dest), "Destination is equal to origin\nChoose another name?")) return false; } if (strncmp(dest, orig, strnlen(orig, 255)) == 0) { @@ -505,7 +505,7 @@ bool PathCopyWorker(char* dest, char* orig, bool overwrite, bool move) { u32 user_select = ShowSelectPrompt(3, optionstr, "Destination already exists:\n%s", namestr); if (user_select == 1) { do { - if (!ShowInputPrompt(dname, 255 - (dname - dest), "Choose new destination name")) + if (!ShowStringPrompt(dname, 255 - (dname - dest), "Choose new destination name")) return false; } while (f_stat(dest, NULL) == FR_OK); } else if (user_select != 2) return (user_select == 3); diff --git a/source/godmode.c b/source/godmode.c index 92d33f0..3ddc323 100644 --- a/source/godmode.c +++ b/source/godmode.c @@ -233,13 +233,13 @@ u32 HexViewer(const char* path) { } rows = (dual_screen ? 2 : 1) * SCREEN_HEIGHT / (8 + (2*vpad)); total_shown = rows * cols; - if (offset % cols) offset -= (offset % cols); // fix offset (align to cols) last_mode = mode; ClearScreenF(true, dual_screen, COLOR_STD_BG); if (!dual_screen) memcpy(BOT_SCREEN, bottom_cpy, (SCREEN_HEIGHT * SCREEN_WIDTH_BOT * 3)); } // fix offset (if required) - if (offset + total_shown > fsize + cols) + if (offset % cols) offset -= (offset % cols); // fix offset (align to cols) + if (offset + total_shown > fsize + cols) // if offset too big offset = (total_shown > fsize) ? 0 : (fsize + cols - total_shown - (fsize % cols)); // get data, using max data size (if new offset) if (offset != last_offset) { @@ -305,6 +305,11 @@ u32 HexViewer(const char* path) { else if ((pad_state & BUTTON_R1) && (pad_state & BUTTON_Y)) mode = (mode + 1) % 4; else if (pad_state & BUTTON_A) edit_mode = true; else if (pad_state & BUTTON_B) break; + else if (pad_state & BUTTON_X) { + u64 new_offset = ShowHexPrompt(offset, 8, "Current offset: %08X\nEnter new offset below.", + (unsigned int) offset); + if (new_offset != (u64) -1) offset = new_offset; + } if (edit_mode && CheckWritePermissions(path)) { // setup edit mode cursor = 0; edit_start = ((offset - (offset % 0x200) <= (edit_bsize / 2)) || (fsize < edit_bsize)) ? 0 : @@ -449,7 +454,7 @@ u32 GodMode() { if (user_select == 1) { // -> show in hex viewer static bool show_instr = true; if (show_instr) { - ShowPrompt(false, "Hexeditor Controls:\n \n\x18\x19\x1A\x1B(+R) - Scroll\nR+Y - Switch view\nA - Enter edit mode\nA+\x18\x19\x1A\x1B - Edit value\nB - Exit\n"); + ShowPrompt(false, "Hexeditor Controls:\n \n\x18\x19\x1A\x1B(+R) - Scroll\nR+Y - Switch view\nX - Goto offset\nA - Enter edit mode\nA+\x18\x19\x1A\x1B - Edit value\nB - Exit\n"); show_instr = false; } HexViewer(curr_entry->path); @@ -648,7 +653,7 @@ u32 GodMode() { char namestr[20+1]; TruncateString(namestr, curr_entry->name, 20, 12); snprintf(newname, 255, curr_entry->name); - if (ShowInputPrompt(newname, 256, "Rename %s?\nEnter new name below.", namestr)) { + if (ShowStringPrompt(newname, 256, "Rename %s?\nEnter new name below.", namestr)) { if (!PathRename(curr_entry->path, newname)) ShowPrompt(false, "Failed renaming path:\n%s", namestr); else { @@ -660,7 +665,7 @@ u32 GodMode() { } else if (pad_state & BUTTON_Y) { // create a folder char dirname[256]; snprintf(dirname, 255, "newdir"); - if (ShowInputPrompt(dirname, 256, "Create a new folder here?\nEnter name below.")) { + if (ShowStringPrompt(dirname, 256, "Create a new folder here?\nEnter name below.")) { if (!DirCreate(current_path, dirname)) { char namestr[36+1]; TruncateString(namestr, dirname, 36, 12); diff --git a/source/ui.c b/source/ui.c index 42480be..0c16a7c 100644 --- a/source/ui.c +++ b/source/ui.c @@ -318,8 +318,7 @@ u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...) { return (sel >= n) ? 0 : sel + 1; } -bool ShowInputPrompt(char* inputstr, u32 max_size, const char *format, ...) { - const char* alphabet = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz(){}[]'`^,~!@#$%&0123456789=+-_."; +bool ShowInputPrompt(char* inputstr, u32 max_size, u32 resize, const char* alphabet, const char *format, va_list va) { const u32 alphabet_size = strnlen(alphabet, 256); const u32 input_shown = 22; const u32 fast_scroll = 4; @@ -328,14 +327,14 @@ bool ShowInputPrompt(char* inputstr, u32 max_size, const char *format, ...) { u32 x, y; char str[STRBUF_SIZE] = { 0 }; - va_list va; - va_start(va, format); vsnprintf(str, STRBUF_SIZE, format, va); - va_end(va); // check / fix up the inputstring if required if (max_size < 2) return false; // catching this, too - if (*inputstr == '\0') snprintf(inputstr, 2, "%c", alphabet[0]); // set the string if it is not set + if ((*inputstr == '\0') || (resize && (strnlen(inputstr, max_size - 1) % resize))) { + memset(inputstr, alphabet[0], resize); // set the string if it is not set or invalid + inputstr[resize] = '\0'; + } str_width = GetDrawStringWidth(str); str_height = GetDrawStringHeight(str) + (8*10); @@ -345,7 +344,7 @@ bool ShowInputPrompt(char* inputstr, u32 max_size, const char *format, ...) { ClearScreenF(true, false, COLOR_STD_BG); DrawStringF(TOP_SCREEN, x, y, COLOR_STD_FONT, COLOR_STD_BG, str); - DrawStringF(TOP_SCREEN, x + 8, y + str_height - 38, COLOR_STD_FONT, COLOR_STD_BG, "R - (\x18\x19) fast scroll\nL - clear string\nX - remove char\nY - insert char"); + DrawStringF(TOP_SCREEN, x + 8, y + str_height - 38, COLOR_STD_FONT, COLOR_STD_BG, "R - (\x18\x19) fast scroll\nL - clear data%s", resize ? "\nX - remove char\nY - insert char" : ""); int cursor_a = -1; u32 cursor_s = 0; @@ -384,22 +383,28 @@ bool ShowInputPrompt(char* inputstr, u32 max_size, const char *format, ...) { break; } else if (pad_state & BUTTON_L1) { cursor_a = 0; - cursor_s = 0; - inputstr[0] = alphabet[0]; - inputstr[1] = '\0'; + memset(inputstr, alphabet[0], inputstr_size); + if (resize) { + cursor_s = 0; + inputstr[1] = '\0'; + } } else if (pad_state & BUTTON_X) { - if (inputstr_size > 1) { - memmove(&inputstr[cursor_s], &inputstr[cursor_s + 1], (max_size - 1) - cursor_s); - inputstr_size--; - if (cursor_s >= inputstr_size) + if (resize && (inputstr_size > resize)) { + char* inputfrom = inputstr + cursor_s - (cursor_s % resize) + resize; + char* inputto = inputstr + cursor_s - (cursor_s % resize); + memmove(inputto, inputfrom, max_size - (inputfrom - inputstr)); + inputstr_size -= resize; + while (cursor_s >= inputstr_size) cursor_s--; cursor_a = -1; - } else inputstr[0] = alphabet[0]; + } else if (resize == 1) inputstr[0] = alphabet[0]; } else if (pad_state & BUTTON_Y) { - if (inputstr_size < max_size - 1) { - memmove(&inputstr[cursor_s + 1], &inputstr[cursor_s], (max_size - 1 )- cursor_s); - inputstr_size++; - inputstr[cursor_s] = alphabet[0]; + if (resize && (inputstr_size < max_size - resize)) { + char* inputfrom = inputstr + cursor_s - (cursor_s % resize); + char* inputto = inputstr + cursor_s - (cursor_s % resize) + resize; + memmove(inputto, inputfrom, max_size - (inputto - inputstr)); + inputstr_size += resize; + memset(inputfrom, alphabet[0], resize); cursor_a = 0; } } else if (pad_state & BUTTON_UP) { @@ -416,8 +421,8 @@ bool ShowInputPrompt(char* inputstr, u32 max_size, const char *format, ...) { } else if (pad_state & BUTTON_RIGHT) { if (cursor_s < max_size - 2) cursor_s++; if (cursor_s >= inputstr_size) { - inputstr[cursor_s] = alphabet[0]; - inputstr[cursor_s+1] = '\0'; + memset(inputstr + cursor_s, alphabet[0], resize); + inputstr[cursor_s + resize] = '\0'; } cursor_a = -1; } @@ -431,6 +436,36 @@ bool ShowInputPrompt(char* inputstr, u32 max_size, const char *format, ...) { return ret; } +bool ShowStringPrompt(char* inputstr, u32 max_size, const char *format, ...) { + const char* alphabet = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz(){}[]'`^,~!@#$%&0123456789=+-_."; + bool ret = false; + va_list va; + + va_start(va, format); + ret = ShowInputPrompt(inputstr, max_size, 1, alphabet, format, va); + va_end(va); + + return ret; +} + +u64 ShowHexPrompt(u64 start_val, u32 n_digits, const char *format, ...) { + const char* alphabet = "0123456789ABCDEF"; + char inputstr[16 + 1] = { 0 }; + u64 ret = 0; + va_list va; + + if (n_digits > 16) n_digits = 16; + snprintf(inputstr, 16 + 1, "%0*llX", (int) n_digits, start_val); + + va_start(va, format); + if (ShowInputPrompt(inputstr, n_digits + 1, 0, alphabet, format, va)) { + sscanf(inputstr, "%llX", &ret); + } else ret = (u64) -1; + va_end(va); + + return ret; +} + bool ShowProgress(u64 current, u64 total, const char* opstr) { static u32 last_prog_width = 0; diff --git a/source/ui.h b/source/ui.h index 116f2fb..311750f 100644 --- a/source/ui.h +++ b/source/ui.h @@ -70,5 +70,6 @@ void ShowString(const char *format, ...); bool ShowPrompt(bool ask, const char *format, ...); bool ShowUnlockSequence(u32 seqlvl, const char *format, ...); u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...); -bool ShowInputPrompt(char* inputstr, u32 max_size, const char *format, ...); +bool ShowStringPrompt(char* inputstr, u32 max_size, const char *format, ...); +u64 ShowHexPrompt(u64 start_val, u32 n_digits, const char *format, ...); bool ShowProgress(u64 current, u64 total, const char* opstr);