Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion external/imgui_gradient
4 changes: 4 additions & 0 deletions include/entropy/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ struct AppState {
std::map<std::string, bool> featureEnabled;
ImGG::GradientWidget gradient_widget;

// Recent files
std::vector<std::pair<std::string, std::string>> recentCacheFiles;

void resetHexDisplayGradientColors();
};

Expand All @@ -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<void(size_t)> loadHexData);
void addToRecentFiles(AppState &state, const std::string &cache_path, const std::string &file_path);

} // namespace entropy
4 changes: 2 additions & 2 deletions include/entropy/version.h
Original file line number Diff line number Diff line change
@@ -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"
71 changes: 70 additions & 1 deletion src/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)});
Expand Down Expand Up @@ -50,6 +71,8 @@ int parseCommandLine(int argc, char **argv, AppState &state) {
state.file.read(reinterpret_cast<char *>(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";
Expand Down Expand Up @@ -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)
Expand All @@ -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;
Expand All @@ -123,8 +150,11 @@ void handleDroppedFiles(AppState &state, UiState &uiState, std::function<void(si
state.current_block = 0;
state.block_slider = 0;
state.redrawBlock = true;
if (state.originalFile.empty())
if (state.originalFile.empty()) {
state.promptForSource = true;
}
loadHexData(0);
addToRecentFiles(state, path, "");
}
} else {
state.showCacheGen = true;
Expand Down Expand Up @@ -153,6 +183,8 @@ void handleDroppedFiles(AppState &state, UiState &uiState, std::function<void(si
uiState.highlighted_sector = SIZE_MAX;
uiState.currentSectorData.clear();
uiState.currentSectorIndex = 0;

addToRecentFiles(state, cacheFile, path);
}
}

Expand Down Expand Up @@ -353,9 +385,45 @@ void mainLoop(GLFWwindow *window, GLuint tex, AppState &state, UiState &uiState,
if (ImGui::MenuItem("Open Cache")) {
ImGuiFileDialog::Instance()->OpenDialog("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<char *>(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();
}

Expand Down Expand Up @@ -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;
}
Expand Down
9 changes: 9 additions & 0 deletions src/ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ void renderSearchWindow(UiState &uiState, AppState &appState, std::function<void
}
}

ImGui::SameLine();

if (ImGui::Button("Find Previous")) {
size_t found_index = SIZE_MAX;
size_t start = (uiState.highlighted_sector == SIZE_MAX ? appState.all_cache_data.size() : uiState.highlighted_sector);
Expand Down Expand Up @@ -332,6 +334,8 @@ void handleFileDialogs(UiState &uiState, AppState &appState, IGFD::FileDialogCon
uiState.highlighted_sector = SIZE_MAX;
uiState.currentSectorData.clear();
uiState.currentSectorIndex = 0;
// Add to recent files
addToRecentFiles(appState, filePathName, "");
}
}
ImGuiFileDialog::Instance()->Close();
Expand All @@ -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();
}
Expand All @@ -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
}
Expand Down