diff --git a/src/render.cpp b/src/render.cpp index 93ea1a3..92283fd 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -395,11 +395,9 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms) } internal -Term_Viewer make_term_viewer(u16 n_cols) +Term_Viewer make_term_viewer() { Term_Viewer viewer {}; - viewer.max_cols = n_cols ? n_cols : 32; - viewer.col_key = ACol_Green; viewer.col_page_start = ACol_Bright_Magenta; viewer.col_checksum = ACol_Yellow; @@ -485,7 +483,7 @@ String8 render_legend_to_string(Arena *arena, const Term_Viewer &viewer, const A internal String8 render_range_to_string(Arena *arena, App_State &app, u64 len, u64 n_cols) { - Term_Viewer viewer = make_term_viewer(n_cols); + Term_Viewer viewer = make_term_viewer(); String8 legend = render_legend_to_string(arena, viewer, app); @@ -496,18 +494,34 @@ String8 render_range_to_string(Arena *arena, App_State &app, u64 len, u64 n_cols String8 ntpl_desc = rntuple_description(scratch.arena, app.rndata); String8 header_str = push_str8f(scratch.arena, "RNTuple '%s' (%s) from file \"%s\"", app.ntpl_name.c(), ntpl_desc.c(), app.inspected_file.name.c()); + + if (n_cols == 0) + n_cols = 32; + u64 n_lines = len / n_cols; + u64 max_addr = app.inspected_file.size; + + // Calculate how much space do we need to fix line addr numbers. + // The biggest address is gonna take up the most space + const f32 RECP_LOG_16 = 0.360673760222f; + // NOTE: +1 for the ":" + u64 max_addr_len = 1 + ceilf(logf(max_addr + 1) * RECP_LOG_16); + const u64 n_spaces_after_line_addr = 3; + u64 line_addr_size = (max_addr_len + n_spaces_after_line_addr) * n_lines; + String8 line_addr_fmt = push_str8f(scratch.arena, "%%0%dlX:", max_addr_len - 1); // NOTE: +3 because we need 2 chars for each byte + 1 whitespace. u64 buf_size = (ACOL_MAX_LEN + 3) * len; - u64 n_newlines = len / viewer.max_cols; - buf_size += n_newlines; + buf_size += n_lines; // one newline per line + buf_size += n_lines * ACOL_MAX_LEN; // reset color every line + buf_size += line_addr_size; buf_size += 1; // initial newline buf_size += header_str.size; - buf_size += 2; // two newlines - buf_size += 2; // two newlines + buf_size += 2; // two newlines after header + buf_size += 2; // two newlines before legend buf_size += legend.size; buf_size += 1; // trailing zero - u8 *buf = arena_push_array_nozero(arena, buf_size); + u64 arena_start_pos = arena_pos(arena); + char *buf = arena_push_array_nozero(arena, buf_size); buf[len] = 0; u64 start = app.viewer.base_display_addr; @@ -516,11 +530,10 @@ String8 render_range_to_string(Arena *arena, App_State &app, u64 len, u64 n_cols app.last_pinfo = &invalid_pinfo; const u8 *data = app.inspected_file.mem; - u64 max_addr = app.inspected_file.size; assert(start <= max_addr); len = min(len, max_addr - start); - u8 *cur = buf; + char *cur = buf; *cur++ = '\n'; // header @@ -529,6 +542,13 @@ String8 render_range_to_string(Arena *arena, App_State &app, u64 len, u64 n_cols *cur++ = '\n'; *cur++ = '\n'; + // first line addr + cur += sprintf(cur, line_addr_fmt.c(), start); + for (u32 i = 0; i < n_spaces_after_line_addr; ++i) + *cur++ = ' '; + + String8 col_none = ansi_color_table[ACol_None]; + for (u64 i = 0; i < len; ++i) { u64 off = start + i; @@ -542,12 +562,17 @@ String8 render_range_to_string(Arena *arena, App_State &app, u64 len, u64 n_cols cur += acol_str.size; /// Write the human-readable byte - String8 byte_str = push_str8f(scratch.arena, "%02X ", data[off]); - memcpy(cur, byte_str.str, byte_str.size); - cur += byte_str.size; + cur += sprintf(cur, "%02X ", data[off]); - if ((i + 1) % viewer.max_cols == 0) + // new line + if ((i + 1) % n_cols == 0) { *cur++ = '\n'; + memcpy(cur, col_none.c(), col_none.size); + cur += col_none.size; + cur += sprintf(cur, line_addr_fmt.c(), off + 1); + for (u32 i = 0; i < n_spaces_after_line_addr; ++i) + *cur++ = ' '; + } assert((u64)(cur - buf) < (u64)buf_size); } @@ -559,5 +584,8 @@ String8 render_range_to_string(Arena *arena, App_State &app, u64 len, u64 n_cols *cur = 0; - return { buf, (u64)(cur - buf) }; + u64 len_used = (u64)(cur - buf); + arena_pop_to(arena, arena_start_pos + len_used); + + return { (u8 *)buf, len_used }; } diff --git a/src/rntviewer.cpp b/src/rntviewer.cpp index ac4852e..b4bfc67 100644 --- a/src/rntviewer.cpp +++ b/src/rntviewer.cpp @@ -13,6 +13,8 @@ #include #include +#include +#include #include #include