ESP Tree view.

This commit is contained in:
2022-09-10 22:12:31 +10:00
parent 222df3c54c
commit ad3e4b14fc
4 changed files with 242 additions and 82 deletions

View File

@@ -1,42 +1,152 @@
// Dear ImGui: standalone example application for GLFW + OpenGL 3, using programmable pipeline
// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Read online: https://github.com/ocornut/imgui/tree/master/docs
// Based on Dear ImGui GLFW + OpenGL 3 standalone example
#include "ESPReader.h"
#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_opengl3.h"
#include <stdio.h>
#include <cstdlib>
#undef NDEBUG
#include <assert.h>
#define NDEBUG
#include <GLFW/glfw3.h> // Will drag system OpenGL headers
const float BASE_FONT_SIZE = 13;
const ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings;
MetaTree ReadESP(const char *filename);
GLFWwindow *Setup(void);
void NewFrame(void);
void Fullscreen(void);
void Render(GLFWwindow *window, const ImVec4 clear_color);
void Cleanup(GLFWwindow *window);
void ChangeScale(bool *scale_update, const float scale);
void ScalingWidget(bool *scale_update, float *scale);
void ESPTreeWalk(MetaNode *m);
static void glfw_error_callback(int error, const char *description)
{
fprintf(stderr, "Glfw Error %d: %s\n", error, description);
}
void ChangeScale(bool *scale_update, const float scale);
void ScalingWidget(bool *scale_update, float *scale);
int main(int, char **)
{
// Setup window
glfwSetErrorCallback(glfw_error_callback);
if (!glfwInit())
GLFWwindow *window = Setup();
if (!window)
return 1;
// GL 3.0 + GLSL 130
MetaTree m = ReadESP("Skyrim.esm");
m.root->user = (void *)true;
// Our state
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
bool scale_update = false;
float scale = 1.0f;
// Main loop
while (!glfwWindowShouldClose(window))
{
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
glfwPollEvents();
// Interface scaling
ChangeScale(&scale_update, scale);
// Start the Dear ImGui frame
NewFrame();
// Setup for fullscreen
Fullscreen();
// Begin window
ImGui::Begin("ESP Browser", NULL, window_flags);
ScalingWidget(&scale_update, &scale);
ESPTreeWalk(m.root);
// End window
ImGui::End();
Render(window, clear_color);
}
free(m.esp.data);
free(m.tree.data);
Cleanup(window);
return 0;
}
MetaTree ReadESP(const char *filename)
{
errno_t ret = 0;
SizedBuf esp_buf = { 0 };
ESPStats stats = { 0 };
SizedBuf tree_buf = { 0 };
MetaTree tree = { 0 };
// Read in the esp file
{
FILE *fp;
ret = fopen_s(&fp, "Skyrim.esm", "rb");
assert(fp && !ret);
fseek(fp, 0L, SEEK_END);
esp_buf.size = ftell(fp);
rewind(fp);
esp_buf.data = (char *)malloc(esp_buf.size);
assert(esp_buf.data);
size_t read = fread(esp_buf.data, sizeof(char), esp_buf.size, fp);
fclose(fp);
assert(read == esp_buf.size);
}
// Calculate esp stats
stats = espr_stats(esp_buf);
// Construct the meta tree
{
tree_buf.size = espr_tree_size(stats);
tree_buf.data = (char *)malloc(tree_buf.size);
assert(tree_buf.data);
tree = espr_create_tree(esp_buf, tree_buf);
}
// lazy file pointer cleanup
_fcloseall();
return tree;
}
GLFWwindow *Setup(void)
{
// Setup window
glfwSetErrorCallback(glfw_error_callback);
if (!glfwInit())
return NULL;
// GL 3.0 + GLSL 130
const char *glsl_version = "#version 130";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// Create window with graphics context
// Create window with graphics context
GLFWwindow *window = glfwCreateWindow(1920, 1080, "Dear ImGui GLFW+OpenGL3 example", NULL, NULL);
if (window == NULL)
return 1;
return NULL;
glfwMakeContextCurrent(window);
glfwSwapInterval(1); // Enable vsync
@@ -67,80 +177,60 @@ int main(int, char **)
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init(glsl_version);
// Our state
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
bool scale_update = false;
float scale = 1.0f;
return window;
}
// Main loop
while (!glfwWindowShouldClose(window))
void NewFrame(void)
{
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
}
void Fullscreen(void)
{
const ImGuiViewport *viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->WorkPos);
ImGui::SetNextWindowSize(viewport->WorkSize);
}
void Render(GLFWwindow * window, const ImVec4 clear_color)
{
ImGuiIO &io = ImGui::GetIO();
ImGui::Render();
int display_w, display_h;
glfwGetFramebufferSize(window, &display_w, &display_h);
glViewport(0, 0, display_w, display_h);
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
// Update and Render additional Platform Windows
// (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
// For this specific demo app we could also call glfwMakeContextCurrent(window) directly)
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
glfwPollEvents();
static ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings;
// Interface scaling
ChangeScale(&scale_update, scale);
// Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// setup for fullscreen
const ImGuiViewport *viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->WorkPos);
ImGui::SetNextWindowSize(viewport->WorkSize);
ImGui::Begin("ESP Browser", NULL, flags);
ScalingWidget(&scale_update, &scale);
if (ImGui::TreeNode("Test"))
{
ImGui::Text("Text");
ImGui::TreePop();
}
ImGui::End();
// Rendering
ImGui::Render();
int display_w, display_h;
glfwGetFramebufferSize(window, &display_w, &display_h);
glViewport(0, 0, display_w, display_h);
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
// Update and Render additional Platform Windows
// (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
// For this specific demo app we could also call glfwMakeContextCurrent(window) directly)
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
GLFWwindow *backup_current_context = glfwGetCurrentContext();
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
glfwMakeContextCurrent(backup_current_context);
}
glfwSwapBuffers(window);
GLFWwindow *backup_current_context = glfwGetCurrentContext();
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
glfwMakeContextCurrent(backup_current_context);
}
// Cleanup
glfwSwapBuffers(window);
}
void Cleanup(GLFWwindow *window)
{
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
void ChangeScale(bool *scale_update, const float scale)
@@ -152,7 +242,8 @@ void ChangeScale(bool *scale_update, const float scale)
if (*scale_update) {
ImFontConfig font_config;
font_config.SizePixels = (BASE_FONT_SIZE * scale);
// Truncate to 2 decimal places
font_config.SizePixels = ((float)(int)(BASE_FONT_SIZE * scale * 100)) / 100;
io.Fonts->Clear();
io.Fonts->AddFontDefault(&font_config);
ImGui_ImplOpenGL3_UpdateFontsTexture();
@@ -179,3 +270,22 @@ void ScalingWidget(bool *scale_update, float *scale)
ImGui::PopItemWidth();
}
void ESPTreeWalk(MetaNode *m)
{
char buf[1024] = { 0 };
SizedBuf sb = { buf, 1024 };
espr_meta_string(m, sb);
if (m->n.type == NT_RECORD) {
ImGui::BulletText(buf);
} else {
if (ImGui::TreeNode(buf)) {
MetaNode *c = m->first_child;
while (c) {
ESPTreeWalk(c);
c = c->next;
}
ImGui::TreePop();
}
}
}