Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "rl.h"
- volatile int exit_flag=0;
- char *watch_module_id = NULL;
- char watch_wahe_name[51];
- #define BYTES_PER_UNIT (32.*1024.)
- #define CITA_MAX_INFO_SIZE 128
- typedef struct
- {
- int focus_index;
- xy_t pos0, pos1;
- double zoomscale_base, zoomscale_top;
- double time0, time1, time2, time3;
- double result_id_v;
- int zoom_transition_on, filter_count;
- } filter_focus_t;
- typedef struct
- {
- int64_t addr, size;
- char info[CITA_MAX_INFO_SIZE+1], *label;
- xy_t pos;
- rect_t area;
- col_t colour;
- double row;
- int filtered, filter_pos;
- } mem_range_t;
- typedef struct
- {
- char *name;
- int64_t addr;
- } mem_type_start_t;
- typedef enum { no_img, pal8, bw_bit, rgbx8 } vis_mode_t;
- const char *vis_mode_name[] = { "None", "Palettised bytes", "Black & white bits", "sRGBX 8-bit" };
- vis_mode_t vis_mode = no_img;
- mem_range_t *mem_range = NULL;
- size_t mem_range_count = 0, mem_range_as = 0;
- mem_type_start_t *mts = NULL;
- size_t mts_count = 0, mts_as = 0, mts_index = 0;
- double max_row, starting_row = 0.;
- size_t pixel_address = (size_t) -1;
- int first_range_in_current_file;
- int vert = 1, img_update = 0, image_stride = 0, image_offset = 0;
- size_t filtered_size = 0;
- xy_t flip_xy(xy_t a)
- {
- if (vert)
- return (xy(a.y, a.x));
- return a;
- }
- xyi_t flip_xyi(xyi_t a)
- {
- if (vert)
- return (xyi(a.y, a.x));
- return a;
- }
- size_t pix_to_addr(xyi_t pos, xyi_t im_dim)
- {
- pos = flip_xyi(pos);
- int32_t dim_y = flip_xyi(im_dim).y;
- pos.y -= image_offset;
- if (vis_mode == bw_bit)
- {
- pos.y >>= 3;
- dim_y >>= 3;
- }
- if (vis_mode == rgbx8)
- {
- pos.y *= 4;
- dim_y *= 4;
- }
- return pos.x * dim_y + pos.y;
- }
- sqrgb_t *make_byte_palette()
- {
- sqrgb_t *pal = calloc(256, sizeof(sqrgb_t));
- for (int i=0; i < 256; i++)
- {
- double t = (255. - (double) i) * 0.2;
- double m = sqrt((double) i / 255.);
- double red = (1.-fabs(sin_tr(0.16 * t))) * m;
- double grn = (1.-fabs(sin_tr(0.02 * t))) * (double) i/255.;
- double blu = (1.-fabs(sin_tr(0.15 * t))) * m;
- pal[i].r = sqrt(red) * 1023. + 0.5;
- pal[i].g = sqrt(grn) * 4092. + 0.5;
- pal[i].b = sqrt(blu) * 1023. + 0.5;
- }
- return pal;
- }
- void prepare_focus_transition(filter_focus_t *focus, int way)
- {
- // Update result ID
- focus->result_id_v = circ_index(nearbyint(focus->result_id_v) + way, focus->filter_count);
- // Find message index of new focus message
- for (int ir=0; ir < mem_range_count; ir++)
- if (mem_range[ir].filter_pos == focus->result_id_v)
- {
- focus->focus_index = ir;
- break;
- }
- if (focus->focus_index < 0) // not sure why
- focus->focus_index = 0;
- focus->pos0 = xyq_to_xy(zc.offset_uq);
- focus->pos1 = rect_p01(mem_range[focus->focus_index].area);
- focus->zoomscale_base = zc.zoomscale;
- focus->zoomscale_top = MINN(focus->zoomscale_base, 14. / hypot_xy(focus->pos0, focus->pos1));
- focus->time0 = get_time_hr();
- focus->time1 = focus->time0 + 0.13 * (focus->zoomscale_base != focus->zoomscale_top);
- focus->time2 = focus->time1 + 0.5 * MAXN(0., hypot_xy(focus->pos0, focus->pos1) * focus->zoomscale_top - 7.) / (14.-7.);
- focus->time3 = focus->time2 + 0.13 * (focus->zoomscale_base != focus->zoomscale_top);
- focus->zoom_transition_on = 1;
- }
- void perform_focus_transition(filter_focus_t *focus)
- {
- double now, t;
- if (focus->zoom_transition_on == 0)
- return;
- now = get_time_hr();
- if (now <= focus->time1) // zoom out at pos0
- {
- zc.offset_uq = xy_to_xyq(focus->pos0);
- t = (now - focus->time0) / (focus->time1 - focus->time0);
- //t = floor(t * 2.) / 2.;
- zc.zoomscale = exp(mix(log(focus->zoomscale_base), log(focus->zoomscale_top), t));
- }
- else if (now <= focus->time2) // travel from pos0 to pos1 zoomed out
- {
- t = (now - focus->time1) / (focus->time2 - focus->time1);
- //t = floor(t * 3.) / 3.;
- zc.offset_uq = xy_to_xyq(mix_xy(focus->pos0, focus->pos1, set_xy(t)));
- zc.zoomscale = focus->zoomscale_top;
- }
- else if (now <= focus->time3) // zoom in at pos1
- {
- zc.offset_uq = xy_to_xyq(focus->pos1);
- t = (now - focus->time2) / (focus->time3 - focus->time2);
- //t = floor(t * 2.) / 2.;
- zc.zoomscale = exp(mix(log(focus->zoomscale_top), log(focus->zoomscale_base), t));
- }
- else // end the transition
- {
- zc.offset_uq = xy_to_xyq(focus->pos1);
- zc.zoomscale = focus->zoomscale_base;
- focus->zoom_transition_on = 0;
- }
- calc_screen_limits(&zc);
- }
- void knob_print_addr_hex(char *str, knob_t *knob_data, double value)
- {
- sprintf(str, "0x%zx", (size_t)nearbyint(value));
- }
- double knob_parse_addr_hex(const char *str, knob_t *knob_data)
- {
- int64_t vi = 0;
- sscanf(str, "%" SCNi64, &vi);
- return (double)vi;
- }
- void cita_vis_options_window(int *memory_update, int *update_cont, xy_t *visual_item_rect, int *knob_ret, char **filter_string, filter_focus_t *focus, double *image_stride_v, double *image_offset_v)
- {
- // GUI layout
- static gui_layout_t layout={0};
- const char *layout_src[] = {
- "elem 0", "type none", "label Options", "pos 0 0", "dim 3 12;1;6", "off 0 1", "",
- "elem 20", "type knob", "label A square is", "knob 0.015625 64 8192 log %.2g", "knob_unit kB", "link_pos_id 60.cb", "pos -0;1 -0;3", "dim 1", "off 1", "",
- "elem 21", "type knob", "label Image stride", "knob 1 256 16384 logoff %.0f", "knob_arg 40", "knob_unit pixels", "link_pos_id 20", "pos 0;2 0", "dim 1", "off 0 1", "",
- "elem 22", "type knob", "label Pixel offset", "knob 0 0 80 linear %.0f", "link_pos_id 21.rb", "pos 0 -0;1;6", "dim 0;8", "off 1", "",
- "elem 30", "type textedit", "link_pos_id 70.cb", "pos 0 -0;6;6", "dim 2 0;7", "off 0;6 1", "",
- "elem 31", "type label", "label Filter:", "link_pos_id 30.lt", "pos 0;1 0;0;6", "dim 1;10 0;4", "off 0", "",
- "elem 40", "type button", "label \342\207\246", "link_pos_id 30.lb", "pos 0 -0;2", "dim 0;7", "off 0 1", "",
- "elem 41", "type button", "label Go", "link_pos_id 40.r_", "pos 0;1;6 0", "dim 0;7", "off 0 1", "",
- "elem 42", "type button", "label \342\207\250", "link_pos_id 41.r_", "pos 0;1;6 0", "dim 0;7", "off 0 1", "",
- "elem 45", "type knob", "label Result #", "knob 0 0 667 linear %.0f", "link_pos_id 41.cb", "pos 0 -0;1;6", "dim 1;2;6", "off 0;6 1", "",
- "elem 46", "type label", "link_pos_id 45.cb", "pos 0 -0;2;6", "dim 2 0;4;6", "off 0;6 1", "",
- "elem 50", "type button", "label Update", "pos 0;6 -1", "dim 2 0;9", "off 0 1", "",
- "elem 51", "type checkbox", "label Update continuously", "link_pos_id 50.cb", "pos 0 -0;2", "dim 2 0;6", "off 0;6 1", "",
- "elem 60", "type selmenu", "link_pos_id 51.cb", "pos 0 -0;6;6", "dim 2 0;6", "off 0;6 1", "",
- "elem 61", "type label", "label Visualisation mode", "link_pos_id 60.lt", "pos 0;1 0;0;6", "dim 1;10 0;3", "off 0", "",
- "elem 70", "type knob", "label View address", "knob 0 0 4.29497e+09 logoff", "knob_arg 1e+06", "link_pos_id 60.cb", "pos 0 -2", "dim 2", "off 0;6 1", "",
- "elem 80", "type checkbox", "label Vertical layout", "link_pos_id 46.cb", "pos 0 -0;2;6", "dim 2 0;4", "off 0;6 1", "",
- };
- gui_layout_init_pos_scale(&layout, XY0, 1., XY0, 0);
- make_gui_layout(&layout, layout_src, sizeof(layout_src)/sizeof(char *), "CIT Alloc visualiser options");
- // GUI window
- static flwindow_t window={0};
- flwindow_init_defaults(&window);
- flwindow_init_pinned(&window);
- window.bg_opacity = 0.94;
- window.shadow_strength = 0.5*window.bg_opacity;
- draw_dialog_window_fromlayout(&window, cur_wind_on, &cur_parent_area, &layout, 0);
- // GUI controls
- *memory_update = ctrl_button_fromlayout(&layout, 50);
- ctrl_checkbox_fromlayout(update_cont, &layout, 51);
- // Address knob
- double addr_offset = 0.;
- if (mts)
- addr_offset = mts[mts_index].addr;
- static double addr_v=NAN;
- static int addr_ret = 0;
- xy_t new_pos0 = XYNAN;
- static xy_t new_pos1 = {NAN, NAN};
- knob_t *knob_data = get_knob_data_fromlayout(&layout, 70);
- knob_data->display_print_func = knob_print_addr_hex;
- knob_data->editor_print_func = knob_print_addr_hex;
- knob_data->parse_func = knob_parse_addr_hex;
- knob_data->max = 65536.*65536.-1.;
- if (knob_data->knob_state.down == 0 && knob_data->edit_open == 0 && addr_ret == 0)
- {
- if (pixel_address != (size_t) -1)
- {
- addr_v = pixel_address;
- pixel_address = (size_t) -1;
- }
- else
- addr_v = flip_xy(zc.offset_u).x * (vert?-1.:1.) * BYTES_PER_UNIT + addr_offset;
- }
- if (addr_ret == 1)
- if (vert)
- new_pos0 = xy(zc.offset_u.x, -(addr_v-addr_offset)/BYTES_PER_UNIT);
- else
- new_pos0 = xy((addr_v-addr_offset)/BYTES_PER_UNIT, zc.offset_u.y);
- addr_ret = ctrl_knob_fromlayout(&addr_v, &layout, 70);
- // Visualisation knobs
- visual_item_rect->x = 1.;
- *knob_ret |= ctrl_knob_fromlayout(&visual_item_rect->y, &layout, 20); // range box thickness
- ctrl_knob_fromlayout(image_stride_v, &layout, 21); // image stride in pixels
- set_knob_circularity_fromlayout(1, &layout, 22);
- get_knob_data_fromlayout(&layout, 22)->max = nearbyint(*image_stride_v);
- ctrl_knob_fromlayout(image_offset_v, &layout, 22); // image pixel offset
- // Filter field
- draw_label_fromlayout(&layout, 31, ALIG_LEFT | MONODIGITS);
- ctrl_textedit_fromlayout(&layout, 30);
- *filter_string = get_textedit_string_fromlayout(&layout, 30);
- // Message focus controls
- if (ctrl_button_fromlayout(&layout, 40))
- prepare_focus_transition(focus, -1);
- if (ctrl_button_fromlayout(&layout, 41))
- prepare_focus_transition(focus, 0);
- if (ctrl_button_fromlayout(&layout, 42))
- prepare_focus_transition(focus, 1);
- get_knob_data_fromlayout(&layout, 45)->max = MAXN(1., focus->filter_count-1);
- ctrl_knob_fromlayout(&focus->result_id_v, &layout, 45);
- // Vertical layout
- if (ctrl_checkbox_fromlayout(&vert, &layout, 80))
- {
- new_pos1 = neg_xy(zc.offset_u);
- swap_double(&new_pos1.x, &new_pos1.y);
- img_update = 1;
- }
- // Update offset menu index
- if (mts && mts_index != get_selmenu_selid_fromlayout(&layout, 60))
- gui_layout_selmenu_set_entry_id(mts_index, &layout, 60);
- // Offset menu
- int menu_count = sizeof(vis_mode_name)/sizeof(char*);
- gui_layout_selmenu_set_count(menu_count, &layout, 60);
- gui_layout_selmenu_set_entry_id(vis_mode, &layout, 60);
- if (ctrl_selmenu_fromlayout(&layout, 60))
- {
- vis_mode = get_selmenu_selid_fromlayout(&layout, 60);
- img_update = 1;
- }
- for (int i=0; i < menu_count; i++)
- draw_selmenu_entry_fromlayout(i, vis_mode_name[i], &layout, 60);
- draw_label_fromlayout(&layout, 61, ALIG_LEFT | MONODIGITS);
- // Combined size of highlighted ranges
- if (filtered_size < 5000)
- gui_printf_to_label(&layout, 46, 0, "%d B", filtered_size);
- else if (filtered_size < 90 << 10)
- gui_printf_to_label(&layout, 46, 0, "%.2f kB", filtered_size/1024.);
- else if (filtered_size < 900 << 10)
- gui_printf_to_label(&layout, 46, 0, "%.1f kB", filtered_size/1024.);
- else
- gui_printf_to_label(&layout, 46, 0, "%.2f MB", filtered_size/1048576.);
- draw_label_fromlayout(&layout, 46, ALIG_CENTRE | MONODIGITS);
- change_zoom(new_pos1, NAN);
- new_pos1 = new_pos0;
- }
- int mem_range_add(int64_t addr, int64_t size, const char *info, int info_size)
- {
- mem_range_t range = {0};
- if (size <= 0)
- return -1;
- range.addr = addr;
- range.size = size;
- memcpy(range.info, info, info_size);
- range.info[info_size] = '\0';
- buffer_t buf = {0};
- bufprintf(&buf, "%s\n", range.info);
- if (range.size > 90 << 20)
- bufprintf(&buf, "%.0f MB, ", range.size/1048576.);
- else if (range.size > 9 << 20)
- bufprintf(&buf, "%.1f MB, ", range.size/1048576.);
- else if (range.size > 1000 << 10)
- bufprintf(&buf, "%.2f MB, ", range.size/1048576.);
- else if (range.size > 9000)
- bufprintf(&buf, "%.0f kB, ", range.size/1024.);
- bufprintf(&buf, "%zd / %#zx B at %#zx", range.size, range.size, range.addr);
- range.label = buf.buf;
- // Add range to table
- if (mem_range_count == 0 || (range.addr != mem_range[mem_range_count - 1].addr || range.size != mem_range[mem_range_count - 1].size))
- alloc_enough(&mem_range, mem_range_count += 1, &mem_range_as, sizeof(mem_range_t), 1.2);
- // Replace the previous range if they have the same range
- else
- free_null(&mem_range[mem_range_count - 1].label);
- mem_range[mem_range_count - 1] = range;
- // Calculate obj file colour
- mem_range[mem_range_count - 1].colour = add_col(make_grey(0.2), get_colour_seq((double) get_string_hash(range.info)*0.007+1.5, xyz(0.36, 0.187, 0.13), set_xyz(0.2)));
- // Calculate the row to avoid overlapping with other ranges
- mem_range[mem_range_count - 1].row = starting_row;
- for (int ir = first_range_in_current_file; ir < mem_range_count-1; ir++)
- //if (mem_range[ir].addr <= range.addr+range.size-1 && mem_range[ir].addr+mem_range[ir].size-1 >= range.addr)
- if (MAXN(mem_range[ir].addr, range.addr) < MINN(mem_range[ir].addr+mem_range[ir].size, range.addr+range.size))
- mem_range[mem_range_count - 1].row = MAXN(mem_range[mem_range_count - 1].row, mem_range[ir].row + 1.);
- max_row = MAXN(max_row, mem_range[mem_range_count - 1].row);
- return mem_range_count - 1;
- }
- size_t get_module_stack_pointer()
- {
- size_t ptr=0;
- char cmd[300];
- sprintf(cmd, "From module ID %s\nGet stack pointer of module ID %s", module_id, watch_module_id);
- char *response = wahe_run_command(cmd);
- if (response)
- sscanf(response, "%" SCNi64, &ptr);
- free(response);
- return ptr;
- }
- typedef struct
- {
- int index, addr, time, link, info;
- } cita_layout_t;
- int64_t get_int_at_addr(uint8_t *addr, int size_of_int, int int_signed)
- {
- switch (size_of_int)
- {
- case 1: if (int_signed) return (int64_t) *(int8_t *) addr; else return (int64_t) *(uint8_t *) addr;
- case 2: if (int_signed) return (int64_t) *(int16_t *) addr; else return (int64_t) *(uint16_t *) addr;
- case 4: if (int_signed) return (int64_t) *(int32_t *) addr; else return (int64_t) *(uint32_t *) addr;
- case 8: return *(int64_t *) addr;
- case 3:
- int32_t low = (int32_t) *(uint16_t *) addr;
- int32_t v = addr[2];
- v = (v << 16) | low;
- if (int_signed && v >> 23)
- v |= 0xFF000000;
- return v;
- }
- return 0;
- }
- void cita_visualiser()
- {
- int i;
- static int init=1, options_detach=0;
- static xy_t visual_item_rect = {NAN, NAN};
- static double box_aspect_ratio_v = NAN, image_stride_v = NAN, image_offset_v = NAN;
- static int visual_item_length_ret = 0, os_openfile_diag = 0, memory_update = 1, update_cont = 1, full_memory = 1;
- static char *filter_string = NULL, *filter_string_prev;
- static buffer_t table0={0}, table1={0}, memory={0};
- static size_t heap_base=0, memory_size=0;
- int refilter = 0;
- static sqrgb_t *palette;
- static raster_t data_image={0};
- int cita_elem_size=0;
- cita_layout_t cita_size={0}, cita_pos={0};
- static int refresh_data_layout = 0;
- static filter_focus_t focus = {0};
- // Getting a file path from the command line
- if (init)
- {
- focus.filter_count = -1;
- focus.focus_index = -1;
- filter_string_prev = make_string_copy("");
- palette = make_byte_palette();
- data_image.table_index = -1;
- init = 0;
- }
- // Check what might trigger updating
- if (update_cont)
- memory_update = 1;
- if (isfinite(image_stride_v) && image_stride_v > 0. && image_stride != (int) nearbyint(image_stride_v))
- {
- image_stride = (int) nearbyint(image_stride_v);
- img_update = 1;
- }
- if (isfinite(image_offset_v) && image_offset != (int) nearbyint(image_offset_v))
- {
- image_offset = (int) nearbyint(image_offset_v);
- img_update = 1;
- }
- // Refresh heap copy
- if (watch_module_id && (memory_update || img_update))
- {
- char *response, cmd[200];
- if (memory_update)
- {
- heap_base = 0;
- memory_size = 0;
- // Get heap base
- sprintf(cmd, "From module ID %s\nGet heap base of module ID %s", module_id, watch_module_id);
- response = wahe_run_command(cmd);
- if (response)
- sscanf(response, "%" SCNi64, &heap_base);
- free(response);
- // Get memory size
- sprintf(cmd, "From module ID %s\nGet memory size of module ID %s", module_id, watch_module_id);
- response = wahe_run_command(cmd);
- if (response)
- sscanf(response, "%" SCNi64, &memory_size);
- free(response);
- if (heap_base == 0 || memory_size == 0)
- goto watch_end;
- }
- // Copy full memory
- if (full_memory)
- {
- if (memory_update)
- {
- memory.len = memory_size;
- buf_alloc_enough(&memory, memory_size);
- sprintf(cmd, "From module ID %s\nCopy %" PRIu64 " bytes at %" PRIu64 " (module %s) to %" PRIu64 " (module %s)", module_id, memory.len, (size_t)0, watch_module_id, (size_t) memory.buf, module_id);
- free(wahe_run_command(cmd));
- }
- // Rasterise data
- const int h = image_stride ? image_stride : 64;
- if (vis_mode == no_img)
- free_raster(&data_image);
- if (vis_mode == pal8)
- {
- data_image.dim = flip_xyi(xyi((memory_size+h-1)/h, h));
- alloc_enough(&data_image.sq, mul_x_by_y_xyi(data_image.dim), &data_image.as, sizeof(sqrgb_t), 1.2);
- memset(data_image.sq, 0, mul_x_by_y_xyi(data_image.dim)*sizeof(sqrgb_t));
- for (int i=0; i < memory_size; i++)
- {
- int io = i + image_offset;
- if (io < mul_x_by_y_xyi(data_image.dim))
- if (vert)
- data_image.sq[io/h*data_image.dim.x + io%h] = palette[memory.buf[i]];
- else
- data_image.sq[io%h*data_image.dim.x + io/h] = palette[memory.buf[i]];
- }
- }
- if (vis_mode == bw_bit)
- {
- data_image.dim = flip_xyi(xyi((memory_size*8+h-1)/h, h));
- alloc_enough(&data_image.sq, mul_x_by_y_xyi(data_image.dim), &data_image.as, sizeof(sqrgb_t), 1.2);
- memset(data_image.sq, 0, mul_x_by_y_xyi(data_image.dim)*sizeof(sqrgb_t));
- for (int i=0; i < memory_size*8; i++)
- {
- int io = i + image_offset;
- if (io < mul_x_by_y_xyi(data_image.dim))
- {
- int ic = get_bit(memory.buf[i>>3], i&7) * 0x81 | (rand_xsm32(i) & 3);
- if (vert)
- data_image.sq[io/h*data_image.dim.x + io%h] = palette[ic];
- else
- data_image.sq[io%h*data_image.dim.x + io/h] = palette[ic];
- }
- }
- }
- if (vis_mode == rgbx8)
- {
- data_image.dim = flip_xyi(xyi((memory_size/4+h-1)/h, h));
- alloc_enough(&data_image.sq, mul_x_by_y_xyi(data_image.dim), &data_image.as, sizeof(sqrgb_t), 1.2);
- memset(data_image.sq, 0, mul_x_by_y_xyi(data_image.dim)*sizeof(sqrgb_t));
- lut_t ssqrgb_l = get_lut_ssqrgb();
- for (int i=0; i < memory_size/4; i++)
- {
- int io = i + image_offset;
- if (io < mul_x_by_y_xyi(data_image.dim))
- {
- sqrgb_t col;
- col.r = ssqrgb_l.lutint[memory.buf[i*4+0]] >> 2;
- col.g = ssqrgb_l.lutint[memory.buf[i*4+1]];
- col.b = ssqrgb_l.lutint[memory.buf[i*4+2]] >> 2;
- if (vert)
- data_image.sq[io/h*data_image.dim.x + io%h] = col;
- else
- data_image.sq[io%h*data_image.dim.x + io/h] = col;
- }
- }
- }
- cl_unref_raster(&data_image);
- }
- // Copy table0
- table0.len = MINN(memory_size - heap_base, 48);
- if (full_memory)
- table0.buf = &memory.buf[heap_base];
- else if (memory_update)
- {
- buf_alloc_enough(&table0, table0.len);
- sprintf(cmd, "From module ID %s\nCopy %" PRIu64 " bytes at %" PRIu64 " (module %s) to %" PRIu64 " (module %s)", module_id, table0.len, heap_base, watch_module_id, (size_t) table0.buf, module_id);
- free(wahe_run_command(cmd));
- }
- // Parse table0
- if (memcmp(&table0.buf[0], "CITA", 4))
- {
- fprintf_rl(stderr, "No CIT Alloc detected at heap base %#zx in module %s (ID %s)\n", heap_base, watch_wahe_name, watch_module_id);
- goto watch_end;
- }
- // Check CITA version and load parameters
- int version_pos = *(int32_t *)&table0.buf[4];
- char *version = &table0.buf[version_pos];
- const char *p = version;
- while (p[0])
- {
- if (strncmp("CITA", p, 4) == 0)
- if (strncmp(version, "CITA 1.0", 8))
- {
- fprintf_rl(stderr, "Module %s (ID %s) has an unknown CIT Alloc version: \"%s\"\n", watch_wahe_name, watch_module_id, version);
- goto watch_end;
- }
- sscanf(p, "Address %d", &cita_size.addr);
- sscanf(p, "Index %d", &cita_size.index);
- sscanf(p, "Time %d", &cita_size.time);
- sscanf(p, "Link %d", &cita_size.link);
- sscanf(p, "Info %d", &cita_size.info);
- p = skip_line(p);
- }
- cita_pos.index = 0;
- cita_pos.addr = cita_pos.index + 2 * cita_size.index;
- cita_pos.time = cita_pos.addr + 3 * cita_size.addr;
- cita_pos.link = cita_pos.time + 2 * cita_size.time;
- cita_pos.info = cita_pos.link + 1 * cita_size.link;
- cita_elem_size = cita_pos.info + 1 * cita_size.info;
- if (isnan(image_stride_v))
- image_stride_v = cita_elem_size;
- size_t elem_addr = *(int32_t *)&table0.buf[16];
- size_t elem_count = *(int32_t *)&table0.buf[20];
- // Copy table1
- table1.len = elem_count * cita_elem_size;
- if (full_memory)
- table1.buf = &memory.buf[elem_addr];
- else if (memory_update)
- {
- buf_alloc_enough(&table1, table1.len);
- sprintf(cmd, "From module ID %s\nCopy %" PRIu64 " bytes at %" PRIu64 " (module %s) to %" PRIu64 " (module %s)", module_id, table1.len, elem_addr, watch_module_id, (size_t) table1.buf, module_id);
- free(wahe_run_command(cmd));
- }
- // Set MTS
- alloc_enough(&mts, mts_count = 1, &mts_as, sizeof(mem_type_start_t), 1.);
- mts[0].name = sprintf_alloc("Module %s (ID %s)", watch_wahe_name, watch_module_id);
- mts[0].addr = heap_base;
- // Free previous structure
- for (int ir = 0; ir < mem_range_count; ir++)
- free_null(&mem_range[ir].label);
- free_null(&mem_range);
- mem_range_as = mem_range_count = 0;
- // Add top range
- mem_range_add(0, memory_size, "RAM", 3);
- // Add range
- int32_t next_index;
- size_t ir = 0, count = 0;
- do
- {
- if ((ir+1)*cita_elem_size <= table1.len && ir >= 0)
- {
- // Read the next element's index
- next_index = get_int_at_addr(&table1.buf[ir*cita_elem_size + cita_pos.index + cita_size.index], cita_size.index, 1);
- if (next_index > elem_count || next_index < 0)
- {
- next_index = 0;
- // Find the next index by going through the table
- for (int32_t i=0; i < elem_count; i++)
- if (get_int_at_addr(&table1.buf[i*cita_elem_size + cita_pos.index], cita_size.index, 1) == ir) // if that element points back to this element
- {
- next_index = i;
- break;
- }
- }
- size_t range_addr = get_int_at_addr(&table1.buf[ir*cita_elem_size + cita_pos.addr], cita_size.addr, 0);
- size_t range_end = get_int_at_addr(&table1.buf[ir*cita_elem_size + cita_pos.addr + cita_size.addr], cita_size.addr, 0);
- char *info = &table1.buf[ir*cita_elem_size + cita_pos.info];
- mem_range_add(range_addr, range_end-range_addr, info, cita_size.info);
- ir = next_index;
- }
- else
- {
- char cmd[200];
- sprintf(cmd, "From module ID %s\nPrint ir out of range: %zd, elem_count = %zd\n", module_id, ir, elem_count);
- next_index = 0;
- }
- count++;
- }
- while (next_index && count < elem_count);
- refresh_data_layout = 1;
- refilter = 1;
- // Update flags
- memory_update = 0;
- img_update = 0;
- }
- watch_end:
- if (visual_item_length_ret)
- {
- visual_item_length_ret = 0;
- refresh_data_layout = 1;
- }
- // Apply filter
- if (filter_string && (strcmp(filter_string, filter_string_prev) || refilter))
- {
- refilter = 0;
- free(filter_string_prev);
- filter_string_prev = make_string_copy(filter_string);
- focus.filter_count = 0;
- filtered_size = 0;
- for (int ir = 0; ir < mem_range_count; ir++)
- if (strstr_i(mem_range[ir].label, filter_string))
- {
- mem_range[ir].filtered = 0;
- mem_range[ir].filter_pos = focus.filter_count;
- focus.filter_count++;
- if (mem_range[ir].row > 0)
- filtered_size += mem_range[ir].size;
- }
- else
- {
- mem_range[ir].filtered = 1;
- mem_range[ir].filter_pos = -1;
- }
- }
- // Calculate visual layout of messages
- xy_t byte_scale = xy(visual_item_rect.x / BYTES_PER_UNIT, (visual_item_rect.y*1024.) / BYTES_PER_UNIT);
- if (refresh_data_layout && isfinite_xy(visual_item_rect))
- {
- refresh_data_layout = 0;
- for (int ir=0; ir < mem_range_count; ir++)
- {
- // Set position
- mem_range[ir].pos = flip_xy(xy(byte_scale.x * (double) (mem_range[ir].addr + (ir ? image_offset : 0) - mts[mts_index].addr), -byte_scale.y * (1.06 * (mem_range[ir].row-1) - 1.)));
- if (vert)
- {
- mem_range[ir].pos.y = -mem_range[ir].pos.y;
- mem_range[ir].pos.x = -mem_range[ir].pos.x;
- }
- mem_range[ir].area = make_rect_off(mem_range[ir].pos, flip_xy(xy((double) mem_range[ir].size * byte_scale.x, byte_scale.y)), xy(0., 1.));
- }
- }
- // Focus transition
- perform_focus_transition(&focus);
- // Draw range data
- col_t filtered_colour = make_colour(0.3, 0.015, 0., 1.);
- for (int ir = 0; ir < mem_range_count; ir++)
- {
- if (check_box_on_screen(mem_range[ir].area))
- {
- col_t colour = mem_range[ir].colour;
- if (mem_range[ir].filtered)
- colour = filtered_colour;
- // Draw box and label
- draw_rangebox_fade_to_solid(mem_range[ir].area, "", colour);
- if (rect_min_side(sc_rect(mem_range[ir].area)) > 4.)
- draw_string_bestfit_asis(font, mem_range[ir].label, sc_rect(mem_range[ir].area), 1./12., 1e30, colour, 1., drawing_thickness, vert ? ALIG_LEFT : ALIG_LEFT | MONODIGITS, NULL);
- }
- }
- // Draw data pixels
- if (data_image.sq && mem_range)
- {
- rect_t area = make_rect_off(add_xy(mem_range[0].pos, flip_xy(xy(0., -byte_scale.y*2.06 * (vert?-1:1.)))), flip_xy(xy((double) mem_range[0].size * byte_scale.x, byte_scale.y*1e6)), xy(0., 1.));
- area = fit_rect_in_area(xyi_to_xy(data_image.dim), area, flip_xy(xy(0.5, vert?0.:1.)));
- xy_t r_scale, r_offset, r_scale_inv, r_offset_inv;
- rect_range_and_dim_to_scale_offset(area, data_image.dim, &r_scale, &r_offset, 0);
- rect_range_and_dim_to_scale_offset_inv(area, data_image.dim, &r_scale_inv, &r_offset_inv, 0);
- // Calculate hovered pixel address
- ctrl_button_state_t butt_state={0};
- ctrl_button_invis(area, &butt_state);
- if (butt_state.over)
- {
- xyi_t pix_pos = xy_to_xyi(nearbyint_xy(mad_xy(mouse.u, r_scale_inv, r_offset_inv)));
- pixel_address = pix_to_addr(pix_pos, data_image.dim);
- }
- // Draw data image
- blit_in_rect(&data_image, sc_rect(area), 1, AA_NEAREST_INTERP);
- // Get module's current stack pointer
- size_t stack_ptr = get_module_stack_pointer();
- // Draw data labels
- col_t label_col_pos = make_colour(0.5, 0.5, 0.5, 1.);
- col_t label_col_neg = make_colour(-0.5, -0.5, -0.5, 1.);
- col_t stack_top_col = make_colour(0.1, 0.1, 0.4, 1.);
- if (zc.zoomscale * r_scale.x > 3./12.)
- {
- xyi_t ip, label_range = xyi(74., 38.);
- xyi_t pix_pos = xy_to_xyi(nearbyint_xy(mad_xy(zc.offset_u, r_scale_inv, r_offset_inv)));
- for (ip.y = MAXN(0, pix_pos.y-label_range.y); ip.y < MINN(data_image.dim.y, pix_pos.y+label_range.y); ip.y++)
- for (ip.x = MAXN(0, pix_pos.x-label_range.x); ip.x < MINN(data_image.dim.x, pix_pos.x+label_range.x); ip.x++)
- {
- size_t addr = pix_to_addr(ip, data_image.dim);
- if (vis_mode == pal8 && addr < memory_size)
- {
- // Pixel area
- uint8_t byte = memory.buf[addr];
- if (byte)
- {
- // Print label
- double scale = isprint(byte) ? 11./12. : 8./12.;
- char label[32];
- if (isprint(byte))
- sprintf(label, "%c", byte);
- else
- sprintf(label, "%d %#02x", byte, byte);
- // Draw label
- xy_t pos = mad_xy(xyi_to_xy(ip), r_scale, r_offset);
- rect_t area = make_rect_centred(pos, set_xy(r_scale.x * scale));
- draw_label(label, area, byte < 235 ? label_col_pos : label_col_neg, ALIG_CENTRE | MONODIGITS);
- }
- // Draw stack pointer hint
- if (addr < stack_ptr)
- {
- xy_t pos = mad_xy(xyi_to_xy(ip), r_scale, r_offset);
- rect_t area = make_rect_centred(pos, set_xy(r_scale.x));
- draw_rect_full(sc_rect(area), drawing_thickness, stack_top_col, blend_add, 1.);
- }
- }
- }
- }
- }
- // GUI window
- window_register(1, cita_vis_options_window, NULL, make_rect_off(xy(-zc.limit_u.x, zc.limit_u.y), xy(6., 12.), xy(0., 1.)), &options_detach, 8, &memory_update, &update_cont, &visual_item_rect, &visual_item_length_ret, &filter_string, &focus, &image_stride_v, &image_offset_v);
- }
- int main_loop(void *data)
- {
- sdl_main_param_t param={0};
- param.window_name = "CIT Alloc Visualiser";
- param.func = cita_visualiser;
- param.use_drawq = 1;
- param.maximise_window = 1;
- param.gui_toolbar = 1;
- param.show_cursor = 1;
- param.exit_flag = &exit_flag;
- rl_sdl_standard_main_loop(param);
- return 0;
- }
- static rl_thread_t thread_handle=NULL;
- EXPORT("module_message_input")
- char *module_message_input(char *message)
- {
- static char *ret_msg = NULL;
- int n;
- if (message == NULL)
- return NULL;
- free(ret_msg);
- ret_msg = NULL;
- // Parse each line
- for (const char *line = message; line; line = find_next_line(line))
- {
- // Receive module index
- if (sscanf(line, "Module ID %60s", module_id) == 1)
- // Create thread
- rl_thread_create(&thread_handle, main_loop, NULL);
- // Receive wahe_run_command() pointer
- #ifndef __wasm__
- sscanf(line, "wahe_run_command() = %zx", (size_t *) &wahe_run_command);
- #endif
- // Init
- n = 0;
- sscanf(line, "Init%n", &n);
- if (n)
- {}
- // Deinit
- n = 0;
- sscanf(line, "Deinit%n", &n);
- if (n)
- {
- exit_flag = 1;
- rl_thread_join_and_null(&thread_handle);
- }
- // Documentation
- n = 0;
- sscanf(line, "Documentation%n", &n);
- if (n)
- {
- return "module_message_input() takes:\n\n"
- " Watch module <WAHE instance name>\n"
- " Example: Watch module Time_mod\n\n"
- ;
- }
- // Watch module, this tells us the WAHE setup name of the instance whose CIT Alloc heap to watch
- if (sscanf(line, "Watch module %50s", watch_wahe_name) == 1)
- {
- char cmd[68];
- sprintf(cmd, "Get ID of module %s", watch_wahe_name);
- free(watch_module_id);
- watch_module_id = wahe_run_command(cmd);
- }
- }
- return NULL;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement