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
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:
- 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).
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.

View file

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

View file

@ -5,8 +5,8 @@ struct Defer_Guard {
F _f;
};
struct Defer_Guard_Helper {
template <typename F>
Defer_Guard<F> operator+(F&& f) { return Defer_Guard<F>(static_cast<F &&>(f)); }
template <typename F>
Defer_Guard<F> operator+(F&& f) { return Defer_Guard<F>(static_cast<F &&>(f)); }
};
#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 {
HoverSec_None = 0,
// Hide = don't show at all, even the title
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.
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 Section &section;
Arena *arena;
@ -142,20 +139,6 @@ struct Sec_Hover_Fn {
u8 cur_section_nesting = 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>
void titled_section(const char *title, F &&sec_body_fn, u64 flags = 0)
{
@ -167,19 +150,11 @@ struct Sec_Hover_Fn {
sec_body_fn();
// 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;
}
assert(cur_field_off >= sec_start);
b8 hovered = off >= sec_start && off <= cur_field_off;
if (!hovered) {
if (flags & HoverSec_HideIfNotHovered)
pop_str8_node_child(prev_desc, info.desc);
else if (flags & HoverSec_CollapseIfNotHovered)
info.desc->first_child = info.desc->last_child = nullptr;
if (!hovered & (flags & HoverSec_HideIfNotHovered)) {
pop_str8_node_child(prev_desc, info.desc);
} else if (display_grouped) {
// 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;
@ -211,9 +186,7 @@ struct Sec_Hover_Fn {
b8 hovered = cur_field_off <= off && off < cur_field_off + field_len;
T val;
if (!read(&val, cur_field_off))
return false;
memcpy(&val, (u8 *)data + cur_field_off, field_len);
String8_Node *desc = display_val(arena, info.desc, desc_fmt, val);
if (hovered && !display_grouped)
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).
TStrSize str_size;
if (!read(&str_size, cur_field_off))
return;
memcpy(&str_size, data + cur_field_off, sizeof(TStrSize));
// DEBUG
if (str_size > 1000) {
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;
u8 *buf = arena_push_array_nozero<u8>(arena, str_size + 1);
u64 size_to_read = str_size;
if (!read(buf, cur_field_off + sizeof(TStrSize), &size_to_read))
return;
memcpy(buf, data + cur_field_off + sizeof(TStrSize), str_size);
buf[str_size] = 0;
String8 s = { buf, str_size };
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)
{
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);
if (hovered && !display_grouped)
info.highlighted_desc = dsc;
@ -291,15 +257,13 @@ struct Sec_Hover_Fn {
// Returns true if `was_zipped` was read.
b8 maybe_rootzip(b8 *was_zipped = nullptr)
{
// TODO boundary checks
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;
if (display_val_rootzip(arena, info.desc, "Zipped Block", data + cur_field_off)) {
if (was_zipped)
*was_zipped = true;
if (display_grouped || hovered) {
if (was_zipped)
*was_zipped = true;
info.rng = { cur_field_off, range_len };
if (hovered)
info.highlighted_desc = info.desc;
@ -316,9 +280,7 @@ struct Sec_Hover_Fn {
{
titled_section(title, [this] {
u16 version_be;
if (!read(&version_be, cur_field_off + 4))
return;
memcpy(&version_be, data + cur_field_off + 4, sizeof(u16));
u32 version = bswap(version_be);
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) {
u64 size;
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 {
Frame_INVALID,
Frame_Record,
Frame_List,
Frame_COUNT
};
static constexpr const char *frame_type_str[Frame_COUNT] = {
"INVALID", "Record", "List"
Frame_List
};
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;
titled_section(titlestr.c(), [this, &frame_type, &frame_size = size, n_items] {
i64 size;
if (!read(&size, cur_field_off)) {
frame_size = 0;
frame_type = Frame_INVALID;
return;
}
memcpy(&size, data + cur_field_off, sizeof(size));
// Sanity check
if (size > 1000000) {
fprintf(stderr, "Frame size read at 0x%" PRIX64 " looks bogus"
@ -404,11 +357,7 @@ struct Sec_Hover_Fn {
frame_type = Frame_INVALID;
} else {
frame_type = Frame_List;
if (!read(n_items, cur_field_off + sizeof(i64))) {
frame_size = 0;
frame_type = Frame_INVALID;
return;
}
memcpy(n_items, data + cur_field_off + sizeof(i64), sizeof(u32));
field<i64>("List frame size: %" PRIi64 " B", hover_display_val_le_abs<i64>);
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 Alias: %s");
field_str8<u32>("Description: %s");
});
}, HoverSec_HideIfNotHovered);
}
void column_desc(const char *title)
@ -475,15 +424,13 @@ struct Sec_Hover_Fn {
field_le<double>("Value Min: %f");
field_le<double>("Value Max: %f");
}
});
}, HoverSec_HideIfNotHovered);
}
void schema_description(const char *title)
{
titled_section(title, [this] {
frame<Frame_List>("Fields", [this] (u32 idx) {
field_desc(push_str8f(arena, "Field %u", idx).c());
});
frame<Frame_List>("Fields", [this] (u32 idx) { 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>("Alias Columns", [this] (u32 idx) {
frame<Frame_Record>(push_str8f(arena, "Alias Column %u", idx).c(), [this] {
@ -557,7 +504,7 @@ struct Sec_Hover_Fn {
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>("Entry Span: %" PRIu64);
field_le<u32>("N Clusters: %u");
@ -598,7 +545,7 @@ struct Sec_Hover_Fn {
b8 has_checksum = n_elems < 0;
push_str8_node_child(arena, info.desc, "Has Checksum: %s", has_checksum ? "yes" : "no");
locator("Element Locator");
});
}, HoverSec_HideIfNotHovered);
}
i64 n_cols;
@ -614,12 +561,12 @@ struct Sec_Hover_Fn {
if (n_cols >= 0)
field_le<i32>("Compression Settings: %d");
});
});
}, HoverSec_HideIfNotHovered);
});
}
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 size;
@ -627,11 +574,8 @@ struct Sec_Hover_Fn {
titled_section(title, [this, title, start_off, &size, &frame_body_fn] {
u32 n_items = 0;
Frame_Type ftype = frame_header(size, &n_items);
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]);
if (ftype != FType)
return;
}
if constexpr (FType == Frame_List) {
// Sadness here.
@ -681,8 +625,7 @@ struct Sec_Hover_Fn {
{
titled_section("TFile Header", [this] {
u32 root_version_be;
if (!read(&root_version_be, cur_field_off + 4))
return;
memcpy(&root_version_be, data + cur_field_off + 4, sizeof(u32));
u32 root_version = bswap(root_version_be);
b8 is_big = root_version > 1000'000;
@ -722,8 +665,7 @@ struct Sec_Hover_Fn {
field_str8<u8>("File Title: %s");
u16 version_be;
if (!read(&version_be, cur_field_off))
return;
memcpy(&version_be, data + cur_field_off, sizeof(u16));
u16 version = bswap(version_be);
b8 is_big = version > 1000;
@ -779,8 +721,7 @@ struct Sec_Hover_Fn {
titled_section("TFile FreeList", [this] {
tkey();
u16 version_be;
if (!read(&version_be, cur_field_off))
return;
memcpy(&version_be, data + cur_field_off, sizeof(u16));
u32 version = bswap(version_be);
b8 is_big = version > 1000;
@ -853,6 +794,7 @@ struct Sec_Hover_Fn {
if (zipped) {
// XXX: why -1?
range("Compressed payload", section.range.len - section.post_size - sizeof(u64) - 1);
field_le<u64>("Checksum: 0x%" PRIX64);
} else {
envelope_preamble();
// 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>("ROOT version: %s");
schema_description("Schema Description");
field_le<u64>("Checksum: 0x%" PRIX64);
}
field_le<u64>("Checksum: 0x%" PRIX64);
}, HoverSec_HideIfNotHovered);
});
}
@ -880,23 +822,20 @@ struct Sec_Hover_Fn {
if (zipped) {
// XXX: why -1?
range("Payload", section.range.len - section.post_size - sizeof(u64) - 1);
field_le<u64>("Checksum: 0x%" PRIX64);
} else {
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.
field_le<u64>("Flags: 0x%" PRIX64);
field_le<u64>("Header checksum: 0x%" PRIX64);
frame<Frame_Record>("Schema Extension", [this] {
schema_description("Schema Extension");
});
frame<Frame_List>("Column Groups", [this] (u32) {
field_le<u32>("Column Id: %u");
});
frame<Frame_List>("Cluster Groups", [this] (u32) {
cluster_group();
});
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>("Cluster Groups", [this] (u32) { cluster_group(); });
range("Payload", section.range.len - cur_field_off);
field_le<u64>("Checksum: 0x%" PRIX64);
}
field_le<u64>("Checksum: 0x%" PRIX64);
}, HoverSec_HideIfNotHovered);
});
}
@ -924,13 +863,13 @@ struct Sec_Hover_Fn {
if (zipped) {
// XXX: why -1?
range("Payload", section.range.len - section.post_size - sizeof(u64) - 1);
field_le<u64>("Checksum: 0x%" PRIX64);
} else {
envelope_preamble();
field_le<u64>("Header checksum: 0x%" PRIX64);
frame<Frame_List>("Cluster Summaries", [this] (u32) { cluster_summary(); });
frame<Frame_List>("Clusters", [this] (u32) { cluster(); });
}
field_le<u64>("Checksum: 0x%" PRIX64);
}, HoverSec_HideIfNotHovered);
});
}
@ -999,7 +938,6 @@ Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, co
break;
case Sec_TKey_List:
printf("0x%lX - 0x%lX (pre %lu)\n", section.range.start, section.range.end(), section.pre_size);
hover.tkey_list();
break;

View file

@ -1,63 +1,63 @@
internal
b8 init_imgui(GLFWwindow* window) {
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void) io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.IniFilename = nullptr;
io.LogFilename = nullptr;
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void) io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.IniFilename = nullptr;
io.LogFilename = nullptr;
ImGui::StyleColorsDark();
ImGui::StyleColorsDark();
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 330");
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 330");
return true;
return true;
}
internal
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
GLFWwindow *init_glfw(i32 desired_win_width, i32 desired_win_height)
{
glfwSetErrorCallback(glfw_error_callback);
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
glfwWindowHint(GLFW_DECORATED, GLFW_TRUE);
glfwWindowHint(GLFW_DEPTH_BITS, 32);
glfwSetErrorCallback(glfw_error_callback);
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
glfwWindowHint(GLFW_DECORATED, GLFW_TRUE);
glfwWindowHint(GLFW_DEPTH_BITS, 32);
#ifndef NDEBUG
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
#endif
GLFWwindow *window = glfwCreateWindow(
desired_win_width, desired_win_height,
"RNTuple Viewer " V_MAJOR "." V_MINOR,
nullptr,
nullptr
);
GLFWwindow *window = glfwCreateWindow(
desired_win_width, desired_win_height,
"RNTuple Viewer " V_MAJOR "." V_MINOR,
nullptr,
nullptr
);
glfwMakeContextCurrent(window);
glfwMakeContextCurrent(window);
return window;
return window;
}
internal
void monitor_key(GLFWwindow *window, u8 *key_state, i32 glfw_key, Input_Key key) {
u8 &state = key_state[key];
if (glfwGetKey(window, glfw_key) == GLFW_PRESS) {
if (!(state & KEY_STATE_IS_DOWN)) state |= KEY_STATE_JUST_PRESSED;
state |= KEY_STATE_IS_DOWN;
} else if (glfwGetKey(window, glfw_key) == GLFW_RELEASE) {
if (state & KEY_STATE_IS_DOWN) state |= KEY_STATE_JUST_RELEASED;
state &= ~KEY_STATE_IS_DOWN;
}
u8 &state = key_state[key];
if (glfwGetKey(window, glfw_key) == GLFW_PRESS) {
if (!(state & KEY_STATE_IS_DOWN)) state |= KEY_STATE_JUST_PRESSED;
state |= KEY_STATE_IS_DOWN;
} else if (glfwGetKey(window, glfw_key) == GLFW_RELEASE) {
if (state & KEY_STATE_IS_DOWN) state |= KEY_STATE_JUST_RELEASED;
state &= ~KEY_STATE_IS_DOWN;
}
}
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);
while (!app.should_quit) {
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();
delta_time_ms = time_since_prev_frame_us * 0.001f;
last_saved_time = frame_start;
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();
delta_time_ms = time_since_prev_frame_us * 0.001f;
last_saved_time = frame_start;
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);
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);
glfwPollEvents();
glfwPollEvents();
// Update window size
{
Window_Data &wdata = app.win_data;
// Update window size
{
Window_Data &wdata = app.win_data;
i32 prev_width = wdata.width;
i32 prev_height = wdata.height;
i32 prev_width = wdata.width;
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_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// Check if the inspected file changed
{
char buf[sizeof(inotify_event) + NAME_MAX + 1];
ssize_t nbytes = read(app.inspected_file.inot, buf, sizeof(buf));
if (nbytes)
app.inspected_file.size = file_size(app.inspected_file.stream);
}
// Check if the inspected file changed
{
char buf[sizeof(inotify_event) + NAME_MAX + 1];
ssize_t nbytes = read(app.inspected_file.inot, buf, sizeof(buf));
if (nbytes)
app.inspected_file.size = file_size(app.inspected_file.stream);
}
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS || glfwWindowShouldClose(window)) {
app.should_quit = true;
break;
}
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS || glfwWindowShouldClose(window)) {
app.should_quit = true;
break;
}
b32 focused = glfwGetWindowAttrib(window, GLFW_FOCUSED);
if (focused) {
// Update keyboard
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_UP, KEY_UP);
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_RIGHT, KEY_RIGHT);
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_LEFT_SHIFT, KEY_SHIFT);
b32 focused = glfwGetWindowAttrib(window, GLFW_FOCUSED);
if (focused) {
// Update keyboard
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_UP, KEY_UP);
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_RIGHT, KEY_RIGHT);
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_LEFT_SHIFT, KEY_SHIFT);
// Update mouse
f64 mposx, mposy;
glfwGetCursorPos(window, &mposx, &mposy);
// Update mouse
f64 mposx, mposy;
glfwGetCursorPos(window, &mposx, &mposy);
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_RIGHT, MOUSE_BTN_RIGHT);
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_RIGHT, MOUSE_BTN_RIGHT);
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.x = static_cast<i32>(mposx);
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_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window);
glfwSwapBuffers(window);
}
}

View file

@ -1,14 +1,14 @@
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() {
using namespace std::chrono;
time_point scope_end_t = high_resolution_clock::now();
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);
}
Prof_Scope_Print(const char *name) : scope_name { name }, scope_start_t { std::chrono::high_resolution_clock::now() } {}
~Prof_Scope_Print() {
using namespace std::chrono;
time_point scope_end_t = high_resolution_clock::now();
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);
}
const char *scope_name;
std::chrono::time_point<std::chrono::high_resolution_clock> scope_start_t;
const char *scope_name;
std::chrono::time_point<std::chrono::high_resolution_clock> scope_start_t;
};
#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()) {
sec.id = Sec_TKey_List;
sec.range = rdata.rng_tkeys_list;
// FIXME!
// sec.range.len += rblob_sz;
// printf("with rblob_sz: 0x%lX\n", sec.range.end());
sec.pre_size = rblob_sz;
return sec;
}

View file

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

View file

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