diff --git a/.gitmodules b/.gitmodules index 21d5847..7d97485 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,4 +10,4 @@ [submodule "external/imgui_gradient"] path = external/imgui_gradient - url = https://github.com/maede97/imgui_gradient + url = https://github.com/Coollab-Art/imgui_gradient diff --git a/external/imgui_gradient b/external/imgui_gradient index fd082b4..6fcb6b8 160000 --- a/external/imgui_gradient +++ b/external/imgui_gradient @@ -1 +1 @@ -Subproject commit fd082b4440b6e386cba39ce9e2818db2dab20650 +Subproject commit 6fcb6b814839e2adb6d41edc9b27e42a02114c83 diff --git a/include/entropy/app.h b/include/entropy/app.h index fc8d16a..2cf28c4 100644 --- a/include/entropy/app.h +++ b/include/entropy/app.h @@ -80,6 +80,9 @@ struct AppState { std::map featureEnabled; ImGG::GradientWidget gradient_widget; + // Recent files + std::vector> recentCacheFiles; + void resetHexDisplayGradientColors(); }; @@ -91,5 +94,6 @@ void updateAutoplay(AppState &state); void initializeWindowAndGL(GLFWwindow *&window, GLuint &tex); void mainLoop(GLFWwindow *window, GLuint tex, AppState &state, UiState &uiState, IGFD::FileDialogConfig &config, std::function loadHexData); +void addToRecentFiles(AppState &state, const std::string &cache_path, const std::string &file_path); } // namespace entropy \ No newline at end of file diff --git a/include/entropy/version.h b/include/entropy/version.h index ab0e8b2..f65ff82 100644 --- a/include/entropy/version.h +++ b/include/entropy/version.h @@ -1,4 +1,4 @@ #pragma once -#define VERSION "1.8.1" -#define DATE "28.01.2026" +#define VERSION "1.8.2" +#define DATE "10.02.2026" diff --git a/src/app.cpp b/src/app.cpp index a9491ab..d021fab 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -10,6 +10,27 @@ namespace entropy { #define ALL_FILES_FILTER "All files {((.*))}" +void addToRecentFiles(AppState &state, const std::string &cache_file, const std::string &file_path) { + const std::string cache_ext = ".cache.bin"; + if (cache_file.size() < cache_ext.size() || cache_file.substr(cache_file.size() - cache_ext.size()) != cache_ext) { + return; + } + + auto pair = std::make_pair(cache_file, file_path); + + // Remove if already exists (to move to front) + auto it = std::find(state.recentCacheFiles.begin(), state.recentCacheFiles.end(), pair); + if (it != state.recentCacheFiles.end()) { + state.recentCacheFiles.erase(it); + } + // Add to front + state.recentCacheFiles.insert(state.recentCacheFiles.begin(), pair); + // Keep only 10 most recent + if (state.recentCacheFiles.size() > 10) { + state.recentCacheFiles.pop_back(); + } +} + void AppState::resetHexDisplayGradientColors() { gradient_widget.gradient().clear(); gradient_widget.gradient().add_mark(ImGG::Mark{ImGG::RelativePosition{0.0f}, ImVec4(0.0f, 0.0f, 1.0f, 1.0f)}); @@ -50,6 +71,8 @@ int parseCommandLine(int argc, char **argv, AppState &state) { state.file.read(reinterpret_cast(state.all_cache_data.data()), state.file_size); state.redrawBlock = true; + + addToRecentFiles(state, cache_path, source_path); } else { std::cerr << "First argument must be a .cache.bin file when " "providing two arguments.\n"; @@ -82,6 +105,8 @@ int parseCommandLine(int argc, char **argv, AppState &state) { state.redrawBlock = true; state.promptForSource = true; + + addToRecentFiles(state, state.lastCacheFile, ""); } else { // Start cache generation for the provided source file (background // thread) @@ -98,6 +123,8 @@ int parseCommandLine(int argc, char **argv, AppState &state) { state.cacheThread = std::thread([arg_path, cache_file]() { generateCacheThreaded(arg_path, cache_file); }); state.cacheThread.detach(); + + addToRecentFiles(state, cache_file, arg_path); } } return 0; @@ -123,8 +150,11 @@ void handleDroppedFiles(AppState &state, UiState &uiState, std::functionOpenDialog("OpenCacheDlg", "Open Cache File", ".cache.bin", config); } + if (ImGui::MenuItem("Find")) { uiState.showSearchWindow = true; } + + // Recent files submenu + if (!state.recentCacheFiles.empty() && ImGui::BeginMenu("Recent Cache Files")) { + for (const auto &filePair : state.recentCacheFiles) { + std::string menuItemText; + if (filePair.second.length() > 0) + menuItemText = filePair.first + " | " + filePair.second; + else + menuItemText = filePair.first; + if (ImGui::MenuItem(menuItemText.c_str())) { + // Open the selected recent cache file + state.lastCacheFile = filePair.first; + state.originalFile = filePair.second; + state.file.close(); + state.file.open(filePair.first, std::ios::binary); + if (state.file) { + state.file.seekg(0, std::ios::end); + state.file_size = (size_t)state.file.tellg(); + state.file.seekg(0, std::ios::beg); + state.all_cache_data.resize(state.file_size); + state.file.read(reinterpret_cast(state.all_cache_data.data()), state.file_size); + state.current_block = 0; + state.block_slider = 0; + state.redrawBlock = true; + if (state.originalFile.empty()) { + state.promptForSource = true; + } + + loadHexData(0); + addToRecentFiles(state, filePair.first, filePair.second); + } + } + } + ImGui::EndMenu(); + } ImGui::EndMenu(); } @@ -422,6 +490,7 @@ void mainLoop(GLFWwindow *window, GLuint tex, AppState &state, UiState &uiState, state.current_block = 0; state.block_slider = 0; state.redrawBlock = true; + loadHexData(0); } state.showCacheGen = false; } diff --git a/src/ui.cpp b/src/ui.cpp index 9c8fb34..75272c3 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -177,6 +177,8 @@ void renderSearchWindow(UiState &uiState, AppState &appState, std::functionClose(); @@ -350,6 +354,8 @@ void handleFileDialogs(UiState &uiState, AppState &appState, IGFD::FileDialogCon appState.originalFile = fileToCache; appState.cacheThread = std::thread([fileToCache, cacheFile]() { generateCacheThreaded(fileToCache, cacheFile); }); appState.cacheThread.detach(); + + addToRecentFiles(appState, cacheFile, fileToCache); } ImGuiFileDialog::Instance()->Close(); } @@ -370,6 +376,9 @@ void handleFileDialogs(UiState &uiState, AppState &appState, IGFD::FileDialogCon if (uiState.showHexView) { loadHexData(uiState.currentSectorIndex); } + + addToRecentFiles(appState, appState.lastCacheFile, sourcePath); + } else { // Size mismatch, do not set }