mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-31 05:15:55 -05:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63edfb8d52 | ||
|
|
8d3ca3292e | ||
|
|
25df658653 | ||
|
|
6b20a9bdd5 | ||
|
|
d399a6427a | ||
|
|
2f1a707fd3 | ||
|
|
cbfe52c756 | ||
|
|
3c1f0057ae | ||
|
|
1a9bd12af0 | ||
|
|
1b853c6a84 | ||
|
|
b9034523b5 | ||
|
|
5af9af1e5a | ||
|
|
eac9fe1b70 | ||
|
|
3cecc0693b |
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# Updating the version here will update it throughout ImHex as well
|
||||
set(IMHEX_VERSION "1.13.1")
|
||||
set(IMHEX_VERSION "1.13.2")
|
||||
project(imhex VERSION ${IMHEX_VERSION})
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<h1 align="center">:mag: ImHex</h1>
|
||||
<a href="https://imhex.werwolv.net"><h1 align="center" >:mag: ImHex</h1></a>
|
||||
|
||||
<p align="center">A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.</p>
|
||||
|
||||
@@ -123,7 +123,9 @@ Nightlies are available via GitHub Actions [here](https://github.com/WerWolv/ImH
|
||||
- [DMG](https://nightly.link/WerWolv/ImHex/workflows/build/master/macOS%20DMG.zip)
|
||||
- Linux • __x86_64__
|
||||
- [ELF](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20ELF.zip)
|
||||
- [DEB](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20DEB.zip)
|
||||
- [Flatpak](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20Flatpak.zip)
|
||||
- [AppImage](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20AppImage.zip)
|
||||
|
||||
## Compiling
|
||||
|
||||
|
||||
4
external/ImGui/include/imgui_memory_editor.h
vendored
4
external/ImGui/include/imgui_memory_editor.h
vendored
@@ -268,7 +268,7 @@ struct MemoryEditor
|
||||
const float height_separator = style.ItemSpacing.y;
|
||||
float footer_height = 0;
|
||||
if (OptShowOptions)
|
||||
footer_height += height_separator + ImGui::GetFrameHeightWithSpacing() * 1;
|
||||
footer_height += height_separator + ImGui::GetFrameHeightWithSpacing() * 2;
|
||||
|
||||
ImGui::BeginChild("offset", ImVec2(0, s.LineHeight), false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav);
|
||||
ImGui::Text("%*c ", s.AddrDigitsCount, ' ');
|
||||
@@ -731,7 +731,7 @@ struct MemoryEditor
|
||||
if (GotoAddr < mem_size)
|
||||
{
|
||||
ImGui::BeginChild("##scrolling");
|
||||
ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + (GotoAddr / Cols) * ImGui::GetTextLineHeight());
|
||||
ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + (GotoAddr / Cols) * ImGui::GetTextLineHeight() * 2);
|
||||
ImGui::EndChild();
|
||||
}
|
||||
GotoAddr = (size_t)-1;
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace hex::plugin::builtin {
|
||||
[[nodiscard]] bool hasViewMenuItemEntry() const override { return false; }
|
||||
|
||||
[[nodiscard]] ImVec2 getMinSize() const override {
|
||||
return ImVec2(500, 300) * SharedData::globalScale;
|
||||
return scaled(ImVec2(500, 300));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::SmallProgressBar(taskProgress, (ImGui::GetCurrentWindow()->MenuBarHeight() - 10 * SharedData::globalScale) / 2.0);
|
||||
ImGui::SmallProgressBar(taskProgress, (ImGui::GetCurrentWindow()->MenuBarHeight() - 10_scaled) / 2.0);
|
||||
ImGui::InfoTooltip(taskName.c_str());
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ namespace hex::plugin::builtin {
|
||||
if (ImHexApi::Provider::isValid())
|
||||
preview = providers[SharedData::currentProvider]->getName();
|
||||
|
||||
ImGui::SetNextItemWidth(200 * SharedData::globalScale);
|
||||
ImGui::SetNextItemWidth(200_scaled);
|
||||
if (ImGui::BeginCombo("", preview.c_str())) {
|
||||
|
||||
for (int i = 0; i < providers.size(); i++) {
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace hex::plugin::builtin {
|
||||
if (ImHexApi::Provider::isValid() && provider >= 0)
|
||||
preview = providers[provider]->getName();
|
||||
|
||||
ImGui::SetNextItemWidth(200 * SharedData::globalScale);
|
||||
ImGui::SetNextItemWidth(200_scaled);
|
||||
if (ImGui::BeginCombo("", preview.c_str())) {
|
||||
|
||||
for (int i = 0; i < providers.size(); i++) {
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void ViewHelp::drawAboutPopup() {
|
||||
ImGui::SetNextWindowSize(ImVec2(600, 350) * SharedData::globalScale, ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(scaled(ImVec2(600, 350)), ImGuiCond_Always);
|
||||
if (ImGui::BeginPopupModal(View::toWindowName("hex.builtin.view.help.about.name").c_str(), &this->m_aboutWindowOpen, ImGuiWindowFlags_NoResize)) {
|
||||
|
||||
if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape)))
|
||||
|
||||
@@ -175,11 +175,11 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
if (provider->getPageCount() > 1) {
|
||||
ImGui::SameLine();
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::TextFormatted("hex.builtin.view.hexeditor.page"_lang, provider->getCurrentPage() + 1, provider->getPageCount());
|
||||
auto linePos = ImGui::GetCursorPosY() - 15_scaled;
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosY(linePos);
|
||||
|
||||
if (ImGui::ArrowButton("prevPage", ImGuiDir_Left)) {
|
||||
provider->setCurrentPage(provider->getCurrentPage() - 1);
|
||||
@@ -194,6 +194,13 @@ namespace hex::plugin::builtin {
|
||||
|
||||
EventManager::post<EventRegionSelected>(Region { std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd), 1 });
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosY(linePos);
|
||||
|
||||
ImGui::TextFormatted("hex.builtin.view.hexeditor.page"_lang, provider->getCurrentPage() + 1, provider->getPageCount());
|
||||
}
|
||||
|
||||
this->drawSearchPopup();
|
||||
|
||||
@@ -17,14 +17,14 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
static bool beginPatternDataTable(prv::Provider* &provider, const std::vector<pl::PatternData*> &patterns, std::vector<pl::PatternData*> &sortedPatterns) {
|
||||
if (ImGui::BeginTable("##patterndatatable", 6, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) {
|
||||
if (ImGui::BeginTable("##patterndatatable", 6, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) {
|
||||
ImGui::TableSetupScrollFreeze(0, 1);
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.var_name"_lang, 0, -1, ImGui::GetID("name"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.color"_lang, 0, -1, ImGui::GetID("color"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.offset"_lang, 0, -1, ImGui::GetID("offset"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.size"_lang, 0, -1, ImGui::GetID("size"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.type"_lang, 0, -1, ImGui::GetID("type"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.value"_lang, 0, -1, ImGui::GetID("value"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.var_name"_lang, 0, 0, ImGui::GetID("name"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.color"_lang, 0, 0, ImGui::GetID("color"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.offset"_lang, 0, 0, ImGui::GetID("offset"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.size"_lang, 0, 0, ImGui::GetID("size"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.type"_lang, 0, 0, ImGui::GetID("type"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.value"_lang, 0, 0, ImGui::GetID("value"));
|
||||
|
||||
auto sortSpecs = ImGui::TableGetSortSpecs();
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void ViewStore::drawContent() {
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(600, 400) * SharedData::globalScale, ImVec2(FLT_MAX, FLT_MAX));
|
||||
ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(600, 400)), ImVec2(FLT_MAX, FLT_MAX));
|
||||
if (ImGui::BeginPopupModal(View::toWindowName("hex.builtin.view.store.name").c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
if (this->m_apiRequest.valid()) {
|
||||
if (this->m_apiRequest.wait_for(0s) != std::future_status::ready)
|
||||
|
||||
@@ -19,6 +19,6 @@ namespace hex {
|
||||
|
||||
std::string getExecutablePath();
|
||||
|
||||
std::vector<std::string> getPath(ImHexPath path);
|
||||
std::vector<std::string> getPath(ImHexPath path, bool listNonExisting = false);
|
||||
|
||||
}
|
||||
@@ -23,8 +23,14 @@
|
||||
#define TOKEN_CONCAT(x, y) TOKEN_CONCAT_IMPL(x, y)
|
||||
#define ANONYMOUS_VARIABLE(prefix) TOKEN_CONCAT(prefix, __COUNTER__)
|
||||
|
||||
struct ImVec2;
|
||||
|
||||
namespace hex {
|
||||
|
||||
long double operator""_scaled(long double value);
|
||||
long double operator""_scaled(unsigned long long value);
|
||||
ImVec2 scaled(const ImVec2 &vector);
|
||||
|
||||
std::string to_string(u128 value);
|
||||
std::string to_string(s128 value);
|
||||
|
||||
@@ -109,6 +115,11 @@ namespace hex {
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr uint64_t bitmask(uint8_t bits) {
|
||||
return (uint64_t(1) << (bits)) - 1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr T changeEndianess(T value, size_t size, std::endian endian) {
|
||||
if (endian == std::endian::native)
|
||||
|
||||
@@ -1448,7 +1448,7 @@ namespace hex::pl {
|
||||
|
||||
// If a field is named padding, it was created through a padding expression and only advances the bit position
|
||||
if (name != "padding") {
|
||||
auto field = new PatternDataBitfieldField(evaluator->dataOffset(), bitOffset, bitSize, evaluator);
|
||||
auto field = new PatternDataBitfieldField(evaluator->dataOffset(), bitOffset, bitSize, pattern, evaluator);
|
||||
field->setVariableName(name);
|
||||
fields.push_back(field);
|
||||
}
|
||||
@@ -1505,69 +1505,37 @@ namespace hex::pl {
|
||||
auto pattern = this->createPatterns(evaluator).front();
|
||||
ON_SCOPE_EXIT { delete pattern; };
|
||||
|
||||
auto readValue = [&evaluator](auto &value, PatternData *pattern) {
|
||||
if (pattern->isLocal()) {
|
||||
auto &literal = evaluator->getStack()[pattern->getOffset()];
|
||||
|
||||
std::visit(overloaded {
|
||||
[&](std::string &assignmentValue) { },
|
||||
[&](PatternData *assignmentValue) { },
|
||||
[&](auto &&assignmentValue) { value = assignmentValue; }
|
||||
}, literal);
|
||||
}
|
||||
else
|
||||
evaluator->getProvider()->read(pattern->getOffset(), &value, pattern->getSize());
|
||||
|
||||
value = hex::changeEndianess(value, pattern->getSize(), pattern->getEndian());
|
||||
};
|
||||
|
||||
auto readString = [&evaluator](std::string &value, PatternData *pattern) {
|
||||
if (pattern->isLocal()) {
|
||||
auto &literal = evaluator->getStack()[pattern->getOffset()];
|
||||
|
||||
std::visit(overloaded {
|
||||
[&](std::string &assignmentValue) { value = assignmentValue; },
|
||||
[&](auto &&assignmentValue) { }
|
||||
}, literal);
|
||||
}
|
||||
else {
|
||||
value.resize(pattern->getSize());
|
||||
evaluator->getProvider()->read(pattern->getOffset(), value.data(), value.size());
|
||||
value.erase(std::find(value.begin(), value.end(), '\0'), value.end());
|
||||
}
|
||||
};
|
||||
|
||||
Token::Literal literal;
|
||||
if (dynamic_cast<PatternDataUnsigned*>(pattern) || dynamic_cast<PatternDataEnum*>(pattern)) {
|
||||
u128 value = 0;
|
||||
readValue(value, pattern);
|
||||
readVariable(evaluator, value, pattern);
|
||||
literal = value;
|
||||
} else if (dynamic_cast<PatternDataSigned*>(pattern)) {
|
||||
s128 value = 0;
|
||||
readValue(value, pattern);
|
||||
readVariable(evaluator, value, pattern);
|
||||
value = hex::signExtend(pattern->getSize() * 8, value);
|
||||
literal = value;
|
||||
} else if (dynamic_cast<PatternDataFloat*>(pattern)) {
|
||||
if (pattern->getSize() == sizeof(u16)) {
|
||||
u16 value = 0;
|
||||
readValue(value, pattern);
|
||||
readVariable(evaluator, value, pattern);
|
||||
literal = double(float16ToFloat32(value));
|
||||
} else if (pattern->getSize() == sizeof(float)) {
|
||||
float value = 0;
|
||||
readValue(value, pattern);
|
||||
readVariable(evaluator, value, pattern);
|
||||
literal = double(value);
|
||||
} else if (pattern->getSize() == sizeof(double)) {
|
||||
double value = 0;
|
||||
readValue(value, pattern);
|
||||
readVariable(evaluator, value, pattern);
|
||||
literal = value;
|
||||
} else LogConsole::abortEvaluation("invalid floating point type access", this);
|
||||
} else if (dynamic_cast<PatternDataCharacter*>(pattern)) {
|
||||
char value = 0;
|
||||
readValue(value, pattern);
|
||||
readVariable(evaluator, value, pattern);
|
||||
literal = value;
|
||||
} else if (dynamic_cast<PatternDataBoolean*>(pattern)) {
|
||||
bool value = false;
|
||||
readValue(value, pattern);
|
||||
readVariable(evaluator, value, pattern);
|
||||
literal = value;
|
||||
} else if (dynamic_cast<PatternDataString*>(pattern)) {
|
||||
std::string value;
|
||||
@@ -1582,7 +1550,7 @@ namespace hex::pl {
|
||||
if (!dynamic_cast<PatternDataString*>(assignmentValue) && !dynamic_cast<PatternDataCharacter*>(assignmentValue))
|
||||
LogConsole::abortEvaluation(hex::format("cannot assign '{}' to string", pattern->getTypeName()), this);
|
||||
|
||||
readString(value, assignmentValue);
|
||||
readVariable(evaluator, value, assignmentValue);
|
||||
},
|
||||
[&, this](auto &&assignmentValue) { LogConsole::abortEvaluation(hex::format("cannot assign '{}' to string", pattern->getTypeName()), this); }
|
||||
}, literal);
|
||||
@@ -1596,7 +1564,7 @@ namespace hex::pl {
|
||||
literal = value;
|
||||
} else if (auto bitfieldFieldPattern = dynamic_cast<PatternDataBitfieldField*>(pattern)) {
|
||||
u64 value = 0;
|
||||
readValue(value, pattern);
|
||||
readVariable(evaluator, value, pattern);
|
||||
literal = u128(hex::extract(bitfieldFieldPattern->getBitOffset() + (bitfieldFieldPattern->getBitSize() - 1), bitfieldFieldPattern->getBitOffset(), value));
|
||||
} else {
|
||||
literal = pattern->clone();
|
||||
@@ -1718,8 +1686,13 @@ namespace hex::pl {
|
||||
}
|
||||
|
||||
PatternData *indexPattern;
|
||||
if (currPattern->isLocal())
|
||||
indexPattern = std::get<PatternData*>(evaluator->getStack()[currPattern->getOffset()]);
|
||||
if (currPattern->isLocal()) {
|
||||
auto stackLiteral = evaluator->getStack()[currPattern->getOffset()];
|
||||
if (auto stackPattern = std::get_if<PatternData*>(&stackLiteral); stackPattern != nullptr)
|
||||
indexPattern = *stackPattern;
|
||||
else
|
||||
return { currPattern };
|
||||
}
|
||||
else
|
||||
indexPattern = currPattern;
|
||||
|
||||
@@ -1744,6 +1717,34 @@ namespace hex::pl {
|
||||
|
||||
private:
|
||||
Path m_path;
|
||||
|
||||
void readVariable(Evaluator *evaluator, auto &value, PatternData *variablePattern) const {
|
||||
constexpr bool isString = std::same_as<std::remove_cvref_t<decltype(value)>, std::string>;
|
||||
|
||||
if (variablePattern->isLocal()) {
|
||||
auto &literal = evaluator->getStack()[variablePattern->getOffset()];
|
||||
|
||||
std::visit(overloaded {
|
||||
[&](std::string &assignmentValue) {
|
||||
if constexpr (isString) value = assignmentValue;
|
||||
},
|
||||
[&](PatternData *assignmentValue) { readVariable(evaluator, value, assignmentValue); },
|
||||
[&](auto &&assignmentValue) { value = assignmentValue; }
|
||||
}, literal);
|
||||
}
|
||||
else {
|
||||
if constexpr (isString) {
|
||||
value.resize(variablePattern->getSize());
|
||||
evaluator->getProvider()->read(variablePattern->getOffset(), value.data(), value.size());
|
||||
value.erase(std::find(value.begin(), value.end(), '\0'), value.end());
|
||||
} else {
|
||||
evaluator->getProvider()->read(variablePattern->getOffset(), &value, variablePattern->getSize());
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr (!isString)
|
||||
value = hex::changeEndianess(value, variablePattern->getSize(), variablePattern->getEndian());
|
||||
}
|
||||
};
|
||||
|
||||
class ASTNodeScopeResolution : public ASTNode {
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
#include <vector>
|
||||
|
||||
#include <hex/pattern_language/log_console.hpp>
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <hex/helpers/concepts.hpp>
|
||||
|
||||
namespace hex::prv { class Provider; }
|
||||
|
||||
|
||||
@@ -74,14 +74,14 @@ namespace hex::pl {
|
||||
this->m_evaluator->patternDestroyed();
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
Evaluator *m_evaluator = nullptr;
|
||||
};
|
||||
|
||||
class PatternData : public PatternCreationLimiter {
|
||||
public:
|
||||
PatternData(u64 offset, size_t size, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternCreationLimiter(evaluator), m_offset(offset), m_size(size), m_color(color), m_parent(nullptr), m_evaluator(evaluator) {
|
||||
: PatternCreationLimiter(evaluator), m_offset(offset), m_size(size), m_color(color) {
|
||||
constexpr u32 Palette[] = { 0x70b4771f, 0x700e7fff, 0x702ca02c, 0x702827d6, 0x70bd6794, 0x704b568c, 0x70c277e3, 0x707f7f7f, 0x7022bdbc, 0x70cfbe17 };
|
||||
|
||||
if (color != 0)
|
||||
@@ -100,7 +100,7 @@ namespace hex::pl {
|
||||
virtual PatternData* clone() = 0;
|
||||
|
||||
[[nodiscard]] u64 getOffset() const { return this->m_offset; }
|
||||
virtual void setOffset(u64 offset) { this->m_offset = offset; }
|
||||
void setOffset(u64 offset) { this->m_offset = offset; }
|
||||
|
||||
[[nodiscard]] size_t getSize() const { return this->m_size; }
|
||||
void setSize(size_t size) { this->m_size = size; }
|
||||
@@ -120,9 +120,6 @@ namespace hex::pl {
|
||||
[[nodiscard]] std::endian getEndian() const { return this->m_endian; }
|
||||
void setEndian(std::endian endian) { this->m_endian = endian; }
|
||||
|
||||
[[nodiscard]] PatternData* getParent() const { return this->m_parent; }
|
||||
void setParent(PatternData *parent) { this->m_parent = parent; }
|
||||
|
||||
[[nodiscard]] std::string getDisplayName() const { return this->m_displayName.value_or(this->m_variableName); }
|
||||
void setDisplayName(const std::string &name) { this->m_displayName = name; }
|
||||
|
||||
@@ -136,26 +133,14 @@ namespace hex::pl {
|
||||
virtual void createEntry(prv::Provider* &provider) = 0;
|
||||
[[nodiscard]] virtual std::string getFormattedName() const = 0;
|
||||
|
||||
virtual std::optional<u32> highlightBytes(size_t offset) {
|
||||
auto currOffset = this->getOffset();
|
||||
if (offset >= currOffset && offset < (currOffset + this->getSize()))
|
||||
return this->getColor();
|
||||
else
|
||||
return { };
|
||||
}
|
||||
|
||||
virtual std::map<u64, u32> getHighlightedAddresses() {
|
||||
if (this->isHidden()) return { };
|
||||
if (this->m_highlightedAddresses.empty()) {
|
||||
for (u64 i = 0; i < this->getSize(); i++)
|
||||
this->m_highlightedAddresses.insert({ this->getOffset() + i, this->getColor() });
|
||||
}
|
||||
|
||||
return this->m_highlightedAddresses;
|
||||
}
|
||||
std::map<u64, u32> result;
|
||||
for (u64 i = 0; i < this->getSize(); i++)
|
||||
result.insert({ this->getOffset() + i, this->getColor() });
|
||||
|
||||
virtual void clearHighlightedAddresses() {
|
||||
this->m_highlightedAddresses.clear();
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void sort(ImGuiTableSortSpecs *sortSpecs, prv::Provider *provider) { }
|
||||
@@ -258,6 +243,28 @@ namespace hex::pl {
|
||||
this->m_local == other.m_local;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
std::string formatDisplayValue(const std::string &value, const Token::Literal &literal) const {
|
||||
if (!this->m_formatterFunction.has_value())
|
||||
return value;
|
||||
else {
|
||||
try {
|
||||
auto result = this->m_formatterFunction->func(this->getEvaluator(), { literal });
|
||||
|
||||
if (result.has_value()) {
|
||||
if (auto displayValue = std::get_if<std::string>(&result.value()); displayValue != nullptr)
|
||||
return *displayValue;
|
||||
else
|
||||
return "???";
|
||||
} else {
|
||||
return "???";
|
||||
}
|
||||
} catch (LogConsole::EvaluateError &error) {
|
||||
return "Error: " + error.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void createDefaultEntry(const std::string &value, const Token::Literal &literal) const {
|
||||
ImGui::TableNextRow();
|
||||
@@ -278,19 +285,7 @@ namespace hex::pl {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{}", this->getFormattedName());
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (!this->m_formatterFunction.has_value())
|
||||
ImGui::TextUnformatted(value.c_str());
|
||||
else {
|
||||
auto result = this->m_formatterFunction->func(this->getEvaluator(), { literal });
|
||||
|
||||
if (result.has_value()) {
|
||||
if (auto displayValue = std::get_if<std::string>(&result.value()); displayValue != nullptr)
|
||||
ImGui::TextUnformatted(displayValue->c_str());
|
||||
} else {
|
||||
ImGui::TextUnformatted("???");
|
||||
}
|
||||
}
|
||||
ImGui::TextFormatted("{}", formatDisplayValue(value, literal));
|
||||
}
|
||||
|
||||
void drawCommentTooltip() const {
|
||||
@@ -303,7 +298,6 @@ namespace hex::pl {
|
||||
|
||||
protected:
|
||||
std::endian m_endian = std::endian::native;
|
||||
std::map<u64, u32> m_highlightedAddresses;
|
||||
bool m_hidden = false;
|
||||
|
||||
private:
|
||||
@@ -316,11 +310,9 @@ namespace hex::pl {
|
||||
std::optional<std::string> m_comment;
|
||||
std::string m_typeName;
|
||||
|
||||
Evaluator *m_evaluator = nullptr;
|
||||
std::optional<ContentRegistry::PatternLanguage::Function> m_formatterFunction;
|
||||
std::optional<ContentRegistry::PatternLanguage::Function> m_transformFunction;
|
||||
|
||||
PatternData *m_parent;
|
||||
bool m_local = false;
|
||||
};
|
||||
|
||||
@@ -378,7 +370,7 @@ namespace hex::pl {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{}", this->getFormattedName());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("*(0x{0:X})", data);
|
||||
ImGui::TextFormatted("{}", formatDisplayValue(hex::format("*(0x{0:X})", data), u128(data)));
|
||||
|
||||
if (open) {
|
||||
this->m_pointedAt->createEntry(provider);
|
||||
@@ -387,25 +379,13 @@ namespace hex::pl {
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<u32> highlightBytes(size_t offset) override {
|
||||
if (offset >= this->getOffset() && offset < (this->getOffset() + this->getSize()))
|
||||
return this->getColor();
|
||||
else if (auto color = this->m_pointedAt->highlightBytes(offset); color.has_value())
|
||||
return color.value();
|
||||
else
|
||||
return { };
|
||||
}
|
||||
|
||||
std::map<u64, u32> getHighlightedAddresses() override {
|
||||
if (this->m_highlightedAddresses.empty()) {
|
||||
auto ownAddresses = PatternData::getHighlightedAddresses();
|
||||
auto pointedToAddresses = this->m_pointedAt->getHighlightedAddresses();
|
||||
|
||||
ownAddresses.merge(pointedToAddresses);
|
||||
this->m_highlightedAddresses = ownAddresses;
|
||||
}
|
||||
|
||||
return this->m_highlightedAddresses;
|
||||
return ownAddresses;
|
||||
}
|
||||
[[nodiscard]] std::string getFormattedName() const override {
|
||||
std::string result = this->m_pointedAt->getFormattedName() + "* : ";
|
||||
@@ -765,17 +745,6 @@ namespace hex::pl {
|
||||
return new PatternDataDynamicArray(*this);
|
||||
}
|
||||
|
||||
void setOffset(u64 offset) override {
|
||||
if (!this->isLocal()) {
|
||||
for (auto &entry : this->m_entries) {
|
||||
entry->setOffset(offset + (entry->getOffset() - this->getOffset()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PatternData::setOffset(offset);
|
||||
}
|
||||
|
||||
void setColor(u32 color) override {
|
||||
PatternData::setColor(color);
|
||||
for (auto &entry : this->m_entries)
|
||||
@@ -809,41 +778,40 @@ namespace hex::pl {
|
||||
ImGui::TextUnformatted("]");
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted("{ ... }");
|
||||
ImGui::TextFormatted("{}", this->formatDisplayValue("{ ... }", this));
|
||||
}
|
||||
|
||||
if (open) {
|
||||
for (auto &member : this->m_entries)
|
||||
member->draw(provider);
|
||||
for (u64 i = 0; i < this->m_entries.size(); i++) {
|
||||
this->m_entries[i]->draw(provider);
|
||||
|
||||
if (i >= (this->m_displayEnd - 1)) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::Selectable("... (Double-click to see more items)", false, ImGuiSelectableFlags_SpanAllColumns);
|
||||
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
||||
this->m_displayEnd += 50;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->isInlined())
|
||||
ImGui::TreePop();
|
||||
} else {
|
||||
this->m_displayEnd = 50;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<u32> highlightBytes(size_t offset) override{
|
||||
for (auto &entry : this->m_entries) {
|
||||
if (auto color = entry->highlightBytes(offset); color.has_value())
|
||||
return color.value();
|
||||
}
|
||||
|
||||
return { };
|
||||
}
|
||||
|
||||
std::map<u64, u32> getHighlightedAddresses() override {
|
||||
if (this->m_highlightedAddresses.empty()) {
|
||||
for (auto &entry : this->m_entries) {
|
||||
this->m_highlightedAddresses.merge(entry->getHighlightedAddresses());
|
||||
}
|
||||
std::map<u64, u32> result;
|
||||
|
||||
for (auto &entry : this->m_entries) {
|
||||
result.merge(entry->getHighlightedAddresses());
|
||||
}
|
||||
|
||||
return this->m_highlightedAddresses;
|
||||
}
|
||||
|
||||
void clearHighlightedAddresses() override {
|
||||
for (auto &entry : this->m_entries)
|
||||
entry->clearHighlightedAddresses();
|
||||
PatternData::clearHighlightedAddresses();
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string getFormattedName() const override {
|
||||
@@ -859,7 +827,6 @@ namespace hex::pl {
|
||||
|
||||
for (auto &entry : this->m_entries) {
|
||||
entry->setColor(this->getColor());
|
||||
entry->setParent(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -881,6 +848,7 @@ namespace hex::pl {
|
||||
|
||||
private:
|
||||
std::vector<PatternData*> m_entries;
|
||||
u64 m_displayEnd = 50;
|
||||
};
|
||||
|
||||
class PatternDataStaticArray : public PatternData, public Inlinable {
|
||||
@@ -929,7 +897,7 @@ namespace hex::pl {
|
||||
ImGui::TextUnformatted("]");
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted("{ ... }");
|
||||
ImGui::TextFormatted("{}", this->formatDisplayValue("{ ... }", this));
|
||||
}
|
||||
|
||||
if (open) {
|
||||
@@ -938,48 +906,39 @@ namespace hex::pl {
|
||||
entry->setVariableName(hex::format("[{0}]", index));
|
||||
entry->setOffset(this->getOffset() + index * this->m_template->getSize());
|
||||
entry->draw(provider);
|
||||
|
||||
if (index >= (this->m_displayEnd - 1)) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::Selectable("... (Double-click to see more items)", false, ImGuiSelectableFlags_SpanAllColumns);
|
||||
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
||||
this->m_displayEnd += 50;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete entry;
|
||||
|
||||
if (!this->isInlined())
|
||||
ImGui::TreePop();
|
||||
} else {
|
||||
this->m_displayEnd = 50;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<u32> highlightBytes(size_t offset) override{
|
||||
auto entry = this->m_template->clone();
|
||||
ON_SCOPE_EXIT { delete entry; };
|
||||
|
||||
if (offset < this->getOffset() || offset >= this->getOffset() + this->getSize())
|
||||
return { };
|
||||
|
||||
auto index = (offset - this->getOffset()) / this->m_template->getSize();
|
||||
entry->setOffset(this->getOffset() + this->m_template->getSize() * index);
|
||||
if (auto color = entry->highlightBytes(offset); color.has_value())
|
||||
return color.value();
|
||||
else
|
||||
return { };
|
||||
}
|
||||
|
||||
std::map<u64, u32> getHighlightedAddresses() override {
|
||||
if (this->m_highlightedAddresses.empty()) {
|
||||
auto entry = this->m_template->clone();
|
||||
auto startOffset = this->m_template->getOffset();
|
||||
|
||||
for (u64 address = this->getOffset(); address < this->getOffset() + this->getSize(); address += this->m_template->getSize()) {
|
||||
entry->setOffset(address);
|
||||
entry->clearHighlightedAddresses();
|
||||
this->m_highlightedAddresses.merge(entry->getHighlightedAddresses());
|
||||
}
|
||||
|
||||
delete entry;
|
||||
std::map<u64, u32> result;
|
||||
for (u64 address = this->getOffset(); address < this->getOffset() + this->getSize(); address += this->m_template->getSize()) {
|
||||
this->m_template->setOffset(address);
|
||||
result.merge(this->m_template->getHighlightedAddresses());
|
||||
}
|
||||
|
||||
return this->m_highlightedAddresses;
|
||||
}
|
||||
this->m_template->setOffset(startOffset);
|
||||
|
||||
void clearHighlightedAddresses() override {
|
||||
this->m_template->clearHighlightedAddresses();
|
||||
PatternData::clearHighlightedAddresses();
|
||||
return result;
|
||||
}
|
||||
|
||||
void setColor(u32 color) override {
|
||||
@@ -1009,7 +968,6 @@ namespace hex::pl {
|
||||
|
||||
this->setColor(this->m_template->getColor());
|
||||
this->m_template->setEndian(templ->getEndian());
|
||||
this->m_template->setParent(this);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator==(const PatternData &other) const override {
|
||||
@@ -1023,6 +981,7 @@ namespace hex::pl {
|
||||
private:
|
||||
PatternData *m_template;
|
||||
size_t m_entryCount;
|
||||
u64 m_displayEnd = 50;
|
||||
};
|
||||
|
||||
class PatternDataStruct : public PatternData, public Inlinable {
|
||||
@@ -1046,16 +1005,6 @@ namespace hex::pl {
|
||||
return new PatternDataStruct(*this);
|
||||
}
|
||||
|
||||
void setOffset(u64 offset) override {
|
||||
if (!this->isLocal()) {
|
||||
for (auto &member: this->m_members) {
|
||||
member->setOffset(offset + (member->getOffset() - this->getOffset()));
|
||||
}
|
||||
}
|
||||
|
||||
PatternData::setOffset(offset);
|
||||
}
|
||||
|
||||
void createEntry(prv::Provider* &provider) override {
|
||||
bool open = true;
|
||||
|
||||
@@ -1072,7 +1021,7 @@ namespace hex::pl {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(ImColor(0xFFD69C56), "struct"); ImGui::SameLine(); ImGui::TextUnformatted(this->getTypeName().c_str());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted("{ ... }");
|
||||
ImGui::TextFormatted("{}", this->formatDisplayValue("{ ... }", this));
|
||||
}
|
||||
|
||||
if (open) {
|
||||
@@ -1085,29 +1034,13 @@ namespace hex::pl {
|
||||
|
||||
}
|
||||
|
||||
std::optional<u32> highlightBytes(size_t offset) override{
|
||||
for (auto &member : this->m_members) {
|
||||
if (auto color = member->highlightBytes(offset); color.has_value())
|
||||
return color.value();
|
||||
}
|
||||
|
||||
return { };
|
||||
}
|
||||
|
||||
std::map<u64, u32> getHighlightedAddresses() override {
|
||||
if (this->m_highlightedAddresses.empty()) {
|
||||
for (auto &member : this->m_members) {
|
||||
this->m_highlightedAddresses.merge(member->getHighlightedAddresses());
|
||||
}
|
||||
std::map<u64, u32> result;
|
||||
for (auto &member : this->m_members) {
|
||||
result.merge(member->getHighlightedAddresses());
|
||||
}
|
||||
|
||||
return this->m_highlightedAddresses;
|
||||
}
|
||||
|
||||
void clearHighlightedAddresses() override {
|
||||
for (auto &member : this->m_members)
|
||||
member->clearHighlightedAddresses();
|
||||
PatternData::clearHighlightedAddresses();
|
||||
return result;
|
||||
}
|
||||
|
||||
void setColor(u32 color) override {
|
||||
@@ -1142,7 +1075,6 @@ namespace hex::pl {
|
||||
if (member == nullptr) continue;
|
||||
|
||||
this->m_members.push_back(member);
|
||||
member->setParent(this);
|
||||
}
|
||||
|
||||
this->m_sortedMembers = this->m_members;
|
||||
@@ -1191,16 +1123,6 @@ namespace hex::pl {
|
||||
return new PatternDataUnion(*this);
|
||||
}
|
||||
|
||||
void setOffset(u64 offset) override {
|
||||
if (!this->isLocal()) {
|
||||
for (auto &member: this->m_members) {
|
||||
member->setOffset(offset + (member->getOffset() - this->getOffset()));
|
||||
}
|
||||
}
|
||||
|
||||
PatternData::setOffset(offset);
|
||||
}
|
||||
|
||||
void createEntry(prv::Provider* &provider) override {
|
||||
bool open = true;
|
||||
|
||||
@@ -1218,7 +1140,7 @@ namespace hex::pl {
|
||||
ImGui::TextColored(ImColor(0xFFD69C56), "union"); ImGui::SameLine(); ImGui::TextUnformatted(PatternData::getTypeName().c_str());
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted("{ ... }");
|
||||
ImGui::TextFormatted("{}", this->formatDisplayValue("{ ... }", this));
|
||||
}
|
||||
|
||||
if (open) {
|
||||
@@ -1231,29 +1153,14 @@ namespace hex::pl {
|
||||
|
||||
}
|
||||
|
||||
std::optional<u32> highlightBytes(size_t offset) override{
|
||||
for (auto &member : this->m_members) {
|
||||
if (auto color = member->highlightBytes(offset); color.has_value())
|
||||
return color.value();
|
||||
}
|
||||
|
||||
return { };
|
||||
}
|
||||
|
||||
std::map<u64, u32> getHighlightedAddresses() override {
|
||||
if (this->m_highlightedAddresses.empty()) {
|
||||
for (auto &member : this->m_members) {
|
||||
this->m_highlightedAddresses.merge(member->getHighlightedAddresses());
|
||||
}
|
||||
std::map<u64, u32> result;
|
||||
|
||||
for (auto &member : this->m_members) {
|
||||
result.merge(member->getHighlightedAddresses());
|
||||
}
|
||||
|
||||
return this->m_highlightedAddresses;
|
||||
}
|
||||
|
||||
void clearHighlightedAddresses() override {
|
||||
for (auto &member : this->m_members)
|
||||
member->clearHighlightedAddresses();
|
||||
PatternData::clearHighlightedAddresses();
|
||||
return result;
|
||||
}
|
||||
|
||||
void setColor(u32 color) override {
|
||||
@@ -1287,7 +1194,6 @@ namespace hex::pl {
|
||||
if (member == nullptr) continue;
|
||||
|
||||
this->m_members.push_back(member);
|
||||
member->setParent(this);
|
||||
}
|
||||
|
||||
this->m_sortedMembers = this->m_members;
|
||||
@@ -1372,7 +1278,7 @@ namespace hex::pl {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextColored(ImColor(0xFFD69C56), "enum"); ImGui::SameLine(); ImGui::TextUnformatted(PatternData::getTypeName().c_str());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{} (0x{:0{}X})", valueString.c_str(), value, this->getSize() * 2);
|
||||
ImGui::TextFormatted("{}", this->formatDisplayValue(hex::format("{} (0x{:0{}X})", valueString.c_str(), value, this->getSize() * 2), this));
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string getFormattedName() const override {
|
||||
@@ -1410,8 +1316,8 @@ namespace hex::pl {
|
||||
|
||||
class PatternDataBitfieldField : public PatternData {
|
||||
public:
|
||||
PatternDataBitfieldField(u64 offset, u8 bitOffset, u8 bitSize, Evaluator *evaluator, u32 color = 0)
|
||||
: m_bitOffset(bitOffset), m_bitSize(bitSize), PatternData(offset, 0, evaluator, color) {
|
||||
PatternDataBitfieldField(u64 offset, u8 bitOffset, u8 bitSize, PatternData *bitField, Evaluator *evaluator, u32 color = 0)
|
||||
: m_bitOffset(bitOffset), m_bitSize(bitSize), m_bitField(bitField), PatternData(offset, 0, evaluator, color) {
|
||||
|
||||
}
|
||||
|
||||
@@ -1420,10 +1326,10 @@ namespace hex::pl {
|
||||
}
|
||||
|
||||
void createEntry(prv::Provider* &provider) override {
|
||||
std::vector<u8> value(this->getParent()->getSize(), 0);
|
||||
provider->read(this->getParent()->getOffset(), &value[0], value.size());
|
||||
std::vector<u8> value(this->m_bitField->getSize(), 0);
|
||||
provider->read(this->m_bitField->getOffset(), &value[0], value.size());
|
||||
|
||||
if (this->getParent()->getEndian() == std::endian::little)
|
||||
if (this->m_bitField->getEndian() == std::endian::little)
|
||||
std::reverse(value.begin(), value.end());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
@@ -1448,7 +1354,7 @@ namespace hex::pl {
|
||||
u8 numBytes = (this->m_bitSize / 8) + 1;
|
||||
|
||||
u64 extractedValue = hex::extract(this->m_bitOffset + (this->m_bitSize - 1), this->m_bitOffset, value);
|
||||
ImGui::TextFormatted("{0} (0x{1:X})", extractedValue, extractedValue);
|
||||
ImGui::TextFormatted("{}", this->formatDisplayValue(hex::format("{0} (0x{1:X})", extractedValue, extractedValue), this));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1475,6 +1381,7 @@ namespace hex::pl {
|
||||
|
||||
private:
|
||||
u8 m_bitOffset, m_bitSize;
|
||||
PatternData *m_bitField;
|
||||
};
|
||||
|
||||
class PatternDataBitfield : public PatternData, public Inlinable {
|
||||
@@ -1525,7 +1432,7 @@ namespace hex::pl {
|
||||
valueString += hex::format("{0:02X} ", i);
|
||||
valueString += "}";
|
||||
|
||||
ImGui::TextUnformatted(valueString.c_str());
|
||||
ImGui::TextFormatted("{}", this->formatDisplayValue(valueString, this));
|
||||
}
|
||||
|
||||
if (open) {
|
||||
@@ -1553,7 +1460,6 @@ namespace hex::pl {
|
||||
for (auto &field : this->m_fields) {
|
||||
field->setSize(this->getSize());
|
||||
field->setColor(this->getColor());
|
||||
field->setParent(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace hex {
|
||||
#endif
|
||||
}
|
||||
|
||||
std::vector<std::string> getPath(ImHexPath path) {
|
||||
std::vector<std::string> getPath(ImHexPath path, bool listNonExisting) {
|
||||
std::vector<std::string> result;
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
@@ -195,9 +195,11 @@ namespace hex {
|
||||
}
|
||||
#endif
|
||||
|
||||
result.erase(std::remove_if(result.begin(), result.end(), [](const auto& path){
|
||||
return !std::filesystem::is_directory(path);
|
||||
}), result.end());
|
||||
if (!listNonExisting) {
|
||||
result.erase(std::remove_if(result.begin(), result.end(), [](const auto& path){
|
||||
return !std::filesystem::is_directory(path);
|
||||
}), result.end());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <filesystem>
|
||||
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <hex/helpers/shared_data.hpp>
|
||||
|
||||
#if defined (OS_WINDOWS)
|
||||
#include <windows.h>
|
||||
@@ -18,6 +19,18 @@
|
||||
|
||||
namespace hex {
|
||||
|
||||
long double operator""_scaled(long double value) {
|
||||
return value * SharedData::globalScale;
|
||||
}
|
||||
|
||||
long double operator""_scaled(unsigned long long value) {
|
||||
return value * SharedData::globalScale;
|
||||
}
|
||||
|
||||
ImVec2 scaled(const ImVec2 &vector) {
|
||||
return vector * SharedData::globalScale;
|
||||
}
|
||||
|
||||
std::string to_string(u128 value) {
|
||||
char data[45] = { 0 };
|
||||
|
||||
|
||||
@@ -81,11 +81,11 @@ namespace hex::pl {
|
||||
Token::Literal castedLiteral = std::visit(overloaded {
|
||||
[&](double &value) -> Token::Literal {
|
||||
if (dynamic_cast<PatternDataUnsigned*>(pattern))
|
||||
return u128(value);
|
||||
return u128(value) & bitmask(pattern->getSize() * 8);
|
||||
else if (dynamic_cast<PatternDataSigned*>(pattern))
|
||||
return s128(value);
|
||||
return s128(value) & bitmask(pattern->getSize() * 8);
|
||||
else if (dynamic_cast<PatternDataFloat*>(pattern))
|
||||
return value;
|
||||
return pattern->getSize() == sizeof(float) ? double(float(value)) : value;
|
||||
else
|
||||
LogConsole::abortEvaluation(hex::format("cannot cast type 'double' to type '{}'", pattern->getTypeName()));
|
||||
},
|
||||
@@ -102,18 +102,18 @@ namespace hex::pl {
|
||||
LogConsole::abortEvaluation(hex::format("cannot cast type '{}' to type '{}'", value->getTypeName(), pattern->getTypeName()));
|
||||
},
|
||||
[&](auto &&value) -> Token::Literal {
|
||||
if (dynamic_cast<PatternDataUnsigned*>(pattern))
|
||||
return u128(value);
|
||||
if (dynamic_cast<PatternDataUnsigned*>(pattern) || dynamic_cast<PatternDataEnum*>(pattern))
|
||||
return u128(value) & bitmask(pattern->getSize() * 8);
|
||||
else if (dynamic_cast<PatternDataSigned*>(pattern))
|
||||
return s128(value);
|
||||
return s128(value) & bitmask(pattern->getSize() * 8);
|
||||
else if (dynamic_cast<PatternDataCharacter*>(pattern))
|
||||
return char(value);
|
||||
else if (dynamic_cast<PatternDataBoolean*>(pattern))
|
||||
return bool(value);
|
||||
else if (dynamic_cast<PatternDataFloat*>(pattern))
|
||||
return double(value);
|
||||
return pattern->getSize() == sizeof(float) ? double(float(value)) : value;
|
||||
else
|
||||
LogConsole::abortEvaluation(hex::format("cannot cast type 'string' to type '{}'", pattern->getTypeName()));
|
||||
LogConsole::abortEvaluation(hex::format("cannot cast integer literal to type '{}'", pattern->getTypeName()));
|
||||
}
|
||||
}, value);
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
void View::drawCommonInterfaces() {
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(400, 100) * SharedData::globalScale, ImVec2(600, 300) * SharedData::globalScale);
|
||||
ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300)));
|
||||
if (ImGui::BeginPopupModal("hex.common.info"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::TextWrapped("%s", SharedData::popupMessage.c_str());
|
||||
ImGui::NewLine();
|
||||
@@ -35,7 +35,7 @@ namespace hex {
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(400, 100) * SharedData::globalScale, ImVec2(600, 300) * SharedData::globalScale);
|
||||
ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300)));
|
||||
if (ImGui::BeginPopupModal("hex.common.error"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::TextWrapped("%s", SharedData::popupMessage.c_str());
|
||||
ImGui::NewLine();
|
||||
@@ -47,7 +47,7 @@ namespace hex {
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(400, 100) * SharedData::globalScale, ImVec2(600, 300) * SharedData::globalScale);
|
||||
ImGui::SetNextWindowSizeConstraints(scaled(ImVec2(400, 100)), scaled(ImVec2(600, 300)));
|
||||
if (ImGui::BeginPopupModal("hex.common.fatal"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::TextWrapped("%s", SharedData::popupMessage.c_str());
|
||||
ImGui::NewLine();
|
||||
@@ -85,7 +85,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
ImVec2 View::getMinSize() const {
|
||||
return ImVec2(480, 720) * SharedData::globalScale;
|
||||
return scaled(ImVec2(480, 720));
|
||||
}
|
||||
|
||||
ImVec2 View::getMaxSize() const {
|
||||
|
||||
@@ -175,7 +175,7 @@ namespace hex::init {
|
||||
}
|
||||
}
|
||||
|
||||
this->m_window = glfwCreateWindow(640 * SharedData::globalScale, 400 * SharedData::globalScale, "Starting ImHex...", nullptr, nullptr);
|
||||
this->m_window = glfwCreateWindow(640_scaled, 400_scaled, "Starting ImHex...", nullptr, nullptr);
|
||||
if (this->m_window == nullptr) {
|
||||
log::fatal("Failed to create GLFW window!");
|
||||
exit(EXIT_FAILURE);
|
||||
@@ -203,7 +203,7 @@ namespace hex::init {
|
||||
|
||||
ImFontConfig cfg;
|
||||
cfg.OversampleH = cfg.OversampleV = 1, cfg.PixelSnapH = true;
|
||||
cfg.SizePixels = 13.0f * SharedData::globalScale;
|
||||
cfg.SizePixels = 13.0_scaled;
|
||||
io.Fonts->AddFontDefault(&cfg);
|
||||
|
||||
cfg.MergeMode = true;
|
||||
@@ -214,7 +214,7 @@ namespace hex::init {
|
||||
};
|
||||
std::uint8_t *px;
|
||||
int w, h;
|
||||
io.Fonts->AddFontFromMemoryCompressedTTF(font_awesome_compressed_data, font_awesome_compressed_size, 11.0f * SharedData::globalScale, &cfg, fontAwesomeRange);
|
||||
io.Fonts->AddFontFromMemoryCompressedTTF(font_awesome_compressed_data, font_awesome_compressed_size, 11.0_scaled, &cfg, fontAwesomeRange);
|
||||
io.Fonts->GetTexDataAsRGBA32(&px, &w, &h);
|
||||
|
||||
// Create new font atlas
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace hex::init {
|
||||
};
|
||||
|
||||
for (auto path : paths) {
|
||||
for (auto &folder : hex::getPath(path)) {
|
||||
for (auto &folder : hex::getPath(path, true)) {
|
||||
try {
|
||||
std::filesystem::create_directories(folder);
|
||||
} catch (...) {
|
||||
@@ -136,7 +136,7 @@ namespace hex::init {
|
||||
fonts->Clear();
|
||||
|
||||
cfg.OversampleH = cfg.OversampleV = 1, cfg.PixelSnapH = true;
|
||||
cfg.SizePixels = 13.0f * SharedData::fontScale;
|
||||
cfg.SizePixels = 13.0F * SharedData::fontScale;
|
||||
fonts->AddFontDefault(&cfg);
|
||||
} else {
|
||||
// Load custom font
|
||||
@@ -151,9 +151,9 @@ namespace hex::init {
|
||||
|
||||
cfg.MergeMode = true;
|
||||
|
||||
fonts->AddFontFromMemoryCompressedTTF(font_awesome_compressed_data, font_awesome_compressed_size, 13.0f * SharedData::fontScale, &cfg, fontAwesomeRange);
|
||||
fonts->AddFontFromMemoryCompressedTTF(codicons_compressed_data, codicons_compressed_size, 13.0f * SharedData::fontScale, &cfg, codiconsRange);
|
||||
fonts->AddFontFromMemoryCompressedTTF(unifont_compressed_data, unifont_compressed_size, 13.0f * SharedData::fontScale, &cfg, unifontRange);
|
||||
fonts->AddFontFromMemoryCompressedTTF(font_awesome_compressed_data, font_awesome_compressed_size, 13.0F * SharedData::fontScale, &cfg, fontAwesomeRange);
|
||||
fonts->AddFontFromMemoryCompressedTTF(codicons_compressed_data, codicons_compressed_size, 13.0F * SharedData::fontScale, &cfg, codiconsRange);
|
||||
fonts->AddFontFromMemoryCompressedTTF(unifont_compressed_data, unifont_compressed_size, 13.0F * SharedData::fontScale, &cfg, unifontRange);
|
||||
|
||||
ImGuiFreeType::BuildFontAtlas(fonts);
|
||||
|
||||
|
||||
@@ -319,10 +319,14 @@
|
||||
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - buttonSize.x * 6);
|
||||
#if defined(DEBUG)
|
||||
if (ImGui::TitleBarButton(ICON_VS_DEBUG, buttonSize)) {
|
||||
if (ImGui::GetIO().KeyCtrl && ImGui::GetIO().KeyShift) {
|
||||
if (ImGui::GetIO().KeyCtrl) {
|
||||
// Explicitly trigger a segfault by writing to an invalid memory location
|
||||
// Used for debugging crashes
|
||||
*reinterpret_cast<u8*>(0x10) = 0x10;
|
||||
} else if (ImGui::GetIO().KeyShift) {
|
||||
// Explicitly trigger an abort by throwing an uncaught exception
|
||||
// Used for debugging exception errors
|
||||
throw std::runtime_error("Debug Error");
|
||||
} else {
|
||||
hex::openWebpage("https://imhex.werwolv.net/debug");
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <iostream>
|
||||
#include <numeric>
|
||||
#include <thread>
|
||||
#include <assert.h>
|
||||
|
||||
#include <romfs/romfs.hpp>
|
||||
|
||||
@@ -259,9 +260,19 @@ namespace hex {
|
||||
auto signalHandler = [](int signalNumber) {
|
||||
EventManager::post<EventAbnormalTermination>(signalNumber);
|
||||
|
||||
if (std::uncaught_exceptions() > 0) {
|
||||
log::fatal("Uncaught exception thrown!");
|
||||
}
|
||||
|
||||
// Let's not loop on this...
|
||||
std::signal(signalNumber, nullptr);
|
||||
std::raise(signalNumber);
|
||||
|
||||
#if defined(DEBUG)
|
||||
assert(false);
|
||||
#else
|
||||
std::raise(signalNumber);
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
std::signal(SIGTERM, signalHandler);
|
||||
@@ -406,7 +417,7 @@ namespace hex {
|
||||
static char title[256];
|
||||
ImFormatString(title, IM_ARRAYSIZE(title), "%s/DockSpace_%08X", ImGui::GetCurrentWindow()->Name, ImGui::GetID("MainDock"));
|
||||
if (ImGui::Begin(title)) {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10 * SharedData::globalScale, 10 * SharedData::globalScale));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10_scaled, 10_scaled));
|
||||
if (ImGui::BeginChild("Welcome Screen", ImVec2(0, 0), false, ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoScrollWithMouse)) {
|
||||
this->drawWelcomeScreen();
|
||||
}
|
||||
@@ -517,10 +528,12 @@ namespace hex {
|
||||
}
|
||||
|
||||
if (view->getWindowOpenState()) {
|
||||
bool hasWindow = ImGui::FindWindowByName(View::toWindowName(view->getUnlocalizedName()).c_str()) != nullptr;
|
||||
auto window = ImGui::FindWindowByName(View::toWindowName(view->getUnlocalizedName()).c_str());
|
||||
bool hasWindow = window != nullptr;
|
||||
bool focused = false;
|
||||
|
||||
if (hasWindow) {
|
||||
|
||||
if (hasWindow && !(window->Flags & ImGuiWindowFlags_Popup)) {
|
||||
ImGui::Begin(View::toWindowName(view->getUnlocalizedName()).c_str());
|
||||
|
||||
focused = ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows);
|
||||
@@ -585,7 +598,7 @@ namespace hex {
|
||||
|
||||
|
||||
ImGui::UnderlinedText("hex.welcome.header.start"_lang);
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5 * SharedData::globalScale);
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5_scaled);
|
||||
{
|
||||
if (ImGui::IconHyperlink(ICON_VS_NEW_FILE, "hex.welcome.start.create_file"_lang))
|
||||
EventManager::post<RequestOpenWindow>("Create File");
|
||||
@@ -613,7 +626,7 @@ namespace hex {
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 9);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::UnderlinedText("hex.welcome.start.recent"_lang);
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5 * SharedData::globalScale);
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5_scaled);
|
||||
{
|
||||
if (!SharedData::recentFilePaths.empty()) {
|
||||
for (auto &path : SharedData::recentFilePaths) {
|
||||
@@ -638,7 +651,7 @@ namespace hex {
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 6);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui:: UnderlinedText("hex.welcome.header.help"_lang);
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5 * SharedData::globalScale);
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5_scaled);
|
||||
{
|
||||
if (ImGui::IconHyperlink(ICON_VS_GITHUB, "hex.welcome.help.repo"_lang)) hex::openWebpage("hex.welcome.help.repo.link"_lang);
|
||||
if (ImGui::IconHyperlink(ICON_VS_ORGANIZATION, "hex.welcome.help.gethelp"_lang)) hex::openWebpage("hex.welcome.help.gethelp.link"_lang);
|
||||
@@ -765,7 +778,7 @@ namespace hex {
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||
|
||||
this->m_windowTitle = "ImHex";
|
||||
this->m_window = glfwCreateWindow(1280 * SharedData::globalScale, 720 * SharedData::globalScale, this->m_windowTitle.c_str(), nullptr, nullptr);
|
||||
this->m_window = glfwCreateWindow(1280_scaled, 720_scaled, this->m_windowTitle.c_str(), nullptr, nullptr);
|
||||
|
||||
glfwSetWindowUserPointer(this->m_window, this);
|
||||
|
||||
@@ -890,7 +903,7 @@ namespace hex {
|
||||
EventManager::post<EventWindowClosing>(window);
|
||||
});
|
||||
|
||||
glfwSetWindowSizeLimits(this->m_window, 720 * SharedData::globalScale, 480 * SharedData::globalScale, GLFW_DONT_CARE, GLFW_DONT_CARE);
|
||||
glfwSetWindowSizeLimits(this->m_window, 720_scaled, 480_scaled, GLFW_DONT_CARE, GLFW_DONT_CARE);
|
||||
|
||||
glfwShowWindow(this->m_window);
|
||||
}
|
||||
@@ -916,7 +929,7 @@ namespace hex {
|
||||
for (auto &entry : SharedData::fontAtlas->ConfigData)
|
||||
io.Fonts->ConfigData.push_back(entry);
|
||||
|
||||
io.ConfigViewportsNoTaskBarIcon = true;
|
||||
io.ConfigViewportsNoTaskBarIcon = false;
|
||||
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB;
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT;
|
||||
|
||||
@@ -10,10 +10,10 @@ namespace hex::test {
|
||||
auto testBitfield = create<PatternDataBitfield>("TestBitfield", "testBitfield", 0x12, (4 * 4) / 8, nullptr);
|
||||
testBitfield->setEndian(std::endian::big);
|
||||
testBitfield->setFields({
|
||||
create<PatternDataBitfieldField>("", "a", 0x12, 0, 4, nullptr),
|
||||
create<PatternDataBitfieldField>("", "b", 0x12, 4, 4, nullptr),
|
||||
create<PatternDataBitfieldField>("", "c", 0x12, 8, 4, nullptr),
|
||||
create<PatternDataBitfieldField>("", "d", 0x12, 12, 4, nullptr)
|
||||
create<PatternDataBitfieldField>("", "a", 0x12, 0, 4, testBitfield, nullptr),
|
||||
create<PatternDataBitfieldField>("", "b", 0x12, 4, 4, testBitfield, nullptr),
|
||||
create<PatternDataBitfieldField>("", "c", 0x12, 8, 4, testBitfield, nullptr),
|
||||
create<PatternDataBitfieldField>("", "d", 0x12, 12, 4, testBitfield, nullptr)
|
||||
});
|
||||
|
||||
addPattern(testBitfield);
|
||||
|
||||
Reference in New Issue
Block a user