Added hexviewer feature for all files

... virtual files, too!
This commit is contained in:
d0k3 2016-04-08 21:03:40 +02:00
parent 45501d47eb
commit 080e4f2e29
2 changed files with 112 additions and 4 deletions

View File

@ -7,7 +7,7 @@
#include "virtual.h" #include "virtual.h"
#include "image.h" #include "image.h"
#define VERSION "0.2.8" #define VERSION "0.3.1"
#define N_PANES 2 #define N_PANES 2
#define IMG_DRV "789I" #define IMG_DRV "789I"
@ -20,6 +20,11 @@
#define COLOR_ROOT COLOR_GREY #define COLOR_ROOT COLOR_GREY
#define COLOR_ENTRY(e) (((e)->marked) ? COLOR_MARKED : ((e)->type == T_DIR) ? COLOR_DIR : ((e)->type == T_FILE) ? COLOR_FILE : ((e)->type == T_ROOT) ? COLOR_ROOT : COLOR_GREY) #define COLOR_ENTRY(e) (((e)->marked) ? COLOR_MARKED : ((e)->type == T_DIR) ? COLOR_DIR : ((e)->type == T_FILE) ? COLOR_FILE : ((e)->type == T_ROOT) ? COLOR_ROOT : COLOR_GREY)
#define COLOR_HVOFFS RGB(0x40, 0x60, 0x50)
#define COLOR_HVOFFSI COLOR_DARKESTGREY
#define COLOR_HVASCII RGB(0x40, 0x80, 0x50)
#define COLOR_HVHEX(i) ((i % 2) ? RGB(0x30, 0x90, 0x30) : RGB(0x30, 0x80, 0x30))
typedef struct { typedef struct {
char path[256]; char path[256];
u32 cursor; u32 cursor;
@ -153,6 +158,106 @@ void DrawDirContents(DirStruct* contents, u32 cursor, u32* scroll) {
} else DrawRectangleF(false, SCREEN_WIDTH_BOT - bar_width, 0, bar_width, SCREEN_HEIGHT, COLOR_STD_BG); } else DrawRectangleF(false, SCREEN_WIDTH_BOT - bar_width, 0, bar_width, SCREEN_HEIGHT, COLOR_STD_BG);
} }
u32 HexViewer(const char* path) {
static u32 mode = 0;
u8 data[(SCREEN_HEIGHT / 8) * 16]; // this is the maximum size
int x_off, x_hex, x_ascii;
u32 vpad, hlpad, hrpad;
u32 rows, cols;
u32 total_shown;
u32 total_data;
u32 last_mode = 0xFF;
u32 offset = 0;
while (true) {
if (mode != last_mode) {
switch (mode) { // display mode
case 1:
vpad = hlpad = hrpad = 1;
cols = 12;
x_off = 0;
x_ascii = SCREEN_WIDTH_TOP - (8 * cols);
x_hex = x_off + (8*8) + 12;
break;
case 2:
vpad = 1;
hlpad = 0;
hrpad = 1;
cols = 16;
x_off = -1;
x_ascii = SCREEN_WIDTH_TOP - (8 * cols);
x_hex = 0;
break;
case 3:
vpad = hlpad = hrpad = 1;
cols = 16;
x_off = 20;
x_ascii = -1;
x_hex = x_off + (8*8) + 12;
break;
default:
vpad = hlpad = hrpad = 2;
cols = 8;
x_off = (SCREEN_WIDTH_TOP - SCREEN_WIDTH_BOT) / 2;
x_ascii = SCREEN_WIDTH_TOP - x_off - (8 * cols);
x_hex = (SCREEN_WIDTH_TOP - ((hlpad + 16 + hrpad) * cols)) / 2;
break;
}
rows = 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, false, COLOR_STD_BG);
}
total_data = FileGetData(path, data, total_shown, offset); // get data
// display data on screen
for (u32 row = 0; row < rows; row++) {
char ascii[16 + 1] = { 0 };
u32 y = row * (8 + (2*vpad)) + vpad;
u32 curr_pos = row * cols;
u32 cutoff = (curr_pos >= total_data) ? 0 : (total_data >= curr_pos + cols) ? cols : total_data - curr_pos;
memcpy(ascii, data + curr_pos, cols);
for (u32 col = 0; col < cols; col++)
if ((col >= cutoff) || (ascii[col] == 0x00)) ascii[col] = ' ';
// draw offset / ASCII representation
if (x_off >= 0) DrawStringF(true, x_off, y, cutoff ? COLOR_HVOFFS : COLOR_HVOFFSI, COLOR_STD_BG,
"%08X", (unsigned int) offset + curr_pos);
if (x_ascii >= 0) {
DrawString(TOP_SCREEN0, ascii, x_ascii, y, COLOR_HVASCII, COLOR_STD_BG);
DrawString(TOP_SCREEN1, ascii, x_ascii, y, COLOR_HVASCII, COLOR_STD_BG);
}
// draw HEX values
for (u32 col = 0; (col < cols) && (x_hex >= 0); col++) {
u32 x = (x_hex + hlpad) + ((16 + hrpad + hlpad) * col);
if (col < cutoff)
DrawStringF(true, x, y, COLOR_HVHEX(col), COLOR_STD_BG, "%02X", (unsigned int) data[curr_pos + col]);
else DrawStringF(true, x, y, COLOR_HVHEX(col), COLOR_STD_BG, " ");
}
}
// handle user input
u32 pad_state = InputWait();
u32 step_ud = (pad_state & BUTTON_R1) ? total_shown * 16 : cols;
u32 step_lr = (pad_state & BUTTON_R1) ? total_shown * 256 : total_shown;
if (pad_state & BUTTON_DOWN) offset += step_ud;
else if (pad_state & BUTTON_RIGHT) offset += step_lr;
else if (pad_state & BUTTON_UP) offset = (offset > step_ud) ? offset - step_ud : 0;
else if (pad_state & BUTTON_LEFT) offset = (offset > step_lr) ? offset - step_lr : 0;
else if (pad_state & BUTTON_L1) mode = (mode + 1) % 4;
else if ((pad_state & BUTTON_L1) && (pad_state & BUTTON_R1)) CreateScreenshot();
else if (pad_state & BUTTON_B) break;
}
ClearScreenF(true, false, COLOR_STD_BG);
return 0;
}
u32 GodMode() { u32 GodMode() {
static const u32 quick_stp = 20; static const u32 quick_stp = 20;
u32 exit_mode = GODMODE_EXIT_REBOOT; u32 exit_mode = GODMODE_EXIT_REBOOT;
@ -224,10 +329,10 @@ u32 GodMode() {
cursor = 1; cursor = 1;
scroll = 0; scroll = 0;
} else cursor = 0; } else cursor = 0;
} else if ((pad_state & BUTTON_A) && (curr_entry->type == T_FILE) && } else if ((pad_state & BUTTON_A) && (curr_entry->type == T_FILE)) { // process a file
(PathToNumFS(curr_entry->path) == 0)) { // try to mount image / only on SD
u32 file_type = IdentifyImage(curr_entry->path); u32 file_type = IdentifyImage(curr_entry->path);
if (file_type && ShowPrompt(true, "This looks like a %s image\nTry to mount it?", (file_type == IMG_NAND) ? "NAND" : "FAT")) { if (file_type && (PathToNumFS(curr_entry->path) == 0) && ShowPrompt(true, // try to mount image / only on SD
"This looks like a %s image\nTry to mount it?", (file_type == IMG_NAND) ? "NAND" : "FAT")) {
DeinitExtFS(); DeinitExtFS();
u32 mount_state = MountImage(curr_entry->path); u32 mount_state = MountImage(curr_entry->path);
InitExtFS(); InitExtFS();
@ -243,6 +348,8 @@ u32 GodMode() {
} }
if (clipboard->n_entries && (strcspn(clipboard->entry[0].path, IMG_DRV) == 0)) if (clipboard->n_entries && (strcspn(clipboard->entry[0].path, IMG_DRV) == 0))
clipboard->n_entries = 0; // remove invalid clipboard stuff clipboard->n_entries = 0; // remove invalid clipboard stuff
} else if (ShowPrompt(true, "Show HexViewer?\n \nControls:\n\x18\x19\x1A\x1B(+R) - Scroll\nL - Switch view\nB - Exit\n")) {
HexViewer(curr_entry->path);
} }
} else if (*current_path && ((pad_state & BUTTON_B) || // one level down } else if (*current_path && ((pad_state & BUTTON_B) || // one level down
((pad_state & BUTTON_A) && (curr_entry->type == T_DOTDOT)))) { ((pad_state & BUTTON_A) && (curr_entry->type == T_DOTDOT)))) {

View File

@ -31,6 +31,7 @@
#define COLOR_TINTEDYELLOW RGB(0xD0, 0xD0, 0x60) #define COLOR_TINTEDYELLOW RGB(0xD0, 0xD0, 0x60)
#define COLOR_TINTEDGREEN RGB(0x70, 0x80, 0x70) #define COLOR_TINTEDGREEN RGB(0x70, 0x80, 0x70)
#define COLOR_DARKGREY RGB(0x50, 0x50, 0x50) #define COLOR_DARKGREY RGB(0x50, 0x50, 0x50)
#define COLOR_DARKESTGREY RGB(0x20, 0x20, 0x20)
#define COLOR_TRANSPARENT RGB(0xFF, 0x00, 0xEF) // otherwise known as 'super fuchsia' #define COLOR_TRANSPARENT RGB(0xFF, 0x00, 0xEF) // otherwise known as 'super fuchsia'