mem: use a JustUI scene for the memory browser

This commit is contained in:
Lephenixnoir 2021-03-12 15:18:04 +01:00
parent 9a9c366821
commit 1dfe4e0375
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
6 changed files with 181 additions and 200 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

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

View File

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

View File

@ -5,6 +5,17 @@
#include <gintctl/mem.h>
#include <gintctl/util.h>
#include <gintctl/assets.h>
#include <gintctl/widgets/gscreen.h>
#include <justui/jpainted.h>
#include <justui/jinput.h>
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
}

View File

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

View File

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