Compare commits

..

No commits in common. "master" and "grouped" have entirely different histories.

9 changed files with 174 additions and 237 deletions

View file

@ -10,7 +10,8 @@ $ git clone --recurse-submodules <repo_url>
``` ```
### Dependencies ### Dependencies
rntviewer currently only fully works on Linux, with the terminal-only version working on MacOS as well. rntviewer currently only fully works on Linux, with the terminal-only version working
on MacOS as well (PRs welcome).
The dependencies are: The dependencies are:
- GLFW3 (`libglfw3-dev` on debian, `glfw-devel` on fedora, `glfw` on arch) - GLFW3 (`libglfw3-dev` on debian, `glfw-devel` on fedora, `glfw` on arch)
@ -19,7 +20,7 @@ The dependencies are:
Other than those, rntviewer depends on Dear ImGui and GLAD (both included in the source tree). Other than those, rntviewer depends on Dear ImGui and GLAD (both included in the source tree).
For the graphical version, the OS must support OpenGL 3.3 or higher. The machine must support OpenGL 3.3 or higher.
For the terminal-only version you don't need GLFW3, ImGui or OpenGL support. For the terminal-only version you don't need GLFW3, ImGui or OpenGL support.

View file

@ -12,7 +12,7 @@ struct Inspected_File {
String8 name; String8 name;
// @Platform: inotify file descriptor // @Platform: inotify file descriptor
int inot; int inot;
}; };
@ -29,8 +29,8 @@ struct App_State {
Viewer viewer; Viewer viewer;
#endif #endif
String8 ntpl_name; String8 ntpl_name;
u64 base_display_addr; u64 base_display_addr;
Delta_Time_Accum delta_time_accum; Delta_Time_Accum delta_time_accum;
@ -44,6 +44,6 @@ size_t file_size(FILE *f)
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
size_t res = ftell(f); size_t res = ftell(f);
fseek(f, 0, SEEK_SET); fseek(f, 0, SEEK_SET);
return res; return res;
} }

View file

@ -5,8 +5,8 @@ struct Defer_Guard {
F _f; F _f;
}; };
struct Defer_Guard_Helper { struct Defer_Guard_Helper {
template <typename F> template <typename F>
Defer_Guard<F> operator+(F&& f) { return Defer_Guard<F>(static_cast<F &&>(f)); } Defer_Guard<F> operator+(F&& f) { return Defer_Guard<F>(static_cast<F &&>(f)); }
}; };
#define CONCAT_STR_INTERNAL(A, B) A##B #define CONCAT_STR_INTERNAL(A, B) A##B

View file

@ -124,15 +124,12 @@ using Display_Range_Fn = String8_Node *(*)(Arena *, String8_Node *, const char *
enum Hover_Section_Flags { enum Hover_Section_Flags {
HoverSec_None = 0, HoverSec_None = 0,
// Hide = don't show at all, even the title
HoverSec_HideIfNotHovered = 1, HoverSec_HideIfNotHovered = 1,
// Collapse = only show the title
HoverSec_CollapseIfNotHovered = 2,
}; };
// Functor used by get_section_hover_info to describe the structure of a section and print data about it. // Functor used by get_section_hover_info to describe the structure of a section and print data about it.
struct Sec_Hover_Fn { struct Sec_Hover_Fn {
u64 off; // the hovered offset relative to the start of `data` u64 off; // the offset relative to the start of `data`
const u8 *data; // the entire file data const u8 *data; // the entire file data
const Section &section; const Section &section;
Arena *arena; Arena *arena;
@ -142,20 +139,6 @@ struct Sec_Hover_Fn {
u8 cur_section_nesting = 0; u8 cur_section_nesting = 0;
u8 innermost_section_highlighted = 0; u8 innermost_section_highlighted = 0;
template <typename T>
b8 read(T *val, u64 offset, u64 *size = nullptr) const
{
u64 nb = size ? *size : sizeof(T);
if (offset + nb > section.range.end()) {
fprintf(stderr, "Trying to read bytes 0x%" PRIX64 "-0x%" PRIX64 " which are past the end of the section 0x%" PRIX64 "!\n",
offset, offset + nb, section.range.end());
return false;
}
memcpy(val, data + offset, nb);
return true;
}
template <typename F> template <typename F>
void titled_section(const char *title, F &&sec_body_fn, u64 flags = 0) void titled_section(const char *title, F &&sec_body_fn, u64 flags = 0)
{ {
@ -167,19 +150,11 @@ struct Sec_Hover_Fn {
sec_body_fn(); sec_body_fn();
// assert(cur_field_off >= sec_start); assert(cur_field_off >= sec_start);
if (cur_field_off < sec_start) {// TEMP DEBUG
fprintf(stderr, "Something wrong going on in %s!\n", title);
return;
}
b8 hovered = off >= sec_start && off <= cur_field_off; b8 hovered = off >= sec_start && off <= cur_field_off;
if (!hovered) { if (!hovered & (flags & HoverSec_HideIfNotHovered)) {
if (flags & HoverSec_HideIfNotHovered) pop_str8_node_child(prev_desc, info.desc);
pop_str8_node_child(prev_desc, info.desc);
else if (flags & HoverSec_CollapseIfNotHovered)
info.desc->first_child = info.desc->last_child = nullptr;
} else if (display_grouped) { } else if (display_grouped) {
// if we're in display_grouped mode, we want to highlight the entire range of the section; // if we're in display_grouped mode, we want to highlight the entire range of the section;
u64 sec_len = cur_field_off - sec_start; u64 sec_len = cur_field_off - sec_start;
@ -211,9 +186,7 @@ struct Sec_Hover_Fn {
b8 hovered = cur_field_off <= off && off < cur_field_off + field_len; b8 hovered = cur_field_off <= off && off < cur_field_off + field_len;
T val; T val;
if (!read(&val, cur_field_off)) memcpy(&val, (u8 *)data + cur_field_off, field_len);
return false;
String8_Node *desc = display_val(arena, info.desc, desc_fmt, val); String8_Node *desc = display_val(arena, info.desc, desc_fmt, val);
if (hovered && !display_grouped) if (hovered && !display_grouped)
info.highlighted_desc = desc; info.highlighted_desc = desc;
@ -232,9 +205,7 @@ struct Sec_Hover_Fn {
{ {
// String size can be stored as different types, like u8 (by ROOT I/O) or u32 (by RNTuple). // String size can be stored as different types, like u8 (by ROOT I/O) or u32 (by RNTuple).
TStrSize str_size; TStrSize str_size;
if (!read(&str_size, cur_field_off)) memcpy(&str_size, data + cur_field_off, sizeof(TStrSize));
return;
// DEBUG // DEBUG
if (str_size > 1000) { if (str_size > 1000) {
printf("read str_size = %u at offset 0x%lX!\n", str_size, cur_field_off); printf("read str_size = %u at offset 0x%lX!\n", str_size, cur_field_off);
@ -244,10 +215,7 @@ struct Sec_Hover_Fn {
b8 hovered = cur_field_off <= off && off < cur_field_off + field_len; b8 hovered = cur_field_off <= off && off < cur_field_off + field_len;
u8 *buf = arena_push_array_nozero<u8>(arena, str_size + 1); u8 *buf = arena_push_array_nozero<u8>(arena, str_size + 1);
u64 size_to_read = str_size; memcpy(buf, data + cur_field_off + sizeof(TStrSize), str_size);
if (!read(buf, cur_field_off + sizeof(TStrSize), &size_to_read))
return;
buf[str_size] = 0; buf[str_size] = 0;
String8 s = { buf, str_size }; String8 s = { buf, str_size };
String8_Node *desc = display_val(arena, info.desc, desc_fmt, s); String8_Node *desc = display_val(arena, info.desc, desc_fmt, s);
@ -276,8 +244,6 @@ struct Sec_Hover_Fn {
void range(const char *desc, u64 range_len, Display_Range_Fn display_val = hover_display_generic_range) void range(const char *desc, u64 range_len, Display_Range_Fn display_val = hover_display_generic_range)
{ {
b8 hovered = cur_field_off <= off && off < cur_field_off + range_len; b8 hovered = cur_field_off <= off && off < cur_field_off + range_len;
if (cur_field_off + range_len > section.range.end())
return;
String8_Node *dsc = display_val(arena, info.desc, desc, data + cur_field_off, range_len); String8_Node *dsc = display_val(arena, info.desc, desc, data + cur_field_off, range_len);
if (hovered && !display_grouped) if (hovered && !display_grouped)
info.highlighted_desc = dsc; info.highlighted_desc = dsc;
@ -291,15 +257,13 @@ struct Sec_Hover_Fn {
// Returns true if `was_zipped` was read. // Returns true if `was_zipped` was read.
b8 maybe_rootzip(b8 *was_zipped = nullptr) b8 maybe_rootzip(b8 *was_zipped = nullptr)
{ {
// TODO boundary checks
const u64 range_len = 9; const u64 range_len = 9;
if (cur_field_off + range_len > section.range.end())
return false;
b8 hovered = cur_field_off <= off && off < cur_field_off + range_len; b8 hovered = cur_field_off <= off && off < cur_field_off + range_len;
if (display_val_rootzip(arena, info.desc, "Zipped Block", data + cur_field_off)) { if (display_val_rootzip(arena, info.desc, "Zipped Block", data + cur_field_off)) {
if (was_zipped)
*was_zipped = true;
if (display_grouped || hovered) { if (display_grouped || hovered) {
if (was_zipped)
*was_zipped = true;
info.rng = { cur_field_off, range_len }; info.rng = { cur_field_off, range_len };
if (hovered) if (hovered)
info.highlighted_desc = info.desc; info.highlighted_desc = info.desc;
@ -316,9 +280,7 @@ struct Sec_Hover_Fn {
{ {
titled_section(title, [this] { titled_section(title, [this] {
u16 version_be; u16 version_be;
if (!read(&version_be, cur_field_off + 4)) memcpy(&version_be, data + cur_field_off + 4, sizeof(u16));
return;
u32 version = bswap(version_be); u32 version = bswap(version_be);
b8 is_big = version > 1000; b8 is_big = version > 1000;
@ -356,7 +318,7 @@ struct Sec_Hover_Fn {
range("Envelope size: %s", 6, [] (Arena *arena, String8_Node *prev, const char *fmt, const u8 *payload, u64) { range("Envelope size: %s", 6, [] (Arena *arena, String8_Node *prev, const char *fmt, const u8 *payload, u64) {
u64 size; u64 size;
memcpy(&size, payload, 6); memcpy(&size, payload, 6);
return push_str8_node_child(arena, prev, fmt, to_pretty_size(arena, size).c()); return push_str8_node_child(arena, prev, fmt, to_pretty_size(arena, size));
}); });
}); });
} }
@ -364,12 +326,7 @@ struct Sec_Hover_Fn {
enum Frame_Type { enum Frame_Type {
Frame_INVALID, Frame_INVALID,
Frame_Record, Frame_Record,
Frame_List, Frame_List
Frame_COUNT
};
static constexpr const char *frame_type_str[Frame_COUNT] = {
"INVALID", "Record", "List"
}; };
Frame_Type frame_header(u64 &size, u32 *n_items = nullptr, const char *title = nullptr) Frame_Type frame_header(u64 &size, u32 *n_items = nullptr, const char *title = nullptr)
@ -378,11 +335,7 @@ struct Sec_Hover_Fn {
Frame_Type frame_type = Frame_INVALID; Frame_Type frame_type = Frame_INVALID;
titled_section(titlestr.c(), [this, &frame_type, &frame_size = size, n_items] { titled_section(titlestr.c(), [this, &frame_type, &frame_size = size, n_items] {
i64 size; i64 size;
if (!read(&size, cur_field_off)) { memcpy(&size, data + cur_field_off, sizeof(size));
frame_size = 0;
frame_type = Frame_INVALID;
return;
}
// Sanity check // Sanity check
if (size > 1000000) { if (size > 1000000) {
fprintf(stderr, "Frame size read at 0x%" PRIX64 " looks bogus" fprintf(stderr, "Frame size read at 0x%" PRIX64 " looks bogus"
@ -404,11 +357,7 @@ struct Sec_Hover_Fn {
frame_type = Frame_INVALID; frame_type = Frame_INVALID;
} else { } else {
frame_type = Frame_List; frame_type = Frame_List;
if (!read(n_items, cur_field_off + sizeof(i64))) { memcpy(n_items, data + cur_field_off + sizeof(i64), sizeof(u32));
frame_size = 0;
frame_type = Frame_INVALID;
return;
}
field<i64>("List frame size: %" PRIi64 " B", hover_display_val_le_abs<i64>); field<i64>("List frame size: %" PRIi64 " B", hover_display_val_le_abs<i64>);
field_le<u32>("List frame n.items: %u"); field_le<u32>("List frame n.items: %u");
} }
@ -450,7 +399,7 @@ struct Sec_Hover_Fn {
field_str8<u32>("Type Name: %s"); field_str8<u32>("Type Name: %s");
field_str8<u32>("Type Alias: %s"); field_str8<u32>("Type Alias: %s");
field_str8<u32>("Description: %s"); field_str8<u32>("Description: %s");
}); }, HoverSec_HideIfNotHovered);
} }
void column_desc(const char *title) void column_desc(const char *title)
@ -475,15 +424,13 @@ struct Sec_Hover_Fn {
field_le<double>("Value Min: %f"); field_le<double>("Value Min: %f");
field_le<double>("Value Max: %f"); field_le<double>("Value Max: %f");
} }
}); }, HoverSec_HideIfNotHovered);
} }
void schema_description(const char *title) void schema_description(const char *title)
{ {
titled_section(title, [this] { titled_section(title, [this] {
frame<Frame_List>("Fields", [this] (u32 idx) { frame<Frame_List>("Fields", [this] (u32 idx) { field_desc(push_str8f(arena, "Field %u", idx).c()); });
field_desc(push_str8f(arena, "Field %u", idx).c());
});
frame<Frame_List>("Columns", [this] (u32 idx) { column_desc(push_str8f(arena, "Column %u", idx).c()); }); frame<Frame_List>("Columns", [this] (u32 idx) { column_desc(push_str8f(arena, "Column %u", idx).c()); });
frame<Frame_List>("Alias Columns", [this] (u32 idx) { frame<Frame_List>("Alias Columns", [this] (u32 idx) {
frame<Frame_Record>(push_str8f(arena, "Alias Column %u", idx).c(), [this] { frame<Frame_Record>(push_str8f(arena, "Alias Column %u", idx).c(), [this] {
@ -557,7 +504,7 @@ struct Sec_Hover_Fn {
void cluster_group() void cluster_group()
{ {
frame<Frame_Record>("Cluster Group", [this] { frame<Frame_List>("Cluster Group", [this] (u32) {
field_le<u64>("Min Entry: %" PRIu64); field_le<u64>("Min Entry: %" PRIu64);
field_le<u64>("Entry Span: %" PRIu64); field_le<u64>("Entry Span: %" PRIu64);
field_le<u32>("N Clusters: %u"); field_le<u32>("N Clusters: %u");
@ -598,7 +545,7 @@ struct Sec_Hover_Fn {
b8 has_checksum = n_elems < 0; b8 has_checksum = n_elems < 0;
push_str8_node_child(arena, info.desc, "Has Checksum: %s", has_checksum ? "yes" : "no"); push_str8_node_child(arena, info.desc, "Has Checksum: %s", has_checksum ? "yes" : "no");
locator("Element Locator"); locator("Element Locator");
}); }, HoverSec_HideIfNotHovered);
} }
i64 n_cols; i64 n_cols;
@ -614,12 +561,12 @@ struct Sec_Hover_Fn {
if (n_cols >= 0) if (n_cols >= 0)
field_le<i32>("Compression Settings: %d"); field_le<i32>("Compression Settings: %d");
}); });
}); }, HoverSec_HideIfNotHovered);
}); });
} }
template <Frame_Type FType, typename F> template <Frame_Type FType, typename F>
void frame(const char *title, F &&frame_body_fn, u64 sec_flags = HoverSec_CollapseIfNotHovered) void frame(const char *title, F &&frame_body_fn, u64 sec_flags = 0)
{ {
u64 start_off = cur_field_off; u64 start_off = cur_field_off;
u64 size; u64 size;
@ -627,11 +574,8 @@ struct Sec_Hover_Fn {
titled_section(title, [this, title, start_off, &size, &frame_body_fn] { titled_section(title, [this, title, start_off, &size, &frame_body_fn] {
u32 n_items = 0; u32 n_items = 0;
Frame_Type ftype = frame_header(size, &n_items); Frame_Type ftype = frame_header(size, &n_items);
if (ftype != FType) { if (ftype != FType)
fprintf(stderr, "Frame %s was supposed to be of type %s but it's of type %s\n",
title, frame_type_str[FType], frame_type_str[ftype]);
return; return;
}
if constexpr (FType == Frame_List) { if constexpr (FType == Frame_List) {
// Sadness here. // Sadness here.
@ -681,8 +625,7 @@ struct Sec_Hover_Fn {
{ {
titled_section("TFile Header", [this] { titled_section("TFile Header", [this] {
u32 root_version_be; u32 root_version_be;
if (!read(&root_version_be, cur_field_off + 4)) memcpy(&root_version_be, data + cur_field_off + 4, sizeof(u32));
return;
u32 root_version = bswap(root_version_be); u32 root_version = bswap(root_version_be);
b8 is_big = root_version > 1000'000; b8 is_big = root_version > 1000'000;
@ -722,8 +665,7 @@ struct Sec_Hover_Fn {
field_str8<u8>("File Title: %s"); field_str8<u8>("File Title: %s");
u16 version_be; u16 version_be;
if (!read(&version_be, cur_field_off)) memcpy(&version_be, data + cur_field_off, sizeof(u16));
return;
u16 version = bswap(version_be); u16 version = bswap(version_be);
b8 is_big = version > 1000; b8 is_big = version > 1000;
@ -779,8 +721,7 @@ struct Sec_Hover_Fn {
titled_section("TFile FreeList", [this] { titled_section("TFile FreeList", [this] {
tkey(); tkey();
u16 version_be; u16 version_be;
if (!read(&version_be, cur_field_off)) memcpy(&version_be, data + cur_field_off, sizeof(u16));
return;
u32 version = bswap(version_be); u32 version = bswap(version_be);
b8 is_big = version > 1000; b8 is_big = version > 1000;
@ -853,6 +794,7 @@ struct Sec_Hover_Fn {
if (zipped) { if (zipped) {
// XXX: why -1? // XXX: why -1?
range("Compressed payload", section.range.len - section.post_size - sizeof(u64) - 1); range("Compressed payload", section.range.len - section.post_size - sizeof(u64) - 1);
field_le<u64>("Checksum: 0x%" PRIX64);
} else { } else {
envelope_preamble(); envelope_preamble();
// NOTE: flags in principle require a more complex handling, but for now they are unused, // NOTE: flags in principle require a more complex handling, but for now they are unused,
@ -862,8 +804,8 @@ struct Sec_Hover_Fn {
field_str8<u32>("Description: %s"); field_str8<u32>("Description: %s");
field_str8<u32>("ROOT version: %s"); field_str8<u32>("ROOT version: %s");
schema_description("Schema Description"); schema_description("Schema Description");
field_le<u64>("Checksum: 0x%" PRIX64);
} }
field_le<u64>("Checksum: 0x%" PRIX64);
}, HoverSec_HideIfNotHovered); }, HoverSec_HideIfNotHovered);
}); });
} }
@ -880,23 +822,20 @@ struct Sec_Hover_Fn {
if (zipped) { if (zipped) {
// XXX: why -1? // XXX: why -1?
range("Payload", section.range.len - section.post_size - sizeof(u64) - 1); range("Payload", section.range.len - section.post_size - sizeof(u64) - 1);
field_le<u64>("Checksum: 0x%" PRIX64);
} else { } else {
envelope_preamble(); envelope_preamble();
// TODO: flags in principle require a more complex handling, but for now they are unused, // NOTE: flags in principle require a more complex handling, but for now they are unused,
// so they're always occupying only 8 bytes. // so they're always occupying only 8 bytes.
field_le<u64>("Flags: 0x%" PRIX64); field_le<u64>("Flags: 0x%" PRIX64);
field_le<u64>("Header checksum: 0x%" PRIX64); field_le<u64>("Header checksum: 0x%" PRIX64);
frame<Frame_Record>("Schema Extension", [this] { schema_description("Schema Extension");
schema_description("Schema Extension"); // NOTE: Column groups are currently unused, so this should always be empty
}); frame<Frame_List>("Column Groups", [] (u32) {});
frame<Frame_List>("Column Groups", [this] (u32) { frame<Frame_List>("Cluster Groups", [this] (u32) { cluster_group(); });
field_le<u32>("Column Id: %u"); range("Payload", section.range.len - cur_field_off);
}); field_le<u64>("Checksum: 0x%" PRIX64);
frame<Frame_List>("Cluster Groups", [this] (u32) {
cluster_group();
});
} }
field_le<u64>("Checksum: 0x%" PRIX64);
}, HoverSec_HideIfNotHovered); }, HoverSec_HideIfNotHovered);
}); });
} }
@ -924,13 +863,13 @@ struct Sec_Hover_Fn {
if (zipped) { if (zipped) {
// XXX: why -1? // XXX: why -1?
range("Payload", section.range.len - section.post_size - sizeof(u64) - 1); range("Payload", section.range.len - section.post_size - sizeof(u64) - 1);
field_le<u64>("Checksum: 0x%" PRIX64);
} else { } else {
envelope_preamble(); envelope_preamble();
field_le<u64>("Header checksum: 0x%" PRIX64); field_le<u64>("Header checksum: 0x%" PRIX64);
frame<Frame_List>("Cluster Summaries", [this] (u32) { cluster_summary(); }); frame<Frame_List>("Cluster Summaries", [this] (u32) { cluster_summary(); });
frame<Frame_List>("Clusters", [this] (u32) { cluster(); }); frame<Frame_List>("Clusters", [this] (u32) { cluster(); });
} }
field_le<u64>("Checksum: 0x%" PRIX64);
}, HoverSec_HideIfNotHovered); }, HoverSec_HideIfNotHovered);
}); });
} }
@ -999,7 +938,6 @@ Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, co
break; break;
case Sec_TKey_List: case Sec_TKey_List:
printf("0x%lX - 0x%lX (pre %lu)\n", section.range.start, section.range.end(), section.pre_size);
hover.tkey_list(); hover.tkey_list();
break; break;

View file

@ -1,63 +1,63 @@
internal internal
b8 init_imgui(GLFWwindow* window) { b8 init_imgui(GLFWwindow* window) {
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
ImGui::CreateContext(); ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void) io; ImGuiIO& io = ImGui::GetIO(); (void) io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.IniFilename = nullptr; io.IniFilename = nullptr;
io.LogFilename = nullptr; io.LogFilename = nullptr;
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 330"); ImGui_ImplOpenGL3_Init("#version 330");
return true; return true;
} }
internal internal
void glfw_error_callback(i32 error, const char *description) { void glfw_error_callback(i32 error, const char *description) {
fprintf(stderr, "GLFW error %d: %s\n", error, description); fprintf(stderr, "GLFW error %d: %s\n", error, description);
} }
internal internal
GLFWwindow *init_glfw(i32 desired_win_width, i32 desired_win_height) GLFWwindow *init_glfw(i32 desired_win_width, i32 desired_win_height)
{ {
glfwSetErrorCallback(glfw_error_callback); glfwSetErrorCallback(glfw_error_callback);
glfwInit(); glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE); glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); glfwWindowHint(GLFW_DECORATED, GLFW_TRUE);
glfwWindowHint(GLFW_DEPTH_BITS, 32); glfwWindowHint(GLFW_DEPTH_BITS, 32);
#ifndef NDEBUG #ifndef NDEBUG
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true); glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
#endif #endif
GLFWwindow *window = glfwCreateWindow( GLFWwindow *window = glfwCreateWindow(
desired_win_width, desired_win_height, desired_win_width, desired_win_height,
"RNTuple Viewer " V_MAJOR "." V_MINOR, "RNTuple Viewer " V_MAJOR "." V_MINOR,
nullptr, nullptr,
nullptr nullptr
); );
glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);
return window; return window;
} }
internal internal
void monitor_key(GLFWwindow *window, u8 *key_state, i32 glfw_key, Input_Key key) { void monitor_key(GLFWwindow *window, u8 *key_state, i32 glfw_key, Input_Key key) {
u8 &state = key_state[key]; u8 &state = key_state[key];
if (glfwGetKey(window, glfw_key) == GLFW_PRESS) { if (glfwGetKey(window, glfw_key) == GLFW_PRESS) {
if (!(state & KEY_STATE_IS_DOWN)) state |= KEY_STATE_JUST_PRESSED; if (!(state & KEY_STATE_IS_DOWN)) state |= KEY_STATE_JUST_PRESSED;
state |= KEY_STATE_IS_DOWN; state |= KEY_STATE_IS_DOWN;
} else if (glfwGetKey(window, glfw_key) == GLFW_RELEASE) { } else if (glfwGetKey(window, glfw_key) == GLFW_RELEASE) {
if (state & KEY_STATE_IS_DOWN) state |= KEY_STATE_JUST_RELEASED; if (state & KEY_STATE_IS_DOWN) state |= KEY_STATE_JUST_RELEASED;
state &= ~KEY_STATE_IS_DOWN; state &= ~KEY_STATE_IS_DOWN;
} }
} }
internal internal
@ -85,75 +85,75 @@ void run_main_loop(GLFWwindow *window, Arena *arena, App_State &app)
app.delta_time_accum.base = arena_push_array<f32>(arena, app.delta_time_accum.max); app.delta_time_accum.base = arena_push_array<f32>(arena, app.delta_time_accum.max);
while (!app.should_quit) { while (!app.should_quit) {
chr::time_point frame_start = chr::high_resolution_clock::now(); chr::time_point frame_start = chr::high_resolution_clock::now();
u64 time_since_prev_frame_us = chr::duration_cast<chr::microseconds>(frame_start - last_saved_time).count(); u64 time_since_prev_frame_us = chr::duration_cast<chr::microseconds>(frame_start - last_saved_time).count();
delta_time_ms = time_since_prev_frame_us * 0.001f; delta_time_ms = time_since_prev_frame_us * 0.001f;
last_saved_time = frame_start; last_saved_time = frame_start;
for (u32 i = 0; i < MOUSE_BTN_COUNT; ++i) for (u32 i = 0; i < MOUSE_BTN_COUNT; ++i)
app.user_input.mouse_btn_state[i] &= ~(MOUSE_BTN_STATE_JUST_PRESSED|MOUSE_BTN_STATE_JUST_RELEASED); app.user_input.mouse_btn_state[i] &= ~(MOUSE_BTN_STATE_JUST_PRESSED|MOUSE_BTN_STATE_JUST_RELEASED);
glfwPollEvents(); glfwPollEvents();
// Update window size // Update window size
{ {
Window_Data &wdata = app.win_data; Window_Data &wdata = app.win_data;
i32 prev_width = wdata.width; i32 prev_width = wdata.width;
i32 prev_height = wdata.height; i32 prev_height = wdata.height;
glfwGetWindowSize(window, &wdata.width, &wdata.height); glfwGetWindowSize(window, &wdata.width, &wdata.height);
wdata.size_just_changed = prev_width != wdata.width || prev_height != wdata.height; wdata.size_just_changed = prev_width != wdata.width || prev_height != wdata.height;
} }
ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame(); ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
// Check if the inspected file changed // Check if the inspected file changed
{ {
char buf[sizeof(inotify_event) + NAME_MAX + 1]; char buf[sizeof(inotify_event) + NAME_MAX + 1];
ssize_t nbytes = read(app.inspected_file.inot, buf, sizeof(buf)); ssize_t nbytes = read(app.inspected_file.inot, buf, sizeof(buf));
if (nbytes) if (nbytes)
app.inspected_file.size = file_size(app.inspected_file.stream); app.inspected_file.size = file_size(app.inspected_file.stream);
} }
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS || glfwWindowShouldClose(window)) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS || glfwWindowShouldClose(window)) {
app.should_quit = true; app.should_quit = true;
break; break;
} }
b32 focused = glfwGetWindowAttrib(window, GLFW_FOCUSED); b32 focused = glfwGetWindowAttrib(window, GLFW_FOCUSED);
if (focused) { if (focused) {
// Update keyboard // Update keyboard
u8 *key_state = app.user_input.key_state; u8 *key_state = app.user_input.key_state;
monitor_key(window, key_state, GLFW_KEY_Q, KEY_Q); monitor_key(window, key_state, GLFW_KEY_Q, KEY_Q);
monitor_key(window, key_state, GLFW_KEY_UP, KEY_UP); monitor_key(window, key_state, GLFW_KEY_UP, KEY_UP);
monitor_key(window, key_state, GLFW_KEY_DOWN, KEY_DOWN); monitor_key(window, key_state, GLFW_KEY_DOWN, KEY_DOWN);
monitor_key(window, key_state, GLFW_KEY_LEFT, KEY_LEFT); monitor_key(window, key_state, GLFW_KEY_LEFT, KEY_LEFT);
monitor_key(window, key_state, GLFW_KEY_RIGHT, KEY_RIGHT); monitor_key(window, key_state, GLFW_KEY_RIGHT, KEY_RIGHT);
monitor_key(window, key_state, GLFW_KEY_LEFT_ALT, KEY_ALT); monitor_key(window, key_state, GLFW_KEY_LEFT_ALT, KEY_ALT);
monitor_key(window, key_state, GLFW_KEY_TAB, KEY_TAB); monitor_key(window, key_state, GLFW_KEY_TAB, KEY_TAB);
monitor_key(window, key_state, GLFW_KEY_LEFT_SHIFT, KEY_SHIFT); monitor_key(window, key_state, GLFW_KEY_LEFT_SHIFT, KEY_SHIFT);
// Update mouse // Update mouse
f64 mposx, mposy; f64 mposx, mposy;
glfwGetCursorPos(window, &mposx, &mposy); glfwGetCursorPos(window, &mposx, &mposy);
u8 *mouse_btn_state = app.user_input.mouse_btn_state; u8 *mouse_btn_state = app.user_input.mouse_btn_state;
monitor_mouse_btn(window, mouse_btn_state, GLFW_MOUSE_BUTTON_LEFT, MOUSE_BTN_LEFT); monitor_mouse_btn(window, mouse_btn_state, GLFW_MOUSE_BUTTON_LEFT, MOUSE_BTN_LEFT);
monitor_mouse_btn(window, mouse_btn_state, GLFW_MOUSE_BUTTON_RIGHT, MOUSE_BTN_RIGHT); monitor_mouse_btn(window, mouse_btn_state, GLFW_MOUSE_BUTTON_RIGHT, MOUSE_BTN_RIGHT);
app.user_input.mouse_pos.x = static_cast<i32>(mposx); app.user_input.mouse_pos.x = static_cast<i32>(mposx);
app.user_input.mouse_pos.y = static_cast<i32>(mposy); app.user_input.mouse_pos.y = static_cast<i32>(mposy);
} }
update_and_render(arena, app, delta_time_ms); update_and_render(arena, app, delta_time_ms);
ImGui::Render(); ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window); glfwSwapBuffers(window);
} }
} }

View file

@ -1,14 +1,14 @@
struct Prof_Scope_Print { struct Prof_Scope_Print {
Prof_Scope_Print(const char *name) : scope_name { name }, scope_start_t { std::chrono::high_resolution_clock::now() } {} Prof_Scope_Print(const char *name) : scope_name { name }, scope_start_t { std::chrono::high_resolution_clock::now() } {}
~Prof_Scope_Print() { ~Prof_Scope_Print() {
using namespace std::chrono; using namespace std::chrono;
time_point scope_end_t = high_resolution_clock::now(); time_point scope_end_t = high_resolution_clock::now();
duration scope_duration = duration_cast<microseconds>(scope_end_t - scope_start_t); duration scope_duration = duration_cast<microseconds>(scope_end_t - scope_start_t);
fprintf(stderr, "[profile] %s took %.4f ms\n", scope_name, scope_duration.count() * 0.001f); fprintf(stderr, "[profile] %s took %.4f ms\n", scope_name, scope_duration.count() * 0.001f);
} }
const char *scope_name; const char *scope_name;
std::chrono::time_point<std::chrono::high_resolution_clock> scope_start_t; std::chrono::time_point<std::chrono::high_resolution_clock> scope_start_t;
}; };
#define TIMED_SCOPE() const Prof_Scope_Print CONCAT_STR(_prof, __LINE__) { __func__ } #define TIMED_SCOPE() const Prof_Scope_Print CONCAT_STR(_prof, __LINE__) { __func__ }

View file

@ -618,9 +618,7 @@ Section find_section(App_State &app, u64 off, i64 hilite_cluster = -1)
if (rdata.rng_tkeys_list.start <= off && off < rdata.rng_tkeys_list.end()) { if (rdata.rng_tkeys_list.start <= off && off < rdata.rng_tkeys_list.end()) {
sec.id = Sec_TKey_List; sec.id = Sec_TKey_List;
sec.range = rdata.rng_tkeys_list; sec.range = rdata.rng_tkeys_list;
// FIXME! sec.pre_size = rblob_sz;
// sec.range.len += rblob_sz;
// printf("with rblob_sz: 0x%lX\n", sec.range.end());
return sec; return sec;
} }

View file

@ -32,10 +32,10 @@ String8 str8_from_c(const char *str)
internal internal
String8 to_pretty_size(Arena *arena, u64 bytes) String8 to_pretty_size(Arena *arena, u64 bytes)
{ {
if (bytes >= GiB(1)) return push_str8f(arena, "%.1f GiB", (f32)bytes / GiB(1)); if (bytes >= GiB(1)) return push_str8f(arena, "%.1f GiB", (f32)bytes / GiB(1));
if (bytes >= MiB(1)) return push_str8f(arena, "%.1f MiB", (f32)bytes / MiB(1)); if (bytes >= MiB(1)) return push_str8f(arena, "%.1f MiB", (f32)bytes / MiB(1));
if (bytes >= KiB(1)) return push_str8f(arena, "%.1f KiB", (f32)bytes / KiB(1)); if (bytes >= KiB(1)) return push_str8f(arena, "%.1f KiB", (f32)bytes / KiB(1));
return push_str8f(arena, "%zu B", bytes); return push_str8f(arena, "%zu B", bytes);
} }
internal internal

View file

@ -1,26 +1,26 @@
enum Input_Key { enum Input_Key {
KEY_UP, KEY_UP,
KEY_DOWN, KEY_DOWN,
KEY_LEFT, KEY_LEFT,
KEY_RIGHT, KEY_RIGHT,
KEY_Q, KEY_Q,
KEY_ALT, KEY_ALT,
KEY_TAB, KEY_TAB,
KEY_SHIFT, KEY_SHIFT,
KEY_COUNT KEY_COUNT
}; };
enum Key_State : u8 { enum Key_State : u8 {
KEY_STATE_IS_DOWN = 0x1, KEY_STATE_IS_DOWN = 0x1,
KEY_STATE_JUST_PRESSED = 0x2, KEY_STATE_JUST_PRESSED = 0x2,
KEY_STATE_JUST_RELEASED = 0x4, KEY_STATE_JUST_RELEASED = 0x4,
}; };
enum Mouse_Button { enum Mouse_Button {
MOUSE_BTN_LEFT, MOUSE_BTN_LEFT,
MOUSE_BTN_RIGHT, MOUSE_BTN_RIGHT,
MOUSE_BTN_COUNT MOUSE_BTN_COUNT
}; };
enum Mouse_Button_State : u8 { enum Mouse_Button_State : u8 {
@ -30,18 +30,18 @@ enum Mouse_Button_State : u8 {
}; };
struct User_Input { struct User_Input {
u8 key_state[KEY_COUNT]; u8 key_state[KEY_COUNT];
u8 mouse_btn_state[MOUSE_BTN_COUNT]; u8 mouse_btn_state[MOUSE_BTN_COUNT];
struct { i32 x; i32 y; } mouse_pos; struct { i32 x; i32 y; } mouse_pos;
}; };
struct Window_Data { struct Window_Data {
// Real width and height of the window // Real width and height of the window
i32 width; i32 width;
i32 height; i32 height;
bool size_just_changed; bool size_just_changed;
f32 desired_aspect_ratio; f32 desired_aspect_ratio;
}; };