ntrop

2D binary entropy visualization inspired by ..cantor.dust..
git clone https://git.sinitax.com/sinitax/ntrop
Log | Files | Refs | sfeed.txt

commit ec7f7da9eade84b947810e336e6381be9d8c338a
parent 5b72cec00a5f0c5f8a77dde65271fb90b844f779
Author: Louis Burda <quent.burda@gmail.com>
Date:   Sun, 12 Feb 2023 17:19:00 +0100

Added bar and improved usability

Diffstat:
Mntrop.c | 178++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 140 insertions(+), 38 deletions(-)

diff --git a/ntrop.c b/ntrop.c @@ -16,17 +16,25 @@ const char *file_path; uint8_t *file_data; size_t data_len; -size_t data_width; -size_t data_height; +ssize_t data_width; +ssize_t data_height; + +ssize_t data_window_start; +ssize_t data_window_len; Color *value_colors; Color *entropy_colors; int entropy_ctx; -uint64_t zoom; +int zoom; double zoom_x, zoom_y; +int bar_width; +int bar_zoom; +ssize_t bar_start; +bool show_bar; + int window_width; int window_height; char *window_title; @@ -174,6 +182,7 @@ vis(void) { Color *data_colors; Image window_image; + int window_init_frames; size_t pos, len; double mouse_move; ssize_t data_x, data_y; @@ -192,30 +201,46 @@ vis(void) SetTraceLogLevel(LOG_NONE); - window_width = 800; - window_height = 600; - InitWindow(window_width, window_height, window_title); + InitWindow(800, 600, window_title); + + window_image = GenImageColor(800, 600, (Color) { 0 }); - window_image = GenImageColor(window_width, window_height, (Color) { 0 }); - data_width = window_width / 2; - data_height = data_len / data_width + !!(data_len % data_width); - zoom_x = 0; - zoom_y = 0; - zoom = 1; + zoom = 2; + bar_zoom = 4; + bar_start = 0; + bar_width = MAX(80, window_width / 7); + show_bar = true; + + data_window_start = 0; + data_window_len = data_len; show_pos = false; + + window_init_frames = 2; while (!WindowShouldClose()) { if (IsKeyPressed(KEY_Q)) break; - if (IsWindowResized()) { + if (window_init_frames || IsWindowResized() || IsKeyPressed(KEY_G)) { window_width = GetScreenWidth(); window_height = GetScreenHeight(); - data_width = MAX(MIN(data_len, MIN(window_width / 2, 400)), 1); - data_height = data_len / data_width + !!(data_len % data_width); + bar_width = MAX(80, window_width / 7); + if (window_init_frames > 0) { + data_width = MAX(1, MIN(data_len, + (window_width - bar_width) / 2 / zoom)); + data_height = data_window_len / data_width + + !!(data_window_len % data_width); + data_window_len = MIN(data_len, + MAX(window_width / 2 / zoom + * window_height / 2 / zoom, 200)); + } + if (IsKeyPressed(KEY_G)) + zoom = 2; zoom_x = (data_width - 1.F * window_width / zoom) / 2.F; zoom_y = (data_height - 1.F * window_height / zoom) / 2.F; ImageResize(&window_image, window_width, window_height); + if (window_init_frames) + window_init_frames -= 1; } mouse_x = MIN(MAX(0, GetMouseX()), window_width); @@ -227,14 +252,32 @@ vis(void) drag_zoom_x = zoom_x; drag_zoom_y = zoom_y; drag = true; + }else if (!IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { + drag = false; } - if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { + + if (drag && show_bar && drag_mouse_x < bar_width) { + if (mouse_y > window_height - 20) { + bar_start += bar_zoom * bar_width * 20; + } else if (mouse_y < 20) { + bar_start -= bar_zoom * bar_width * 20; + } + bar_start = MIN((ssize_t) data_len + - bar_width * window_height * bar_zoom, bar_start); + bar_start = MAX(0, bar_start); + + data_window_start = bar_start + (mouse_y * bar_width + mouse_x) * bar_zoom; + data_window_start = MAX(0, MIN( + (ssize_t) data_len - data_window_len, + data_window_start - data_window_len / 2)); + } else if (drag) { zoom_x = drag_zoom_x - (mouse_x - drag_mouse_x) * 1.F / zoom; zoom_y = drag_zoom_y - (mouse_y - drag_mouse_y) * 1.F / zoom; - } else { - drag = false; } + if (show_bar && mouse_x < bar_width) { + } + mouse_move = GetMouseWheelMove(); if (mouse_move > 0 && zoom < ZOOM_MAX) { zoom_x += (1.F * window_width / zoom / 2) @@ -251,24 +294,50 @@ vis(void) } show_pos ^= IsKeyPressed(KEY_T); + show_bar ^= IsKeyPressed(KEY_B); if (IsKeyDown(KEY_LEFT_ALT)) { - if (key_press_hold(KEY_LEFT) && data_width > 0) - data_width -= 1; - else if (key_press_hold(KEY_RIGHT)) - data_width += 1; + if (key_press_hold(KEY_LEFT) || key_press_hold(KEY_A)) { + data_width -= IsKeyDown(KEY_LEFT_SHIFT) ? 5 : 1; + } else if (key_press_hold(KEY_RIGHT) || key_press_hold(KEY_D)) { + data_width += IsKeyDown(KEY_LEFT_SHIFT) ? 5 : 1; + } + data_width = MAX(0, data_width); + } else if (IsKeyDown(KEY_LEFT_SHIFT)) { + if (key_press_hold(KEY_LEFT) || key_press_hold(KEY_A)) { + data_window_start -= 1; + } else if (key_press_hold(KEY_RIGHT) || key_press_hold(KEY_D)) { + data_window_start += 1; + } + data_window_start = MAX(0, data_window_start); + } else if (IsKeyDown(KEY_LEFT_CONTROL)) { + if (key_press_hold(KEY_LEFT) || key_press_hold(KEY_A)) { + data_window_start -= bar_zoom * bar_width * 4; + } else if (key_press_hold(KEY_RIGHT) || key_press_hold(KEY_D)) { + data_window_start += bar_zoom * bar_width * 4; + } + data_window_start = MAX(0, data_window_start); + if (key_press_hold(KEY_UP) || key_press_hold(KEY_W)) { + data_window_len -= bar_zoom * bar_width * 4; + } else if (key_press_hold(KEY_DOWN) || key_press_hold(KEY_S)) { + data_window_len += bar_zoom * bar_width * 4; + } + data_window_len = MAX(0, data_window_len); } else { - if (key_press_hold(KEY_LEFT)) + if (key_press_hold(KEY_LEFT) || key_press_hold(KEY_A)) { zoom_x -= 20.F / zoom; - else if (key_press_hold(KEY_RIGHT)) + } else if (key_press_hold(KEY_RIGHT) || key_press_hold(KEY_D)) { zoom_x += 20.F / zoom; + } - if (key_press_hold(KEY_UP)) + if (key_press_hold(KEY_UP) || key_press_hold(KEY_W)) { zoom_y -= 20.F / zoom; - else if (key_press_hold(KEY_DOWN)) + } else if (key_press_hold(KEY_DOWN) || key_press_hold(KEY_S)) { zoom_y += 20.F / zoom; + } } - data_height = data_len / data_width + !!(data_len % data_width); + len = MIN(data_window_len, data_len - data_window_start); + data_height = len / data_width + !!(len % data_width); if (IsKeyPressed(KEY_P)) { show_value = !show_value; @@ -278,7 +347,6 @@ vis(void) data_colors = entropy_colors; } - ImageClearBackground(&window_image, BLACK); for (y = 0; y < window_height; y++) { @@ -292,36 +360,70 @@ vis(void) continue; data_pos = data_y * data_width + data_x; - if (data_pos < data_len) { + data_pos += data_window_start; + len = data_window_start + data_window_len; + if (len % window_width) + len += window_width - (len % window_width); + if (data_pos < len && data_pos < data_len) { ImageDrawPixel(&window_image, x, y, data_colors[data_pos]); } } } - Texture2D tex = LoadTextureFromImage(window_image); - - BeginDrawing(); + if (show_bar) { + ImageDrawRectangle(&window_image, + 0, 0, bar_width, window_height, BLACK); + ImageDrawRectangle(&window_image, bar_width, 0, + 3, window_height, BLACK); + ImageDrawLine(&window_image, bar_width + 1, 0, + bar_width + 1, window_height, GRAY); + + for (y = 0; y < window_height; y++) { + for (x = 0; x < bar_width; x++) { + data_pos = bar_start + (y * bar_width + x) * bar_zoom; + if (data_pos < data_len) { + ImageDrawPixel(&window_image, + x, y, value_colors[data_pos]); + } + } + } - ClearBackground(BLACK); + pos = (data_window_start - bar_start) / bar_width / bar_zoom; + ImageDrawLine(&window_image, 0, pos, + bar_width, pos, WHITE); - DrawTexture(tex, 0, 0, WHITE); + pos = MIN(data_len, data_window_start + data_window_len); + pos = (pos - bar_start) / bar_width / bar_zoom; + ImageDrawLine(&window_image, 0, pos, + bar_width, pos, WHITE); + } if (show_pos) { data_x = (ssize_t) zoom_x + (mouse_x / zoom); data_y = (ssize_t) zoom_y + (mouse_y / zoom); if (data_x >= 0 && data_x < data_width && data_y >= 0 && data_y < data_height) { - pos = data_y * data_width + data_x; + pos = data_window_start + data_y * data_width + data_x; snprintf(fmtbuf, sizeof(fmtbuf), "0x%08lx", pos); len = MeasureText(fmtbuf, 20); - DrawRectangle(window_width - len - 6, 0, - len + 6, 19, WHITE); - DrawText(fmtbuf, window_width - len - 3, + ImageDrawRectangle(&window_image, + window_width - len - 9, 0, + len + 9, 19, WHITE); + ImageDrawText(&window_image, + fmtbuf, window_width - len - 6, 0, 20, BLACK); } } + Texture2D tex = LoadTextureFromImage(window_image); + + BeginDrawing(); + + ClearBackground(BLACK); + + DrawTexture(tex, 0, 0, WHITE); + EndDrawing(); UnloadTexture(tex);