From 1dfe4e0375077dea0819448d52f0cd84343317d7 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Fri, 12 Mar 2021 15:18:04 +0100 Subject: [PATCH] mem: use a JustUI scene for the memory browser --- assets-fx/img/opt_mem.png | Bin 3918 -> 6001 bytes include/gintctl/widgets/gscreen.h | 29 +++- src/libs/justui.c | 19 +-- src/mem/mem.c | 257 +++++++++++------------------- src/widgets/gscreen.c | 65 ++++++-- src/widgets/gtable.c | 11 +- 6 files changed, 181 insertions(+), 200 deletions(-) diff --git a/assets-fx/img/opt_mem.png b/assets-fx/img/opt_mem.png index 44ba00b0c59a1c3d083fcbd771975680cdc4620e..695517bc56aef5211fc9fb19fa368c6c49868fd6 100644 GIT binary patch delta 5993 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 D&?AYD diff --git a/include/gintctl/widgets/gscreen.h b/include/gintctl/widgets/gscreen.h index e9d2177..526cace 100644 --- a/include/gintctl/widgets/gscreen.h +++ b/include/gintctl/widgets/gscreen.h @@ -30,6 +30,8 @@ typedef struct { /* Fixed widets */ jlabel *title; jfkeys *fkeys; + /* Current function bar level */ + int8_t fkey_level; } gscreen; @@ -55,6 +57,17 @@ gscreen *gscreen_create(char const *title, char const *fkeys); #define gscreen_create2(short, img, long, fkeys) gscreen_create(long, fkeys) #endif +//--- +// Function bar settings +//--- + +/* gscreen_set_fkeys_level(): Select the function key bar */ +void gscreen_set_fkeys_level(gscreen *s, int level); + +//--- +// Tab settings +//--- + /* gscreen_add_tab(): Add a tab to the stacked layout The child's parent will be changed. The widget will also have a stretch of (1, 1, false) set by default. If not NULL, the last parameter indicates @@ -65,6 +78,16 @@ void gscreen_add_tab(gscreen *scene, void *widget, void *focus); void gscreen_add_tabs(gscreen *s, ...); #define gscreen_add_tabs(...) gscreen_add_tabs(__VA_ARGS__, NULL) +/* gscreen_set_tab_title_visible(): Set whether title bar is shown on a tab */ +void gscreen_set_tab_title_visible(gscreen *s, int tab, bool visible); + +/* gscreen_set_tab_fkeys_visible(): Set whether fkeys are shown on a tab */ +void gscreen_set_tab_fkeys_visible(gscreen *s, int tab, bool visible); + +//--- +// Tab navigation +//--- + /* gscreen_show_tab(): Show a tab from the stack Returns true if the tab changed, false if it was already active or if it is an invalid tab widget. */ @@ -76,12 +99,6 @@ int gscreen_current_tab(gscreen *s); /* gscreen_in(): Check if we're in a specific tab */ bool gscreen_in(gscreen *s, int tab); -/* gscreen_set_tab_title_visible(): Set whether title bar is shown on a tab */ -void gscreen_set_tab_title_visible(gscreen *s, int tab, bool visible); - -/* gscreen_set_tab_fkeys_visible(): Set whether fkeys are shown on a tab */ -void gscreen_set_tab_fkeys_visible(gscreen *s, int tab, bool visible); - //--- // Focus management //--- diff --git a/src/libs/justui.c b/src/libs/justui.c index 4144016..9cef506 100644 --- a/src/libs/justui.c +++ b/src/libs/justui.c @@ -103,11 +103,11 @@ void gintctl_libs_justui(void) jwidget_set_border(c1, J_BORDER_SOLID, 1, C_BLACK); jwidget_set_stretch(c1, 1, 1, false); - jwidget_set_stretch(c3, 2, 0, false); + jwidget_set_stretch(c3, 2, 1, false); gtable_set_rows(c3, 5); gtable_set_column_titles(c3, "C1", "C2", "Column 3"); gtable_set_column_sizes(c3, 1, 1, 3); - gtable_set_font(c3, &font_mini); + gtable_set_font(c3, _(&font_mini, dfont_default())); jinput *input = jinput_create("Prompt:" _(," "), 12, tab1); jwidget_set_stretch(input, 1, 0, false); @@ -118,8 +118,8 @@ void gintctl_libs_justui(void) gtable *tree = gtable_create(3, widget_tree_gen, scr->scene, NULL); gtable_set_column_titles(tree, "Type", "Size", "Content"); gtable_set_column_sizes(tree, 3, 2, 2); - gtable_set_row_spacing(tree, 2); - gtable_set_font(tree, &font_mini); + gtable_set_row_spacing(tree, _(2,3)); + gtable_set_font(tree, _(&font_mini, dfont_default())); // Scene setup @@ -127,15 +127,12 @@ void gintctl_libs_justui(void) gscreen_add_tab(scr, tree, tree); jscene_set_focused_widget(scr->scene, c3); gtable_set_rows(tree, recursive_widget_count(scr->scene)); - gscreen_set_tab_title_visible(scr, 1, false); + gscreen_set_tab_title_visible(scr, 1, _(false,true)); - jevent e; - key_event_t k; int key = 0; - while(key != KEY_EXIT) { - jscene_run(scr->scene, &e, &k); + jevent e = jscene_run(scr->scene); if(e.type == JSCENE_PAINT) { @@ -154,8 +151,8 @@ void gintctl_libs_justui(void) gscreen_focus(scr, c3); } - if(k.type != KEYEV_DOWN) continue; - key = k.key; + if(e.type != JSCENE_KEY || e.key.type != KEYEV_DOWN) continue; + key = e.key.key; if(key == KEY_F3 && gscreen_in(scr, 0)) { diff --git a/src/mem/mem.c b/src/mem/mem.c index e877909..e5bb6fc 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -5,6 +5,17 @@ #include #include +#include + +#include +#include +#include + +struct view { + uint32_t base; + bool ascii; + int lines; +}; /* Code of exception that occurs during a memory access */ static uint32_t exception = 0; @@ -29,10 +40,7 @@ int line(uint8_t *mem, char *header, char *bytes, char *ascii, int n) exception = 0; gint_exc_catch(catch_exc); uint8_t z; - __asm__ volatile( - "mov.l %1, %0" - : "=r"(z) - : "m"(*mem)); + __asm__ volatile("mov.l %1, %0" : "=r"(z) : "m"(*mem)); gint_exc_catch(NULL); sprintf(header, "%08X:", (uint32_t)mem); @@ -72,194 +80,119 @@ int line(uint8_t *mem, char *header, char *bytes, char *ascii, int n) ascii[n] = 0; for(int k = 0; 2 * k < n; k++) - { sprintf(bytes + 5 * k, "%02X%02X ", mem[2*k], mem[2*k+1]); - } + return 0; } -void draw_input(int x, int y, char *text, int cursor_pos) +static void paint_mem(int x, int y, struct view *v) { - int w, h; - int next = text[cursor_pos]; - text[cursor_pos] = 0; - dsize(text, NULL, &w, &h); - text[cursor_pos] = next; + char header[12], bytes[48], ascii[24]; + uint32_t addr = v->base; + uint8_t *mem = (void *)addr; - dtext(x, y, C_BLACK, text); - dline(x+w, y, x+w, y+h-1, C_BLACK); + for(int i = 0; i < v->lines; i++, mem += 8, addr += 8) + { + GUNUSED int status = line(mem, header, bytes, ascii, 8); + + #ifdef FX9860G + font_t const *old_font = dfont(&font_hexa); + dtext(x, y + 6*i, C_BLACK, v->ascii ? ascii : header); + dtext(x + 40, y + 6*i, C_BLACK, bytes); + dfont(old_font); + #endif + + #ifdef FXCG50 + dtext(x, y + 12*i, C_BLACK, header); + dtext(x + 85, y + 12*i, status ? C_RED : C_BLACK, bytes); + + for(int k = 7; k >= 0; k--) + { + ascii[k+1] = 0; + dtext(x + 250 + 9*k, y + 12*i, C_BLACK, ascii+k); + } + #endif + } } /* gintctl_mem(): Memory browser */ void gintctl_mem(void) { - uint32_t base = 0x88000000; - key_event_t ev; + struct view v = { .base = 0x88000000, .ascii = false, .lines = _(9,14) }; + + gscreen *s = gscreen_create2(NULL, &img_opt_mem, + "Memory browser", "@JUMP;;#ROM;#RAM;#ILRAM;#ADDIN"); + jwidget *tab = jwidget_create(NULL); + jpainted *mem = jpainted_create(paint_mem, &v, _(115,321), _(53,167), tab); + jinput *input = jinput_create("Go to:" _(," "), 12, tab); + + jwidget_set_margin(mem, _(0,8), 0, _(0,8), 0); + jwidget_set_margin(input, 0, 0, 0, _(1,4)); + jwidget_set_stretch(input, 1, 0, false); + jwidget_set_visible(input, false); + jlayout_set_vbox(tab)->spacing = _(3,4); + gscreen_add_tab(s, tab, NULL); + int key = 0; - - #ifdef FX9860G - extern font_t font_hexa; - font_t const *old_font = dfont(&font_hexa); - int view_ascii = 0; - #endif - - char header[12]; - char bytes[48]; - char ascii[24]; - - int size = 8; - int lines = _(9,14); - - char input[9]; - int input_pos = -1; - int input_len = -1; - int input_keys[16] = { - KEY_0, KEY_1, KEY_2, KEY_3, - KEY_4, KEY_5, KEY_6, KEY_7, - KEY_8, KEY_9, KEY_XOT, KEY_LOG, - KEY_LN, KEY_SIN, KEY_COS, KEY_TAN, - }; - while(key != KEY_EXIT) { - dclear(C_WHITE); + bool input_focus = (jscene_focused_widget(s->scene) == input); + jevent e = jscene_run(s->scene); - uint32_t addr = base; - uint8_t *mem = (void *)addr; - - for(int i = 0; i < lines; i++) + if(e.type == JSCENE_PAINT) { - GUNUSED int status = line(mem,header,bytes,ascii,size); - - #ifdef FX9860G - dtext( 5, 6*i + 1, C_BLACK, view_ascii?ascii:header); - dtext(45, 6*i + 1, C_BLACK, bytes); - #endif - - #ifdef FXCG50 - dtext(25, 26 + 12*i, C_BLACK, header); - dtext(110, 26 + 12*i, status ? C_RED : C_BLACK, bytes); - - for(int k = size - 1; k >= 0; k--) - { - ascii[k+1] = 0; - dtext(275 + 9*k, 26 + 12*i, C_BLACK, ascii+k); - } - #endif - - mem += size; - addr += size; + dclear(C_WHITE); + jscene_render(s->scene); + dupdate(); } - - #ifdef FX9860G - if(input_pos < 0) - { - extern bopti_image_t img_opt_mem; - dsubimage(0, 56, &img_opt_mem, 0, 0, 128, 8, - DIMAGE_NONE); - if(view_ascii) dsubimage(23, 56, &img_opt_mem, 23, 9, - 21, 8, DIMAGE_NONE); - } - else - { - extern font_t font_mini; - font_t const *old_font = dfont(&font_mini); - - dtext(1, 57, C_BLACK, "Go to:"); - draw_input(24, 57, input, input_pos); - - dfont(old_font); - } - #endif - - #ifdef FXCG50 - row_title("Memory browser"); - if(input_pos < 0) - { - fkey_button(1, "JUMP"); - fkey_action(3, "ROM"); - fkey_action(4, "RAM"); - fkey_action(5, "ILRAM"); - fkey_action(6, "ADDIN"); - } - else - { - dtext(4, 210, C_BLACK, "Go to:"); - draw_input(52, 210, input, input_pos); - } - #endif - - dupdate(); - ev = getkey(); - key = ev.key; - - int move_speed = 1; - if(ev.shift || keydown(KEY_SHIFT)) move_speed = 8; - - if(key == KEY_UP) base -= move_speed * size * lines; - if(key == KEY_DOWN) base += move_speed * size * lines; - - if(key == KEY_F1 && input_pos < 0) - { - input[0] = 0; - input_pos = 0; - input_len = 0; - } - if(key == KEY_EXIT && input_pos >= 0) - { - input_pos = -1; - input_len = -1; - /* Don't quit the memory viewer */ - key = 0; - } - if(key == KEY_EXE && input_pos >= 0) + if(e.type == JINPUT_VALIDATED) { /* Parse string into hexa */ uint32_t target = 0; - for(int k = 0; k < input_len; k++) + char const *str = jinput_value(input); + + for(int k = 0; k < str[k]; k++) { target <<= 4; - if(input[k] <= '9') target += (input[k] - '0'); - else target += (input[k] - 'A' + 10); - - base = target & ~7; + if(str[k] <= '9') target += (str[k] - '0'); + else target += ((str[k]|0x20) - 'a' + 10); } - - input_pos = -1; - input_len = -1; + v.base = target & ~7; + } + if(e.type == JINPUT_VALIDATED || e.type == JINPUT_CANCELED) + { + jwidget_set_visible(input, false); + gscreen_set_tab_fkeys_visible(s, 0, true); + gscreen_focus(s, NULL); } - for(int i = 0; i < 16; i++) - if(key == input_keys[i] && input_pos >= 0 && input_len < 8) + if(e.type != JSCENE_KEY || e.key.type == KEYEV_UP) continue; + key = e.key.key; + + int move_speed = (e.key.shift ? 8 : 1); + if(key == KEY_UP) v.base -= move_speed * 8 * v.lines; + if(key == KEY_DOWN) v.base += move_speed * 8 * v.lines; + + if(key == KEY_F1 && !input_focus) { - /* Insert at input_pos, shift everything else right */ - for(int k = 8; k >= input_pos; k--) - input[k + 1] = input[k]; - input[input_pos++] = i + '0' + 7 * (i > 9); - input_len++; + jinput_clear(input); + jwidget_set_visible(input, true); + gscreen_set_tab_fkeys_visible(s, 0, false); + gscreen_focus(s, input); } - if(key == KEY_DEL && input_pos > 0) - { - /* Shift everything after input_pos left one place */ - for(int k = input_pos - 1; k < 8; k++) - input[k] = input[k + 1]; - input_pos--; - input_len--; - } - if(key == KEY_LEFT && input_pos > 0) input_pos--; - if(key == KEY_RIGHT && input_pos < input_len) input_pos++; #ifdef FX9860G - if(key == KEY_F2 && input_pos < 0) view_ascii = !view_ascii; + if(key == KEY_F2 && !input_focus) + { + v.ascii = !v.ascii; + jfkeys_set_level(s->fkeys, v.ascii); + } #endif - if(key == KEY_F3 && input_pos < 0) base = 0x80000000; - if(key == KEY_F4 && input_pos < 0) base = 0x88000000; - if(key == KEY_F5 && input_pos < 0) base = 0xe5200000; - if(key == KEY_F6 && input_pos < 0) base = 0x00300000; + if(key == KEY_F3 && !input_focus) v.base = 0x80000000; + if(key == KEY_F4 && !input_focus) v.base = 0x88000000; + if(key == KEY_F5 && !input_focus) v.base = 0xe5200000; + if(key == KEY_F6 && !input_focus) v.base = 0x00300000; + mem->widget.update = 1; } - - #ifdef FX9860G - dfont(old_font); - #endif } diff --git a/src/widgets/gscreen.c b/src/widgets/gscreen.c index 772fac1..34bf225 100644 --- a/src/widgets/gscreen.c +++ b/src/widgets/gscreen.c @@ -23,6 +23,7 @@ gscreen *gscreen_create(char const *name, char const *labels) g->scene = s; g->tabs = NULL; g->tab_count = 0; + g->fkey_level = 0; jlabel *title = name ? jlabel_create(name, s) : NULL; jwidget *stack = jwidget_create(s); @@ -63,6 +64,27 @@ gscreen *gscreen_create(char const *name, char const *labels) return g; } +/* tab_stack(): Stacked widget where the tabs are located */ +static jwidget *tab_stack(gscreen *s) +{ + int index = (s->title != NULL) ? 1 : 0; + return s->scene->widget.children[index]; +} + +//--- +// Function bar settings +//--- + +/* gscreen_set_fkeys_level(): Select the function key bar */ +void gscreen_set_fkeys_level(gscreen *s, int level) +{ + s->fkey_level = level; +} + +//--- +// Tab settings +//--- + void gscreen_add_tab(gscreen *s, void *widget, void *focus) { struct gscreen_tab *t = realloc(s->tabs, (s->tab_count+1) * sizeof *t); @@ -74,8 +96,7 @@ void gscreen_add_tab(gscreen *s, void *widget, void *focus) s->tabs[s->tab_count].focus = focus; s->tab_count++; - jwidget *stack = s->scene->widget.children[1]; - jwidget_add_child(stack, widget); + jwidget_add_child(tab_stack(s), widget); jwidget_set_stretch(widget, 1, 1, false); } @@ -92,9 +113,31 @@ void gscreen_add_tabs(gscreen *s, ...) va_end(args); } +void gscreen_set_tab_title_visible(gscreen *s, int tab, bool visible) +{ + if(!s->title || tab < 0 || tab >= s->tab_count) return; + s->tabs[tab].title_visible = visible; + + if(gscreen_current_tab(s) == tab) + jwidget_set_visible(s->title, visible); +} + +void gscreen_set_tab_fkeys_visible(gscreen *s, int tab, bool visible) +{ + if(!s->fkeys || tab < 0 || tab >= s->tab_count) return; + s->tabs[tab].fkeys_visible = visible; + + if(gscreen_current_tab(s) == tab) + jwidget_set_visible(s->fkeys, visible); +} + +//--- +// Tab navigation +//--- + bool gscreen_show_tab(gscreen *s, int tab) { - jwidget *stack = s->scene->widget.children[1]; + jwidget *stack = tab_stack(s); jlayout_stack *l = jlayout_get_stack(stack); /* Find widget ID in the stack @@ -119,7 +162,7 @@ bool gscreen_show_tab(gscreen *s, int tab) int gscreen_current_tab(gscreen *s) { - jwidget *stack = s->scene->widget.children[1]; + jwidget *stack = tab_stack(s); jlayout_stack *l = jlayout_get_stack(stack); return l->active; } @@ -129,17 +172,9 @@ bool gscreen_in(gscreen *s, int tab) return gscreen_current_tab(s) == tab; } -void gscreen_set_tab_title_visible(gscreen *s, int tab, bool visible) -{ - if(tab < 0 || tab >= s->tab_count) return; - s->tabs[tab].title_visible = visible; -} - -void gscreen_set_tab_fkeys_visible(gscreen *s, int tab, bool visible) -{ - if(tab < 0 || tab >= s->tab_count) return; - s->tabs[tab].fkeys_visible = visible; -} +//--- +// Focus management +//--- void gscreen_focus(gscreen *s, void *widget) { diff --git a/src/widgets/gtable.c b/src/widgets/gtable.c index 12b6330..443e0fd 100644 --- a/src/widgets/gtable.c +++ b/src/widgets/gtable.c @@ -311,17 +311,16 @@ static bool gtable_poly_event(void *t0, jevent e) if(e.type != JWIDGET_KEY) return false; - key_event_t kev = e.data.key; - if(kev.type == KEYEV_UP) return false; + if(e.key.type == KEYEV_UP) return false; - if(kev.key == KEY_DOWN && t->offset < end) { - if(kev.shift) t->offset = end; + if(e.key.key == KEY_DOWN && t->offset < end) { + if(e.key.shift) t->offset = end; else t->offset++; t->widget.update = 1; return true; } - if(kev.key == KEY_UP && t->offset > 0) { - if(kev.shift) t->offset = 0; + if(e.key.key == KEY_UP && t->offset > 0) { + if(e.key.shift) t->offset = 0; else t->offset--; t->widget.update = 1; return true;