mirror of https://github.com/WerWolv/ImHex
refactor: Get rid of `this->m_`
This commit is contained in:
parent
dd4be3b772
commit
c7ab4a4569
|
|
@ -28,7 +28,7 @@ namespace hex {
|
|||
* @return Unlocalized name of the achievement
|
||||
*/
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedName() const {
|
||||
return this->m_unlocalizedName;
|
||||
return m_unlocalizedName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -36,7 +36,7 @@ namespace hex {
|
|||
* @return Unlocalized category of the achievement
|
||||
*/
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedCategory() const {
|
||||
return this->m_unlocalizedCategory;
|
||||
return m_unlocalizedCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -44,7 +44,7 @@ namespace hex {
|
|||
* @return Whether the achievement is unlocked
|
||||
*/
|
||||
[[nodiscard]] bool isUnlocked() const {
|
||||
return this->m_progress == this->m_maxProgress;
|
||||
return m_progress == m_maxProgress;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -53,7 +53,7 @@ namespace hex {
|
|||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setDescription(std::string description) {
|
||||
this->m_unlocalizedDescription = std::move(description);
|
||||
m_unlocalizedDescription = std::move(description);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -64,7 +64,7 @@ namespace hex {
|
|||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& addRequirement(std::string requirement) {
|
||||
this->m_requirements.emplace_back(std::move(requirement));
|
||||
m_requirements.emplace_back(std::move(requirement));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -75,7 +75,7 @@ namespace hex {
|
|||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& addVisibilityRequirement(std::string requirement) {
|
||||
this->m_visibilityRequirements.emplace_back(std::move(requirement));
|
||||
m_visibilityRequirements.emplace_back(std::move(requirement));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -85,7 +85,7 @@ namespace hex {
|
|||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setBlacked() {
|
||||
this->m_blacked = true;
|
||||
m_blacked = true;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -95,7 +95,7 @@ namespace hex {
|
|||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setInvisible() {
|
||||
this->m_invisible = true;
|
||||
m_invisible = true;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -105,7 +105,7 @@ namespace hex {
|
|||
* @return Whether the achievement is blacked
|
||||
*/
|
||||
[[nodiscard]] bool isBlacked() const {
|
||||
return this->m_blacked;
|
||||
return m_blacked;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -113,7 +113,7 @@ namespace hex {
|
|||
* @return Whether the achievement is invisible
|
||||
*/
|
||||
[[nodiscard]] bool isInvisible() const {
|
||||
return this->m_invisible;
|
||||
return m_invisible;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -121,7 +121,7 @@ namespace hex {
|
|||
* @return List of requirements of the achievement
|
||||
*/
|
||||
[[nodiscard]] const std::vector<std::string> &getRequirements() const {
|
||||
return this->m_requirements;
|
||||
return m_requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -129,7 +129,7 @@ namespace hex {
|
|||
* @return List of visibility requirements of the achievement
|
||||
*/
|
||||
[[nodiscard]] const std::vector<std::string> &getVisibilityRequirements() const {
|
||||
return this->m_visibilityRequirements;
|
||||
return m_visibilityRequirements;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -137,7 +137,7 @@ namespace hex {
|
|||
* @return Unlocalized description of the achievement
|
||||
*/
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedDescription() const {
|
||||
return this->m_unlocalizedDescription;
|
||||
return m_unlocalizedDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -145,15 +145,15 @@ namespace hex {
|
|||
* @return Icon of the achievement
|
||||
*/
|
||||
[[nodiscard]] const ImGuiExt::Texture &getIcon() const {
|
||||
if (this->m_iconData.empty())
|
||||
return this->m_icon;
|
||||
|
||||
if (this->m_icon.isValid())
|
||||
if (m_iconData.empty())
|
||||
return m_icon;
|
||||
|
||||
this->m_icon = ImGuiExt::Texture(this->m_iconData.data(), this->m_iconData.size(), ImGuiExt::Texture::Filter::Linear);
|
||||
if (m_icon.isValid())
|
||||
return m_icon;
|
||||
|
||||
return this->m_icon;
|
||||
m_icon = ImGuiExt::Texture(m_iconData.data(), m_iconData.size(), ImGuiExt::Texture::Filter::Linear);
|
||||
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -162,9 +162,9 @@ namespace hex {
|
|||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setIcon(std::span<const std::byte> data) {
|
||||
this->m_iconData.reserve(data.size());
|
||||
m_iconData.reserve(data.size());
|
||||
for (auto &byte : data)
|
||||
this->m_iconData.emplace_back(static_cast<u8>(byte));
|
||||
m_iconData.emplace_back(static_cast<u8>(byte));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -175,7 +175,7 @@ namespace hex {
|
|||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setIcon(std::span<const u8> data) {
|
||||
this->m_iconData.assign(data.begin(), data.end());
|
||||
m_iconData.assign(data.begin(), data.end());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -186,7 +186,7 @@ namespace hex {
|
|||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setIcon(std::vector<u8> data) {
|
||||
this->m_iconData = std::move(data);
|
||||
m_iconData = std::move(data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -197,9 +197,9 @@ namespace hex {
|
|||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setIcon(const std::vector<std::byte> &data) {
|
||||
this->m_iconData.reserve(data.size());
|
||||
m_iconData.reserve(data.size());
|
||||
for (auto &byte : data)
|
||||
this->m_iconData.emplace_back(static_cast<u8>(byte));
|
||||
m_iconData.emplace_back(static_cast<u8>(byte));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -210,7 +210,7 @@ namespace hex {
|
|||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setRequiredProgress(u32 progress) {
|
||||
this->m_maxProgress = progress;
|
||||
m_maxProgress = progress;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -220,7 +220,7 @@ namespace hex {
|
|||
* @return Required progress to unlock the achievement
|
||||
*/
|
||||
[[nodiscard]] u32 getRequiredProgress() const {
|
||||
return this->m_maxProgress;
|
||||
return m_maxProgress;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -228,7 +228,7 @@ namespace hex {
|
|||
* @return Current progress of the achievement
|
||||
*/
|
||||
[[nodiscard]] u32 getProgress() const {
|
||||
return this->m_progress;
|
||||
return m_progress;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -236,7 +236,7 @@ namespace hex {
|
|||
* @param callback Callback to call when the achievement is clicked
|
||||
*/
|
||||
void setClickCallback(const std::function<void(Achievement &)> &callback) {
|
||||
this->m_clickCallback = callback;
|
||||
m_clickCallback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -244,7 +244,7 @@ namespace hex {
|
|||
* @return Callback to call when the achievement is clicked
|
||||
*/
|
||||
[[nodiscard]] const std::function<void(Achievement &)> &getClickCallback() const {
|
||||
return this->m_clickCallback;
|
||||
return m_clickCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -252,7 +252,7 @@ namespace hex {
|
|||
* @return Whether the achievement is temporary
|
||||
*/
|
||||
[[nodiscard]] bool isTemporary() const {
|
||||
return this->m_temporary;
|
||||
return m_temporary;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -261,16 +261,16 @@ namespace hex {
|
|||
*/
|
||||
void setUnlocked(bool unlocked) {
|
||||
if (unlocked) {
|
||||
if (this->m_progress < this->m_maxProgress)
|
||||
this->m_progress++;
|
||||
if (m_progress < m_maxProgress)
|
||||
m_progress++;
|
||||
} else {
|
||||
this->m_progress = 0;
|
||||
m_progress = 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void setProgress(u32 progress) {
|
||||
this->m_progress = progress;
|
||||
m_progress = progress;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -64,32 +64,32 @@ namespace hex {
|
|||
friend class Widget;
|
||||
|
||||
Interface& requiresRestart() {
|
||||
this->m_requiresRestart = true;
|
||||
m_requiresRestart = true;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Interface& setEnabledCallback(std::function<bool()> callback) {
|
||||
this->m_enabledCallback = std::move(callback);
|
||||
m_enabledCallback = std::move(callback);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Interface& setChangedCallback(std::function<void(Widget&)> callback) {
|
||||
this->m_changedCallback = std::move(callback);
|
||||
m_changedCallback = std::move(callback);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Interface& setTooltip(const std::string &tooltip) {
|
||||
this->m_tooltip = tooltip;
|
||||
m_tooltip = tooltip;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
Widget& getWidget() const {
|
||||
return *this->m_widget;
|
||||
return *m_widget;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -104,27 +104,27 @@ namespace hex {
|
|||
|
||||
[[nodiscard]]
|
||||
bool doesRequireRestart() const {
|
||||
return this->m_interface.m_requiresRestart;
|
||||
return m_interface.m_requiresRestart;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool isEnabled() const {
|
||||
return !this->m_interface.m_enabledCallback || this->m_interface.m_enabledCallback();
|
||||
return !m_interface.m_enabledCallback || m_interface.m_enabledCallback();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const std::optional<std::string>& getTooltip() const {
|
||||
return this->m_interface.m_tooltip;
|
||||
return m_interface.m_tooltip;
|
||||
}
|
||||
|
||||
void onChanged() {
|
||||
if (this->m_interface.m_changedCallback)
|
||||
this->m_interface.m_changedCallback(*this);
|
||||
if (m_interface.m_changedCallback)
|
||||
m_interface.m_changedCallback(*this);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
Interface& getInterface() {
|
||||
return this->m_interface;
|
||||
return m_interface;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -140,7 +140,7 @@ namespace hex {
|
|||
void load(const nlohmann::json &data) override;
|
||||
nlohmann::json store() override;
|
||||
|
||||
[[nodiscard]] bool isChecked() const { return this->m_value; }
|
||||
[[nodiscard]] bool isChecked() const { return m_value; }
|
||||
|
||||
private:
|
||||
bool m_value;
|
||||
|
|
@ -154,7 +154,7 @@ namespace hex {
|
|||
void load(const nlohmann::json &data) override;
|
||||
nlohmann::json store() override;
|
||||
|
||||
[[nodiscard]] i32 getValue() const { return this->m_value; }
|
||||
[[nodiscard]] i32 getValue() const { return m_value; }
|
||||
|
||||
private:
|
||||
int m_value;
|
||||
|
|
@ -169,7 +169,7 @@ namespace hex {
|
|||
void load(const nlohmann::json &data) override;
|
||||
nlohmann::json store() override;
|
||||
|
||||
[[nodiscard]] float getValue() const { return this->m_value; }
|
||||
[[nodiscard]] float getValue() const { return m_value; }
|
||||
|
||||
private:
|
||||
float m_value;
|
||||
|
|
@ -221,7 +221,7 @@ namespace hex {
|
|||
nlohmann::json store() override;
|
||||
|
||||
[[nodiscard]]
|
||||
const std::string& getValue() const { return this->m_value; }
|
||||
const std::string& getValue() const { return m_value; }
|
||||
|
||||
private:
|
||||
std::string m_value;
|
||||
|
|
@ -235,7 +235,7 @@ namespace hex {
|
|||
nlohmann::json store() override;
|
||||
|
||||
[[nodiscard]] std::fs::path getPath() const {
|
||||
return this->m_value;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -842,10 +842,10 @@ namespace hex {
|
|||
virtual void draw(u64 address, const u8 *data, size_t size, bool upperCase) = 0;
|
||||
virtual bool drawEditing(u64 address, u8 *data, size_t size, bool upperCase, bool startedEditing) = 0;
|
||||
|
||||
[[nodiscard]] u16 getBytesPerCell() const { return this->m_bytesPerCell; }
|
||||
[[nodiscard]] u16 getMaxCharsPerCell() const { return this->m_maxCharsPerCell; }
|
||||
[[nodiscard]] u16 getBytesPerCell() const { return m_bytesPerCell; }
|
||||
[[nodiscard]] u16 getMaxCharsPerCell() const { return m_maxCharsPerCell; }
|
||||
|
||||
[[nodiscard]] const UnlocalizedString& getUnlocalizedName() const { return this->m_unlocalizedName; }
|
||||
[[nodiscard]] const UnlocalizedString& getUnlocalizedName() const { return m_unlocalizedName; }
|
||||
|
||||
protected:
|
||||
const static int TextInputFlags;
|
||||
|
|
@ -903,20 +903,20 @@ namespace hex {
|
|||
|
||||
}
|
||||
|
||||
[[nodiscard]] Hash *getType() { return this->m_type; }
|
||||
[[nodiscard]] const Hash *getType() const { return this->m_type; }
|
||||
[[nodiscard]] const std::string &getName() const { return this->m_name; }
|
||||
[[nodiscard]] Hash *getType() { return m_type; }
|
||||
[[nodiscard]] const Hash *getType() const { return m_type; }
|
||||
[[nodiscard]] const std::string &getName() const { return m_name; }
|
||||
|
||||
const std::vector<u8>& get(const Region& region, prv::Provider *provider) {
|
||||
if (this->m_cache.empty()) {
|
||||
this->m_cache = this->m_callback(region, provider);
|
||||
if (m_cache.empty()) {
|
||||
m_cache = m_callback(region, provider);
|
||||
}
|
||||
|
||||
return this->m_cache;
|
||||
return m_cache;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
this->m_cache.clear();
|
||||
m_cache.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -934,7 +934,7 @@ namespace hex {
|
|||
virtual void load(const nlohmann::json &json) = 0;
|
||||
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedName() const {
|
||||
return this->m_unlocalizedName;
|
||||
return m_unlocalizedName;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -45,15 +45,15 @@ namespace hex {
|
|||
class EventId {
|
||||
public:
|
||||
explicit constexpr EventId(const char *eventName) {
|
||||
this->m_hash = 0x811C'9DC5;
|
||||
m_hash = 0x811C'9DC5;
|
||||
for (auto c : std::string_view(eventName)) {
|
||||
this->m_hash = (this->m_hash >> 5) | (this->m_hash << 27);
|
||||
this->m_hash ^= c;
|
||||
m_hash = (m_hash >> 5) | (m_hash << 27);
|
||||
m_hash ^= c;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool operator==(const EventId &other) const {
|
||||
return this->m_hash == other.m_hash;
|
||||
return m_hash == other.m_hash;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -71,7 +71,7 @@ namespace hex {
|
|||
explicit Event(Callback func) noexcept : m_func(std::move(func)) { }
|
||||
|
||||
void operator()(Params... params) const noexcept {
|
||||
this->m_func(params...);
|
||||
m_func(params...);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ namespace hex {
|
|||
Highlighting() = default;
|
||||
Highlighting(Region region, color_t color);
|
||||
|
||||
[[nodiscard]] const Region &getRegion() const { return this->m_region; }
|
||||
[[nodiscard]] const color_t &getColor() const { return this->m_color; }
|
||||
[[nodiscard]] const Region &getRegion() const { return m_region; }
|
||||
[[nodiscard]] const color_t &getColor() const { return m_color; }
|
||||
|
||||
private:
|
||||
Region m_region = {};
|
||||
|
|
@ -47,9 +47,9 @@ namespace hex {
|
|||
Tooltip() = default;
|
||||
Tooltip(Region region, std::string value, color_t color);
|
||||
|
||||
[[nodiscard]] const Region &getRegion() const { return this->m_region; }
|
||||
[[nodiscard]] const color_t &getColor() const { return this->m_color; }
|
||||
[[nodiscard]] const std::string &getValue() const { return this->m_value; }
|
||||
[[nodiscard]] const Region &getRegion() const { return m_region; }
|
||||
[[nodiscard]] const color_t &getColor() const { return m_color; }
|
||||
[[nodiscard]] const std::string &getValue() const { return m_value; }
|
||||
|
||||
private:
|
||||
Region m_region = {};
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ namespace hex {
|
|||
|
||||
auto operator<=>(const Key &) const = default;
|
||||
|
||||
[[nodiscard]] constexpr u32 getKeyCode() const { return this->m_key; }
|
||||
[[nodiscard]] constexpr u32 getKeyCode() const { return m_key; }
|
||||
private:
|
||||
u32 m_key = 0;
|
||||
};
|
||||
|
|
@ -181,17 +181,17 @@ namespace hex {
|
|||
}
|
||||
|
||||
Shortcut &operator+=(const Key &other) {
|
||||
this->m_keys.insert(other);
|
||||
m_keys.insert(other);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator<(const Shortcut &other) const {
|
||||
return this->m_keys < other.m_keys;
|
||||
return m_keys < other.m_keys;
|
||||
}
|
||||
|
||||
bool operator==(const Shortcut &other) const {
|
||||
auto thisKeys = this->m_keys;
|
||||
auto thisKeys = m_keys;
|
||||
auto otherKeys = other.m_keys;
|
||||
|
||||
thisKeys.erase(CurrentView);
|
||||
|
|
@ -203,7 +203,7 @@ namespace hex {
|
|||
}
|
||||
|
||||
bool isLocal() const {
|
||||
return this->m_keys.contains(CurrentView);
|
||||
return m_keys.contains(CurrentView);
|
||||
}
|
||||
|
||||
std::string toString() const {
|
||||
|
|
@ -223,7 +223,7 @@ namespace hex {
|
|||
|
||||
constexpr static auto Concatination = " + ";
|
||||
|
||||
auto keys = this->m_keys;
|
||||
auto keys = m_keys;
|
||||
if (keys.erase(CTRL) > 0) {
|
||||
result += CTRL_NAME;
|
||||
result += Concatination;
|
||||
|
|
@ -369,7 +369,7 @@ namespace hex {
|
|||
return result;
|
||||
}
|
||||
|
||||
const std::set<Key>& getKeys() const { return this->m_keys; }
|
||||
const std::set<Key>& getKeys() const { return m_keys; }
|
||||
|
||||
private:
|
||||
friend Shortcut operator+(const Key &lhs, const Key &rhs);
|
||||
|
|
|
|||
|
|
@ -105,8 +105,8 @@ namespace hex {
|
|||
|
||||
Step& addStep();
|
||||
|
||||
const UnlocalizedString& getUnlocalizedName() const { return this->m_unlocalizedName; }
|
||||
const UnlocalizedString& getUnlocalizedDescription() const { return this->m_unlocalizedDescription; }
|
||||
const UnlocalizedString& getUnlocalizedName() const { return m_unlocalizedName; }
|
||||
const UnlocalizedString& getUnlocalizedDescription() const { return m_unlocalizedDescription; }
|
||||
|
||||
private:
|
||||
friend class TutorialManager;
|
||||
|
|
|
|||
|
|
@ -28,29 +28,29 @@ namespace hex::dp {
|
|||
Attribute(IOType ioType, Type type, UnlocalizedString unlocalizedName);
|
||||
~Attribute();
|
||||
|
||||
[[nodiscard]] int getId() const { return this->m_id; }
|
||||
void setId(int id) { this->m_id = id; }
|
||||
[[nodiscard]] int getId() const { return m_id; }
|
||||
void setId(int id) { m_id = id; }
|
||||
|
||||
[[nodiscard]] IOType getIOType() const { return this->m_ioType; }
|
||||
[[nodiscard]] Type getType() const { return this->m_type; }
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedName() const { return this->m_unlocalizedName; }
|
||||
[[nodiscard]] IOType getIOType() const { return m_ioType; }
|
||||
[[nodiscard]] Type getType() const { return m_type; }
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedName() const { return m_unlocalizedName; }
|
||||
|
||||
void addConnectedAttribute(int linkId, Attribute *to) { this->m_connectedAttributes.insert({ linkId, to }); }
|
||||
void removeConnectedAttribute(int linkId) { this->m_connectedAttributes.erase(linkId); }
|
||||
[[nodiscard]] std::map<int, Attribute *> &getConnectedAttributes() { return this->m_connectedAttributes; }
|
||||
void addConnectedAttribute(int linkId, Attribute *to) { m_connectedAttributes.insert({ linkId, to }); }
|
||||
void removeConnectedAttribute(int linkId) { m_connectedAttributes.erase(linkId); }
|
||||
[[nodiscard]] std::map<int, Attribute *> &getConnectedAttributes() { return m_connectedAttributes; }
|
||||
|
||||
[[nodiscard]] Node *getParentNode() const { return this->m_parentNode; }
|
||||
[[nodiscard]] Node *getParentNode() const { return m_parentNode; }
|
||||
|
||||
[[nodiscard]] std::vector<u8>& getOutputData() {
|
||||
if (!this->m_outputData.empty())
|
||||
return this->m_outputData;
|
||||
if (!m_outputData.empty())
|
||||
return m_outputData;
|
||||
else
|
||||
return this->m_defaultData;
|
||||
return m_defaultData;
|
||||
}
|
||||
|
||||
void clearOutputData() { this->m_outputData.clear(); }
|
||||
void clearOutputData() { m_outputData.clear(); }
|
||||
|
||||
[[nodiscard]] std::vector<u8>& getDefaultData() { return this->m_defaultData; }
|
||||
[[nodiscard]] std::vector<u8>& getDefaultData() { return m_defaultData; }
|
||||
|
||||
static void setIdCounter(int id);
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ namespace hex::dp {
|
|||
std::vector<u8> m_defaultData;
|
||||
|
||||
friend class Node;
|
||||
void setParentNode(Node *node) { this->m_parentNode = node; }
|
||||
void setParentNode(Node *node) { m_parentNode = node; }
|
||||
|
||||
static int s_idCounter;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ namespace hex::dp {
|
|||
public:
|
||||
Link(int from, int to);
|
||||
|
||||
[[nodiscard]] int getId() const { return this->m_id; }
|
||||
void setId(int id) { this->m_id = id; }
|
||||
[[nodiscard]] int getId() const { return m_id; }
|
||||
void setId(int id) { m_id = id; }
|
||||
|
||||
[[nodiscard]] int getFromId() const { return this->m_from; }
|
||||
[[nodiscard]] int getToId() const { return this->m_to; }
|
||||
[[nodiscard]] int getFromId() const { return m_from; }
|
||||
[[nodiscard]] int getToId() const { return m_to; }
|
||||
|
||||
static void setIdCounter(int id);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,20 +26,20 @@ namespace hex::dp {
|
|||
|
||||
virtual ~Node() = default;
|
||||
|
||||
[[nodiscard]] int getId() const { return this->m_id; }
|
||||
void setId(int id) { this->m_id = id; }
|
||||
[[nodiscard]] int getId() const { return m_id; }
|
||||
void setId(int id) { m_id = id; }
|
||||
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedName() const { return this->m_unlocalizedName; }
|
||||
void setUnlocalizedName(const UnlocalizedString &unlocalizedName) { this->m_unlocalizedName = unlocalizedName; }
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedName() const { return m_unlocalizedName; }
|
||||
void setUnlocalizedName(const UnlocalizedString &unlocalizedName) { m_unlocalizedName = unlocalizedName; }
|
||||
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedTitle() const { return this->m_unlocalizedTitle; }
|
||||
void setUnlocalizedTitle(std::string title) { this->m_unlocalizedTitle = std::move(title); }
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedTitle() const { return m_unlocalizedTitle; }
|
||||
void setUnlocalizedTitle(std::string title) { m_unlocalizedTitle = std::move(title); }
|
||||
|
||||
[[nodiscard]] std::vector<Attribute> &getAttributes() { return this->m_attributes; }
|
||||
[[nodiscard]] const std::vector<Attribute> &getAttributes() const { return this->m_attributes; }
|
||||
[[nodiscard]] std::vector<Attribute> &getAttributes() { return m_attributes; }
|
||||
[[nodiscard]] const std::vector<Attribute> &getAttributes() const { return m_attributes; }
|
||||
|
||||
void setCurrentOverlay(prv::Overlay *overlay) {
|
||||
this->m_overlay = overlay;
|
||||
m_overlay = overlay;
|
||||
}
|
||||
|
||||
virtual void drawNode() { }
|
||||
|
|
@ -54,20 +54,20 @@ namespace hex::dp {
|
|||
};
|
||||
|
||||
void resetOutputData() {
|
||||
for (auto &attribute : this->m_attributes)
|
||||
for (auto &attribute : m_attributes)
|
||||
attribute.clearOutputData();
|
||||
}
|
||||
|
||||
void resetProcessedInputs() {
|
||||
this->m_processedInputs.clear();
|
||||
m_processedInputs.clear();
|
||||
}
|
||||
|
||||
void setPosition(ImVec2 pos) {
|
||||
this->m_position = pos;
|
||||
m_position = pos;
|
||||
}
|
||||
|
||||
[[nodiscard]] ImVec2 getPosition() const {
|
||||
return this->m_position;
|
||||
return m_position;
|
||||
}
|
||||
|
||||
static void setIdCounter(int id);
|
||||
|
|
@ -107,13 +107,13 @@ namespace hex::dp {
|
|||
}
|
||||
|
||||
void markInputProcessed(u32 index) {
|
||||
const auto &[iter, inserted] = this->m_processedInputs.insert(index);
|
||||
const auto &[iter, inserted] = m_processedInputs.insert(index);
|
||||
if (!inserted)
|
||||
throwNodeError("Recursion detected!");
|
||||
}
|
||||
|
||||
void unmarkInputProcessed(u32 index) {
|
||||
this->m_processedInputs.erase(index);
|
||||
m_processedInputs.erase(index);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
@ -124,9 +124,9 @@ namespace hex::dp {
|
|||
void setOverlayData(u64 address, const std::vector<u8> &data);
|
||||
|
||||
void setAttributes(std::vector<Attribute> attributes) {
|
||||
this->m_attributes = std::move(attributes);
|
||||
m_attributes = std::move(attributes);
|
||||
|
||||
for (auto &attr : this->m_attributes)
|
||||
for (auto &attr : m_attributes)
|
||||
attr.setParentNode(this);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -17,13 +17,13 @@ namespace hex {
|
|||
BinaryPattern() = default;
|
||||
explicit BinaryPattern(const std::string &pattern) : m_patterns(parseBinaryPatternString(pattern)) { }
|
||||
|
||||
[[nodiscard]] bool isValid() const { return !this->m_patterns.empty(); }
|
||||
[[nodiscard]] bool isValid() const { return !m_patterns.empty(); }
|
||||
|
||||
[[nodiscard]] bool matches(const std::vector<u8> &bytes) const {
|
||||
if (bytes.size() < this->m_patterns.size())
|
||||
if (bytes.size() < m_patterns.size())
|
||||
return false;
|
||||
|
||||
for (u32 i = 0; i < this->m_patterns.size(); i++) {
|
||||
for (u32 i = 0; i < m_patterns.size(); i++) {
|
||||
if (!this->matchesByte(bytes[i], i))
|
||||
return false;
|
||||
}
|
||||
|
|
@ -32,13 +32,13 @@ namespace hex {
|
|||
}
|
||||
|
||||
[[nodiscard]] bool matchesByte(u8 byte, u32 offset) const {
|
||||
const auto &pattern = this->m_patterns[offset];
|
||||
const auto &pattern = m_patterns[offset];
|
||||
|
||||
return (byte & pattern.mask) == pattern.value;
|
||||
}
|
||||
|
||||
[[nodiscard]] u64 getSize() const {
|
||||
return this->m_patterns.size();
|
||||
return m_patterns.size();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -29,13 +29,13 @@ namespace hex {
|
|||
|
||||
[[nodiscard]] std::pair<std::string_view, size_t> getEncodingFor(std::span<u8> buffer) const;
|
||||
[[nodiscard]] size_t getEncodingLengthFor(std::span<u8> buffer) const;
|
||||
[[nodiscard]] size_t getLongestSequence() const { return this->m_longestSequence; }
|
||||
[[nodiscard]] size_t getLongestSequence() const { return m_longestSequence; }
|
||||
|
||||
[[nodiscard]] bool valid() const { return this->m_valid; }
|
||||
[[nodiscard]] bool valid() const { return m_valid; }
|
||||
|
||||
[[nodiscard]] const std::string& getTableContent() const { return this->m_tableContent; }
|
||||
[[nodiscard]] const std::string& getTableContent() const { return m_tableContent; }
|
||||
|
||||
[[nodiscard]] const std::string& getName() const { return this->m_name; }
|
||||
[[nodiscard]] const std::string& getName() const { return m_name; }
|
||||
|
||||
private:
|
||||
void parse(const std::string &content);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace hex {
|
|||
explicit ResultBase(u32 statusCode) : m_statusCode(statusCode), m_valid(true) { }
|
||||
|
||||
[[nodiscard]] u32 getStatusCode() const {
|
||||
return this->m_statusCode;
|
||||
return m_statusCode;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isSuccess() const {
|
||||
|
|
@ -39,7 +39,7 @@ namespace hex {
|
|||
}
|
||||
|
||||
[[nodiscard]] bool isValid() const {
|
||||
return this->m_valid;
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -55,7 +55,7 @@ namespace hex {
|
|||
|
||||
[[nodiscard]]
|
||||
const T& getData() const {
|
||||
return this->m_data;
|
||||
return m_data;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -76,31 +76,31 @@ namespace hex {
|
|||
static void setProxyUrl(std::string proxy);
|
||||
|
||||
void setMethod(std::string method) {
|
||||
this->m_method = std::move(method);
|
||||
m_method = std::move(method);
|
||||
}
|
||||
|
||||
void setUrl(std::string url) {
|
||||
this->m_url = std::move(url);
|
||||
m_url = std::move(url);
|
||||
}
|
||||
|
||||
void addHeader(std::string key, std::string value) {
|
||||
this->m_headers[std::move(key)] = std::move(value);
|
||||
m_headers[std::move(key)] = std::move(value);
|
||||
}
|
||||
|
||||
void setBody(std::string body) {
|
||||
this->m_body = std::move(body);
|
||||
m_body = std::move(body);
|
||||
}
|
||||
|
||||
void setTimeout(u32 timeout) {
|
||||
this->m_timeout = timeout;
|
||||
m_timeout = timeout;
|
||||
}
|
||||
|
||||
float getProgress() const {
|
||||
return this->m_progress;
|
||||
return m_progress;
|
||||
}
|
||||
|
||||
void cancel() {
|
||||
this->m_canceled = true;
|
||||
m_canceled = true;
|
||||
}
|
||||
|
||||
template<typename T = std::string>
|
||||
|
|
|
|||
|
|
@ -44,24 +44,24 @@ namespace hex {
|
|||
|
||||
template<typename T>
|
||||
HttpRequest::Result<T> HttpRequest::executeImpl(std::vector<u8> &data) {
|
||||
strcpy(this->m_attr.requestMethod, this->m_method.c_str());
|
||||
this->m_attr.attributes = EMSCRIPTEN_FETCH_SYNCHRONOUS | EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;
|
||||
strcpy(m_attr.requestMethod, m_method.c_str());
|
||||
m_attr.attributes = EMSCRIPTEN_FETCH_SYNCHRONOUS | EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;
|
||||
|
||||
if (!this->m_body.empty()) {
|
||||
this->m_attr.requestData = this->m_body.c_str();
|
||||
this->m_attr.requestDataSize = this->m_body.size();
|
||||
if (!m_body.empty()) {
|
||||
m_attr.requestData = m_body.c_str();
|
||||
m_attr.requestDataSize = m_body.size();
|
||||
}
|
||||
|
||||
std::vector<const char*> headers;
|
||||
for (auto it = this->m_headers.begin(); it != this->m_headers.end(); it++) {
|
||||
for (auto it = m_headers.begin(); it != m_headers.end(); it++) {
|
||||
headers.push_back(it->first.c_str());
|
||||
headers.push_back(it->second.c_str());
|
||||
}
|
||||
headers.push_back(nullptr);
|
||||
this->m_attr.requestHeaders = headers.data();
|
||||
m_attr.requestHeaders = headers.data();
|
||||
|
||||
// Send request
|
||||
emscripten_fetch_t* fetch = emscripten_fetch(&this->m_attr, this->m_url.c_str());
|
||||
emscripten_fetch_t* fetch = emscripten_fetch(&m_attr, m_url.c_str());
|
||||
|
||||
data.resize(fetch->numBytes);
|
||||
std::copy(fetch->data, fetch->data + fetch->numBytes, data.begin());
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ namespace hex {
|
|||
std::vector<u8> response;
|
||||
|
||||
wolv::io::File file(path, wolv::io::File::Mode::Create);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEFUNCTION, writeToFile);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEDATA, &file);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeToFile);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &file);
|
||||
|
||||
return this->executeImpl<T>(response);
|
||||
});
|
||||
|
|
@ -30,7 +30,7 @@ namespace hex {
|
|||
return std::async(std::launch::async, [this, path, mimeName]{
|
||||
auto fileName = wolv::util::toUTF8String(path.filename());
|
||||
|
||||
curl_mime *mime = curl_mime_init(this->m_curl);
|
||||
curl_mime *mime = curl_mime_init(m_curl);
|
||||
curl_mimepart *part = curl_mime_addpart(mime);
|
||||
|
||||
wolv::io::File file(path, wolv::io::File::Mode::Read);
|
||||
|
|
@ -58,11 +58,11 @@ namespace hex {
|
|||
curl_mime_filename(part, fileName.c_str());
|
||||
curl_mime_name(part, mimeName.c_str());
|
||||
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_MIMEPOST, mime);
|
||||
curl_easy_setopt(m_curl, CURLOPT_MIMEPOST, mime);
|
||||
|
||||
std::vector<u8> responseData;
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEDATA, &responseData);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &responseData);
|
||||
|
||||
return this->executeImpl<T>(responseData);
|
||||
});
|
||||
|
|
@ -71,7 +71,7 @@ namespace hex {
|
|||
template<typename T>
|
||||
std::future<HttpRequest::Result<T>> HttpRequest::uploadFile(std::vector<u8> data, const std::string &mimeName, const std::fs::path &fileName) {
|
||||
return std::async(std::launch::async, [this, data = std::move(data), mimeName, fileName]{
|
||||
curl_mime *mime = curl_mime_init(this->m_curl);
|
||||
curl_mime *mime = curl_mime_init(m_curl);
|
||||
curl_mimepart *part = curl_mime_addpart(mime);
|
||||
|
||||
curl_mime_data(part, reinterpret_cast<const char *>(data.data()), data.size());
|
||||
|
|
@ -79,11 +79,11 @@ namespace hex {
|
|||
curl_mime_filename(part, fileNameStr.c_str());
|
||||
curl_mime_name(part, mimeName.c_str());
|
||||
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_MIMEPOST, mime);
|
||||
curl_easy_setopt(m_curl, CURLOPT_MIMEPOST, mime);
|
||||
|
||||
std::vector<u8> responseData;
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEDATA, &responseData);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &responseData);
|
||||
|
||||
return this->executeImpl<T>(responseData);
|
||||
});
|
||||
|
|
@ -94,8 +94,8 @@ namespace hex {
|
|||
return std::async(std::launch::async, [this] {
|
||||
|
||||
std::vector<u8> responseData;
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEDATA, &responseData);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &responseData);
|
||||
|
||||
return this->executeImpl<T>(responseData);
|
||||
});
|
||||
|
|
@ -103,33 +103,33 @@ namespace hex {
|
|||
|
||||
template<typename T>
|
||||
HttpRequest::Result<T> HttpRequest::executeImpl(std::vector<u8> &data) {
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_URL, this->m_url.c_str());
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_CUSTOMREQUEST, this->m_method.c_str());
|
||||
curl_easy_setopt(m_curl, CURLOPT_URL, m_url.c_str());
|
||||
curl_easy_setopt(m_curl, CURLOPT_CUSTOMREQUEST, m_method.c_str());
|
||||
|
||||
setDefaultConfig();
|
||||
|
||||
if (!this->m_body.empty()) {
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_POSTFIELDS, this->m_body.c_str());
|
||||
if (!m_body.empty()) {
|
||||
curl_easy_setopt(m_curl, CURLOPT_POSTFIELDS, m_body.c_str());
|
||||
}
|
||||
|
||||
curl_slist *headers = nullptr;
|
||||
headers = curl_slist_append(headers, "Cache-Control: no-cache");
|
||||
ON_SCOPE_EXIT { curl_slist_free_all(headers); };
|
||||
|
||||
for (auto &[key, value] : this->m_headers) {
|
||||
for (auto &[key, value] : m_headers) {
|
||||
std::string header = hex::format("{}: {}", key, value);
|
||||
headers = curl_slist_append(headers, header.c_str());
|
||||
}
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_HTTPHEADER, headers);
|
||||
curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, headers);
|
||||
|
||||
{
|
||||
std::scoped_lock lock(this->m_transmissionMutex);
|
||||
std::scoped_lock lock(m_transmissionMutex);
|
||||
|
||||
auto result = curl_easy_perform(this->m_curl);
|
||||
auto result = curl_easy_perform(m_curl);
|
||||
if (result != CURLE_OK){
|
||||
char *url = nullptr;
|
||||
curl_easy_getinfo(this->m_curl, CURLINFO_EFFECTIVE_URL, &url);
|
||||
log::error("Http request '{0} {1}' failed with error {2}: '{3}'", this->m_method, url, u32(result), curl_easy_strerror(result));
|
||||
curl_easy_getinfo(m_curl, CURLINFO_EFFECTIVE_URL, &url);
|
||||
log::error("Http request '{0} {1}' failed with error {2}: '{3}'", m_method, url, u32(result), curl_easy_strerror(result));
|
||||
checkProxyErrors();
|
||||
|
||||
return { };
|
||||
|
|
@ -137,7 +137,7 @@ namespace hex {
|
|||
}
|
||||
|
||||
long statusCode = 0;
|
||||
curl_easy_getinfo(this->m_curl, CURLINFO_RESPONSE_CODE, &statusCode);
|
||||
curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &statusCode);
|
||||
|
||||
return Result<T>(statusCode, { data.begin(), data.end() });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,46 +42,46 @@ namespace hex::gl {
|
|||
Vector() = default;
|
||||
Vector(const T val) {
|
||||
for (size_t i = 0; i < Size; i++)
|
||||
this->m_data[i] = val;
|
||||
m_data[i] = val;
|
||||
}
|
||||
|
||||
Vector(std::array<T, Size> data) : m_data(data) { }
|
||||
Vector(Vector &&other) noexcept : m_data(std::move(other.m_data)) { }
|
||||
Vector(const Vector &other) : m_data(other.m_data) { }
|
||||
|
||||
T &operator[](size_t index) { return this->m_data[index]; }
|
||||
const T &operator[](size_t index) const { return this->m_data[index]; }
|
||||
T &operator[](size_t index) { return m_data[index]; }
|
||||
const T &operator[](size_t index) const { return m_data[index]; }
|
||||
|
||||
std::array<T, Size> &asArray() { return this->m_data; }
|
||||
std::array<T, Size> &asArray() { return m_data; }
|
||||
|
||||
T *data() { return this->m_data.data(); }
|
||||
const T *data() const { return this->m_data.data(); }
|
||||
T *data() { return m_data.data(); }
|
||||
const T *data() const { return m_data.data(); }
|
||||
|
||||
[[nodiscard]] size_t size() const { return this->m_data.size(); }
|
||||
[[nodiscard]] size_t size() const { return m_data.size(); }
|
||||
|
||||
auto operator=(const Vector& other) {
|
||||
for (size_t i = 0; i < Size; i++)
|
||||
this->m_data[i] = other[i];
|
||||
m_data[i] = other[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto operator+=(const Vector& other) {
|
||||
for (size_t i = 0; i < Size; i++)
|
||||
this->m_data[i] += other.m_data[i];
|
||||
m_data[i] += other.m_data[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto operator+=(const T scalar) {
|
||||
for (size_t i = 0; i < Size; i++)
|
||||
this->m_data[i] += scalar;
|
||||
m_data[i] += scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto operator-=(Vector other) {
|
||||
for (size_t i = 0; i < Size; i++)
|
||||
this->m_data[i] -= other.m_data[i];
|
||||
m_data[i] -= other.m_data[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -89,14 +89,14 @@ namespace hex::gl {
|
|||
|
||||
auto operator-=(const T scalar) {
|
||||
for (size_t i = 0; i < Size; i++)
|
||||
this->m_data[i] -= scalar;
|
||||
m_data[i] -= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector operator*=(const T scalar) {
|
||||
for (size_t i = 0; i < Size; i++)
|
||||
this->m_data[i] *= scalar;
|
||||
m_data[i] *= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -125,15 +125,15 @@ namespace hex::gl {
|
|||
auto dot(const Vector& other) {
|
||||
T result = 0;
|
||||
for (size_t i = 0; i < Size; i++)
|
||||
result += this->m_data[i] * other[i];
|
||||
result += m_data[i] * other[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
auto cross(const Vector& other) {
|
||||
static_assert(Size == 3, "Cross product is only defined for 3D vectors");
|
||||
return Vector({this->m_data[1] * other[2] - this->m_data[2] * other[1],
|
||||
this->m_data[2] * other[0] - this->m_data[0] * other[2],
|
||||
this->m_data[0] * other[1] - this->m_data[1] * other[0]});
|
||||
return Vector({m_data[1] * other[2] - m_data[2] * other[1],
|
||||
m_data[2] * other[0] - m_data[0] * other[2],
|
||||
m_data[0] * other[1] - m_data[1] * other[0]});
|
||||
}
|
||||
|
||||
auto magnitude() {
|
||||
|
|
@ -150,7 +150,7 @@ namespace hex::gl {
|
|||
|
||||
auto operator==(const Vector& other) {
|
||||
for (size_t i = 0; i < Size; i++)
|
||||
if (this->m_data[i] != other[i])
|
||||
if (m_data[i] != other[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ namespace hex {
|
|||
wolv::util::Expected<std::vector<u8>, IPSError> toIPSPatch() const;
|
||||
wolv::util::Expected<std::vector<u8>, IPSError> toIPS32Patch() const;
|
||||
|
||||
const auto& get() const { return this->m_patches; }
|
||||
auto& get() { return this->m_patches; }
|
||||
const auto& get() const { return m_patches; }
|
||||
auto& get() { return m_patches; }
|
||||
|
||||
private:
|
||||
std::map<u64, u8> m_patches;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ namespace hex {
|
|||
void extract(const std::fs::path &path, const std::fs::path &outputPath);
|
||||
void extractAll(const std::fs::path &outputPath);
|
||||
|
||||
[[nodiscard]] bool isValid() const { return this->m_valid; }
|
||||
[[nodiscard]] bool isValid() const { return m_valid; }
|
||||
|
||||
private:
|
||||
mtar_t m_ctx = { };
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ namespace hex::prv {
|
|||
public:
|
||||
Overlay() = default;
|
||||
|
||||
void setAddress(u64 address) { this->m_address = address; }
|
||||
[[nodiscard]] u64 getAddress() const { return this->m_address; }
|
||||
void setAddress(u64 address) { m_address = address; }
|
||||
[[nodiscard]] u64 getAddress() const { return m_address; }
|
||||
|
||||
[[nodiscard]] u64 getSize() const { return this->m_data.size(); }
|
||||
[[nodiscard]] std::vector<u8> &getData() { return this->m_data; }
|
||||
[[nodiscard]] u64 getSize() const { return m_data.size(); }
|
||||
[[nodiscard]] std::vector<u8> &getData() { return m_data; }
|
||||
|
||||
private:
|
||||
u64 m_address = 0;
|
||||
|
|
|
|||
|
|
@ -210,23 +210,23 @@ namespace hex::prv {
|
|||
[[nodiscard]] virtual nlohmann::json storeSettings(nlohmann::json settings) const;
|
||||
virtual void loadSettings(const nlohmann::json &settings);
|
||||
|
||||
void markDirty(bool dirty = true) { this->m_dirty = dirty; }
|
||||
[[nodiscard]] bool isDirty() const { return this->m_dirty; }
|
||||
void markDirty(bool dirty = true) { m_dirty = dirty; }
|
||||
[[nodiscard]] bool isDirty() const { return m_dirty; }
|
||||
|
||||
[[nodiscard]] virtual std::pair<Region, bool> getRegionValidity(u64 address) const;
|
||||
|
||||
void skipLoadInterface() { this->m_skipLoadInterface = true; }
|
||||
[[nodiscard]] bool shouldSkipLoadInterface() const { return this->m_skipLoadInterface; }
|
||||
void skipLoadInterface() { m_skipLoadInterface = true; }
|
||||
[[nodiscard]] bool shouldSkipLoadInterface() const { return m_skipLoadInterface; }
|
||||
|
||||
void setErrorMessage(const std::string &errorMessage) { this->m_errorMessage = errorMessage; }
|
||||
[[nodiscard]] const std::string& getErrorMessage() const { return this->m_errorMessage; }
|
||||
void setErrorMessage(const std::string &errorMessage) { m_errorMessage = errorMessage; }
|
||||
[[nodiscard]] const std::string& getErrorMessage() const { return m_errorMessage; }
|
||||
|
||||
template<std::derived_from<undo::Operation> T>
|
||||
bool addUndoableOperation(auto && ... args) {
|
||||
return this->m_undoRedoStack.add<T>(std::forward<decltype(args)...>(args)...);
|
||||
return m_undoRedoStack.add<T>(std::forward<decltype(args)...>(args)...);
|
||||
}
|
||||
|
||||
[[nodiscard]] undo::Stack& getUndoStack() { return this->m_undoRedoStack; }
|
||||
[[nodiscard]] undo::Stack& getUndoStack() { return m_undoRedoStack; }
|
||||
|
||||
protected:
|
||||
u32 m_currPage = 0;
|
||||
|
|
|
|||
|
|
@ -34,19 +34,19 @@ namespace hex {
|
|||
}
|
||||
|
||||
T& get(prv::Provider *provider = ImHexApi::Provider::get()) {
|
||||
return this->m_data[provider];
|
||||
return m_data[provider];
|
||||
}
|
||||
|
||||
const T& get(prv::Provider *provider = ImHexApi::Provider::get()) const {
|
||||
return this->m_data[provider];
|
||||
return m_data[provider];
|
||||
}
|
||||
|
||||
void set(const T &data, prv::Provider *provider = ImHexApi::Provider::get()) {
|
||||
this->m_data[provider] = data;
|
||||
m_data[provider] = data;
|
||||
}
|
||||
|
||||
void set(T &&data, prv::Provider *provider = ImHexApi::Provider::get()) {
|
||||
this->m_data[provider] = std::move(data);
|
||||
m_data[provider] = std::move(data);
|
||||
}
|
||||
|
||||
T& operator*() {
|
||||
|
|
@ -74,15 +74,15 @@ namespace hex {
|
|||
private:
|
||||
void onCreate() {
|
||||
EventProviderOpened::subscribe(this, [this](prv::Provider *provider) {
|
||||
this->m_data.emplace(provider, T());
|
||||
m_data.emplace(provider, T());
|
||||
});
|
||||
|
||||
EventProviderDeleted::subscribe(this, [this](prv::Provider *provider){
|
||||
this->m_data.erase(provider);
|
||||
m_data.erase(provider);
|
||||
});
|
||||
|
||||
EventImHexClosing::subscribe(this, [this] {
|
||||
this->m_data.clear();
|
||||
m_data.clear();
|
||||
});
|
||||
|
||||
// Moves the data of this PerProvider instance from one provider to another
|
||||
|
|
@ -94,11 +94,11 @@ namespace hex {
|
|||
if (node.empty()) return;
|
||||
|
||||
// Delete the value from the new provider, that we want to replace
|
||||
this->m_data.erase(to);
|
||||
m_data.erase(to);
|
||||
|
||||
// Re-insert it with the key of the new provider
|
||||
node.key() = to;
|
||||
this->m_data.insert(std::move(node));
|
||||
m_data.insert(std::move(node));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,40 +14,40 @@ namespace hex::prv::undo {
|
|||
|
||||
OperationGroup(const OperationGroup &other) {
|
||||
for (const auto &operation : other.m_operations)
|
||||
this->m_operations.emplace_back(operation->clone());
|
||||
m_operations.emplace_back(operation->clone());
|
||||
}
|
||||
|
||||
void undo(Provider *provider) override {
|
||||
for (auto &operation : this->m_operations)
|
||||
for (auto &operation : m_operations)
|
||||
operation->undo(provider);
|
||||
}
|
||||
|
||||
void redo(Provider *provider) override {
|
||||
for (auto &operation : this->m_operations)
|
||||
for (auto &operation : m_operations)
|
||||
operation->redo(provider);
|
||||
}
|
||||
|
||||
void addOperation(std::unique_ptr<Operation> &&newOperation) {
|
||||
auto newRegion = newOperation->getRegion();
|
||||
if (newRegion.getStartAddress() < this->m_startAddress)
|
||||
this->m_startAddress = newRegion.getStartAddress();
|
||||
if (newRegion.getEndAddress() > this->m_endAddress)
|
||||
this->m_endAddress = newRegion.getEndAddress();
|
||||
if (newRegion.getStartAddress() < m_startAddress)
|
||||
m_startAddress = newRegion.getStartAddress();
|
||||
if (newRegion.getEndAddress() > m_endAddress)
|
||||
m_endAddress = newRegion.getEndAddress();
|
||||
|
||||
if (this->m_formattedContent.size() <= 10)
|
||||
this->m_formattedContent.emplace_back(newOperation->format());
|
||||
if (m_formattedContent.size() <= 10)
|
||||
m_formattedContent.emplace_back(newOperation->format());
|
||||
else
|
||||
this->m_formattedContent.back() = hex::format("[{}x] ...", (this->m_operations.size() - 10) + 1);
|
||||
m_formattedContent.back() = hex::format("[{}x] ...", (m_operations.size() - 10) + 1);
|
||||
|
||||
this->m_operations.emplace_back(std::move(newOperation));
|
||||
m_operations.emplace_back(std::move(newOperation));
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string format() const override {
|
||||
return hex::format("{}", Lang(this->m_unlocalizedName));
|
||||
return hex::format("{}", Lang(m_unlocalizedName));
|
||||
}
|
||||
|
||||
[[nodiscard]] Region getRegion() const override {
|
||||
return Region { this->m_startAddress, (this->m_endAddress - this->m_startAddress) + 1 };
|
||||
return Region { m_startAddress, (m_endAddress - m_startAddress) + 1 };
|
||||
}
|
||||
|
||||
std::unique_ptr<Operation> clone() const override {
|
||||
|
|
@ -55,7 +55,7 @@ namespace hex::prv::undo {
|
|||
}
|
||||
|
||||
std::vector<std::string> formatContent() const override {
|
||||
return this->m_formattedContent;
|
||||
return m_formattedContent;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -39,21 +39,21 @@ namespace hex::prv::undo {
|
|||
bool add(std::unique_ptr<Operation> &&operation);
|
||||
|
||||
const std::vector<std::unique_ptr<Operation>> &getAppliedOperations() const {
|
||||
return this->m_undoStack;
|
||||
return m_undoStack;
|
||||
}
|
||||
|
||||
const std::vector<std::unique_ptr<Operation>> &getUndoneOperations() const {
|
||||
return this->m_redoStack;
|
||||
return m_redoStack;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
this->m_undoStack.clear();
|
||||
this->m_redoStack.clear();
|
||||
m_undoStack.clear();
|
||||
m_redoStack.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
[[nodiscard]] Operation* getLastOperation() const {
|
||||
return this->m_undoStack.back().get();
|
||||
return m_undoStack.back().get();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -90,25 +90,25 @@ namespace ImGuiExt {
|
|||
Texture& operator=(Texture&& other) noexcept;
|
||||
|
||||
[[nodiscard]] constexpr bool isValid() const noexcept {
|
||||
return this->m_textureId != nullptr;
|
||||
return m_textureId != nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] operator ImTextureID() const noexcept {
|
||||
return this->m_textureId;
|
||||
return m_textureId;
|
||||
}
|
||||
|
||||
[[nodiscard]] operator intptr_t() const noexcept {
|
||||
return reinterpret_cast<intptr_t>(this->m_textureId);
|
||||
return reinterpret_cast<intptr_t>(m_textureId);
|
||||
}
|
||||
|
||||
[[nodiscard]] auto getSize() const noexcept {
|
||||
return ImVec2(this->m_width, this->m_height);
|
||||
return ImVec2(m_width, m_height);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto getAspectRatio() const noexcept {
|
||||
if (this->m_height == 0) return 1.0F;
|
||||
if (m_height == 0) return 1.0F;
|
||||
|
||||
return float(this->m_width) / float(this->m_height);
|
||||
return float(m_width) / float(m_height);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -37,23 +37,23 @@ namespace hex {
|
|||
[[nodiscard]] static std::vector<std::unique_ptr<PopupBase>> &getOpenPopups();
|
||||
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedName() const {
|
||||
return this->m_unlocalizedName;
|
||||
return m_unlocalizedName;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool hasCloseButton() const {
|
||||
return this->m_closeButton;
|
||||
return m_closeButton;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isModal() const {
|
||||
return this->m_modal;
|
||||
return m_modal;
|
||||
}
|
||||
|
||||
void close() {
|
||||
this->m_close = true;
|
||||
m_close = true;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool shouldClose() const {
|
||||
return this->m_close;
|
||||
return m_close;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -21,34 +21,34 @@ namespace hex::ui {
|
|||
}
|
||||
|
||||
const std::vector<const T*> &draw(const auto &entries) {
|
||||
if (this->m_filteredEntries.empty() && this->m_searchBuffer.empty()) {
|
||||
if (m_filteredEntries.empty() && m_searchBuffer.empty()) {
|
||||
for (auto &entry : entries)
|
||||
this->m_filteredEntries.push_back(&entry);
|
||||
m_filteredEntries.push_back(&entry);
|
||||
}
|
||||
|
||||
if (ImGui::InputText("##search", this->m_searchBuffer)) {
|
||||
this->m_pendingUpdate = true;
|
||||
if (ImGui::InputText("##search", m_searchBuffer)) {
|
||||
m_pendingUpdate = true;
|
||||
}
|
||||
|
||||
if (this->m_pendingUpdate && !this->m_updateTask.isRunning()) {
|
||||
this->m_pendingUpdate = false;
|
||||
this->m_filteredEntries.clear();
|
||||
this->m_filteredEntries.reserve(entries.size());
|
||||
if (m_pendingUpdate && !m_updateTask.isRunning()) {
|
||||
m_pendingUpdate = false;
|
||||
m_filteredEntries.clear();
|
||||
m_filteredEntries.reserve(entries.size());
|
||||
|
||||
this->m_updateTask = TaskManager::createBackgroundTask("Searching", [this, &entries, searchBuffer = this->m_searchBuffer](Task&) {
|
||||
m_updateTask = TaskManager::createBackgroundTask("Searching", [this, &entries, searchBuffer = m_searchBuffer](Task&) {
|
||||
for (auto &entry : entries) {
|
||||
if (searchBuffer.empty() || this->m_comparator(searchBuffer, entry))
|
||||
this->m_filteredEntries.push_back(&entry);
|
||||
if (searchBuffer.empty() || m_comparator(searchBuffer, entry))
|
||||
m_filteredEntries.push_back(&entry);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return this->m_filteredEntries;
|
||||
return m_filteredEntries;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
this->m_filteredEntries.clear();
|
||||
m_filteredEntries.clear();
|
||||
}
|
||||
private:
|
||||
std::atomic<bool> m_pendingUpdate = false;
|
||||
|
|
|
|||
|
|
@ -176,60 +176,60 @@ namespace hex {
|
|||
namespace Widgets {
|
||||
|
||||
bool Checkbox::draw(const std::string &name) {
|
||||
return ImGui::Checkbox(name.c_str(), &this->m_value);
|
||||
return ImGui::Checkbox(name.c_str(), &m_value);
|
||||
}
|
||||
|
||||
void Checkbox::load(const nlohmann::json &data) {
|
||||
if (data.is_number()) {
|
||||
this->m_value = data.get<int>() != 0;
|
||||
m_value = data.get<int>() != 0;
|
||||
} else if (data.is_boolean()) {
|
||||
this->m_value = data.get<bool>();
|
||||
m_value = data.get<bool>();
|
||||
} else {
|
||||
log::warn("Invalid data type loaded from settings for checkbox!");
|
||||
}
|
||||
}
|
||||
|
||||
nlohmann::json Checkbox::store() {
|
||||
return this->m_value;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
|
||||
bool SliderInteger::draw(const std::string &name) {
|
||||
return ImGui::SliderInt(name.c_str(), &this->m_value, this->m_min, this->m_max);
|
||||
return ImGui::SliderInt(name.c_str(), &m_value, m_min, m_max);
|
||||
}
|
||||
|
||||
void SliderInteger::load(const nlohmann::json &data) {
|
||||
if (data.is_number_integer()) {
|
||||
this->m_value = data.get<int>();
|
||||
m_value = data.get<int>();
|
||||
} else {
|
||||
log::warn("Invalid data type loaded from settings for slider!");
|
||||
}
|
||||
}
|
||||
|
||||
nlohmann::json SliderInteger::store() {
|
||||
return this->m_value;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
|
||||
bool SliderFloat::draw(const std::string &name) {
|
||||
return ImGui::SliderFloat(name.c_str(), &this->m_value, this->m_min, this->m_max);
|
||||
return ImGui::SliderFloat(name.c_str(), &m_value, m_min, m_max);
|
||||
}
|
||||
|
||||
void SliderFloat::load(const nlohmann::json &data) {
|
||||
if (data.is_number()) {
|
||||
this->m_value = data.get<float>();
|
||||
m_value = data.get<float>();
|
||||
} else {
|
||||
log::warn("Invalid data type loaded from settings for slider!");
|
||||
}
|
||||
}
|
||||
|
||||
nlohmann::json SliderFloat::store() {
|
||||
return this->m_value;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
|
||||
ColorPicker::ColorPicker(ImColor defaultColor) {
|
||||
this->m_value = {
|
||||
m_value = {
|
||||
defaultColor.Value.x,
|
||||
defaultColor.Value.y,
|
||||
defaultColor.Value.z,
|
||||
|
|
@ -238,43 +238,43 @@ namespace hex {
|
|||
}
|
||||
|
||||
bool ColorPicker::draw(const std::string &name) {
|
||||
return ImGui::ColorEdit4(name.c_str(), this->m_value.data(), ImGuiColorEditFlags_NoInputs);
|
||||
return ImGui::ColorEdit4(name.c_str(), m_value.data(), ImGuiColorEditFlags_NoInputs);
|
||||
}
|
||||
|
||||
void ColorPicker::load(const nlohmann::json &data) {
|
||||
if (data.is_number()) {
|
||||
ImColor color(data.get<u32>());
|
||||
this->m_value = { color.Value.x, color.Value.y, color.Value.z, color.Value.w };
|
||||
m_value = { color.Value.x, color.Value.y, color.Value.z, color.Value.w };
|
||||
} else {
|
||||
log::warn("Invalid data type loaded from settings for color picker!");
|
||||
}
|
||||
}
|
||||
|
||||
nlohmann::json ColorPicker::store() {
|
||||
const ImColor color(this->m_value[0], this->m_value[1], this->m_value[2], this->m_value[3]);
|
||||
const ImColor color(m_value[0], m_value[1], m_value[2], m_value[3]);
|
||||
|
||||
return static_cast<ImU32>(color);
|
||||
}
|
||||
|
||||
ImColor ColorPicker::getColor() const {
|
||||
return { this->m_value[0], this->m_value[1], this->m_value[2], this->m_value[3] };
|
||||
return { m_value[0], m_value[1], m_value[2], m_value[3] };
|
||||
}
|
||||
|
||||
|
||||
bool DropDown::draw(const std::string &name) {
|
||||
const char *preview = "";
|
||||
if (static_cast<size_t>(this->m_value) < this->m_items.size())
|
||||
preview = this->m_items[this->m_value].c_str();
|
||||
if (static_cast<size_t>(m_value) < m_items.size())
|
||||
preview = m_items[m_value].c_str();
|
||||
|
||||
bool changed = false;
|
||||
if (ImGui::BeginCombo(name.c_str(), Lang(preview))) {
|
||||
|
||||
int index = 0;
|
||||
for (const auto &item : this->m_items) {
|
||||
const bool selected = index == this->m_value;
|
||||
for (const auto &item : m_items) {
|
||||
const bool selected = index == m_value;
|
||||
|
||||
if (ImGui::Selectable(Lang(item), selected)) {
|
||||
this->m_value = index;
|
||||
m_value = index;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
|
@ -291,60 +291,60 @@ namespace hex {
|
|||
}
|
||||
|
||||
void DropDown::load(const nlohmann::json &data) {
|
||||
this->m_value = 0;
|
||||
m_value = 0;
|
||||
|
||||
int defaultItemIndex = 0;
|
||||
|
||||
int index = 0;
|
||||
for (const auto &item : this->m_settingsValues) {
|
||||
if (item == this->m_defaultItem)
|
||||
for (const auto &item : m_settingsValues) {
|
||||
if (item == m_defaultItem)
|
||||
defaultItemIndex = index;
|
||||
|
||||
if (item == data) {
|
||||
this->m_value = index;
|
||||
m_value = index;
|
||||
return;
|
||||
}
|
||||
|
||||
index += 1;
|
||||
}
|
||||
|
||||
this->m_value = defaultItemIndex;
|
||||
m_value = defaultItemIndex;
|
||||
}
|
||||
|
||||
nlohmann::json DropDown::store() {
|
||||
if (this->m_value == -1)
|
||||
return this->m_defaultItem;
|
||||
if (static_cast<size_t>(this->m_value) >= this->m_items.size())
|
||||
return this->m_defaultItem;
|
||||
if (m_value == -1)
|
||||
return m_defaultItem;
|
||||
if (static_cast<size_t>(m_value) >= m_items.size())
|
||||
return m_defaultItem;
|
||||
|
||||
return this->m_settingsValues[this->m_value];
|
||||
return m_settingsValues[m_value];
|
||||
}
|
||||
|
||||
const nlohmann::json& DropDown::getValue() const {
|
||||
return this->m_settingsValues[this->m_value];
|
||||
return m_settingsValues[m_value];
|
||||
}
|
||||
|
||||
|
||||
bool TextBox::draw(const std::string &name) {
|
||||
return ImGui::InputText(name.c_str(), this->m_value);
|
||||
return ImGui::InputText(name.c_str(), m_value);
|
||||
}
|
||||
|
||||
void TextBox::load(const nlohmann::json &data) {
|
||||
if (data.is_string()) {
|
||||
this->m_value = data.get<std::string>();
|
||||
m_value = data.get<std::string>();
|
||||
} else {
|
||||
log::warn("Invalid data type loaded from settings for text box!");
|
||||
}
|
||||
}
|
||||
|
||||
nlohmann::json TextBox::store() {
|
||||
return this->m_value;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
|
||||
bool FilePicker::draw(const std::string &name) {
|
||||
bool changed = false;
|
||||
if (ImGui::InputText("##font_path", this->m_value)) {
|
||||
if (ImGui::InputText("##font_path", m_value)) {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
|
@ -353,7 +353,7 @@ namespace hex {
|
|||
if (ImGuiExt::IconButton(ICON_VS_FOLDER_OPENED, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
|
||||
return fs::openFileBrowser(fs::DialogMode::Open, { { "TTF Font", "ttf" }, { "OTF Font", "otf" } },
|
||||
[&](const std::fs::path &path) {
|
||||
this->m_value = wolv::util::toUTF8String(path);
|
||||
m_value = wolv::util::toUTF8String(path);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -366,14 +366,14 @@ namespace hex {
|
|||
|
||||
void FilePicker::load(const nlohmann::json &data) {
|
||||
if (data.is_string()) {
|
||||
this->m_value = data.get<std::string>();
|
||||
m_value = data.get<std::string>();
|
||||
} else {
|
||||
log::warn("Invalid data type loaded from settings for file picker!");
|
||||
}
|
||||
}
|
||||
|
||||
nlohmann::json FilePicker::store() {
|
||||
return this->m_value;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
bool Label::draw(const std::string& name) {
|
||||
|
|
|
|||
|
|
@ -31,13 +31,13 @@ namespace hex {
|
|||
if (value.empty())
|
||||
continue;
|
||||
|
||||
this->m_entries.insert({ key, value });
|
||||
m_entries.insert({ key, value });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::map<std::string, std::string> &LanguageDefinition::getEntries() const {
|
||||
return this->m_entries;
|
||||
return m_entries;
|
||||
}
|
||||
|
||||
void loadLanguage(const std::string &language) {
|
||||
|
|
@ -121,10 +121,10 @@ namespace hex {
|
|||
|
||||
const std::string &Lang::get() const {
|
||||
auto &lang = LocalizationManager::s_currStrings;
|
||||
if (lang.contains(this->m_unlocalizedString))
|
||||
return lang[this->m_unlocalizedString];
|
||||
if (lang.contains(m_unlocalizedString))
|
||||
return lang[m_unlocalizedString];
|
||||
else
|
||||
return this->m_unlocalizedString;
|
||||
return m_unlocalizedString;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -19,73 +19,73 @@ namespace hex {
|
|||
Plugin::Plugin(const std::fs::path &path) : m_path(path) {
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
this->m_handle = uintptr_t(LoadLibraryW(path.c_str()));
|
||||
m_handle = uintptr_t(LoadLibraryW(path.c_str()));
|
||||
|
||||
if (this->m_handle == uintptr_t(INVALID_HANDLE_VALUE) || this->m_handle == 0) {
|
||||
if (m_handle == uintptr_t(INVALID_HANDLE_VALUE) || m_handle == 0) {
|
||||
log::error("LoadLibraryW failed: {}!", std::system_category().message(::GetLastError()));
|
||||
return;
|
||||
}
|
||||
#else
|
||||
this->m_handle = uintptr_t(dlopen(wolv::util::toUTF8String(path).c_str(), RTLD_LAZY));
|
||||
m_handle = uintptr_t(dlopen(wolv::util::toUTF8String(path).c_str(), RTLD_LAZY));
|
||||
|
||||
if (this->m_handle == 0) {
|
||||
if (m_handle == 0) {
|
||||
log::error("dlopen failed: {}!", dlerror());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
this->m_functions.initializePluginFunction = getPluginFunction<PluginFunctions::InitializePluginFunc>("initializePlugin");
|
||||
this->m_functions.getPluginNameFunction = getPluginFunction<PluginFunctions::GetPluginNameFunc>("getPluginName");
|
||||
this->m_functions.getPluginAuthorFunction = getPluginFunction<PluginFunctions::GetPluginAuthorFunc>("getPluginAuthor");
|
||||
this->m_functions.getPluginDescriptionFunction = getPluginFunction<PluginFunctions::GetPluginDescriptionFunc>("getPluginDescription");
|
||||
this->m_functions.getCompatibleVersionFunction = getPluginFunction<PluginFunctions::GetCompatibleVersionFunc>("getCompatibleVersion");
|
||||
this->m_functions.setImGuiContextFunction = getPluginFunction<PluginFunctions::SetImGuiContextFunc>("setImGuiContext");
|
||||
this->m_functions.isBuiltinPluginFunction = getPluginFunction<PluginFunctions::IsBuiltinPluginFunc>("isBuiltinPlugin");
|
||||
this->m_functions.getSubCommandsFunction = getPluginFunction<PluginFunctions::GetSubCommandsFunc>("getSubCommands");
|
||||
m_functions.initializePluginFunction = getPluginFunction<PluginFunctions::InitializePluginFunc>("initializePlugin");
|
||||
m_functions.getPluginNameFunction = getPluginFunction<PluginFunctions::GetPluginNameFunc>("getPluginName");
|
||||
m_functions.getPluginAuthorFunction = getPluginFunction<PluginFunctions::GetPluginAuthorFunc>("getPluginAuthor");
|
||||
m_functions.getPluginDescriptionFunction = getPluginFunction<PluginFunctions::GetPluginDescriptionFunc>("getPluginDescription");
|
||||
m_functions.getCompatibleVersionFunction = getPluginFunction<PluginFunctions::GetCompatibleVersionFunc>("getCompatibleVersion");
|
||||
m_functions.setImGuiContextFunction = getPluginFunction<PluginFunctions::SetImGuiContextFunc>("setImGuiContext");
|
||||
m_functions.isBuiltinPluginFunction = getPluginFunction<PluginFunctions::IsBuiltinPluginFunc>("isBuiltinPlugin");
|
||||
m_functions.getSubCommandsFunction = getPluginFunction<PluginFunctions::GetSubCommandsFunc>("getSubCommands");
|
||||
}
|
||||
|
||||
Plugin::Plugin(hex::PluginFunctions functions) {
|
||||
this->m_handle = 0;
|
||||
this->m_functions = functions;
|
||||
m_handle = 0;
|
||||
m_functions = functions;
|
||||
}
|
||||
|
||||
|
||||
Plugin::Plugin(Plugin &&other) noexcept {
|
||||
this->m_handle = other.m_handle;
|
||||
m_handle = other.m_handle;
|
||||
other.m_handle = 0;
|
||||
|
||||
this->m_path = std::move(other.m_path);
|
||||
m_path = std::move(other.m_path);
|
||||
|
||||
this->m_functions = other.m_functions;
|
||||
m_functions = other.m_functions;
|
||||
other.m_functions = {};
|
||||
}
|
||||
|
||||
Plugin::~Plugin() {
|
||||
#if defined(OS_WINDOWS)
|
||||
if (this->m_handle != 0)
|
||||
FreeLibrary(HMODULE(this->m_handle));
|
||||
if (m_handle != 0)
|
||||
FreeLibrary(HMODULE(m_handle));
|
||||
#else
|
||||
if (this->m_handle != 0)
|
||||
dlclose(reinterpret_cast<void*>(this->m_handle));
|
||||
if (m_handle != 0)
|
||||
dlclose(reinterpret_cast<void*>(m_handle));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Plugin::initializePlugin() const {
|
||||
const auto pluginName = wolv::util::toUTF8String(this->m_path.filename());
|
||||
const auto pluginName = wolv::util::toUTF8String(m_path.filename());
|
||||
|
||||
const auto requestedVersion = getCompatibleVersion();
|
||||
if (requestedVersion != ImHexApi::System::getImHexVersion()) {
|
||||
if (requestedVersion.empty()) {
|
||||
log::warn("Plugin '{}' did not specify a compatible version, assuming it is compatible with the current version of ImHex.", wolv::util::toUTF8String(this->m_path.filename()));
|
||||
log::warn("Plugin '{}' did not specify a compatible version, assuming it is compatible with the current version of ImHex.", wolv::util::toUTF8String(m_path.filename()));
|
||||
} else {
|
||||
log::error("Refused to load plugin '{}' which was built for a different version of ImHex: '{}'", wolv::util::toUTF8String(this->m_path.filename()), requestedVersion);
|
||||
log::error("Refused to load plugin '{}' which was built for a different version of ImHex: '{}'", wolv::util::toUTF8String(m_path.filename()), requestedVersion);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->m_functions.initializePluginFunction != nullptr) {
|
||||
if (m_functions.initializePluginFunction != nullptr) {
|
||||
try {
|
||||
this->m_functions.initializePluginFunction();
|
||||
m_functions.initializePluginFunction();
|
||||
} catch (const std::exception &e) {
|
||||
log::error("Plugin '{}' threw an exception on init: {}", pluginName, e.what());
|
||||
return false;
|
||||
|
|
@ -100,61 +100,61 @@ namespace hex {
|
|||
|
||||
log::info("Plugin '{}' initialized successfully", pluginName);
|
||||
|
||||
this->m_initialized = true;
|
||||
m_initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Plugin::getPluginName() const {
|
||||
if (this->m_functions.getPluginNameFunction != nullptr)
|
||||
return this->m_functions.getPluginNameFunction();
|
||||
if (m_functions.getPluginNameFunction != nullptr)
|
||||
return m_functions.getPluginNameFunction();
|
||||
else
|
||||
return hex::format("Unknown Plugin @ 0x{0:016X}", this->m_handle);
|
||||
return hex::format("Unknown Plugin @ 0x{0:016X}", m_handle);
|
||||
}
|
||||
|
||||
std::string Plugin::getPluginAuthor() const {
|
||||
if (this->m_functions.getPluginAuthorFunction != nullptr)
|
||||
return this->m_functions.getPluginAuthorFunction();
|
||||
if (m_functions.getPluginAuthorFunction != nullptr)
|
||||
return m_functions.getPluginAuthorFunction();
|
||||
else
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
std::string Plugin::getPluginDescription() const {
|
||||
if (this->m_functions.getPluginDescriptionFunction != nullptr)
|
||||
return this->m_functions.getPluginDescriptionFunction();
|
||||
if (m_functions.getPluginDescriptionFunction != nullptr)
|
||||
return m_functions.getPluginDescriptionFunction();
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string Plugin::getCompatibleVersion() const {
|
||||
if (this->m_functions.getCompatibleVersionFunction != nullptr)
|
||||
return this->m_functions.getCompatibleVersionFunction();
|
||||
if (m_functions.getCompatibleVersionFunction != nullptr)
|
||||
return m_functions.getCompatibleVersionFunction();
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
void Plugin::setImGuiContext(ImGuiContext *ctx) const {
|
||||
if (this->m_functions.setImGuiContextFunction != nullptr)
|
||||
this->m_functions.setImGuiContextFunction(ctx);
|
||||
if (m_functions.setImGuiContextFunction != nullptr)
|
||||
m_functions.setImGuiContextFunction(ctx);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool Plugin::isBuiltinPlugin() const {
|
||||
if (this->m_functions.isBuiltinPluginFunction != nullptr)
|
||||
return this->m_functions.isBuiltinPluginFunction();
|
||||
if (m_functions.isBuiltinPluginFunction != nullptr)
|
||||
return m_functions.isBuiltinPluginFunction();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::fs::path &Plugin::getPath() const {
|
||||
return this->m_path;
|
||||
return m_path;
|
||||
}
|
||||
|
||||
bool Plugin::isLoaded() const {
|
||||
return this->m_initialized;
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
std::span<SubCommand> Plugin::getSubCommands() const {
|
||||
if (this->m_functions.getSubCommandsFunction != nullptr) {
|
||||
auto result = this->m_functions.getSubCommandsFunction();
|
||||
if (m_functions.getSubCommandsFunction != nullptr) {
|
||||
auto result = m_functions.getSubCommandsFunction();
|
||||
return *static_cast<std::vector<SubCommand>*>(result);
|
||||
} else
|
||||
return { };
|
||||
|
|
@ -163,9 +163,9 @@ namespace hex {
|
|||
|
||||
void *Plugin::getPluginFunction(const std::string &symbol) const {
|
||||
#if defined(OS_WINDOWS)
|
||||
return reinterpret_cast<void *>(GetProcAddress(HMODULE(this->m_handle), symbol.c_str()));
|
||||
return reinterpret_cast<void *>(GetProcAddress(HMODULE(m_handle), symbol.c_str()));
|
||||
#else
|
||||
return dlsym(reinterpret_cast<void*>(this->m_handle), symbol.c_str());
|
||||
return dlsym(reinterpret_cast<void*>(m_handle), symbol.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,20 +60,20 @@ namespace hex {
|
|||
|
||||
Task::Task(hex::Task &&other) noexcept {
|
||||
{
|
||||
std::scoped_lock thisLock(this->m_mutex);
|
||||
std::scoped_lock thisLock(m_mutex);
|
||||
std::scoped_lock otherLock(other.m_mutex);
|
||||
|
||||
this->m_function = std::move(other.m_function);
|
||||
this->m_unlocalizedName = std::move(other.m_unlocalizedName);
|
||||
m_function = std::move(other.m_function);
|
||||
m_unlocalizedName = std::move(other.m_unlocalizedName);
|
||||
}
|
||||
|
||||
this->m_maxValue = u64(other.m_maxValue);
|
||||
this->m_currValue = u64(other.m_currValue);
|
||||
m_maxValue = u64(other.m_maxValue);
|
||||
m_currValue = u64(other.m_currValue);
|
||||
|
||||
this->m_finished = bool(other.m_finished);
|
||||
this->m_hadException = bool(other.m_hadException);
|
||||
this->m_interrupted = bool(other.m_interrupted);
|
||||
this->m_shouldInterrupt = bool(other.m_shouldInterrupt);
|
||||
m_finished = bool(other.m_finished);
|
||||
m_hadException = bool(other.m_hadException);
|
||||
m_interrupted = bool(other.m_interrupted);
|
||||
m_shouldInterrupt = bool(other.m_shouldInterrupt);
|
||||
}
|
||||
|
||||
Task::~Task() {
|
||||
|
|
@ -83,92 +83,92 @@ namespace hex {
|
|||
|
||||
void Task::update(u64 value) {
|
||||
// Update the current progress value of the task
|
||||
this->m_currValue.store(value, std::memory_order_relaxed);
|
||||
m_currValue.store(value, std::memory_order_relaxed);
|
||||
|
||||
// Check if the task has been interrupted by the main thread and if yes,
|
||||
// throw an exception that is generally not caught by the task
|
||||
if (this->m_shouldInterrupt.load(std::memory_order_relaxed)) [[unlikely]]
|
||||
if (m_shouldInterrupt.load(std::memory_order_relaxed)) [[unlikely]]
|
||||
throw TaskInterruptor();
|
||||
}
|
||||
|
||||
void Task::setMaxValue(u64 value) {
|
||||
this->m_maxValue = value;
|
||||
m_maxValue = value;
|
||||
}
|
||||
|
||||
|
||||
void Task::interrupt() {
|
||||
this->m_shouldInterrupt = true;
|
||||
m_shouldInterrupt = true;
|
||||
|
||||
// Call the interrupt callback on the current thread if one is set
|
||||
if (this->m_interruptCallback)
|
||||
this->m_interruptCallback();
|
||||
if (m_interruptCallback)
|
||||
m_interruptCallback();
|
||||
}
|
||||
|
||||
void Task::setInterruptCallback(std::function<void()> callback) {
|
||||
this->m_interruptCallback = std::move(callback);
|
||||
m_interruptCallback = std::move(callback);
|
||||
}
|
||||
|
||||
bool Task::isBackgroundTask() const {
|
||||
return this->m_background;
|
||||
return m_background;
|
||||
}
|
||||
|
||||
bool Task::isFinished() const {
|
||||
return this->m_finished;
|
||||
return m_finished;
|
||||
}
|
||||
|
||||
bool Task::hadException() const {
|
||||
return this->m_hadException;
|
||||
return m_hadException;
|
||||
}
|
||||
|
||||
bool Task::shouldInterrupt() const {
|
||||
return this->m_shouldInterrupt;
|
||||
return m_shouldInterrupt;
|
||||
}
|
||||
|
||||
bool Task::wasInterrupted() const {
|
||||
return this->m_interrupted;
|
||||
return m_interrupted;
|
||||
}
|
||||
|
||||
void Task::clearException() {
|
||||
this->m_hadException = false;
|
||||
m_hadException = false;
|
||||
}
|
||||
|
||||
std::string Task::getExceptionMessage() const {
|
||||
std::scoped_lock lock(this->m_mutex);
|
||||
std::scoped_lock lock(m_mutex);
|
||||
|
||||
return this->m_exceptionMessage;
|
||||
return m_exceptionMessage;
|
||||
}
|
||||
|
||||
const UnlocalizedString &Task::getUnlocalizedName() {
|
||||
return this->m_unlocalizedName;
|
||||
return m_unlocalizedName;
|
||||
}
|
||||
|
||||
u64 Task::getValue() const {
|
||||
return this->m_currValue;
|
||||
return m_currValue;
|
||||
}
|
||||
|
||||
u64 Task::getMaxValue() const {
|
||||
return this->m_maxValue;
|
||||
return m_maxValue;
|
||||
}
|
||||
|
||||
void Task::finish() {
|
||||
this->m_finished = true;
|
||||
m_finished = true;
|
||||
}
|
||||
|
||||
void Task::interruption() {
|
||||
this->m_interrupted = true;
|
||||
m_interrupted = true;
|
||||
}
|
||||
|
||||
void Task::exception(const char *message) {
|
||||
std::scoped_lock lock(this->m_mutex);
|
||||
std::scoped_lock lock(m_mutex);
|
||||
|
||||
// Store information about the caught exception
|
||||
this->m_exceptionMessage = message;
|
||||
this->m_hadException = true;
|
||||
m_exceptionMessage = message;
|
||||
m_hadException = true;
|
||||
}
|
||||
|
||||
|
||||
bool TaskHolder::isRunning() const {
|
||||
auto task = this->m_task.lock();
|
||||
auto task = m_task.lock();
|
||||
if (!task)
|
||||
return false;
|
||||
|
||||
|
|
@ -176,7 +176,7 @@ namespace hex {
|
|||
}
|
||||
|
||||
bool TaskHolder::hadException() const {
|
||||
auto task = this->m_task.lock();
|
||||
auto task = m_task.lock();
|
||||
if (!task)
|
||||
return false;
|
||||
|
||||
|
|
@ -184,7 +184,7 @@ namespace hex {
|
|||
}
|
||||
|
||||
bool TaskHolder::shouldInterrupt() const {
|
||||
auto task = this->m_task.lock();
|
||||
auto task = m_task.lock();
|
||||
if (!task)
|
||||
return false;
|
||||
|
||||
|
|
@ -192,7 +192,7 @@ namespace hex {
|
|||
}
|
||||
|
||||
bool TaskHolder::wasInterrupted() const {
|
||||
auto task = this->m_task.lock();
|
||||
auto task = m_task.lock();
|
||||
if (!task)
|
||||
return false;
|
||||
|
||||
|
|
@ -200,7 +200,7 @@ namespace hex {
|
|||
}
|
||||
|
||||
void TaskHolder::interrupt() const {
|
||||
auto task = this->m_task.lock();
|
||||
auto task = m_task.lock();
|
||||
if (!task)
|
||||
return;
|
||||
|
||||
|
|
@ -208,7 +208,7 @@ namespace hex {
|
|||
}
|
||||
|
||||
u32 TaskHolder::getProgress() const {
|
||||
auto task = this->m_task.lock();
|
||||
auto task = m_task.lock();
|
||||
if (!task)
|
||||
return false;
|
||||
|
||||
|
|
|
|||
|
|
@ -217,16 +217,16 @@ namespace hex {
|
|||
}
|
||||
|
||||
TutorialManager::Tutorial::Step& TutorialManager::Tutorial::addStep() {
|
||||
auto &newStep = this->m_steps.emplace_back(this);
|
||||
this->m_currentStep = this->m_steps.end();
|
||||
this->m_latestStep = this->m_currentStep;
|
||||
auto &newStep = m_steps.emplace_back(this);
|
||||
m_currentStep = m_steps.end();
|
||||
m_latestStep = m_currentStep;
|
||||
|
||||
return newStep;
|
||||
}
|
||||
|
||||
void TutorialManager::Tutorial::start() {
|
||||
this->m_currentStep = m_steps.begin();
|
||||
this->m_latestStep = this->m_currentStep;
|
||||
m_currentStep = m_steps.begin();
|
||||
m_latestStep = m_currentStep;
|
||||
if (m_currentStep == m_steps.end())
|
||||
return;
|
||||
|
||||
|
|
@ -234,10 +234,10 @@ namespace hex {
|
|||
}
|
||||
|
||||
void TutorialManager::Tutorial::Step::addHighlights() const {
|
||||
if (this->m_onAppear)
|
||||
this->m_onAppear();
|
||||
if (m_onAppear)
|
||||
m_onAppear();
|
||||
|
||||
for (const auto &[text, ids] : this->m_highlights) {
|
||||
for (const auto &[text, ids] : m_highlights) {
|
||||
IDStack idStack;
|
||||
|
||||
for (const auto &id : ids) {
|
||||
|
|
@ -256,7 +256,7 @@ namespace hex {
|
|||
}
|
||||
|
||||
void TutorialManager::Tutorial::Step::removeHighlights() const {
|
||||
for (const auto &[text, ids] : this->m_highlights) {
|
||||
for (const auto &[text, ids] : m_highlights) {
|
||||
IDStack idStack;
|
||||
|
||||
for (const auto &id : ids) {
|
||||
|
|
@ -289,7 +289,7 @@ namespace hex {
|
|||
|
||||
|
||||
TutorialManager::Tutorial::Step& TutorialManager::Tutorial::Step::addHighlight(const UnlocalizedString &unlocalizedText, std::initializer_list<std::variant<Lang, std::string, int>>&& ids) {
|
||||
this->m_highlights.emplace_back(
|
||||
m_highlights.emplace_back(
|
||||
unlocalizedText,
|
||||
ids
|
||||
);
|
||||
|
|
@ -304,7 +304,7 @@ namespace hex {
|
|||
|
||||
|
||||
TutorialManager::Tutorial::Step& TutorialManager::Tutorial::Step::setMessage(const UnlocalizedString &unlocalizedTitle, const UnlocalizedString &unlocalizedMessage, Position position) {
|
||||
this->m_message = Message {
|
||||
m_message = Message {
|
||||
position,
|
||||
unlocalizedTitle,
|
||||
unlocalizedMessage,
|
||||
|
|
@ -315,10 +315,10 @@ namespace hex {
|
|||
}
|
||||
|
||||
TutorialManager::Tutorial::Step& TutorialManager::Tutorial::Step::allowSkip() {
|
||||
if (this->m_message.has_value()) {
|
||||
this->m_message->allowSkip = true;
|
||||
if (m_message.has_value()) {
|
||||
m_message->allowSkip = true;
|
||||
} else {
|
||||
this->m_message = Message {
|
||||
m_message = Message {
|
||||
Position::Bottom | Position::Right,
|
||||
"",
|
||||
"",
|
||||
|
|
@ -330,13 +330,13 @@ namespace hex {
|
|||
}
|
||||
|
||||
TutorialManager::Tutorial::Step& TutorialManager::Tutorial::Step::onAppear(std::function<void()> callback) {
|
||||
this->m_onAppear = std::move(callback);
|
||||
m_onAppear = std::move(callback);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
TutorialManager::Tutorial::Step& TutorialManager::Tutorial::Step::onComplete(std::function<void()> callback) {
|
||||
this->m_onComplete = std::move(callback);
|
||||
m_onComplete = std::move(callback);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -345,9 +345,9 @@ namespace hex {
|
|||
|
||||
|
||||
bool TutorialManager::Tutorial::Step::isCurrent() const {
|
||||
const auto ¤tStep = this->m_parent->m_currentStep;
|
||||
const auto ¤tStep = m_parent->m_currentStep;
|
||||
|
||||
if (currentStep == this->m_parent->m_steps.end())
|
||||
if (currentStep == m_parent->m_steps.end())
|
||||
return false;
|
||||
|
||||
return &*currentStep == this;
|
||||
|
|
@ -357,9 +357,9 @@ namespace hex {
|
|||
if (this->isCurrent()) {
|
||||
this->advance();
|
||||
|
||||
if (this->m_onComplete) {
|
||||
if (m_onComplete) {
|
||||
TaskManager::doLater([this] {
|
||||
this->m_onComplete();
|
||||
m_onComplete();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace hex::dp {
|
|||
int Node::s_idCounter = 1;
|
||||
|
||||
Node::Node(UnlocalizedString unlocalizedTitle, std::vector<Attribute> attributes) : m_id(s_idCounter++), m_unlocalizedTitle(std::move(unlocalizedTitle)), m_attributes(std::move(attributes)) {
|
||||
for (auto &attr : this->m_attributes)
|
||||
for (auto &attr : m_attributes)
|
||||
attr.setParentNode(this);
|
||||
}
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ namespace hex::dp {
|
|||
auto attribute = this->getConnectedInputAttribute(index);
|
||||
|
||||
if (attribute == nullptr)
|
||||
throwNodeError(hex::format("Nothing connected to input '{0}'", Lang(this->m_attributes[index].getUnlocalizedName())));
|
||||
throwNodeError(hex::format("Nothing connected to input '{0}'", Lang(m_attributes[index].getUnlocalizedName())));
|
||||
|
||||
if (attribute->getType() != Attribute::Type::Buffer)
|
||||
throwNodeError("Tried to read buffer from non-buffer attribute");
|
||||
|
|
@ -141,11 +141,11 @@ namespace hex::dp {
|
|||
}
|
||||
|
||||
void Node::setOverlayData(u64 address, const std::vector<u8> &data) {
|
||||
if (this->m_overlay == nullptr)
|
||||
if (m_overlay == nullptr)
|
||||
throwNodeError("Tried setting overlay data on a node that's not the end of a chain!");
|
||||
|
||||
this->m_overlay->setAddress(address);
|
||||
this->m_overlay->getData() = data;
|
||||
m_overlay->setAddress(address);
|
||||
m_overlay->getData() = data;
|
||||
}
|
||||
|
||||
void Node::setIdCounter(int id) {
|
||||
|
|
|
|||
|
|
@ -110,27 +110,27 @@ namespace hex::crypt {
|
|||
}
|
||||
|
||||
constexpr void reset() {
|
||||
this->m_value = reflect(m_init, NumBits);
|
||||
m_value = reflect(m_init, NumBits);
|
||||
}
|
||||
|
||||
constexpr void processBytes(const unsigned char *data, std::size_t size) {
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
u8 byte;
|
||||
if (this->m_reflectInput)
|
||||
if (m_reflectInput)
|
||||
byte = data[i];
|
||||
else
|
||||
byte = reflect(data[i]);
|
||||
|
||||
this->m_value = this->m_table[(this->m_value ^ byte) & 0xFFL] ^ (this->m_value >> 8);
|
||||
m_value = m_table[(m_value ^ byte) & 0xFFL] ^ (m_value >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr u64 checksum() const {
|
||||
if (this->m_reflectOutput)
|
||||
return this->m_value ^ m_xorOut;
|
||||
if (m_reflectOutput)
|
||||
return m_value ^ m_xorOut;
|
||||
else
|
||||
return reflect(this->m_value, NumBits) ^ m_xorOut;
|
||||
return reflect(m_value, NumBits) ^ m_xorOut;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -12,19 +12,19 @@ namespace hex {
|
|||
}
|
||||
|
||||
EncodingFile::EncodingFile(const hex::EncodingFile &other) {
|
||||
this->m_mapping = std::make_unique<std::map<size_t, std::map<std::vector<u8>, std::string>>>(*other.m_mapping);
|
||||
this->m_tableContent = other.m_tableContent;
|
||||
this->m_longestSequence = other.m_longestSequence;
|
||||
this->m_valid = other.m_valid;
|
||||
this->m_name = other.m_name;
|
||||
m_mapping = std::make_unique<std::map<size_t, std::map<std::vector<u8>, std::string>>>(*other.m_mapping);
|
||||
m_tableContent = other.m_tableContent;
|
||||
m_longestSequence = other.m_longestSequence;
|
||||
m_valid = other.m_valid;
|
||||
m_name = other.m_name;
|
||||
}
|
||||
|
||||
EncodingFile::EncodingFile(EncodingFile &&other) noexcept {
|
||||
this->m_mapping = std::move(other.m_mapping);
|
||||
this->m_tableContent = std::move(other.m_tableContent);
|
||||
this->m_longestSequence = other.m_longestSequence;
|
||||
this->m_valid = other.m_valid;
|
||||
this->m_name = std::move(other.m_name);
|
||||
m_mapping = std::move(other.m_mapping);
|
||||
m_tableContent = std::move(other.m_tableContent);
|
||||
m_longestSequence = other.m_longestSequence;
|
||||
m_valid = other.m_valid;
|
||||
m_name = std::move(other.m_name);
|
||||
}
|
||||
|
||||
EncodingFile::EncodingFile(Type type, const std::fs::path &path) : EncodingFile() {
|
||||
|
|
@ -38,14 +38,14 @@ namespace hex {
|
|||
}
|
||||
|
||||
{
|
||||
this->m_name = path.stem().string();
|
||||
this->m_name = wolv::util::replaceStrings(this->m_name, "_", " ");
|
||||
m_name = path.stem().string();
|
||||
m_name = wolv::util::replaceStrings(m_name, "_", " ");
|
||||
|
||||
if (!this->m_name.empty())
|
||||
this->m_name[0] = std::toupper(this->m_name[0]);
|
||||
if (!m_name.empty())
|
||||
m_name[0] = std::toupper(m_name[0]);
|
||||
}
|
||||
|
||||
this->m_valid = true;
|
||||
m_valid = true;
|
||||
}
|
||||
|
||||
EncodingFile::EncodingFile(Type type, const std::string &content) : EncodingFile() {
|
||||
|
|
@ -57,27 +57,27 @@ namespace hex {
|
|||
return;
|
||||
}
|
||||
|
||||
this->m_name = "Unknown";
|
||||
this->m_valid = true;
|
||||
m_name = "Unknown";
|
||||
m_valid = true;
|
||||
}
|
||||
|
||||
|
||||
EncodingFile &EncodingFile::operator=(const hex::EncodingFile &other) {
|
||||
this->m_mapping = std::make_unique<std::map<size_t, std::map<std::vector<u8>, std::string>>>(*other.m_mapping);
|
||||
this->m_tableContent = other.m_tableContent;
|
||||
this->m_longestSequence = other.m_longestSequence;
|
||||
this->m_valid = other.m_valid;
|
||||
this->m_name = other.m_name;
|
||||
m_mapping = std::make_unique<std::map<size_t, std::map<std::vector<u8>, std::string>>>(*other.m_mapping);
|
||||
m_tableContent = other.m_tableContent;
|
||||
m_longestSequence = other.m_longestSequence;
|
||||
m_valid = other.m_valid;
|
||||
m_name = other.m_name;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
EncodingFile &EncodingFile::operator=(EncodingFile &&other) noexcept {
|
||||
this->m_mapping = std::move(other.m_mapping);
|
||||
this->m_tableContent = std::move(other.m_tableContent);
|
||||
this->m_longestSequence = other.m_longestSequence;
|
||||
this->m_valid = other.m_valid;
|
||||
this->m_name = std::move(other.m_name);
|
||||
m_mapping = std::move(other.m_mapping);
|
||||
m_tableContent = std::move(other.m_tableContent);
|
||||
m_longestSequence = other.m_longestSequence;
|
||||
m_valid = other.m_valid;
|
||||
m_name = std::move(other.m_name);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -85,7 +85,7 @@ namespace hex {
|
|||
|
||||
|
||||
std::pair<std::string_view, size_t> EncodingFile::getEncodingFor(std::span<u8> buffer) const {
|
||||
for (auto riter = this->m_mapping->crbegin(); riter != this->m_mapping->crend(); ++riter) {
|
||||
for (auto riter = m_mapping->crbegin(); riter != m_mapping->crend(); ++riter) {
|
||||
const auto &[size, mapping] = *riter;
|
||||
|
||||
if (size > buffer.size()) continue;
|
||||
|
|
@ -99,7 +99,7 @@ namespace hex {
|
|||
}
|
||||
|
||||
size_t EncodingFile::getEncodingLengthFor(std::span<u8> buffer) const {
|
||||
for (auto riter = this->m_mapping->crbegin(); riter != this->m_mapping->crend(); ++riter) {
|
||||
for (auto riter = m_mapping->crbegin(); riter != m_mapping->crend(); ++riter) {
|
||||
const auto &[size, mapping] = *riter;
|
||||
|
||||
if (size > buffer.size()) continue;
|
||||
|
|
@ -113,8 +113,8 @@ namespace hex {
|
|||
}
|
||||
|
||||
void EncodingFile::parse(const std::string &content) {
|
||||
this->m_tableContent = content;
|
||||
for (const auto &line : splitString(this->m_tableContent, "\n")) {
|
||||
m_tableContent = content;
|
||||
for (const auto &line : splitString(m_tableContent, "\n")) {
|
||||
|
||||
std::string from, to;
|
||||
{
|
||||
|
|
@ -137,13 +137,13 @@ namespace hex {
|
|||
if (to.empty())
|
||||
to = " ";
|
||||
|
||||
if (!this->m_mapping->contains(fromBytes.size()))
|
||||
this->m_mapping->insert({ fromBytes.size(), {} });
|
||||
if (!m_mapping->contains(fromBytes.size()))
|
||||
m_mapping->insert({ fromBytes.size(), {} });
|
||||
|
||||
auto keySize = fromBytes.size();
|
||||
(*this->m_mapping)[keySize].insert({ std::move(fromBytes), to });
|
||||
(*m_mapping)[keySize].insert({ std::move(fromBytes), to });
|
||||
|
||||
this->m_longestSequence = std::max(this->m_longestSequence, keySize);
|
||||
m_longestSequence = std::max(m_longestSequence, keySize);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,25 +5,25 @@
|
|||
namespace hex {
|
||||
|
||||
HttpRequest::HttpRequest(std::string method, std::string url) : m_method(std::move(method)), m_url(std::move(url)) {
|
||||
emscripten_fetch_attr_init(&this->m_attr);
|
||||
emscripten_fetch_attr_init(&m_attr);
|
||||
}
|
||||
|
||||
HttpRequest::HttpRequest(HttpRequest &&other) noexcept {
|
||||
this->m_attr = other.m_attr;
|
||||
m_attr = other.m_attr;
|
||||
|
||||
this->m_method = std::move(other.m_method);
|
||||
this->m_url = std::move(other.m_url);
|
||||
this->m_headers = std::move(other.m_headers);
|
||||
this->m_body = std::move(other.m_body);
|
||||
m_method = std::move(other.m_method);
|
||||
m_url = std::move(other.m_url);
|
||||
m_headers = std::move(other.m_headers);
|
||||
m_body = std::move(other.m_body);
|
||||
}
|
||||
|
||||
HttpRequest& HttpRequest::operator=(HttpRequest &&other) noexcept {
|
||||
this->m_attr = other.m_attr;
|
||||
m_attr = other.m_attr;
|
||||
|
||||
this->m_method = std::move(other.m_method);
|
||||
this->m_url = std::move(other.m_url);
|
||||
this->m_headers = std::move(other.m_headers);
|
||||
this->m_body = std::move(other.m_body);
|
||||
m_method = std::move(other.m_method);
|
||||
m_url = std::move(other.m_url);
|
||||
m_headers = std::move(other.m_headers);
|
||||
m_body = std::move(other.m_body);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,60 +20,60 @@ namespace hex {
|
|||
curl_global_cleanup();
|
||||
};
|
||||
|
||||
this->m_curl = curl_easy_init();
|
||||
m_curl = curl_easy_init();
|
||||
}
|
||||
|
||||
HttpRequest::~HttpRequest() {
|
||||
curl_easy_cleanup(this->m_curl);
|
||||
curl_easy_cleanup(m_curl);
|
||||
}
|
||||
|
||||
HttpRequest::HttpRequest(HttpRequest &&other) noexcept {
|
||||
this->m_curl = other.m_curl;
|
||||
m_curl = other.m_curl;
|
||||
other.m_curl = nullptr;
|
||||
|
||||
this->m_method = std::move(other.m_method);
|
||||
this->m_url = std::move(other.m_url);
|
||||
this->m_headers = std::move(other.m_headers);
|
||||
this->m_body = std::move(other.m_body);
|
||||
m_method = std::move(other.m_method);
|
||||
m_url = std::move(other.m_url);
|
||||
m_headers = std::move(other.m_headers);
|
||||
m_body = std::move(other.m_body);
|
||||
}
|
||||
|
||||
HttpRequest& HttpRequest::operator=(HttpRequest &&other) noexcept {
|
||||
this->m_curl = other.m_curl;
|
||||
m_curl = other.m_curl;
|
||||
other.m_curl = nullptr;
|
||||
|
||||
this->m_method = std::move(other.m_method);
|
||||
this->m_url = std::move(other.m_url);
|
||||
this->m_headers = std::move(other.m_headers);
|
||||
this->m_body = std::move(other.m_body);
|
||||
m_method = std::move(other.m_method);
|
||||
m_url = std::move(other.m_url);
|
||||
m_headers = std::move(other.m_headers);
|
||||
m_body = std::move(other.m_body);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void HttpRequest::setDefaultConfig() {
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_USERAGENT, "ImHex/1.0");
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_DEFAULT_PROTOCOL, "https");
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_SSL_VERIFYPEER, 1L);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_SSL_VERIFYHOST, 2L);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_TIMEOUT_MS, 0L);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_CONNECTTIMEOUT_MS, this->m_timeout);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_NOSIGNAL, 1L);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_XFERINFODATA, this);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_XFERINFOFUNCTION, progressCallback);
|
||||
curl_easy_setopt(m_curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
|
||||
curl_easy_setopt(m_curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
|
||||
curl_easy_setopt(m_curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(m_curl, CURLOPT_USERAGENT, "ImHex/1.0");
|
||||
curl_easy_setopt(m_curl, CURLOPT_DEFAULT_PROTOCOL, "https");
|
||||
curl_easy_setopt(m_curl, CURLOPT_SSL_VERIFYPEER, 1L);
|
||||
curl_easy_setopt(m_curl, CURLOPT_SSL_VERIFYHOST, 2L);
|
||||
curl_easy_setopt(m_curl, CURLOPT_TIMEOUT_MS, 0L);
|
||||
curl_easy_setopt(m_curl, CURLOPT_CONNECTTIMEOUT_MS, m_timeout);
|
||||
curl_easy_setopt(m_curl, CURLOPT_NOSIGNAL, 1L);
|
||||
curl_easy_setopt(m_curl, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(m_curl, CURLOPT_XFERINFODATA, this);
|
||||
curl_easy_setopt(m_curl, CURLOPT_XFERINFOFUNCTION, progressCallback);
|
||||
|
||||
if (s_proxyState)
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_PROXY, s_proxyUrl.c_str());
|
||||
curl_easy_setopt(m_curl, CURLOPT_PROXY, s_proxyUrl.c_str());
|
||||
}
|
||||
|
||||
std::future<HttpRequest::Result<std::vector<u8>>> HttpRequest::downloadFile() {
|
||||
return std::async(std::launch::async, [this] {
|
||||
std::vector<u8> response;
|
||||
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEDATA, &response);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &response);
|
||||
|
||||
return this->executeImpl<std::vector<u8>>(response);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -69,39 +69,39 @@ namespace hex::gl {
|
|||
|
||||
ON_SCOPE_EXIT { glDeleteShader(vertexShader); glDeleteShader(fragmentShader); };
|
||||
|
||||
this->m_program = glCreateProgram();
|
||||
m_program = glCreateProgram();
|
||||
|
||||
glAttachShader(this->m_program, vertexShader);
|
||||
glAttachShader(this->m_program, fragmentShader);
|
||||
glLinkProgram(this->m_program);
|
||||
glAttachShader(m_program, vertexShader);
|
||||
glAttachShader(m_program, fragmentShader);
|
||||
glLinkProgram(m_program);
|
||||
|
||||
int result = false;
|
||||
glGetProgramiv(this->m_program, GL_LINK_STATUS, &result);
|
||||
glGetProgramiv(m_program, GL_LINK_STATUS, &result);
|
||||
if (!result) {
|
||||
std::vector<char> log(512);
|
||||
glGetShaderInfoLog(this->m_program, log.size(), nullptr, log.data());
|
||||
glGetShaderInfoLog(m_program, log.size(), nullptr, log.data());
|
||||
log::error("Failed to link shader: {}", log.data());
|
||||
}
|
||||
}
|
||||
|
||||
Shader::~Shader() {
|
||||
if (this->m_program != 0)
|
||||
glDeleteProgram(this->m_program);
|
||||
if (m_program != 0)
|
||||
glDeleteProgram(m_program);
|
||||
}
|
||||
|
||||
Shader::Shader(Shader &&other) noexcept {
|
||||
this->m_program = other.m_program;
|
||||
m_program = other.m_program;
|
||||
other.m_program = 0;
|
||||
}
|
||||
|
||||
Shader& Shader::operator=(Shader &&other) noexcept {
|
||||
this->m_program = other.m_program;
|
||||
m_program = other.m_program;
|
||||
other.m_program = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Shader::bind() const {
|
||||
glUseProgram(this->m_program);
|
||||
glUseProgram(m_program);
|
||||
}
|
||||
|
||||
void Shader::unbind() const {
|
||||
|
|
@ -118,16 +118,16 @@ namespace hex::gl {
|
|||
|
||||
|
||||
GLint Shader::getUniformLocation(std::string_view name) {
|
||||
auto uniform = this->m_uniforms.find(name.data());
|
||||
if (uniform == this->m_uniforms.end()) {
|
||||
auto location = glGetUniformLocation(this->m_program, name.data());
|
||||
auto uniform = m_uniforms.find(name.data());
|
||||
if (uniform == m_uniforms.end()) {
|
||||
auto location = glGetUniformLocation(m_program, name.data());
|
||||
if (location == -1) {
|
||||
log::warn("Uniform '{}' not found in shader", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
this->m_uniforms[name.data()] = location;
|
||||
uniform = this->m_uniforms.find(name.data());
|
||||
m_uniforms[name.data()] = location;
|
||||
uniform = m_uniforms.find(name.data());
|
||||
}
|
||||
|
||||
return uniform->second;
|
||||
|
|
@ -151,66 +151,66 @@ namespace hex::gl {
|
|||
|
||||
template<typename T>
|
||||
Buffer<T>::Buffer(BufferType type, std::span<const T> data) : m_size(data.size()), m_type(GLuint(type)) {
|
||||
glGenBuffers(1, &this->m_buffer);
|
||||
glBindBuffer(this->m_type, this->m_buffer);
|
||||
glBufferData(this->m_type, data.size_bytes(), data.data(), GL_STATIC_DRAW);
|
||||
glBindBuffer(this->m_type, 0);
|
||||
glGenBuffers(1, &m_buffer);
|
||||
glBindBuffer(m_type, m_buffer);
|
||||
glBufferData(m_type, data.size_bytes(), data.data(), GL_STATIC_DRAW);
|
||||
glBindBuffer(m_type, 0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Buffer<T>::~Buffer() {
|
||||
glDeleteBuffers(1, &this->m_buffer);
|
||||
glDeleteBuffers(1, &m_buffer);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Buffer<T>::Buffer(Buffer &&other) noexcept {
|
||||
this->m_buffer = other.m_buffer;
|
||||
this->m_size = other.m_size;
|
||||
this->m_type = other.m_type;
|
||||
m_buffer = other.m_buffer;
|
||||
m_size = other.m_size;
|
||||
m_type = other.m_type;
|
||||
other.m_buffer = -1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Buffer<T>& Buffer<T>::operator=(Buffer &&other) noexcept {
|
||||
this->m_buffer = other.m_buffer;
|
||||
this->m_size = other.m_size;
|
||||
this->m_type = other.m_type;
|
||||
m_buffer = other.m_buffer;
|
||||
m_size = other.m_size;
|
||||
m_type = other.m_type;
|
||||
other.m_buffer = -1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Buffer<T>::bind() const {
|
||||
glBindBuffer(this->m_type, this->m_buffer);
|
||||
glBindBuffer(m_type, m_buffer);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Buffer<T>::unbind() const {
|
||||
glBindBuffer(this->m_type, 0);
|
||||
glBindBuffer(m_type, 0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
size_t Buffer<T>::getSize() const {
|
||||
return this->m_size;
|
||||
return m_size;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Buffer<T>::draw(unsigned primitive) const {
|
||||
switch (this->m_type) {
|
||||
switch (m_type) {
|
||||
case GL_ARRAY_BUFFER:
|
||||
glDrawArrays(primitive, 0, this->m_size);
|
||||
glDrawArrays(primitive, 0, m_size);
|
||||
break;
|
||||
case GL_ELEMENT_ARRAY_BUFFER:
|
||||
glDrawElements(primitive, this->m_size, impl::getType<T>(), nullptr);
|
||||
glDrawElements(primitive, m_size, impl::getType<T>(), nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Buffer<T>::update(std::span<const T> data) {
|
||||
glBindBuffer(this->m_type, this->m_buffer);
|
||||
glBufferSubData(this->m_type, 0, data.size_bytes(), data.data());
|
||||
glBindBuffer(this->m_type, 0);
|
||||
glBindBuffer(m_type, m_buffer);
|
||||
glBufferSubData(m_type, 0, data.size_bytes(), data.data());
|
||||
glBindBuffer(m_type, 0);
|
||||
}
|
||||
|
||||
template class Buffer<float>;
|
||||
|
|
@ -219,26 +219,26 @@ namespace hex::gl {
|
|||
template class Buffer<u8>;
|
||||
|
||||
VertexArray::VertexArray() {
|
||||
glGenVertexArrays(1, &this->m_array);
|
||||
glGenVertexArrays(1, &m_array);
|
||||
}
|
||||
|
||||
VertexArray::~VertexArray() {
|
||||
glDeleteVertexArrays(1, &this->m_array);
|
||||
glDeleteVertexArrays(1, &m_array);
|
||||
}
|
||||
|
||||
VertexArray::VertexArray(VertexArray &&other) noexcept {
|
||||
this->m_array = other.m_array;
|
||||
m_array = other.m_array;
|
||||
other.m_array = -1;
|
||||
}
|
||||
|
||||
VertexArray& VertexArray::operator=(VertexArray &&other) noexcept {
|
||||
this->m_array = other.m_array;
|
||||
m_array = other.m_array;
|
||||
other.m_array = -1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void VertexArray::bind() const {
|
||||
glBindVertexArray(this->m_array);
|
||||
glBindVertexArray(m_array);
|
||||
}
|
||||
|
||||
void VertexArray::unbind() const {
|
||||
|
|
@ -247,8 +247,8 @@ namespace hex::gl {
|
|||
|
||||
|
||||
Texture::Texture(u32 width, u32 height) : m_texture(0), m_width(width), m_height(height) {
|
||||
glGenTextures(1, &this->m_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, this->m_texture);
|
||||
glGenTextures(1, &m_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
|
||||
|
|
@ -259,26 +259,26 @@ namespace hex::gl {
|
|||
}
|
||||
|
||||
Texture::~Texture() {
|
||||
if (this->m_texture != 0)
|
||||
glDeleteTextures(1, &this->m_texture);
|
||||
if (m_texture != 0)
|
||||
glDeleteTextures(1, &m_texture);
|
||||
}
|
||||
|
||||
Texture::Texture(Texture &&other) noexcept {
|
||||
this->m_texture = other.m_texture;
|
||||
m_texture = other.m_texture;
|
||||
other.m_texture = -1;
|
||||
|
||||
this->m_width = other.m_width;
|
||||
this->m_height = other.m_height;
|
||||
m_width = other.m_width;
|
||||
m_height = other.m_height;
|
||||
}
|
||||
|
||||
Texture& Texture::operator=(Texture &&other) noexcept {
|
||||
this->m_texture = other.m_texture;
|
||||
m_texture = other.m_texture;
|
||||
other.m_texture = -1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Texture::bind() const {
|
||||
glBindTexture(GL_TEXTURE_2D, this->m_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
}
|
||||
|
||||
void Texture::unbind() const {
|
||||
|
|
@ -286,59 +286,59 @@ namespace hex::gl {
|
|||
}
|
||||
|
||||
GLuint Texture::getTexture() const {
|
||||
return this->m_texture;
|
||||
return m_texture;
|
||||
}
|
||||
|
||||
u32 Texture::getWidth() const {
|
||||
return this->m_width;
|
||||
return m_width;
|
||||
}
|
||||
|
||||
u32 Texture::getHeight() const {
|
||||
return this->m_height;
|
||||
return m_height;
|
||||
}
|
||||
|
||||
GLuint Texture::release() {
|
||||
auto copy = this->m_texture;
|
||||
this->m_texture = -1;
|
||||
auto copy = m_texture;
|
||||
m_texture = -1;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
FrameBuffer::FrameBuffer(u32 width, u32 height) {
|
||||
glGenFramebuffers(1, &this->m_frameBuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, this->m_frameBuffer);
|
||||
glGenFramebuffers(1, &m_frameBuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_frameBuffer);
|
||||
|
||||
glGenRenderbuffers(1, &this->m_renderBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, this->m_renderBuffer);
|
||||
glGenRenderbuffers(1, &m_renderBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_renderBuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, this->m_renderBuffer);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_renderBuffer);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
FrameBuffer::~FrameBuffer() {
|
||||
glDeleteFramebuffers(1, &this->m_frameBuffer);
|
||||
glDeleteRenderbuffers(1, &this->m_renderBuffer);
|
||||
glDeleteFramebuffers(1, &m_frameBuffer);
|
||||
glDeleteRenderbuffers(1, &m_renderBuffer);
|
||||
}
|
||||
|
||||
FrameBuffer::FrameBuffer(FrameBuffer &&other) noexcept {
|
||||
this->m_frameBuffer = other.m_frameBuffer;
|
||||
m_frameBuffer = other.m_frameBuffer;
|
||||
other.m_frameBuffer = -1;
|
||||
this->m_renderBuffer = other.m_renderBuffer;
|
||||
m_renderBuffer = other.m_renderBuffer;
|
||||
other.m_renderBuffer = -1;
|
||||
}
|
||||
|
||||
FrameBuffer& FrameBuffer::operator=(FrameBuffer &&other) noexcept {
|
||||
this->m_frameBuffer = other.m_frameBuffer;
|
||||
m_frameBuffer = other.m_frameBuffer;
|
||||
other.m_frameBuffer = -1;
|
||||
this->m_renderBuffer = other.m_renderBuffer;
|
||||
m_renderBuffer = other.m_renderBuffer;
|
||||
other.m_renderBuffer = -1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void FrameBuffer::bind() const {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, this->m_frameBuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_frameBuffer);
|
||||
}
|
||||
|
||||
void FrameBuffer::unbind() const {
|
||||
|
|
@ -346,7 +346,7 @@ namespace hex::gl {
|
|||
}
|
||||
|
||||
void FrameBuffer::attachTexture(const Texture &texture) const {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, this->m_frameBuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_frameBuffer);
|
||||
texture.bind();
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.getTexture(), 0);
|
||||
|
|
|
|||
|
|
@ -33,14 +33,14 @@ namespace hex {
|
|||
|
||||
void writeRaw(u64 offset, const void *buffer, size_t size) override {
|
||||
for (u64 i = 0; i < size; i += 1)
|
||||
this->m_patches[offset] = static_cast<const u8*>(buffer)[i];
|
||||
m_patches[offset] = static_cast<const u8*>(buffer)[i];
|
||||
}
|
||||
|
||||
[[nodiscard]] u64 getActualSize() const override {
|
||||
if (this->m_patches.empty())
|
||||
if (m_patches.empty())
|
||||
return 0;
|
||||
else
|
||||
return this->m_patches.rbegin()->first;
|
||||
return m_patches.rbegin()->first;
|
||||
}
|
||||
|
||||
void resizeRaw(u64 newSize) override {
|
||||
|
|
@ -50,29 +50,29 @@ namespace hex {
|
|||
void insertRaw(u64 offset, u64 size) override {
|
||||
std::vector<std::pair<u64, u8>> patchesToMove;
|
||||
|
||||
for (auto &[address, value] : this->m_patches) {
|
||||
for (auto &[address, value] : m_patches) {
|
||||
if (address > offset)
|
||||
patchesToMove.emplace_back(address, value);
|
||||
}
|
||||
|
||||
for (const auto &[address, value] : patchesToMove)
|
||||
this->m_patches.erase(address);
|
||||
m_patches.erase(address);
|
||||
for (const auto &[address, value] : patchesToMove)
|
||||
this->m_patches.insert({ address + size, value });
|
||||
m_patches.insert({ address + size, value });
|
||||
}
|
||||
|
||||
void removeRaw(u64 offset, u64 size) override {
|
||||
std::vector<std::pair<u64, u8>> patchesToMove;
|
||||
|
||||
for (auto &[address, value] : this->m_patches) {
|
||||
for (auto &[address, value] : m_patches) {
|
||||
if (address > offset)
|
||||
patchesToMove.emplace_back(address, value);
|
||||
}
|
||||
|
||||
for (const auto &[address, value] : patchesToMove)
|
||||
this->m_patches.erase(address);
|
||||
m_patches.erase(address);
|
||||
for (const auto &[address, value] : patchesToMove)
|
||||
this->m_patches.insert({ address - size, value });
|
||||
m_patches.insert({ address - size, value });
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string getName() const override {
|
||||
|
|
@ -82,7 +82,7 @@ namespace hex {
|
|||
[[nodiscard]] std::string getTypeName() const override { return ""; }
|
||||
|
||||
const std::map<u64, u8>& getPatches() const {
|
||||
return this->m_patches;
|
||||
return m_patches;
|
||||
}
|
||||
private:
|
||||
std::map<u64, u8> m_patches;
|
||||
|
|
@ -111,7 +111,7 @@ namespace hex {
|
|||
std::vector<u64> addresses;
|
||||
std::vector<u8> values;
|
||||
|
||||
for (const auto &[address, value] : this->m_patches) {
|
||||
for (const auto &[address, value] : m_patches) {
|
||||
addresses.push_back(address);
|
||||
values.push_back(value);
|
||||
}
|
||||
|
|
@ -161,7 +161,7 @@ namespace hex {
|
|||
std::vector<u64> addresses;
|
||||
std::vector<u8> values;
|
||||
|
||||
for (const auto &[address, value] : this->m_patches) {
|
||||
for (const auto &[address, value] : m_patches) {
|
||||
addresses.push_back(address);
|
||||
values.push_back(value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,22 +20,22 @@ namespace hex {
|
|||
|
||||
auto shortPath = wolv::io::fs::toShortPath(path);
|
||||
if (mode == Tar::Mode::Read)
|
||||
tar_error = mtar_open(&this->m_ctx, shortPath.string().c_str(), "r");
|
||||
tar_error = mtar_open(&m_ctx, shortPath.string().c_str(), "r");
|
||||
else if (mode == Tar::Mode::Write)
|
||||
tar_error = mtar_open(&this->m_ctx, shortPath.string().c_str(), "a");
|
||||
tar_error = mtar_open(&m_ctx, shortPath.string().c_str(), "a");
|
||||
else if (mode == Tar::Mode::Create)
|
||||
tar_error = mtar_open(&this->m_ctx, shortPath.string().c_str(), "w");
|
||||
tar_error = mtar_open(&m_ctx, shortPath.string().c_str(), "w");
|
||||
else
|
||||
tar_error = MTAR_EFAILURE;
|
||||
|
||||
this->m_path = path;
|
||||
this->m_valid = (tar_error == MTAR_ESUCCESS);
|
||||
m_path = path;
|
||||
m_valid = (tar_error == MTAR_ESUCCESS);
|
||||
|
||||
if (!this->m_valid) {
|
||||
this->m_tarOpenErrno = tar_error;
|
||||
if (!m_valid) {
|
||||
m_tarOpenErrno = tar_error;
|
||||
|
||||
// Hopefully this errno corresponds to the file open call in mtar_open
|
||||
this->m_fileOpenErrno = errno;
|
||||
m_fileOpenErrno = errno;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -44,27 +44,27 @@ namespace hex {
|
|||
}
|
||||
|
||||
Tar::Tar(hex::Tar &&other) noexcept {
|
||||
this->m_ctx = other.m_ctx;
|
||||
this->m_path = other.m_path;
|
||||
this->m_valid = other.m_valid;
|
||||
this->m_tarOpenErrno = other.m_tarOpenErrno;
|
||||
this->m_fileOpenErrno = other.m_fileOpenErrno;
|
||||
m_ctx = other.m_ctx;
|
||||
m_path = other.m_path;
|
||||
m_valid = other.m_valid;
|
||||
m_tarOpenErrno = other.m_tarOpenErrno;
|
||||
m_fileOpenErrno = other.m_fileOpenErrno;
|
||||
|
||||
other.m_ctx = { };
|
||||
other.m_valid = false;
|
||||
}
|
||||
|
||||
Tar &Tar::operator=(Tar &&other) noexcept {
|
||||
this->m_ctx = other.m_ctx;
|
||||
m_ctx = other.m_ctx;
|
||||
other.m_ctx = { };
|
||||
|
||||
this->m_path = other.m_path;
|
||||
m_path = other.m_path;
|
||||
|
||||
this->m_valid = other.m_valid;
|
||||
m_valid = other.m_valid;
|
||||
other.m_valid = false;
|
||||
|
||||
this->m_tarOpenErrno = other.m_tarOpenErrno;
|
||||
this->m_fileOpenErrno = other.m_fileOpenErrno;
|
||||
m_tarOpenErrno = other.m_tarOpenErrno;
|
||||
m_fileOpenErrno = other.m_fileOpenErrno;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -73,13 +73,13 @@ namespace hex {
|
|||
|
||||
const std::string PaxHeaderName = "@PaxHeader";
|
||||
mtar_header_t header;
|
||||
while (mtar_read_header(&this->m_ctx, &header) != MTAR_ENULLRECORD) {
|
||||
while (mtar_read_header(&m_ctx, &header) != MTAR_ENULLRECORD) {
|
||||
std::fs::path path = header.name;
|
||||
if (header.name != PaxHeaderName && wolv::io::fs::isSubPath(basePath, path)) {
|
||||
result.emplace_back(header.name);
|
||||
}
|
||||
|
||||
mtar_next(&this->m_ctx);
|
||||
mtar_next(&m_ctx);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -93,21 +93,21 @@ namespace hex {
|
|||
std::replace(fixedPath.begin(), fixedPath.end(), '\\', '/');
|
||||
#endif
|
||||
|
||||
return mtar_find(&this->m_ctx, fixedPath.c_str(), &header) == MTAR_ESUCCESS;
|
||||
return mtar_find(&m_ctx, fixedPath.c_str(), &header) == MTAR_ESUCCESS;
|
||||
}
|
||||
|
||||
std::string Tar::getOpenErrorString() const {
|
||||
return hex::format("{}: {}", mtar_strerror(this->m_tarOpenErrno), std::strerror(this->m_fileOpenErrno));
|
||||
return hex::format("{}: {}", mtar_strerror(m_tarOpenErrno), std::strerror(m_fileOpenErrno));
|
||||
}
|
||||
|
||||
void Tar::close() {
|
||||
if (this->m_valid) {
|
||||
mtar_finalize(&this->m_ctx);
|
||||
mtar_close(&this->m_ctx);
|
||||
if (m_valid) {
|
||||
mtar_finalize(&m_ctx);
|
||||
mtar_close(&m_ctx);
|
||||
}
|
||||
|
||||
this->m_ctx = { };
|
||||
this->m_valid = false;
|
||||
m_ctx = { };
|
||||
m_valid = false;
|
||||
}
|
||||
|
||||
std::vector<u8> Tar::readVector(const std::fs::path &path) {
|
||||
|
|
@ -117,15 +117,15 @@ namespace hex {
|
|||
#if defined(OS_WINDOWS)
|
||||
std::replace(fixedPath.begin(), fixedPath.end(), '\\', '/');
|
||||
#endif
|
||||
int ret = mtar_find(&this->m_ctx, fixedPath.c_str(), &header);
|
||||
int ret = mtar_find(&m_ctx, fixedPath.c_str(), &header);
|
||||
if (ret != MTAR_ESUCCESS){
|
||||
log::debug("Failed to read vector from path {} in tarred file {}: {}",
|
||||
path.string(), this->m_path.string(), mtar_strerror(ret));
|
||||
path.string(), m_path.string(), mtar_strerror(ret));
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<u8> result(header.size, 0x00);
|
||||
mtar_read_data(&this->m_ctx, result.data(), result.size());
|
||||
mtar_read_data(&m_ctx, result.data(), result.size());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -145,7 +145,7 @@ namespace hex {
|
|||
#if defined(OS_WINDOWS)
|
||||
std::replace(fixedPath.begin(), fixedPath.end(), '\\', '/');
|
||||
#endif
|
||||
mtar_write_dir_header(&this->m_ctx, fixedPath.c_str());
|
||||
mtar_write_dir_header(&m_ctx, fixedPath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -153,8 +153,8 @@ namespace hex {
|
|||
#if defined(OS_WINDOWS)
|
||||
std::replace(fixedPath.begin(), fixedPath.end(), '\\', '/');
|
||||
#endif
|
||||
mtar_write_file_header(&this->m_ctx, fixedPath.c_str(), data.size());
|
||||
mtar_write_data(&this->m_ctx, data.data(), data.size());
|
||||
mtar_write_file_header(&m_ctx, fixedPath.c_str(), data.size());
|
||||
mtar_write_data(&m_ctx, data.data(), data.size());
|
||||
}
|
||||
|
||||
void Tar::writeString(const std::fs::path &path, const std::string &data) {
|
||||
|
|
@ -177,24 +177,24 @@ namespace hex {
|
|||
|
||||
void Tar::extract(const std::fs::path &path, const std::fs::path &outputPath) {
|
||||
mtar_header_t header;
|
||||
mtar_find(&this->m_ctx, path.string().c_str(), &header);
|
||||
mtar_find(&m_ctx, path.string().c_str(), &header);
|
||||
|
||||
writeFile(&this->m_ctx, &header, outputPath);
|
||||
writeFile(&m_ctx, &header, outputPath);
|
||||
}
|
||||
|
||||
void Tar::extractAll(const std::fs::path &outputPath) {
|
||||
mtar_header_t header;
|
||||
while (mtar_read_header(&this->m_ctx, &header) != MTAR_ENULLRECORD) {
|
||||
while (mtar_read_header(&m_ctx, &header) != MTAR_ENULLRECORD) {
|
||||
const auto filePath = std::fs::absolute(outputPath / std::fs::path(header.name));
|
||||
|
||||
if (filePath.filename() != "@PaxHeader") {
|
||||
|
||||
std::fs::create_directories(filePath.parent_path());
|
||||
|
||||
writeFile(&this->m_ctx, &header, filePath);
|
||||
writeFile(&m_ctx, &header, filePath);
|
||||
}
|
||||
|
||||
mtar_next(&this->m_ctx);
|
||||
mtar_next(&m_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ namespace hex::prv {
|
|||
}
|
||||
|
||||
Provider::~Provider() {
|
||||
this->m_overlays.clear();
|
||||
m_overlays.clear();
|
||||
|
||||
if (auto selection = ImHexApi::HexEditor::getSelection(); selection.has_value() && selection->provider == this)
|
||||
EventRegionSelected::post(ImHexApi::HexEditor::ProviderRegion { { 0x00, 0x00 }, nullptr });
|
||||
|
|
@ -92,7 +92,7 @@ namespace hex::prv {
|
|||
}
|
||||
|
||||
void Provider::applyOverlays(u64 offset, void *buffer, size_t size) const {
|
||||
for (auto &overlay : this->m_overlays) {
|
||||
for (auto &overlay : m_overlays) {
|
||||
auto overlayOffset = overlay->getAddress();
|
||||
auto overlaySize = overlay->getSize();
|
||||
|
||||
|
|
@ -104,22 +104,22 @@ namespace hex::prv {
|
|||
}
|
||||
|
||||
Overlay *Provider::newOverlay() {
|
||||
return this->m_overlays.emplace_back(std::make_unique<Overlay>()).get();
|
||||
return m_overlays.emplace_back(std::make_unique<Overlay>()).get();
|
||||
}
|
||||
|
||||
void Provider::deleteOverlay(Overlay *overlay) {
|
||||
this->m_overlays.remove_if([overlay](const auto &item) {
|
||||
m_overlays.remove_if([overlay](const auto &item) {
|
||||
return item.get() == overlay;
|
||||
});
|
||||
}
|
||||
|
||||
const std::list<std::unique_ptr<Overlay>> &Provider::getOverlays() const {
|
||||
return this->m_overlays;
|
||||
return m_overlays;
|
||||
}
|
||||
|
||||
|
||||
u64 Provider::getPageSize() const {
|
||||
return this->m_pageSize;
|
||||
return m_pageSize;
|
||||
}
|
||||
|
||||
void Provider::setPageSize(u64 pageSize) {
|
||||
|
|
@ -128,7 +128,7 @@ namespace hex::prv {
|
|||
if (pageSize == 0)
|
||||
return;
|
||||
|
||||
this->m_pageSize = pageSize;
|
||||
m_pageSize = pageSize;
|
||||
}
|
||||
|
||||
u32 Provider::getPageCount() const {
|
||||
|
|
@ -136,22 +136,22 @@ namespace hex::prv {
|
|||
}
|
||||
|
||||
u32 Provider::getCurrentPage() const {
|
||||
return this->m_currPage;
|
||||
return m_currPage;
|
||||
}
|
||||
|
||||
void Provider::setCurrentPage(u32 page) {
|
||||
if (page < getPageCount())
|
||||
this->m_currPage = page;
|
||||
m_currPage = page;
|
||||
}
|
||||
|
||||
|
||||
void Provider::setBaseAddress(u64 address) {
|
||||
this->m_baseAddress = address;
|
||||
m_baseAddress = address;
|
||||
this->markDirty();
|
||||
}
|
||||
|
||||
u64 Provider::getBaseAddress() const {
|
||||
return this->m_baseAddress;
|
||||
return m_baseAddress;
|
||||
}
|
||||
|
||||
u64 Provider::getCurrentPageAddress() const {
|
||||
|
|
@ -159,7 +159,7 @@ namespace hex::prv {
|
|||
}
|
||||
|
||||
u64 Provider::getSize() const {
|
||||
return std::min<u64>(this->getActualSize() - this->getPageSize() * this->m_currPage, this->getPageSize());
|
||||
return std::min<u64>(this->getActualSize() - this->getPageSize() * m_currPage, this->getPageSize());
|
||||
}
|
||||
|
||||
std::optional<u32> Provider::getPageOfAddress(u64 address) const {
|
||||
|
|
@ -176,19 +176,19 @@ namespace hex::prv {
|
|||
}
|
||||
|
||||
void Provider::undo() {
|
||||
this->m_undoRedoStack.undo();
|
||||
m_undoRedoStack.undo();
|
||||
}
|
||||
|
||||
void Provider::redo() {
|
||||
this->m_undoRedoStack.redo();
|
||||
m_undoRedoStack.redo();
|
||||
}
|
||||
|
||||
bool Provider::canUndo() const {
|
||||
return this->m_undoRedoStack.canUndo();
|
||||
return m_undoRedoStack.canUndo();
|
||||
}
|
||||
|
||||
bool Provider::canRedo() const {
|
||||
return this->m_undoRedoStack.canRedo();
|
||||
return m_undoRedoStack.canRedo();
|
||||
}
|
||||
|
||||
bool Provider::hasFilePicker() const {
|
||||
|
|
@ -218,15 +218,15 @@ namespace hex::prv {
|
|||
settings["displayName"] = this->getName();
|
||||
settings["type"] = this->getTypeName();
|
||||
|
||||
settings["baseAddress"] = this->m_baseAddress;
|
||||
settings["currPage"] = this->m_currPage;
|
||||
settings["baseAddress"] = m_baseAddress;
|
||||
settings["currPage"] = m_currPage;
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
void Provider::loadSettings(const nlohmann::json &settings) {
|
||||
this->m_baseAddress = settings["baseAddress"];
|
||||
this->m_currPage = settings["currPage"];
|
||||
m_baseAddress = settings["baseAddress"];
|
||||
m_currPage = settings["currPage"];
|
||||
}
|
||||
|
||||
std::pair<Region, bool> Provider::getRegionValidity(u64 address) const {
|
||||
|
|
@ -236,7 +236,7 @@ namespace hex::prv {
|
|||
bool insideValidRegion = false;
|
||||
|
||||
std::optional<u64> nextRegionAddress;
|
||||
for (const auto &overlay : this->m_overlays) {
|
||||
for (const auto &overlay : m_overlays) {
|
||||
Region overlayRegion = { overlay->getAddress(), overlay->getSize() };
|
||||
if (!nextRegionAddress.has_value() || overlay->getAddress() < nextRegionAddress) {
|
||||
nextRegionAddress = overlayRegion.getStartAddress();
|
||||
|
|
@ -255,11 +255,11 @@ namespace hex::prv {
|
|||
|
||||
|
||||
u32 Provider::getID() const {
|
||||
return this->m_id;
|
||||
return m_id;
|
||||
}
|
||||
|
||||
void Provider::setID(u32 id) {
|
||||
this->m_id = id;
|
||||
m_id = id;
|
||||
if (id > s_idCounter)
|
||||
s_idCounter = id + 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ namespace hex::prv::undo {
|
|||
ON_SCOPE_EXIT { s_locked = false; };
|
||||
|
||||
// If there are no operations, we can't undo anything.
|
||||
if (this->m_undoStack.empty())
|
||||
if (m_undoStack.empty())
|
||||
return;
|
||||
|
||||
for (u32 i = 0; i < count; i += 1) {
|
||||
|
|
@ -38,9 +38,9 @@ namespace hex::prv::undo {
|
|||
}
|
||||
|
||||
// Move last element from the undo stack to the redo stack
|
||||
this->m_redoStack.emplace_back(std::move(this->m_undoStack.back()));
|
||||
this->m_redoStack.back()->undo(this->m_provider);
|
||||
this->m_undoStack.pop_back();
|
||||
m_redoStack.emplace_back(std::move(m_undoStack.back()));
|
||||
m_redoStack.back()->undo(m_provider);
|
||||
m_undoStack.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ namespace hex::prv::undo {
|
|||
ON_SCOPE_EXIT { s_locked = false; };
|
||||
|
||||
// If there are no operations, we can't redo anything.
|
||||
if (this->m_redoStack.empty())
|
||||
if (m_redoStack.empty())
|
||||
return;
|
||||
|
||||
for (u32 i = 0; i < count; i += 1) {
|
||||
|
|
@ -61,9 +61,9 @@ namespace hex::prv::undo {
|
|||
}
|
||||
|
||||
// Move last element from the undo stack to the redo stack
|
||||
this->m_undoStack.emplace_back(std::move(this->m_redoStack.back()));
|
||||
this->m_undoStack.back()->redo(this->m_provider);
|
||||
this->m_redoStack.pop_back();
|
||||
m_undoStack.emplace_back(std::move(m_redoStack.back()));
|
||||
m_undoStack.back()->redo(m_provider);
|
||||
m_redoStack.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -73,17 +73,17 @@ namespace hex::prv::undo {
|
|||
|
||||
auto operation = std::make_unique<OperationGroup>(unlocalizedName);
|
||||
|
||||
i64 startIndex = std::max<i64>(0, this->m_undoStack.size() - count);
|
||||
i64 startIndex = std::max<i64>(0, m_undoStack.size() - count);
|
||||
|
||||
// Move operations from our stack to the group in the same order they were added
|
||||
for (u32 i = 0; i < count; i += 1) {
|
||||
i64 index = startIndex + i;
|
||||
|
||||
operation->addOperation(std::move(this->m_undoStack[index]));
|
||||
operation->addOperation(std::move(m_undoStack[index]));
|
||||
}
|
||||
|
||||
// Remove the empty operations from the stack
|
||||
this->m_undoStack.resize(startIndex);
|
||||
m_undoStack.resize(startIndex);
|
||||
this->add(std::move(operation));
|
||||
}
|
||||
|
||||
|
|
@ -106,23 +106,23 @@ namespace hex::prv::undo {
|
|||
std::scoped_lock lock(s_mutex);
|
||||
|
||||
// Clear the redo stack
|
||||
this->m_redoStack.clear();
|
||||
m_redoStack.clear();
|
||||
|
||||
// Insert the new operation at the end of the list
|
||||
this->m_undoStack.emplace_back(std::move(operation));
|
||||
m_undoStack.emplace_back(std::move(operation));
|
||||
|
||||
// Do the operation
|
||||
this->getLastOperation()->redo(this->m_provider);
|
||||
this->getLastOperation()->redo(m_provider);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Stack::canUndo() const {
|
||||
return !this->m_undoStack.empty();
|
||||
return !m_undoStack.empty();
|
||||
}
|
||||
|
||||
bool Stack::canRedo() const {
|
||||
return !this->m_redoStack.empty();
|
||||
return !m_redoStack.empty();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -46,15 +46,15 @@ namespace ImGuiExt {
|
|||
if (size == 0)
|
||||
return;
|
||||
|
||||
unsigned char *imageData = stbi_load_from_memory(buffer, size, &this->m_width, &this->m_height, nullptr, 4);
|
||||
unsigned char *imageData = stbi_load_from_memory(buffer, size, &m_width, &m_height, nullptr, 4);
|
||||
if (imageData == nullptr) {
|
||||
if (width * height * 4 > size)
|
||||
return;
|
||||
|
||||
imageData = static_cast<unsigned char *>(STBI_MALLOC(size));
|
||||
std::memcpy(imageData, buffer, size);
|
||||
this->m_width = width;
|
||||
this->m_height = height;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
}
|
||||
if (imageData == nullptr)
|
||||
return;
|
||||
|
|
@ -70,10 +70,10 @@ namespace ImGuiExt {
|
|||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->m_width, this->m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
|
||||
stbi_image_free(imageData);
|
||||
|
||||
this->m_textureId = reinterpret_cast<ImTextureID>(static_cast<intptr_t>(texture));
|
||||
m_textureId = reinterpret_cast<ImTextureID>(static_cast<intptr_t>(texture));
|
||||
}
|
||||
|
||||
Texture::Texture(std::span<const std::byte> bytes, Filter filter, int width, int height) : Texture(reinterpret_cast<const ImU8*>(bytes.data()), bytes.size(), filter, width, height) { }
|
||||
|
|
@ -81,7 +81,7 @@ namespace ImGuiExt {
|
|||
Texture::Texture(const std::fs::path &path, Filter filter) : Texture(reinterpret_cast<const char *>(path.u8string().c_str()), filter) { }
|
||||
|
||||
Texture::Texture(const char *path, Filter filter) {
|
||||
unsigned char *imageData = stbi_load(path, &this->m_width, &this->m_height, nullptr, 4);
|
||||
unsigned char *imageData = stbi_load(path, &m_width, &m_height, nullptr, 4);
|
||||
if (imageData == nullptr)
|
||||
return;
|
||||
|
||||
|
|
@ -96,10 +96,10 @@ namespace ImGuiExt {
|
|||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->m_width, this->m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
|
||||
stbi_image_free(imageData);
|
||||
|
||||
this->m_textureId = reinterpret_cast<ImTextureID>(static_cast<intptr_t>(texture));
|
||||
m_textureId = reinterpret_cast<ImTextureID>(static_cast<intptr_t>(texture));
|
||||
}
|
||||
|
||||
Texture::Texture(unsigned int texture, int width, int height) : m_textureId(reinterpret_cast<ImTextureID>(static_cast<intptr_t>(texture))), m_width(width), m_height(height) {
|
||||
|
|
@ -107,19 +107,19 @@ namespace ImGuiExt {
|
|||
}
|
||||
|
||||
Texture::Texture(Texture&& other) noexcept {
|
||||
glDeleteTextures(1, reinterpret_cast<GLuint*>(&this->m_textureId));
|
||||
this->m_textureId = other.m_textureId;
|
||||
this->m_width = other.m_width;
|
||||
this->m_height = other.m_height;
|
||||
glDeleteTextures(1, reinterpret_cast<GLuint*>(&m_textureId));
|
||||
m_textureId = other.m_textureId;
|
||||
m_width = other.m_width;
|
||||
m_height = other.m_height;
|
||||
|
||||
other.m_textureId = nullptr;
|
||||
}
|
||||
|
||||
Texture& Texture::operator=(Texture&& other) noexcept {
|
||||
glDeleteTextures(1, reinterpret_cast<GLuint*>(&this->m_textureId));
|
||||
this->m_textureId = other.m_textureId;
|
||||
this->m_width = other.m_width;
|
||||
this->m_height = other.m_height;
|
||||
glDeleteTextures(1, reinterpret_cast<GLuint*>(&m_textureId));
|
||||
m_textureId = other.m_textureId;
|
||||
m_width = other.m_width;
|
||||
m_height = other.m_height;
|
||||
|
||||
other.m_textureId = nullptr;
|
||||
|
||||
|
|
@ -127,10 +127,10 @@ namespace ImGuiExt {
|
|||
}
|
||||
|
||||
Texture::~Texture() {
|
||||
if (this->m_textureId == nullptr)
|
||||
if (m_textureId == nullptr)
|
||||
return;
|
||||
|
||||
auto glTextureId = static_cast<GLuint>(reinterpret_cast<intptr_t>(this->m_textureId));
|
||||
auto glTextureId = static_cast<GLuint>(reinterpret_cast<intptr_t>(m_textureId));
|
||||
glDeleteTextures(1, &glTextureId);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,33 +36,33 @@ namespace hex {
|
|||
|
||||
|
||||
bool &View::getWindowOpenState() {
|
||||
return this->m_windowOpen;
|
||||
return m_windowOpen;
|
||||
}
|
||||
|
||||
const bool &View::getWindowOpenState() const {
|
||||
return this->m_windowOpen;
|
||||
return m_windowOpen;
|
||||
}
|
||||
|
||||
const UnlocalizedString &View::getUnlocalizedName() const {
|
||||
return this->m_unlocalizedViewName;
|
||||
return m_unlocalizedViewName;
|
||||
}
|
||||
|
||||
std::string View::getName() const {
|
||||
return View::toWindowName(this->m_unlocalizedViewName);
|
||||
return View::toWindowName(m_unlocalizedViewName);
|
||||
}
|
||||
|
||||
bool View::didWindowJustOpen() {
|
||||
return std::exchange(this->m_windowJustOpened, false);
|
||||
return std::exchange(m_windowJustOpened, false);
|
||||
}
|
||||
|
||||
void View::setWindowJustOpened(bool state) {
|
||||
this->m_windowJustOpened = state;
|
||||
m_windowJustOpened = state;
|
||||
}
|
||||
|
||||
void View::trackViewOpenState() {
|
||||
if (this->m_windowOpen && !this->m_prevWindowOpen)
|
||||
if (m_windowOpen && !m_prevWindowOpen)
|
||||
this->setWindowJustOpened(true);
|
||||
this->m_prevWindowOpen = this->m_windowOpen;
|
||||
m_prevWindowOpen = m_windowOpen;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -44,9 +44,9 @@ namespace hex::init {
|
|||
void createTask(const Task &task);
|
||||
|
||||
void addStartupTask(const std::string &taskName, const TaskFunction &function, bool async) {
|
||||
std::scoped_lock lock(this->m_tasksMutex);
|
||||
std::scoped_lock lock(m_tasksMutex);
|
||||
|
||||
this->m_tasks.emplace_back(taskName, function, async);
|
||||
m_tasks.emplace_back(taskName, function, async);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ namespace hex {
|
|||
void frame();
|
||||
void frameEnd();
|
||||
|
||||
void processEvent() { this->m_hadEvent = true; }
|
||||
void processEvent() { m_hadEvent = true; }
|
||||
|
||||
void initGLFW();
|
||||
void initImGui();
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace hex::init {
|
|||
ImHexApi::System::impl::setGPUVendor(reinterpret_cast<const char *>(glGetString(GL_VENDOR)));
|
||||
|
||||
RequestAddInitTask::subscribe([this](const std::string& name, bool async, const TaskFunction &function){
|
||||
this->m_tasks.push_back(Task{ name, function, async });
|
||||
m_tasks.push_back(Task{ name, function, async });
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -142,17 +142,17 @@ namespace hex::init {
|
|||
auto runTask = [&, task] {
|
||||
try {
|
||||
// Save an iterator to the current task name
|
||||
decltype(this->m_currTaskNames)::iterator taskNameIter;
|
||||
decltype(m_currTaskNames)::iterator taskNameIter;
|
||||
{
|
||||
std::lock_guard guard(this->m_progressMutex);
|
||||
this->m_currTaskNames.push_back(task.name + "...");
|
||||
taskNameIter = std::prev(this->m_currTaskNames.end());
|
||||
std::lock_guard guard(m_progressMutex);
|
||||
m_currTaskNames.push_back(task.name + "...");
|
||||
taskNameIter = std::prev(m_currTaskNames.end());
|
||||
}
|
||||
|
||||
// When the task finished, increment the progress bar
|
||||
ON_SCOPE_EXIT {
|
||||
this->m_completedTaskCount += 1;
|
||||
this->m_progress = float(this->m_completedTaskCount) / float(this->m_totalTaskCount);
|
||||
m_completedTaskCount += 1;
|
||||
m_progress = float(m_completedTaskCount) / float(m_totalTaskCount);
|
||||
};
|
||||
|
||||
// Execute the actual task and track the amount of time it took to run
|
||||
|
|
@ -168,23 +168,23 @@ namespace hex::init {
|
|||
log::warn("Task '{}' finished unsuccessfully in {} ms", task.name, milliseconds);
|
||||
|
||||
// Track the overall status of the tasks
|
||||
this->m_taskStatus = this->m_taskStatus && taskStatus;
|
||||
m_taskStatus = m_taskStatus && taskStatus;
|
||||
|
||||
// Erase the task name from the list of running tasks
|
||||
{
|
||||
std::lock_guard guard(this->m_progressMutex);
|
||||
this->m_currTaskNames.erase(taskNameIter);
|
||||
std::lock_guard guard(m_progressMutex);
|
||||
m_currTaskNames.erase(taskNameIter);
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
log::error("Init task '{}' threw an exception: {}", task.name, e.what());
|
||||
this->m_taskStatus = false;
|
||||
m_taskStatus = false;
|
||||
} catch (...) {
|
||||
log::error("Init task '{}' threw an unidentifiable exception", task.name);
|
||||
this->m_taskStatus = false;
|
||||
m_taskStatus = false;
|
||||
}
|
||||
};
|
||||
|
||||
this->m_totalTaskCount += 1;
|
||||
m_totalTaskCount += 1;
|
||||
|
||||
// If the task can be run asynchronously, run it in a separate thread
|
||||
// otherwise run it in this thread and wait for it to finish
|
||||
|
|
@ -200,7 +200,7 @@ namespace hex::init {
|
|||
auto startTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
// Loop over all registered init tasks
|
||||
for (auto it = this->m_tasks.begin(); it != this->m_tasks.end(); ++it) {
|
||||
for (auto it = m_tasks.begin(); it != m_tasks.end(); ++it) {
|
||||
// Construct a new task callback
|
||||
this->createTask(*it);
|
||||
}
|
||||
|
|
@ -208,8 +208,8 @@ namespace hex::init {
|
|||
// Check every 100ms if all tasks have run
|
||||
while (true) {
|
||||
{
|
||||
std::scoped_lock lock(this->m_tasksMutex);
|
||||
if (this->m_completedTaskCount >= this->m_totalTaskCount)
|
||||
std::scoped_lock lock(m_tasksMutex);
|
||||
if (m_completedTaskCount >= m_totalTaskCount)
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -224,14 +224,14 @@ namespace hex::init {
|
|||
// Small extra delay so the last progress step is visible
|
||||
std::this_thread::sleep_for(100ms);
|
||||
|
||||
return this->m_taskStatus.load();
|
||||
return m_taskStatus.load();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
FrameResult WindowSplash::fullFrame() {
|
||||
glfwSetWindowSize(this->m_window, 640_scaled, 400_scaled);
|
||||
centerWindow(this->m_window);
|
||||
glfwSetWindowSize(m_window, 640_scaled, 400_scaled);
|
||||
centerWindow(m_window);
|
||||
|
||||
glfwPollEvents();
|
||||
|
||||
|
|
@ -301,7 +301,7 @@ namespace hex::init {
|
|||
highlightBytes(highlight.start, highlight.count, highlight.color, this->progressLerp);
|
||||
}
|
||||
|
||||
this->progressLerp += (this->m_progress - this->progressLerp) * 0.1F;
|
||||
this->progressLerp += (m_progress - this->progressLerp) * 0.1F;
|
||||
|
||||
// Draw the splash screen foreground
|
||||
drawList->AddImage(this->splashTextTexture, ImVec2(0, 0), this->splashTextTexture.getSize() * scale);
|
||||
|
|
@ -322,21 +322,21 @@ namespace hex::init {
|
|||
|
||||
// Draw the task progress bar
|
||||
{
|
||||
std::lock_guard guard(this->m_progressMutex);
|
||||
std::lock_guard guard(m_progressMutex);
|
||||
|
||||
const auto progressBackgroundStart = ImVec2(99, 357) * scale;
|
||||
const auto progressBackgroundSize = ImVec2(442, 30) * scale;
|
||||
|
||||
const auto progressStart = progressBackgroundStart + ImVec2(0, 20) * scale;
|
||||
const auto progressSize = ImVec2(progressBackgroundSize.x * this->m_progress, 10 * scale);
|
||||
const auto progressSize = ImVec2(progressBackgroundSize.x * m_progress, 10 * scale);
|
||||
|
||||
// Draw progress bar
|
||||
drawList->AddRectFilled(progressStart, progressStart + progressSize, 0xD0FFFFFF);
|
||||
|
||||
// Draw task names separated by | characters
|
||||
if (!this->m_currTaskNames.empty()) {
|
||||
if (!m_currTaskNames.empty()) {
|
||||
drawList->PushClipRect(progressBackgroundStart, progressBackgroundStart + progressBackgroundSize, true);
|
||||
drawList->AddText(progressStart + ImVec2(5, -20) * scale, ImColor(0xFF, 0xFF, 0xFF, 0xFF), hex::format("{}", fmt::join(this->m_currTaskNames, " | ")).c_str());
|
||||
drawList->AddText(progressStart + ImVec2(5, -20) * scale, ImColor(0xFF, 0xFF, 0xFF, 0xFF), hex::format("{}", fmt::join(m_currTaskNames, " | ")).c_str());
|
||||
drawList->PopClipRect();
|
||||
}
|
||||
}
|
||||
|
|
@ -344,13 +344,13 @@ namespace hex::init {
|
|||
// Render the frame
|
||||
ImGui::Render();
|
||||
int displayWidth, displayHeight;
|
||||
glfwGetFramebufferSize(this->m_window, &displayWidth, &displayHeight);
|
||||
glfwGetFramebufferSize(m_window, &displayWidth, &displayHeight);
|
||||
glViewport(0, 0, displayWidth, displayHeight);
|
||||
glClearColor(0.00F, 0.00F, 0.00F, 0.00F);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
glfwSwapBuffers(this->m_window);
|
||||
glfwSwapBuffers(m_window);
|
||||
|
||||
// Check if all background tasks have finished so the splash screen can be closed
|
||||
if (this->tasksSucceeded.wait_for(0s) == std::future_status::ready) {
|
||||
|
|
@ -411,8 +411,8 @@ namespace hex::init {
|
|||
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
|
||||
|
||||
// Create the splash screen window
|
||||
this->m_window = glfwCreateWindow(1, 1, "Starting ImHex...", nullptr, nullptr);
|
||||
if (this->m_window == nullptr) {
|
||||
m_window = glfwCreateWindow(1, 1, "Starting ImHex...", nullptr, nullptr);
|
||||
if (m_window == nullptr) {
|
||||
hex::nativeErrorMessage(hex::format(
|
||||
"Failed to create GLFW window: [{}] {}.\n"
|
||||
"You may not have a renderer available.\n"
|
||||
|
|
@ -423,12 +423,12 @@ namespace hex::init {
|
|||
}
|
||||
|
||||
// Force window to be fully opaque by default
|
||||
glfwSetWindowOpacity(this->m_window, 1.0F);
|
||||
glfwSetWindowOpacity(m_window, 1.0F);
|
||||
|
||||
// Calculate native scale factor for hidpi displays
|
||||
{
|
||||
float xScale = 0, yScale = 0;
|
||||
glfwGetWindowContentScale(this->m_window, &xScale, &yScale);
|
||||
glfwGetWindowContentScale(m_window, &xScale, &yScale);
|
||||
|
||||
auto meanScale = std::midpoint(xScale, yScale);
|
||||
if (meanScale <= 0.0F)
|
||||
|
|
@ -446,7 +446,7 @@ namespace hex::init {
|
|||
log::info("Native scaling set to: {:.1f}", meanScale);
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(this->m_window);
|
||||
glfwMakeContextCurrent(m_window);
|
||||
glfwSwapInterval(1);
|
||||
}
|
||||
|
||||
|
|
@ -456,7 +456,7 @@ namespace hex::init {
|
|||
GImGui = ImGui::CreateContext();
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
ImGui_ImplGlfw_InitForOpenGL(this->m_window, true);
|
||||
ImGui_ImplGlfw_InitForOpenGL(m_window, true);
|
||||
|
||||
#if defined(OS_MACOS)
|
||||
ImGui_ImplOpenGL3_Init("#version 150");
|
||||
|
|
@ -539,7 +539,7 @@ namespace hex::init {
|
|||
}
|
||||
|
||||
void WindowSplash::exitGLFW() const {
|
||||
glfwDestroyWindow(this->m_window);
|
||||
glfwDestroyWindow(m_window);
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ namespace hex {
|
|||
|
||||
void Window::setupNativeWindow() {
|
||||
// Setup borderless window
|
||||
auto hwnd = glfwGetWin32Window(this->m_window);
|
||||
auto hwnd = glfwGetWin32Window(m_window);
|
||||
|
||||
bool borderlessWindowMode = ImHexApi::System::isBorderlessWindowModeEnabled();
|
||||
|
||||
|
|
@ -380,7 +380,7 @@ namespace hex {
|
|||
};
|
||||
|
||||
EventThemeChanged::subscribe([this]{
|
||||
auto hwnd = glfwGetWin32Window(this->m_window);
|
||||
auto hwnd = glfwGetWin32Window(m_window);
|
||||
|
||||
static auto user32Dll = WinUniquePtr<HMODULE>(LoadLibraryA("user32.dll"), FreeLibrary);
|
||||
if (user32Dll != nullptr) {
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ namespace hex {
|
|||
this->setupNativeWindow();
|
||||
this->registerEventHandlers();
|
||||
|
||||
this->m_logoTexture = ImGuiExt::Texture(romfs::get("logo.png").span(), ImGuiExt::Texture::Filter::Linear);
|
||||
m_logoTexture = ImGuiExt::Texture(romfs::get("logo.png").span(), ImGuiExt::Texture::Filter::Linear);
|
||||
|
||||
ContentRegistry::Settings::impl::store();
|
||||
EventSettingsChanged::post();
|
||||
|
|
@ -103,10 +103,10 @@ namespace hex {
|
|||
|
||||
// Handle the close window request by telling GLFW to shut down
|
||||
RequestCloseImHex::subscribe(this, [this](bool noQuestions) {
|
||||
glfwSetWindowShouldClose(this->m_window, GLFW_TRUE);
|
||||
glfwSetWindowShouldClose(m_window, GLFW_TRUE);
|
||||
|
||||
if (!noQuestions)
|
||||
EventWindowClosing::post(this->m_window);
|
||||
EventWindowClosing::post(m_window);
|
||||
});
|
||||
|
||||
// Handle updating the window title
|
||||
|
|
@ -136,27 +136,27 @@ namespace hex {
|
|||
}
|
||||
}
|
||||
|
||||
this->m_windowTitle = prefix + hex::limitStringLength(title, 32) + postfix;
|
||||
this->m_windowTitleFull = prefix + title + postfix;
|
||||
m_windowTitle = prefix + hex::limitStringLength(title, 32) + postfix;
|
||||
m_windowTitleFull = prefix + title + postfix;
|
||||
|
||||
if (this->m_window != nullptr) {
|
||||
if (m_window != nullptr) {
|
||||
if (title != "ImHex")
|
||||
title = "ImHex - " + title;
|
||||
|
||||
glfwSetWindowTitle(this->m_window, title.c_str());
|
||||
glfwSetWindowTitle(m_window, title.c_str());
|
||||
}
|
||||
});
|
||||
|
||||
// Handle opening popups
|
||||
RequestOpenPopup::subscribe(this, [this](auto name) {
|
||||
std::scoped_lock lock(this->m_popupMutex);
|
||||
std::scoped_lock lock(m_popupMutex);
|
||||
|
||||
this->m_popupsToOpen.push_back(name);
|
||||
m_popupsToOpen.push_back(name);
|
||||
});
|
||||
}
|
||||
|
||||
void Window::fullFrame() {
|
||||
this->m_lastStartFrameTime = glfwGetTime();
|
||||
m_lastStartFrameTime = glfwGetTime();
|
||||
|
||||
glfwPollEvents();
|
||||
|
||||
|
|
@ -168,10 +168,10 @@ namespace hex {
|
|||
|
||||
void Window::loop() {
|
||||
u64 frameCount = 0;
|
||||
while (!glfwWindowShouldClose(this->m_window)) {
|
||||
this->m_lastStartFrameTime = glfwGetTime();
|
||||
while (!glfwWindowShouldClose(m_window)) {
|
||||
m_lastStartFrameTime = glfwGetTime();
|
||||
|
||||
if (!glfwGetWindowAttrib(this->m_window, GLFW_VISIBLE) || glfwGetWindowAttrib(this->m_window, GLFW_ICONIFIED)) {
|
||||
if (!glfwGetWindowAttrib(m_window, GLFW_VISIBLE) || glfwGetWindowAttrib(m_window, GLFW_ICONIFIED)) {
|
||||
// If the application is minimized or not visible, don't render anything
|
||||
glfwWaitEvents();
|
||||
} else {
|
||||
|
|
@ -181,30 +181,30 @@ namespace hex {
|
|||
bool frameRateUnlocked =
|
||||
ImGui::IsPopupOpen(ImGuiID(0), ImGuiPopupFlags_AnyPopupId) ||
|
||||
TaskManager::getRunningTaskCount() > 0 ||
|
||||
this->m_buttonDown ||
|
||||
this->m_hadEvent ||
|
||||
!this->m_pressedKeys.empty() ||
|
||||
m_buttonDown ||
|
||||
m_hadEvent ||
|
||||
!m_pressedKeys.empty() ||
|
||||
frameCount < 100;
|
||||
|
||||
// Calculate the time until the next frame
|
||||
const double timeout = std::max(0.0, (1.0 / 5.0) - (glfwGetTime() - this->m_lastStartFrameTime));
|
||||
const double timeout = std::max(0.0, (1.0 / 5.0) - (glfwGetTime() - m_lastStartFrameTime));
|
||||
|
||||
// If the frame rate has been unlocked for 5 seconds, lock it again
|
||||
if ((this->m_lastStartFrameTime - this->m_frameRateUnlockTime) > 5 && this->m_frameRateTemporarilyUnlocked && !frameRateUnlocked) {
|
||||
this->m_frameRateTemporarilyUnlocked = false;
|
||||
if ((m_lastStartFrameTime - m_frameRateUnlockTime) > 5 && m_frameRateTemporarilyUnlocked && !frameRateUnlocked) {
|
||||
m_frameRateTemporarilyUnlocked = false;
|
||||
}
|
||||
|
||||
// If the frame rate is locked, wait for events with a timeout
|
||||
if (frameRateUnlocked || this->m_frameRateTemporarilyUnlocked) {
|
||||
if (!this->m_frameRateTemporarilyUnlocked) {
|
||||
this->m_frameRateTemporarilyUnlocked = true;
|
||||
this->m_frameRateUnlockTime = this->m_lastStartFrameTime;
|
||||
if (frameRateUnlocked || m_frameRateTemporarilyUnlocked) {
|
||||
if (!m_frameRateTemporarilyUnlocked) {
|
||||
m_frameRateTemporarilyUnlocked = true;
|
||||
m_frameRateUnlockTime = m_lastStartFrameTime;
|
||||
}
|
||||
} else {
|
||||
glfwWaitEventsTimeout(timeout);
|
||||
}
|
||||
|
||||
this->m_hadEvent = false;
|
||||
m_hadEvent = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -220,14 +220,14 @@ namespace hex {
|
|||
glfwSwapInterval(0);
|
||||
} else {
|
||||
glfwSwapInterval(0);
|
||||
const auto frameTime = glfwGetTime() - this->m_lastStartFrameTime;
|
||||
const auto frameTime = glfwGetTime() - m_lastStartFrameTime;
|
||||
const auto targetFrameTime = 1.0 / targetFPS;
|
||||
if (frameTime < targetFrameTime) {
|
||||
glfwWaitEventsTimeout(targetFrameTime - frameTime);
|
||||
}
|
||||
}
|
||||
|
||||
this->m_lastFrameTime = glfwGetTime() - this->m_lastStartFrameTime;
|
||||
m_lastFrameTime = glfwGetTime() - m_lastStartFrameTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -288,13 +288,13 @@ namespace hex {
|
|||
// Draw minimize, restore and maximize buttons
|
||||
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - buttonSize.x * 3);
|
||||
if (ImGuiExt::TitleBarButton(ICON_VS_CHROME_MINIMIZE, buttonSize))
|
||||
glfwIconifyWindow(this->m_window);
|
||||
if (glfwGetWindowAttrib(this->m_window, GLFW_MAXIMIZED)) {
|
||||
glfwIconifyWindow(m_window);
|
||||
if (glfwGetWindowAttrib(m_window, GLFW_MAXIMIZED)) {
|
||||
if (ImGuiExt::TitleBarButton(ICON_VS_CHROME_RESTORE, buttonSize))
|
||||
glfwRestoreWindow(this->m_window);
|
||||
glfwRestoreWindow(m_window);
|
||||
} else {
|
||||
if (ImGuiExt::TitleBarButton(ICON_VS_CHROME_MAXIMIZE, buttonSize))
|
||||
glfwMaximizeWindow(this->m_window);
|
||||
glfwMaximizeWindow(m_window);
|
||||
}
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, 0xFF7A70F1);
|
||||
|
|
@ -324,7 +324,7 @@ namespace hex {
|
|||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, scaled({ 1, 1 }));
|
||||
|
||||
ImGui::SetCursorPos(searchBoxPos);
|
||||
if (ImGui::Button(this->m_windowTitle.c_str(), searchBoxSize)) {
|
||||
if (ImGui::Button(m_windowTitle.c_str(), searchBoxSize)) {
|
||||
EventSearchBoxClicked::post(ImGuiMouseButton_Left);
|
||||
}
|
||||
|
||||
|
|
@ -332,8 +332,8 @@ namespace hex {
|
|||
EventSearchBoxClicked::post(ImGuiMouseButton_Right);
|
||||
|
||||
ImGui::PushTextWrapPos(300_scaled);
|
||||
if (!this->m_windowTitleFull.empty())
|
||||
ImGui::SetItemTooltip("%s", this->m_windowTitleFull.c_str());
|
||||
if (!m_windowTitleFull.empty())
|
||||
ImGui::SetItemTooltip("%s", m_windowTitleFull.c_str());
|
||||
ImGui::PopTextWrapPos();
|
||||
|
||||
ImGui::PopStyleVar(3);
|
||||
|
|
@ -482,23 +482,23 @@ namespace hex {
|
|||
if (ImHexApi::System::isBorderlessWindowModeEnabled()) {
|
||||
ImGui::SetCursorPosX(5);
|
||||
|
||||
ImGui::Image(this->m_logoTexture, ImVec2(menuBarHeight, menuBarHeight));
|
||||
ImGui::Image(m_logoTexture, ImVec2(menuBarHeight, menuBarHeight));
|
||||
ImGui::SetCursorPosX(5);
|
||||
ImGui::InvisibleButton("##logo", ImVec2(menuBarHeight, menuBarHeight));
|
||||
ImGui::OpenPopupOnItemClick("WindowingMenu", ImGuiPopupFlags_MouseButtonLeft);
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopup("WindowingMenu")) {
|
||||
bool maximized = glfwGetWindowAttrib(this->m_window, GLFW_MAXIMIZED);
|
||||
bool maximized = glfwGetWindowAttrib(m_window, GLFW_MAXIMIZED);
|
||||
|
||||
ImGui::BeginDisabled(!maximized);
|
||||
if (ImGui::MenuItem(ICON_VS_CHROME_RESTORE " Restore")) glfwRestoreWindow(this->m_window);
|
||||
if (ImGui::MenuItem(ICON_VS_CHROME_RESTORE " Restore")) glfwRestoreWindow(m_window);
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (ImGui::MenuItem(ICON_VS_CHROME_MINIMIZE " Minimize")) glfwIconifyWindow(this->m_window);
|
||||
if (ImGui::MenuItem(ICON_VS_CHROME_MINIMIZE " Minimize")) glfwIconifyWindow(m_window);
|
||||
|
||||
ImGui::BeginDisabled(maximized);
|
||||
if (ImGui::MenuItem(ICON_VS_CHROME_MAXIMIZE " Maximize")) glfwMaximizeWindow(this->m_window);
|
||||
if (ImGui::MenuItem(ICON_VS_CHROME_MAXIMIZE " Maximize")) glfwMaximizeWindow(m_window);
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::Separator();
|
||||
|
|
@ -651,8 +651,8 @@ namespace hex {
|
|||
|
||||
// Open popups when plugins requested it
|
||||
{
|
||||
std::scoped_lock lock(this->m_popupMutex);
|
||||
this->m_popupsToOpen.remove_if([](const auto &name) {
|
||||
std::scoped_lock lock(m_popupMutex);
|
||||
m_popupsToOpen.remove_if([](const auto &name) {
|
||||
if (ImGui::IsPopupOpen(name.c_str()))
|
||||
return true;
|
||||
else
|
||||
|
|
@ -677,7 +677,7 @@ namespace hex {
|
|||
if (popupDelay <= -1.0) {
|
||||
popupDelay = 0.2;
|
||||
} else {
|
||||
popupDelay -= this->m_lastFrameTime;
|
||||
popupDelay -= m_lastFrameTime;
|
||||
if (popupDelay < 0 || popups.size() == 1) {
|
||||
popupDelay = -2.0;
|
||||
currPopup = std::move(popups.back());
|
||||
|
|
@ -825,18 +825,18 @@ namespace hex {
|
|||
}
|
||||
|
||||
// Pass on currently pressed keys to the shortcut handler
|
||||
for (const auto &key : this->m_pressedKeys) {
|
||||
for (const auto &key : m_pressedKeys) {
|
||||
ShortcutManager::process(view, io.KeyCtrl, io.KeyAlt, io.KeyShift, io.KeySuper, focused, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle global shortcuts
|
||||
for (const auto &key : this->m_pressedKeys) {
|
||||
for (const auto &key : m_pressedKeys) {
|
||||
ShortcutManager::processGlobals(io.KeyCtrl, io.KeyAlt, io.KeyShift, io.KeySuper, key);
|
||||
}
|
||||
|
||||
this->m_pressedKeys.clear();
|
||||
m_pressedKeys.clear();
|
||||
}
|
||||
|
||||
void Window::frameEnd() {
|
||||
|
|
@ -853,7 +853,7 @@ namespace hex {
|
|||
ImGui::Render();
|
||||
|
||||
int displayWidth, displayHeight;
|
||||
glfwGetFramebufferSize(this->m_window, &displayWidth, &displayHeight);
|
||||
glfwGetFramebufferSize(m_window, &displayWidth, &displayHeight);
|
||||
glViewport(0, 0, displayWidth, displayHeight);
|
||||
glClearColor(0.00F, 0.00F, 0.00F, 0.00F);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
|
@ -864,7 +864,7 @@ namespace hex {
|
|||
ImGui::RenderPlatformWindowsDefault();
|
||||
glfwMakeContextCurrent(backup_current_context);
|
||||
|
||||
glfwSwapBuffers(this->m_window);
|
||||
glfwSwapBuffers(m_window);
|
||||
|
||||
// Process layout load requests
|
||||
// NOTE: This needs to be done before a new frame is started, otherwise ImGui won't handle docking correctly
|
||||
|
|
@ -919,20 +919,20 @@ namespace hex {
|
|||
}
|
||||
|
||||
// Create window
|
||||
this->m_windowTitle = "ImHex";
|
||||
this->m_window = glfwCreateWindow(1280_scaled, 720_scaled, this->m_windowTitle.c_str(), nullptr, nullptr);
|
||||
m_windowTitle = "ImHex";
|
||||
m_window = glfwCreateWindow(1280_scaled, 720_scaled, m_windowTitle.c_str(), nullptr, nullptr);
|
||||
|
||||
glfwSetWindowUserPointer(this->m_window, this);
|
||||
glfwSetWindowUserPointer(m_window, this);
|
||||
|
||||
if (this->m_window == nullptr) {
|
||||
if (m_window == nullptr) {
|
||||
log::fatal("Failed to create window!");
|
||||
std::abort();
|
||||
}
|
||||
|
||||
// Force window to be fully opaque by default
|
||||
glfwSetWindowOpacity(this->m_window, 1.0F);
|
||||
glfwSetWindowOpacity(m_window, 1.0F);
|
||||
|
||||
glfwMakeContextCurrent(this->m_window);
|
||||
glfwMakeContextCurrent(m_window);
|
||||
glfwSwapInterval(1);
|
||||
|
||||
// Center window
|
||||
|
|
@ -944,16 +944,16 @@ namespace hex {
|
|||
glfwGetMonitorPos(monitor, &monitorX, &monitorY);
|
||||
|
||||
int windowWidth, windowHeight;
|
||||
glfwGetWindowSize(this->m_window, &windowWidth, &windowHeight);
|
||||
glfwGetWindowSize(m_window, &windowWidth, &windowHeight);
|
||||
|
||||
glfwSetWindowPos(this->m_window, monitorX + (mode->width - windowWidth) / 2, monitorY + (mode->height - windowHeight) / 2);
|
||||
glfwSetWindowPos(m_window, monitorX + (mode->width - windowWidth) / 2, monitorY + (mode->height - windowHeight) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Set up initial window position
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
glfwGetWindowPos(this->m_window, &x, &y);
|
||||
glfwGetWindowPos(m_window, &x, &y);
|
||||
|
||||
if (restoreWindowPos) {
|
||||
x = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.x", x);
|
||||
|
|
@ -961,14 +961,14 @@ namespace hex {
|
|||
}
|
||||
|
||||
ImHexApi::System::impl::setMainWindowPosition(x, y);
|
||||
glfwSetWindowPos(this->m_window, x, y);
|
||||
glfwSetWindowPos(m_window, x, y);
|
||||
}
|
||||
|
||||
// Set up initial window size
|
||||
{
|
||||
int width = 0, height = 0;
|
||||
glfwGetWindowSize(this->m_window, &width, &height);
|
||||
glfwSetWindowSize(this->m_window, width, height);
|
||||
glfwGetWindowSize(m_window, &width, &height);
|
||||
glfwSetWindowSize(m_window, width, height);
|
||||
|
||||
if (restoreWindowPos) {
|
||||
width = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.width", width);
|
||||
|
|
@ -976,11 +976,11 @@ namespace hex {
|
|||
}
|
||||
|
||||
ImHexApi::System::impl::setMainWindowSize(width, height);
|
||||
glfwSetWindowSize(this->m_window, width, height);
|
||||
glfwSetWindowSize(m_window, width, height);
|
||||
}
|
||||
|
||||
// Register window move callback
|
||||
glfwSetWindowPosCallback(this->m_window, [](GLFWwindow *window, int x, int y) {
|
||||
glfwSetWindowPosCallback(m_window, [](GLFWwindow *window, int x, int y) {
|
||||
ImHexApi::System::impl::setMainWindowPosition(x, y);
|
||||
|
||||
if (auto g = ImGui::GetCurrentContext(); g == nullptr || g->WithinFrameScope) return;
|
||||
|
|
@ -993,7 +993,7 @@ namespace hex {
|
|||
});
|
||||
|
||||
// Register window resize callback
|
||||
glfwSetWindowSizeCallback(this->m_window, [](GLFWwindow *window, int width, int height) {
|
||||
glfwSetWindowSizeCallback(m_window, [](GLFWwindow *window, int width, int height) {
|
||||
if (!glfwGetWindowAttrib(window, GLFW_ICONIFIED))
|
||||
ImHexApi::System::impl::setMainWindowSize(width, height);
|
||||
|
||||
|
|
@ -1007,7 +1007,7 @@ namespace hex {
|
|||
});
|
||||
|
||||
// Register mouse handling callback
|
||||
glfwSetMouseButtonCallback(this->m_window, [](GLFWwindow *window, int button, int action, int mods) {
|
||||
glfwSetMouseButtonCallback(m_window, [](GLFWwindow *window, int button, int action, int mods) {
|
||||
hex::unused(button, mods);
|
||||
|
||||
auto win = static_cast<Window *>(glfwGetWindowUserPointer(window));
|
||||
|
|
@ -1020,7 +1020,7 @@ namespace hex {
|
|||
});
|
||||
|
||||
// Register scrolling callback
|
||||
glfwSetScrollCallback(this->m_window, [](GLFWwindow *window, double xOffset, double yOffset) {
|
||||
glfwSetScrollCallback(m_window, [](GLFWwindow *window, double xOffset, double yOffset) {
|
||||
hex::unused(xOffset, yOffset);
|
||||
|
||||
auto win = static_cast<Window *>(glfwGetWindowUserPointer(window));
|
||||
|
|
@ -1029,7 +1029,7 @@ namespace hex {
|
|||
|
||||
#if !defined(OS_WEB)
|
||||
// Register key press callback
|
||||
glfwSetKeyCallback(this->m_window, [](GLFWwindow *window, int key, int scanCode, int action, int mods) {
|
||||
glfwSetKeyCallback(m_window, [](GLFWwindow *window, int key, int scanCode, int action, int mods) {
|
||||
hex::unused(mods);
|
||||
|
||||
auto win = static_cast<Window *>(glfwGetWindowUserPointer(window));
|
||||
|
|
@ -1069,7 +1069,7 @@ namespace hex {
|
|||
#endif
|
||||
|
||||
// Register cursor position callback
|
||||
glfwSetCursorPosCallback(this->m_window, [](GLFWwindow *window, double x, double y) {
|
||||
glfwSetCursorPosCallback(m_window, [](GLFWwindow *window, double x, double y) {
|
||||
hex::unused(x, y);
|
||||
|
||||
auto win = static_cast<Window *>(glfwGetWindowUserPointer(window));
|
||||
|
|
@ -1077,12 +1077,12 @@ namespace hex {
|
|||
});
|
||||
|
||||
// Register window close callback
|
||||
glfwSetWindowCloseCallback(this->m_window, [](GLFWwindow *window) {
|
||||
glfwSetWindowCloseCallback(m_window, [](GLFWwindow *window) {
|
||||
EventWindowClosing::post(window);
|
||||
});
|
||||
|
||||
// Register file drop callback
|
||||
glfwSetDropCallback(this->m_window, [](GLFWwindow *, int count, const char **paths) {
|
||||
glfwSetDropCallback(m_window, [](GLFWwindow *, int count, const char **paths) {
|
||||
// Loop over all dropped files
|
||||
for (int i = 0; i < count; i++) {
|
||||
auto path = std::fs::path(reinterpret_cast<const char8_t *>(paths[i]));
|
||||
|
|
@ -1109,13 +1109,13 @@ namespace hex {
|
|||
}
|
||||
});
|
||||
|
||||
glfwSetWindowSizeLimits(this->m_window, 480_scaled, 360_scaled, GLFW_DONT_CARE, GLFW_DONT_CARE);
|
||||
glfwSetWindowSizeLimits(m_window, 480_scaled, 360_scaled, GLFW_DONT_CARE, GLFW_DONT_CARE);
|
||||
|
||||
glfwShowWindow(this->m_window);
|
||||
glfwShowWindow(m_window);
|
||||
}
|
||||
|
||||
void Window::resize(i32 width, i32 height) {
|
||||
glfwSetWindowSize(this->m_window, width, height);
|
||||
glfwSetWindowSize(m_window, width, height);
|
||||
}
|
||||
|
||||
void Window::initImGui() {
|
||||
|
|
@ -1155,7 +1155,7 @@ namespace hex {
|
|||
ImNodes::GetIO().LinkDetachWithModifierClick.Modifier = &always;
|
||||
}
|
||||
|
||||
io.UserData = &this->m_imguiCustomData;
|
||||
io.UserData = &m_imguiCustomData;
|
||||
|
||||
auto scale = ImHexApi::System::getGlobalScale();
|
||||
style.ScaleAllSizes(scale);
|
||||
|
|
@ -1219,7 +1219,7 @@ namespace hex {
|
|||
}
|
||||
|
||||
|
||||
ImGui_ImplGlfw_InitForOpenGL(this->m_window, true);
|
||||
ImGui_ImplGlfw_InitForOpenGL(m_window, true);
|
||||
|
||||
#if defined(OS_MACOS)
|
||||
ImGui_ImplOpenGL3_Init("#version 150");
|
||||
|
|
@ -1238,9 +1238,9 @@ namespace hex {
|
|||
void Window::exitGLFW() {
|
||||
{
|
||||
int x = 0, y = 0, width = 0, height = 0, maximized = 0;
|
||||
glfwGetWindowPos(this->m_window, &x, &y);
|
||||
glfwGetWindowSize(this->m_window, &width, &height);
|
||||
maximized = glfwGetWindowAttrib(this->m_window, GLFW_MAXIMIZED);
|
||||
glfwGetWindowPos(m_window, &x, &y);
|
||||
glfwGetWindowSize(m_window, &width, &height);
|
||||
maximized = glfwGetWindowAttrib(m_window, GLFW_MAXIMIZED);
|
||||
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.x", x);
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.y", y);
|
||||
|
|
@ -1249,10 +1249,10 @@ namespace hex {
|
|||
ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.window.maximized", maximized);
|
||||
}
|
||||
|
||||
glfwDestroyWindow(this->m_window);
|
||||
glfwDestroyWindow(m_window);
|
||||
glfwTerminate();
|
||||
|
||||
this->m_window = nullptr;
|
||||
m_window = nullptr;
|
||||
}
|
||||
|
||||
void Window::exitImGui() {
|
||||
|
|
|
|||
|
|
@ -113,13 +113,13 @@ namespace hex {
|
|||
float xStep = (size.x * 0.95F) / 0xFF;
|
||||
float yStep = (size.y * 0.95F) / 0xFF;
|
||||
|
||||
if (!this->m_processing)
|
||||
for (size_t i = 0; i < (this->m_buffer.empty() ? 0 : this->m_buffer.size() - 1); i++) {
|
||||
auto x = this->m_buffer[i] * xStep;
|
||||
auto y = this->m_buffer[i + 1] * yStep;
|
||||
if (!m_processing)
|
||||
for (size_t i = 0; i < (m_buffer.empty() ? 0 : m_buffer.size() - 1); i++) {
|
||||
auto x = m_buffer[i] * xStep;
|
||||
auto y = m_buffer[i + 1] * yStep;
|
||||
|
||||
auto color = ImLerp(ImColor(0xFF, 0x6D, 0x01).Value, ImColor(0x01, 0x93, 0xFF).Value, float(i) / this->m_buffer.size()) + ImVec4(this->m_glowBuffer[i], this->m_glowBuffer[i], this->m_glowBuffer[i], 0.0F);
|
||||
color.w = this->m_opacity;
|
||||
auto color = ImLerp(ImColor(0xFF, 0x6D, 0x01).Value, ImColor(0x01, 0x93, 0xFF).Value, float(i) / m_buffer.size()) + ImVec4(m_glowBuffer[i], m_glowBuffer[i], m_glowBuffer[i], 0.0F);
|
||||
color.w = m_opacity;
|
||||
|
||||
auto pos = ImGui::GetWindowPos() + ImVec2(size.x * 0.025F, size.y * 0.025F) + ImVec2(x, y);
|
||||
drawList->AddRectFilled(pos, pos + ImVec2(xStep, yStep), ImColor(color));
|
||||
|
|
@ -130,36 +130,36 @@ namespace hex {
|
|||
}
|
||||
|
||||
void process(prv::Provider *provider, u64 address, size_t size) {
|
||||
this->m_processing = true;
|
||||
this->m_buffer = impl::getSampleSelection(provider, address, size, this->m_sampleSize);
|
||||
m_processing = true;
|
||||
m_buffer = impl::getSampleSelection(provider, address, size, m_sampleSize);
|
||||
processImpl();
|
||||
this->m_processing = false;
|
||||
m_processing = false;
|
||||
}
|
||||
|
||||
void process(const std::vector<u8> &buffer) {
|
||||
this->m_processing = true;
|
||||
this->m_buffer = impl::getSampleSelection(buffer, this->m_sampleSize);
|
||||
m_processing = true;
|
||||
m_buffer = impl::getSampleSelection(buffer, m_sampleSize);
|
||||
processImpl();
|
||||
this->m_processing = false;
|
||||
m_processing = false;
|
||||
}
|
||||
|
||||
void reset(u64 size) {
|
||||
this->m_processing = true;
|
||||
this->m_buffer.clear();
|
||||
this->m_buffer.reserve(this->m_sampleSize);
|
||||
this->m_byteCount = 0;
|
||||
this->m_fileSize = size;
|
||||
m_processing = true;
|
||||
m_buffer.clear();
|
||||
m_buffer.reserve(m_sampleSize);
|
||||
m_byteCount = 0;
|
||||
m_fileSize = size;
|
||||
}
|
||||
|
||||
void update(u8 byte) {
|
||||
// Check if there is some space left
|
||||
if (this->m_byteCount < this->m_fileSize) {
|
||||
if ((this->m_byteCount % u64(std::ceil(double(this->m_fileSize) / double(this->m_sampleSize)))) == 0)
|
||||
this->m_buffer.push_back(byte);
|
||||
++this->m_byteCount;
|
||||
if (this->m_byteCount == this->m_fileSize) {
|
||||
if (m_byteCount < m_fileSize) {
|
||||
if ((m_byteCount % u64(std::ceil(double(m_fileSize) / double(m_sampleSize)))) == 0)
|
||||
m_buffer.push_back(byte);
|
||||
++m_byteCount;
|
||||
if (m_byteCount == m_fileSize) {
|
||||
processImpl();
|
||||
this->m_processing = false;
|
||||
m_processing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -167,20 +167,20 @@ namespace hex {
|
|||
|
||||
private:
|
||||
void processImpl() {
|
||||
this->m_glowBuffer.resize(this->m_buffer.size());
|
||||
m_glowBuffer.resize(m_buffer.size());
|
||||
|
||||
std::map<u64, size_t> heatMap;
|
||||
for (size_t i = 0; i < (this->m_buffer.empty() ? 0 : this->m_buffer.size() - 1); i++) {
|
||||
auto count = ++heatMap[this->m_buffer[i] << 8 | heatMap[i + 1]];
|
||||
for (size_t i = 0; i < (m_buffer.empty() ? 0 : m_buffer.size() - 1); i++) {
|
||||
auto count = ++heatMap[m_buffer[i] << 8 | heatMap[i + 1]];
|
||||
|
||||
this->m_highestCount = std::max(this->m_highestCount, count);
|
||||
m_highestCount = std::max(m_highestCount, count);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < (this->m_buffer.empty() ? 0 : this->m_buffer.size() - 1); i++) {
|
||||
this->m_glowBuffer[i] = std::min<float>(0.2F + (float(heatMap[this->m_buffer[i] << 8 | this->m_buffer[i + 1]]) / float(this->m_highestCount / 1000)), 1.0F);
|
||||
for (size_t i = 0; i < (m_buffer.empty() ? 0 : m_buffer.size() - 1); i++) {
|
||||
m_glowBuffer[i] = std::min<float>(0.2F + (float(heatMap[m_buffer[i] << 8 | m_buffer[i + 1]]) / float(m_highestCount / 1000)), 1.0F);
|
||||
}
|
||||
|
||||
this->m_opacity = (log10(float(this->m_sampleSize)) / log10(float(m_highestCount))) / 10.0F;
|
||||
m_opacity = (log10(float(m_sampleSize)) / log10(float(m_highestCount))) / 10.0F;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -209,13 +209,13 @@ namespace hex {
|
|||
float xStep = (size.x * 0.95F) / 0xFF;
|
||||
float yStep = (size.y * 0.95F) / 0xFF;
|
||||
|
||||
if (!this->m_processing)
|
||||
for (size_t i = 0; i < (this->m_buffer.empty() ? 0 : this->m_buffer.size()); i++) {
|
||||
auto x = this->m_buffer[i] * xStep;
|
||||
auto y = yStep * ((float(i) / this->m_buffer.size()) * 0xFF);
|
||||
if (!m_processing)
|
||||
for (size_t i = 0; i < (m_buffer.empty() ? 0 : m_buffer.size()); i++) {
|
||||
auto x = m_buffer[i] * xStep;
|
||||
auto y = yStep * ((float(i) / m_buffer.size()) * 0xFF);
|
||||
|
||||
auto color = ImLerp(ImColor(0xFF, 0x6D, 0x01).Value, ImColor(0x01, 0x93, 0xFF).Value, float(i) / this->m_buffer.size()) + ImVec4(this->m_glowBuffer[i], this->m_glowBuffer[i], this->m_glowBuffer[i], 0.0F);
|
||||
color.w = this->m_opacity;
|
||||
auto color = ImLerp(ImColor(0xFF, 0x6D, 0x01).Value, ImColor(0x01, 0x93, 0xFF).Value, float(i) / m_buffer.size()) + ImVec4(m_glowBuffer[i], m_glowBuffer[i], m_glowBuffer[i], 0.0F);
|
||||
color.w = m_opacity;
|
||||
|
||||
auto pos = ImGui::GetWindowPos() + ImVec2(size.x * 0.025F, size.y * 0.025F) + ImVec2(x, y);
|
||||
drawList->AddRectFilled(pos, pos + ImVec2(xStep, yStep), ImColor(color));
|
||||
|
|
@ -226,56 +226,56 @@ namespace hex {
|
|||
}
|
||||
|
||||
void process(prv::Provider *provider, u64 address, size_t size) {
|
||||
this->m_processing = true;
|
||||
this->m_buffer = impl::getSampleSelection(provider, address, size, this->m_sampleSize);
|
||||
m_processing = true;
|
||||
m_buffer = impl::getSampleSelection(provider, address, size, m_sampleSize);
|
||||
processImpl();
|
||||
this->m_processing = false;
|
||||
m_processing = false;
|
||||
}
|
||||
|
||||
void process(const std::vector<u8> &buffer) {
|
||||
this->m_processing = true;
|
||||
this->m_buffer = impl::getSampleSelection(buffer, this->m_sampleSize);
|
||||
m_processing = true;
|
||||
m_buffer = impl::getSampleSelection(buffer, m_sampleSize);
|
||||
processImpl();
|
||||
this->m_processing = false;
|
||||
m_processing = false;
|
||||
}
|
||||
|
||||
void reset(u64 size) {
|
||||
this->m_processing = true;
|
||||
this->m_buffer.clear();
|
||||
this->m_buffer.reserve(this->m_sampleSize);
|
||||
this->m_byteCount = 0;
|
||||
this->m_fileSize = size;
|
||||
m_processing = true;
|
||||
m_buffer.clear();
|
||||
m_buffer.reserve(m_sampleSize);
|
||||
m_byteCount = 0;
|
||||
m_fileSize = size;
|
||||
}
|
||||
|
||||
void update(u8 byte) {
|
||||
// Check if there is some space left
|
||||
if (this->m_byteCount < this->m_fileSize) {
|
||||
if ((this->m_byteCount % u64(std::ceil(double(this->m_fileSize) / double(this->m_sampleSize)))) == 0)
|
||||
this->m_buffer.push_back(byte);
|
||||
++this->m_byteCount;
|
||||
if (this->m_byteCount == this->m_fileSize) {
|
||||
if (m_byteCount < m_fileSize) {
|
||||
if ((m_byteCount % u64(std::ceil(double(m_fileSize) / double(m_sampleSize)))) == 0)
|
||||
m_buffer.push_back(byte);
|
||||
++m_byteCount;
|
||||
if (m_byteCount == m_fileSize) {
|
||||
processImpl();
|
||||
this->m_processing = false;
|
||||
m_processing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void processImpl() {
|
||||
this->m_glowBuffer.resize(this->m_buffer.size());
|
||||
m_glowBuffer.resize(m_buffer.size());
|
||||
|
||||
std::map<u64, size_t> heatMap;
|
||||
for (size_t i = 0; i < (this->m_buffer.empty() ? 0 : this->m_buffer.size() - 1); i++) {
|
||||
auto count = ++heatMap[this->m_buffer[i] << 8 | heatMap[i + 1]];
|
||||
for (size_t i = 0; i < (m_buffer.empty() ? 0 : m_buffer.size() - 1); i++) {
|
||||
auto count = ++heatMap[m_buffer[i] << 8 | heatMap[i + 1]];
|
||||
|
||||
this->m_highestCount = std::max(this->m_highestCount, count);
|
||||
m_highestCount = std::max(m_highestCount, count);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < (this->m_buffer.empty() ? 0 : this->m_buffer.size() - 1); i++) {
|
||||
this->m_glowBuffer[i] = std::min<float>(0.2F + (float(heatMap[this->m_buffer[i] << 8 | this->m_buffer[i + 1]]) / float(this->m_highestCount / 1000)), 1.0F);
|
||||
for (size_t i = 0; i < (m_buffer.empty() ? 0 : m_buffer.size() - 1); i++) {
|
||||
m_glowBuffer[i] = std::min<float>(0.2F + (float(heatMap[m_buffer[i] << 8 | m_buffer[i + 1]]) / float(m_highestCount / 1000)), 1.0F);
|
||||
}
|
||||
|
||||
this->m_opacity = (log10(float(this->m_sampleSize)) / log10(float(m_highestCount))) / 10.0F;
|
||||
m_opacity = (log10(float(m_sampleSize)) / log10(float(m_highestCount))) / 10.0F;
|
||||
}
|
||||
private:
|
||||
size_t m_sampleSize = 0;
|
||||
|
|
@ -298,7 +298,7 @@ namespace hex {
|
|||
|
||||
void draw(ImVec2 size, ImPlotFlags flags, bool updateHandle = false) {
|
||||
|
||||
if (!this->m_processing && ImPlot::BeginPlot("##ChunkBasedAnalysis", size, flags)) {
|
||||
if (!m_processing && ImPlot::BeginPlot("##ChunkBasedAnalysis", size, flags)) {
|
||||
ImPlot::SetupAxes("hex.builtin.common.address"_lang, "hex.builtin.view.information.entropy"_lang,
|
||||
ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch,
|
||||
ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch);
|
||||
|
|
@ -307,31 +307,31 @@ namespace hex {
|
|||
|
||||
// Set the axis limit to [first block : last block]
|
||||
ImPlot::SetupAxesLimits(
|
||||
this->m_xBlockEntropy.empty() ? 0 : this->m_xBlockEntropy.front(),
|
||||
this->m_xBlockEntropy.empty() ? 0 : this->m_xBlockEntropy.back(),
|
||||
m_xBlockEntropy.empty() ? 0 : m_xBlockEntropy.front(),
|
||||
m_xBlockEntropy.empty() ? 0 : m_xBlockEntropy.back(),
|
||||
-0.1F,
|
||||
1.1F,
|
||||
ImGuiCond_Always);
|
||||
|
||||
// Draw the plot
|
||||
ImPlot::PlotLine("##ChunkBasedAnalysisLine", this->m_xBlockEntropy.data(), this->m_yBlockEntropySampled.data(), this->m_xBlockEntropy.size());
|
||||
ImPlot::PlotLine("##ChunkBasedAnalysisLine", m_xBlockEntropy.data(), m_yBlockEntropySampled.data(), m_xBlockEntropy.size());
|
||||
|
||||
// The parameter updateHandle is used when using the pattern language since we don't have a provider
|
||||
// but just a set of bytes, we won't be able to use the drag bar correctly.
|
||||
if (updateHandle) {
|
||||
// Set a draggable line on the plot
|
||||
if (ImPlot::DragLineX(1, &this->m_handlePosition, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
|
||||
if (ImPlot::DragLineX(1, &m_handlePosition, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
|
||||
// The line was dragged, update the position in the hex editor
|
||||
|
||||
// Clamp the value between the start/end of the region to analyze
|
||||
this->m_handlePosition = std::clamp<double>(
|
||||
this->m_handlePosition,
|
||||
this->m_startAddress,
|
||||
this->m_endAddress);
|
||||
m_handlePosition = std::clamp<double>(
|
||||
m_handlePosition,
|
||||
m_startAddress,
|
||||
m_endAddress);
|
||||
|
||||
// Compute the position inside hex editor
|
||||
u64 address = u64(std::max<double>(this->m_handlePosition, 0)) + this->m_baseAddress;
|
||||
address = std::min<u64>(address, this->m_baseAddress + this->m_fileSize - 1);
|
||||
u64 address = u64(std::max<double>(m_handlePosition, 0)) + m_baseAddress;
|
||||
address = std::min<u64>(address, m_baseAddress + m_fileSize - 1);
|
||||
ImHexApi::HexEditor::setSelection(address, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -340,92 +340,92 @@ namespace hex {
|
|||
}
|
||||
|
||||
void process(prv::Provider *provider, u64 chunkSize, u64 startAddress, u64 endAddress) {
|
||||
this->m_processing = true;
|
||||
m_processing = true;
|
||||
|
||||
// Update attributes
|
||||
this->m_chunkSize = chunkSize;
|
||||
this->m_startAddress = startAddress;
|
||||
this->m_endAddress = endAddress;
|
||||
m_chunkSize = chunkSize;
|
||||
m_startAddress = startAddress;
|
||||
m_endAddress = endAddress;
|
||||
|
||||
this->m_baseAddress = provider->getBaseAddress();
|
||||
this->m_fileSize = provider->getSize();
|
||||
m_baseAddress = provider->getBaseAddress();
|
||||
m_fileSize = provider->getSize();
|
||||
|
||||
// Get a file reader
|
||||
auto reader = prv::ProviderReader(provider);
|
||||
std::vector<u8> bytes = reader.read(this->m_startAddress, this->m_endAddress - this->m_startAddress);
|
||||
std::vector<u8> bytes = reader.read(m_startAddress, m_endAddress - m_startAddress);
|
||||
|
||||
this->processImpl(bytes);
|
||||
|
||||
// Set the diagram handle position to the start of the plot
|
||||
this->m_handlePosition = this->m_startAddress;
|
||||
m_handlePosition = m_startAddress;
|
||||
|
||||
this->m_processing = false;
|
||||
m_processing = false;
|
||||
}
|
||||
|
||||
void process(const std::vector<u8> &buffer, u64 chunkSize) {
|
||||
this->m_processing = true;
|
||||
m_processing = true;
|
||||
|
||||
// Update attributes (use buffer size as end address)
|
||||
this->m_chunkSize = chunkSize;
|
||||
this->m_startAddress = 0;
|
||||
this->m_endAddress = buffer.size();
|
||||
m_chunkSize = chunkSize;
|
||||
m_startAddress = 0;
|
||||
m_endAddress = buffer.size();
|
||||
|
||||
this->m_baseAddress = 0;
|
||||
this->m_fileSize = buffer.size();
|
||||
m_baseAddress = 0;
|
||||
m_fileSize = buffer.size();
|
||||
|
||||
this->processImpl(buffer);
|
||||
|
||||
// Set the diagram handle position to the start of the plot
|
||||
this->m_handlePosition = this->m_startAddress;
|
||||
m_handlePosition = m_startAddress;
|
||||
|
||||
this->m_processing = false;
|
||||
m_processing = false;
|
||||
}
|
||||
|
||||
// Reset the entropy analysis
|
||||
void reset(u64 chunkSize, u64 startAddress, u64 endAddress, u64 baseAddress, u64 size) {
|
||||
this->m_processing = true;
|
||||
m_processing = true;
|
||||
|
||||
// Update attributes
|
||||
this->m_chunkSize = chunkSize;
|
||||
this->m_startAddress = startAddress;
|
||||
this->m_endAddress = endAddress;
|
||||
this->m_baseAddress = baseAddress;
|
||||
this->m_fileSize = size;
|
||||
m_chunkSize = chunkSize;
|
||||
m_startAddress = startAddress;
|
||||
m_endAddress = endAddress;
|
||||
m_baseAddress = baseAddress;
|
||||
m_fileSize = size;
|
||||
|
||||
this->m_blockValueCounts = { 0 };
|
||||
m_blockValueCounts = { 0 };
|
||||
|
||||
// Reset and resize the array
|
||||
this->m_yBlockEntropy.clear();
|
||||
m_yBlockEntropy.clear();
|
||||
|
||||
this->m_byteCount = 0;
|
||||
this->m_blockCount = 0;
|
||||
m_byteCount = 0;
|
||||
m_blockCount = 0;
|
||||
|
||||
// Set the diagram handle position to the start of the plot
|
||||
this->m_handlePosition = this->m_startAddress;
|
||||
m_handlePosition = m_startAddress;
|
||||
}
|
||||
|
||||
// Process one byte at the time
|
||||
void update(u8 byte) {
|
||||
u64 totalBlock = std::ceil((this->m_endAddress - this->m_startAddress) / this->m_chunkSize);
|
||||
u64 totalBlock = std::ceil((m_endAddress - m_startAddress) / m_chunkSize);
|
||||
|
||||
// Check if there is still some
|
||||
if (this->m_blockCount < totalBlock) {
|
||||
if (m_blockCount < totalBlock) {
|
||||
// Increment the occurrence of the current byte
|
||||
this->m_blockValueCounts[byte]++;
|
||||
m_blockValueCounts[byte]++;
|
||||
|
||||
this->m_byteCount++;
|
||||
m_byteCount++;
|
||||
// Check if we processed one complete chunk, if so compute the entropy and start analysing the next chunk
|
||||
if (((this->m_byteCount % this->m_chunkSize) == 0) || this->m_byteCount == (this->m_endAddress - this->m_startAddress)) [[unlikely]] {
|
||||
this->m_yBlockEntropy.push_back(calculateEntropy(this->m_blockValueCounts, this->m_chunkSize));
|
||||
if (((m_byteCount % m_chunkSize) == 0) || m_byteCount == (m_endAddress - m_startAddress)) [[unlikely]] {
|
||||
m_yBlockEntropy.push_back(calculateEntropy(m_blockValueCounts, m_chunkSize));
|
||||
|
||||
this->m_blockCount += 1;
|
||||
this->m_blockValueCounts = { 0 };
|
||||
m_blockCount += 1;
|
||||
m_blockValueCounts = { 0 };
|
||||
}
|
||||
|
||||
// Check if we processed the last block, if so setup the X axis part of the data
|
||||
if (this->m_blockCount == totalBlock) {
|
||||
if (m_blockCount == totalBlock) {
|
||||
processFinalize();
|
||||
this->m_processing = false;
|
||||
m_processing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -456,72 +456,72 @@ namespace hex {
|
|||
// Return the highest entropy value among all of the blocks
|
||||
double getHighestEntropyBlockValue() {
|
||||
double result = 0.0f;
|
||||
if (!this->m_yBlockEntropy.empty())
|
||||
result = *std::max_element(this->m_yBlockEntropy.begin(), this->m_yBlockEntropy.end());
|
||||
if (!m_yBlockEntropy.empty())
|
||||
result = *std::max_element(m_yBlockEntropy.begin(), m_yBlockEntropy.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
// Return the highest entropy value among all of the blocks
|
||||
u64 getHighestEntropyBlockAddress() {
|
||||
u64 address = 0x00;
|
||||
if (!this->m_yBlockEntropy.empty())
|
||||
address = (std::max_element(this->m_yBlockEntropy.begin(), this->m_yBlockEntropy.end()) - this->m_yBlockEntropy.begin()) * this->m_blockSize;
|
||||
return this->m_startAddress + address;
|
||||
if (!m_yBlockEntropy.empty())
|
||||
address = (std::max_element(m_yBlockEntropy.begin(), m_yBlockEntropy.end()) - m_yBlockEntropy.begin()) * m_blockSize;
|
||||
return m_startAddress + address;
|
||||
}
|
||||
|
||||
// Return the highest entropy value among all of the blocks
|
||||
double getLowestEntropyBlockValue() {
|
||||
double result = 0.0f;
|
||||
if (this->m_yBlockEntropy.size() > 1)
|
||||
result = *std::min_element(this->m_yBlockEntropy.begin(), this->m_yBlockEntropy.end() - 1);
|
||||
if (m_yBlockEntropy.size() > 1)
|
||||
result = *std::min_element(m_yBlockEntropy.begin(), m_yBlockEntropy.end() - 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Return the highest entropy value among all of the blocks
|
||||
u64 getLowestEntropyBlockAddress() {
|
||||
u64 address = 0x00;
|
||||
if (this->m_yBlockEntropy.size() > 1)
|
||||
address = (std::min_element(this->m_yBlockEntropy.begin(), this->m_yBlockEntropy.end() - 1) - this->m_yBlockEntropy.begin()) * this->m_blockSize;
|
||||
return this->m_startAddress + address;
|
||||
if (m_yBlockEntropy.size() > 1)
|
||||
address = (std::min_element(m_yBlockEntropy.begin(), m_yBlockEntropy.end() - 1) - m_yBlockEntropy.begin()) * m_blockSize;
|
||||
return m_startAddress + address;
|
||||
}
|
||||
|
||||
// Return the number of blocks that have been processed
|
||||
u64 getSize() const {
|
||||
return this->m_yBlockEntropySampled.size();
|
||||
return m_yBlockEntropySampled.size();
|
||||
}
|
||||
|
||||
// Return the size of the chunk used for this analysis
|
||||
u64 getChunkSize() const {
|
||||
return this->m_chunkSize;
|
||||
return m_chunkSize;
|
||||
}
|
||||
|
||||
void setHandlePosition(u64 filePosition) {
|
||||
this->m_handlePosition = filePosition;
|
||||
m_handlePosition = filePosition;
|
||||
}
|
||||
|
||||
private:
|
||||
// Private method used to factorize the process public method
|
||||
void processImpl(const std::vector<u8> &bytes) {
|
||||
this->m_blockValueCounts = { 0 };
|
||||
m_blockValueCounts = { 0 };
|
||||
|
||||
// Reset and resize the array
|
||||
this->m_yBlockEntropy.clear();
|
||||
m_yBlockEntropy.clear();
|
||||
|
||||
this->m_byteCount = 0;
|
||||
this->m_blockCount = 0;
|
||||
m_byteCount = 0;
|
||||
m_blockCount = 0;
|
||||
|
||||
// Loop over each byte of the file (or a part of it)
|
||||
for (u8 byte: bytes) {
|
||||
// Increment the occurrence of the current byte
|
||||
this->m_blockValueCounts[byte]++;
|
||||
m_blockValueCounts[byte]++;
|
||||
|
||||
this->m_byteCount++;
|
||||
m_byteCount++;
|
||||
// Check if we processed one complete chunk, if so compute the entropy and start analysing the next chunk
|
||||
if (((this->m_byteCount % this->m_chunkSize) == 0) || this->m_byteCount == bytes.size() * 8) [[unlikely]] {
|
||||
this->m_yBlockEntropy.push_back(calculateEntropy(this->m_blockValueCounts, this->m_chunkSize));
|
||||
if (((m_byteCount % m_chunkSize) == 0) || m_byteCount == bytes.size() * 8) [[unlikely]] {
|
||||
m_yBlockEntropy.push_back(calculateEntropy(m_blockValueCounts, m_chunkSize));
|
||||
|
||||
this->m_blockCount += 1;
|
||||
this->m_blockValueCounts = { 0 };
|
||||
m_blockCount += 1;
|
||||
m_blockValueCounts = { 0 };
|
||||
}
|
||||
}
|
||||
processFinalize();
|
||||
|
|
@ -529,23 +529,23 @@ namespace hex {
|
|||
|
||||
void processFinalize() {
|
||||
// Only save at most m_sampleSize elements of the result
|
||||
this->m_yBlockEntropySampled = sampleData(this->m_yBlockEntropy, std::min<size_t>(this->m_blockCount + 1, this->m_sampleSize));
|
||||
m_yBlockEntropySampled = sampleData(m_yBlockEntropy, std::min<size_t>(m_blockCount + 1, m_sampleSize));
|
||||
|
||||
if (!this->m_yBlockEntropySampled.empty())
|
||||
this->m_yBlockEntropySampled.push_back(this->m_yBlockEntropySampled.back());
|
||||
if (!m_yBlockEntropySampled.empty())
|
||||
m_yBlockEntropySampled.push_back(m_yBlockEntropySampled.back());
|
||||
|
||||
double stride = std::max(1.0, double(
|
||||
double(std::ceil((this->m_endAddress - this->m_startAddress)) / this->m_blockSize) / this->m_yBlockEntropySampled.size()));
|
||||
double(std::ceil((m_endAddress - m_startAddress)) / m_blockSize) / m_yBlockEntropySampled.size()));
|
||||
|
||||
this->m_blockCount = this->m_yBlockEntropySampled.size() - 1;
|
||||
m_blockCount = m_yBlockEntropySampled.size() - 1;
|
||||
|
||||
// The m_xBlockEntropy attribute is used to specify the position of entropy values
|
||||
// in the plot when the Y axis doesn't start at 0
|
||||
this->m_xBlockEntropy.clear();
|
||||
this->m_xBlockEntropy.resize(this->m_blockCount);
|
||||
for (u64 i = 0; i < this->m_blockCount; ++i)
|
||||
this->m_xBlockEntropy[i] = ((this->m_startAddress / this->m_blockSize) + stride * i) * this->m_blockSize;
|
||||
this->m_xBlockEntropy.push_back(this->m_endAddress);
|
||||
m_xBlockEntropy.clear();
|
||||
m_xBlockEntropy.resize(m_blockCount);
|
||||
for (u64 i = 0; i < m_blockCount; ++i)
|
||||
m_xBlockEntropy[i] = ((m_startAddress / m_blockSize) + stride * i) * m_blockSize;
|
||||
m_xBlockEntropy.push_back(m_endAddress);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -594,12 +594,12 @@ namespace hex {
|
|||
|
||||
void draw(ImVec2 size, ImPlotFlags flags) {
|
||||
|
||||
if (!this->m_processing && ImPlot::BeginPlot("##distribution", size, flags)) {
|
||||
if (!m_processing && ImPlot::BeginPlot("##distribution", size, flags)) {
|
||||
ImPlot::SetupAxes("hex.builtin.common.value"_lang, "hex.builtin.common.count"_lang,
|
||||
ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch,
|
||||
ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch);
|
||||
ImPlot::SetupAxisScale(ImAxis_Y1, ImPlotScale_Log10);
|
||||
ImPlot::SetupAxesLimits(-1, 256, 1, double(*std::max_element(this->m_valueCounts.begin(), this->m_valueCounts.end())) * 1.1F, ImGuiCond_Always);
|
||||
ImPlot::SetupAxesLimits(-1, 256, 1, double(*std::max_element(m_valueCounts.begin(), m_valueCounts.end())) * 1.1F, ImGuiCond_Always);
|
||||
ImPlot::SetupAxisFormat(ImAxis_X1, impl::IntegerAxisFormatter, (void*)("0x%02llX"));
|
||||
ImPlot::SetupAxisTicks(ImAxis_X1, 0, 255, 17);
|
||||
ImPlot::SetupMouseText(ImPlotLocation_NorthEast);
|
||||
|
|
@ -610,67 +610,67 @@ namespace hex {
|
|||
return result;
|
||||
}();
|
||||
|
||||
ImPlot::PlotBars<ImU64>("##bytes", x.data(), this->m_valueCounts.data(), x.size(), 1);
|
||||
ImPlot::PlotBars<ImU64>("##bytes", x.data(), m_valueCounts.data(), x.size(), 1);
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
}
|
||||
|
||||
void process(prv::Provider *provider, u64 startAddress, u64 endAddress) {
|
||||
this->m_processing = true;
|
||||
m_processing = true;
|
||||
|
||||
// Update attributes
|
||||
this->m_startAddress = startAddress;
|
||||
this->m_endAddress = endAddress;
|
||||
m_startAddress = startAddress;
|
||||
m_endAddress = endAddress;
|
||||
|
||||
// Get a file reader
|
||||
auto reader = prv::ProviderReader(provider);
|
||||
std::vector<u8> bytes = reader.read(this->m_startAddress, this->m_endAddress - this->m_startAddress);
|
||||
std::vector<u8> bytes = reader.read(m_startAddress, m_endAddress - m_startAddress);
|
||||
|
||||
this->processImpl(bytes);
|
||||
|
||||
this->m_processing = false;
|
||||
m_processing = false;
|
||||
}
|
||||
|
||||
void process(const std::vector<u8> &buffer) {
|
||||
this->m_processing = true;
|
||||
m_processing = true;
|
||||
|
||||
// Update attributes
|
||||
this->m_startAddress = 0;
|
||||
this->m_endAddress = buffer.size();
|
||||
m_startAddress = 0;
|
||||
m_endAddress = buffer.size();
|
||||
|
||||
this->processImpl(buffer);
|
||||
|
||||
this->m_processing = false;
|
||||
m_processing = false;
|
||||
}
|
||||
|
||||
// Reset the byte distribution array
|
||||
void reset() {
|
||||
this->m_processing = true;
|
||||
this->m_valueCounts.fill(0);
|
||||
this->m_processing = false;
|
||||
m_processing = true;
|
||||
m_valueCounts.fill(0);
|
||||
m_processing = false;
|
||||
}
|
||||
|
||||
// Process one byte at the time
|
||||
void update(u8 byte) {
|
||||
this->m_processing = true;
|
||||
this->m_valueCounts[byte]++;
|
||||
this->m_processing = false;
|
||||
m_processing = true;
|
||||
m_valueCounts[byte]++;
|
||||
m_processing = false;
|
||||
}
|
||||
|
||||
// Return byte distribution array in it's current state
|
||||
std::array<ImU64, 256> & get() {
|
||||
return this->m_valueCounts;
|
||||
return m_valueCounts;
|
||||
}
|
||||
|
||||
private:
|
||||
// Private method used to factorize the process public method
|
||||
void processImpl(const std::vector<u8> &bytes) {
|
||||
// Reset the array
|
||||
this->m_valueCounts.fill(0);
|
||||
m_valueCounts.fill(0);
|
||||
// Loop over each byte of the file (or a part of it)
|
||||
// Increment the occurrence of the current byte
|
||||
for (u8 byte : bytes)
|
||||
this->m_valueCounts[byte]++;
|
||||
m_valueCounts[byte]++;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -689,13 +689,13 @@ namespace hex {
|
|||
|
||||
void draw(ImVec2 size, ImPlotFlags flags, bool updateHandle = false) {
|
||||
// Draw the result of the analysis
|
||||
if (!this->m_processing && ImPlot::BeginPlot("##byte_types", size, flags)) {
|
||||
if (!m_processing && ImPlot::BeginPlot("##byte_types", size, flags)) {
|
||||
ImPlot::SetupAxes("hex.builtin.common.address"_lang, "hex.builtin.common.percentage"_lang,
|
||||
ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch,
|
||||
ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch);
|
||||
ImPlot::SetupAxesLimits(
|
||||
this->m_xBlockTypeDistributions.empty() ? 0 : this->m_xBlockTypeDistributions.front(),
|
||||
this->m_xBlockTypeDistributions.empty() ? 0 : this->m_xBlockTypeDistributions.back(),
|
||||
m_xBlockTypeDistributions.empty() ? 0 : m_xBlockTypeDistributions.front(),
|
||||
m_xBlockTypeDistributions.empty() ? 0 : m_xBlockTypeDistributions.back(),
|
||||
-0.1F,
|
||||
100.1F,
|
||||
ImGuiCond_Always);
|
||||
|
|
@ -709,25 +709,25 @@ namespace hex {
|
|||
};
|
||||
|
||||
for (u32 i = 0; i < Names.size(); i++) {
|
||||
ImPlot::PlotLine(Names[i], this->m_xBlockTypeDistributions.data(), this->m_yBlockTypeDistributionsSampled[i].data(), this->m_xBlockTypeDistributions.size());
|
||||
ImPlot::PlotLine(Names[i], m_xBlockTypeDistributions.data(), m_yBlockTypeDistributionsSampled[i].data(), m_xBlockTypeDistributions.size());
|
||||
}
|
||||
|
||||
// The parameter updateHandle is used when using the pattern language since we don't have a provider
|
||||
// but just a set of bytes, we won't be able to use the drag bar correctly.
|
||||
if (updateHandle) {
|
||||
// Set a draggable line on the plot
|
||||
if (ImPlot::DragLineX(1, &this->m_handlePosition, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
|
||||
if (ImPlot::DragLineX(1, &m_handlePosition, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
|
||||
// The line was dragged, update the position in the hex editor
|
||||
|
||||
// Clamp the value between the start/end of the region to analyze
|
||||
this->m_handlePosition = std::clamp<double>(
|
||||
this->m_handlePosition,
|
||||
this->m_startAddress,
|
||||
this->m_endAddress);
|
||||
m_handlePosition = std::clamp<double>(
|
||||
m_handlePosition,
|
||||
m_startAddress,
|
||||
m_endAddress);
|
||||
|
||||
// Compute the position inside hex editor
|
||||
u64 address = u64(std::max<double>(this->m_handlePosition, 0)) + this->m_baseAddress;
|
||||
address = std::min<u64>(address, this->m_baseAddress + this->m_fileSize - 1);
|
||||
u64 address = u64(std::max<double>(m_handlePosition, 0)) + m_baseAddress;
|
||||
address = std::min<u64>(address, m_baseAddress + m_fileSize - 1);
|
||||
ImHexApi::HexEditor::setSelection(address, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -736,103 +736,103 @@ namespace hex {
|
|||
}
|
||||
|
||||
void process(prv::Provider *provider, u64 startAddress, u64 endAddress) {
|
||||
this->m_processing = true;
|
||||
m_processing = true;
|
||||
|
||||
// Update attributes
|
||||
this->m_startAddress = startAddress;
|
||||
this->m_endAddress = endAddress;
|
||||
this->m_baseAddress = provider->getBaseAddress();
|
||||
this->m_fileSize = provider->getSize();
|
||||
m_startAddress = startAddress;
|
||||
m_endAddress = endAddress;
|
||||
m_baseAddress = provider->getBaseAddress();
|
||||
m_fileSize = provider->getSize();
|
||||
|
||||
// Get a file reader
|
||||
auto reader = prv::ProviderReader(provider);
|
||||
std::vector<u8> bytes = reader.read(this->m_startAddress, this->m_endAddress - this->m_startAddress);
|
||||
std::vector<u8> bytes = reader.read(m_startAddress, m_endAddress - m_startAddress);
|
||||
|
||||
this->processImpl(bytes);
|
||||
|
||||
// Set the diagram handle position to the start of the plot
|
||||
this->m_handlePosition = this->m_startAddress;
|
||||
m_handlePosition = m_startAddress;
|
||||
|
||||
this->m_processing = false;
|
||||
m_processing = false;
|
||||
}
|
||||
|
||||
void process(const std::vector<u8> &buffer, u64 baseAddress, u64 fileSize) {
|
||||
this->m_processing = true;
|
||||
m_processing = true;
|
||||
|
||||
// Update attributes
|
||||
this->m_startAddress = 0;
|
||||
this->m_endAddress = buffer.size();
|
||||
this->m_baseAddress = baseAddress;
|
||||
this->m_fileSize = fileSize;
|
||||
m_startAddress = 0;
|
||||
m_endAddress = buffer.size();
|
||||
m_baseAddress = baseAddress;
|
||||
m_fileSize = fileSize;
|
||||
|
||||
this->processImpl(buffer);
|
||||
|
||||
// Set the diagram handle position to the start of the plot
|
||||
this->m_handlePosition = this->m_startAddress;
|
||||
m_handlePosition = m_startAddress;
|
||||
|
||||
this->m_processing = false;
|
||||
m_processing = false;
|
||||
}
|
||||
|
||||
// Reset the byte type distribution analysis
|
||||
void reset(u64 startAddress, u64 endAddress, u64 baseAddress, u64 size) {
|
||||
this->m_processing = true;
|
||||
m_processing = true;
|
||||
|
||||
// Update attributes
|
||||
this->m_startAddress = startAddress;
|
||||
this->m_endAddress = endAddress;
|
||||
this->m_baseAddress = baseAddress;
|
||||
this->m_fileSize = size;
|
||||
m_startAddress = startAddress;
|
||||
m_endAddress = endAddress;
|
||||
m_baseAddress = baseAddress;
|
||||
m_fileSize = size;
|
||||
|
||||
this->m_byteCount = 0;
|
||||
this->m_blockCount = 0;
|
||||
this->m_blockValueCounts = { 0 };
|
||||
m_byteCount = 0;
|
||||
m_blockCount = 0;
|
||||
m_blockValueCounts = { 0 };
|
||||
|
||||
// Reset and resize the array
|
||||
this->m_yBlockTypeDistributions.fill({});
|
||||
m_yBlockTypeDistributions.fill({});
|
||||
|
||||
// Set the diagram handle position to the start of the plot
|
||||
this->m_handlePosition = this->m_startAddress;
|
||||
m_handlePosition = m_startAddress;
|
||||
}
|
||||
|
||||
// Process one byte at the time
|
||||
void update(u8 byte) {
|
||||
u64 totalBlock = std::ceil((this->m_endAddress - this->m_startAddress) / this->m_blockSize);
|
||||
u64 totalBlock = std::ceil((m_endAddress - m_startAddress) / m_blockSize);
|
||||
// Check if there is still some block to process
|
||||
if (this->m_blockCount < totalBlock) {
|
||||
if (m_blockCount < totalBlock) {
|
||||
|
||||
this->m_blockValueCounts[byte]++;
|
||||
m_blockValueCounts[byte]++;
|
||||
|
||||
this->m_byteCount++;
|
||||
if (((this->m_byteCount % this->m_blockSize) == 0) || this->m_byteCount == (this->m_endAddress - this->m_startAddress)) [[unlikely]] {
|
||||
auto typeDist = calculateTypeDistribution(this->m_blockValueCounts, this->m_blockSize);
|
||||
m_byteCount++;
|
||||
if (((m_byteCount % m_blockSize) == 0) || m_byteCount == (m_endAddress - m_startAddress)) [[unlikely]] {
|
||||
auto typeDist = calculateTypeDistribution(m_blockValueCounts, m_blockSize);
|
||||
for (size_t i = 0; i < typeDist.size(); i++)
|
||||
this->m_yBlockTypeDistributions[i].push_back(typeDist[i] * 100);
|
||||
m_yBlockTypeDistributions[i].push_back(typeDist[i] * 100);
|
||||
|
||||
this->m_blockCount += 1;
|
||||
this->m_blockValueCounts = { 0 };
|
||||
m_blockCount += 1;
|
||||
m_blockValueCounts = { 0 };
|
||||
}
|
||||
|
||||
// Check if we processed the last block, if so setup the X axis part of the data
|
||||
if (this->m_blockCount == totalBlock) {
|
||||
if (m_blockCount == totalBlock) {
|
||||
|
||||
processFinalize();
|
||||
this->m_processing = false;
|
||||
m_processing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the percentage of plain text character inside the analyzed region
|
||||
double getPlainTextCharacterPercentage() {
|
||||
if (this->m_yBlockTypeDistributions[2].empty() || this->m_yBlockTypeDistributions[4].empty())
|
||||
if (m_yBlockTypeDistributions[2].empty() || m_yBlockTypeDistributions[4].empty())
|
||||
return -1.0;
|
||||
|
||||
|
||||
double plainTextPercentage = std::reduce(this->m_yBlockTypeDistributions[2].begin(), this->m_yBlockTypeDistributions[2].end()) / this->m_yBlockTypeDistributions[2].size();
|
||||
return plainTextPercentage + std::reduce(this->m_yBlockTypeDistributions[4].begin(), this->m_yBlockTypeDistributions[4].end()) / this->m_yBlockTypeDistributions[4].size();
|
||||
double plainTextPercentage = std::reduce(m_yBlockTypeDistributions[2].begin(), m_yBlockTypeDistributions[2].end()) / m_yBlockTypeDistributions[2].size();
|
||||
return plainTextPercentage + std::reduce(m_yBlockTypeDistributions[4].begin(), m_yBlockTypeDistributions[4].end()) / m_yBlockTypeDistributions[4].size();
|
||||
}
|
||||
|
||||
void setHandlePosition(u64 filePosition) {
|
||||
this->m_handlePosition = filePosition;
|
||||
m_handlePosition = filePosition;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -880,24 +880,24 @@ namespace hex {
|
|||
|
||||
// Private method used to factorize the process public method
|
||||
void processImpl(const std::vector<u8> &bytes) {
|
||||
this->m_blockValueCounts = { 0 };
|
||||
m_blockValueCounts = { 0 };
|
||||
|
||||
this->m_yBlockTypeDistributions.fill({});
|
||||
this->m_byteCount = 0;
|
||||
this->m_blockCount = 0;
|
||||
m_yBlockTypeDistributions.fill({});
|
||||
m_byteCount = 0;
|
||||
m_blockCount = 0;
|
||||
|
||||
// Loop over each byte of the file (or a part of it)
|
||||
for (u8 byte : bytes) {
|
||||
this->m_blockValueCounts[byte]++;
|
||||
m_blockValueCounts[byte]++;
|
||||
|
||||
this->m_byteCount++;
|
||||
if (((this->m_byteCount % this->m_blockSize) == 0) || this->m_byteCount == (this->m_endAddress - this->m_startAddress)) [[unlikely]] {
|
||||
auto typeDist = calculateTypeDistribution(this->m_blockValueCounts, this->m_blockSize);
|
||||
m_byteCount++;
|
||||
if (((m_byteCount % m_blockSize) == 0) || m_byteCount == (m_endAddress - m_startAddress)) [[unlikely]] {
|
||||
auto typeDist = calculateTypeDistribution(m_blockValueCounts, m_blockSize);
|
||||
for (size_t i = 0; i < typeDist.size(); i++)
|
||||
this->m_yBlockTypeDistributions[i].push_back(typeDist[i] * 100);
|
||||
m_yBlockTypeDistributions[i].push_back(typeDist[i] * 100);
|
||||
|
||||
this->m_blockCount += 1;
|
||||
this->m_blockValueCounts = { 0 };
|
||||
m_blockCount += 1;
|
||||
m_blockValueCounts = { 0 };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -906,23 +906,23 @@ namespace hex {
|
|||
|
||||
void processFinalize() {
|
||||
// Only save at most m_sampleSize elements of the result
|
||||
for (size_t i = 0; i < this->m_yBlockTypeDistributions.size(); ++i) {
|
||||
this->m_yBlockTypeDistributionsSampled[i] = sampleData(this->m_yBlockTypeDistributions[i], std::min<size_t>(this->m_blockCount + 1, this->m_sampleSize));
|
||||
for (size_t i = 0; i < m_yBlockTypeDistributions.size(); ++i) {
|
||||
m_yBlockTypeDistributionsSampled[i] = sampleData(m_yBlockTypeDistributions[i], std::min<size_t>(m_blockCount + 1, m_sampleSize));
|
||||
|
||||
if (!this->m_yBlockTypeDistributionsSampled[i].empty())
|
||||
this->m_yBlockTypeDistributionsSampled[i].push_back(this->m_yBlockTypeDistributionsSampled[i].back());
|
||||
if (!m_yBlockTypeDistributionsSampled[i].empty())
|
||||
m_yBlockTypeDistributionsSampled[i].push_back(m_yBlockTypeDistributionsSampled[i].back());
|
||||
}
|
||||
|
||||
double stride = std::max(1.0, double(this->m_blockCount) / this->m_yBlockTypeDistributionsSampled[0].size());
|
||||
this->m_blockCount = this->m_yBlockTypeDistributionsSampled[0].size() - 1;
|
||||
double stride = std::max(1.0, double(m_blockCount) / m_yBlockTypeDistributionsSampled[0].size());
|
||||
m_blockCount = m_yBlockTypeDistributionsSampled[0].size() - 1;
|
||||
|
||||
// The m_xBlockTypeDistributions attribute is used to specify the position of entropy
|
||||
// values in the plot when the Y axis doesn't start at 0
|
||||
this->m_xBlockTypeDistributions.clear();
|
||||
this->m_xBlockTypeDistributions.resize(this->m_blockCount);
|
||||
for (u64 i = 0; i < this->m_blockCount; ++i)
|
||||
this->m_xBlockTypeDistributions[i] = this->m_startAddress + (stride * i * this->m_blockSize);
|
||||
this->m_xBlockTypeDistributions.push_back(this->m_endAddress);
|
||||
m_xBlockTypeDistributions.clear();
|
||||
m_xBlockTypeDistributions.resize(m_blockCount);
|
||||
for (u64 i = 0; i < m_blockCount; ++i)
|
||||
m_xBlockTypeDistributions[i] = m_startAddress + (stride * i * m_blockSize);
|
||||
m_xBlockTypeDistributions.push_back(m_endAddress);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -16,16 +16,16 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TextUnformatted("hex.builtin.popup.blocking_task.desc"_lang);
|
||||
ImGui::Separator();
|
||||
|
||||
if (this->m_task.getProgress() == 0)
|
||||
if (m_task.getProgress() == 0)
|
||||
ImGuiExt::TextSpinner("");
|
||||
else
|
||||
ImGui::ProgressBar(this->m_task.getProgress() / 100.0F);
|
||||
ImGui::ProgressBar(m_task.getProgress() / 100.0F);
|
||||
|
||||
ImGui::NewLine();
|
||||
if (ImGui::ButtonEx("hex.builtin.common.cancel"_lang, ImVec2(ImGui::GetContentRegionAvail().x, 0)) || ImGui::IsKeyDown(ImGuiKey_Escape))
|
||||
this->m_task.interrupt();
|
||||
m_task.interrupt();
|
||||
|
||||
if (!this->m_task.isRunning()) {
|
||||
if (!m_task.isRunning()) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,23 +24,23 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void drawContent() override {
|
||||
ImGui::PushItemWidth(600_scaled);
|
||||
ImGui::BeginDisabled(this->m_requestTask.isRunning());
|
||||
if (ImGui::InputText("##input", this->m_inputBuffer, ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||
ImGui::BeginDisabled(m_requestTask.isRunning());
|
||||
if (ImGui::InputText("##input", m_inputBuffer, ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||
this->executeQuery();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if (ImGui::BeginChild("##answer", scaled(ImVec2(600, 350)), true, ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
|
||||
if (!this->m_requestTask.isRunning()) {
|
||||
if (this->m_answer.empty()) {
|
||||
if (this->m_noAnswer)
|
||||
if (!m_requestTask.isRunning()) {
|
||||
if (m_answer.empty()) {
|
||||
if (m_noAnswer)
|
||||
ImGuiExt::TextFormattedCentered("{}", "hex.builtin.popup.docs_question.no_answer"_lang);
|
||||
else
|
||||
ImGuiExt::TextFormattedCentered("{}", "hex.builtin.popup.docs_question.prompt"_lang);
|
||||
} else {
|
||||
int id = 1;
|
||||
for (auto &[type, text] : this->m_answer) {
|
||||
for (auto &[type, text] : m_answer) {
|
||||
ImGui::PushID(id);
|
||||
switch (type) {
|
||||
case TextBlockType::Text:
|
||||
|
|
@ -79,10 +79,10 @@ namespace hex::plugin::builtin {
|
|||
|
||||
private:
|
||||
void executeQuery() {
|
||||
this->m_requestTask = TaskManager::createBackgroundTask("Query Docs", [this, input = this->m_inputBuffer](Task &) {
|
||||
this->m_noAnswer = false;
|
||||
m_requestTask = TaskManager::createBackgroundTask("Query Docs", [this, input = m_inputBuffer](Task &) {
|
||||
m_noAnswer = false;
|
||||
for (auto space : { "xj7sbzGbHH260vbpZOu1", "WZzDdGjxmgMSIE3xly6o" }) {
|
||||
this->m_answer.clear();
|
||||
m_answer.clear();
|
||||
|
||||
auto request = HttpRequest("POST", hex::format("https://api.gitbook.com/v1/spaces/{}/search/ask", space));
|
||||
|
||||
|
|
@ -115,19 +115,19 @@ namespace hex::plugin::builtin {
|
|||
|
||||
if (block.starts_with("rust\n")) {
|
||||
block = block.substr(5);
|
||||
this->m_answer.emplace_back(TextBlockType::Code, block);
|
||||
m_answer.emplace_back(TextBlockType::Code, block);
|
||||
} else if (block.starts_with("cpp\n")) {
|
||||
block = block.substr(4);
|
||||
this->m_answer.emplace_back(TextBlockType::Code, block);
|
||||
m_answer.emplace_back(TextBlockType::Code, block);
|
||||
} else {
|
||||
this->m_answer.emplace_back(TextBlockType::Text, block);
|
||||
m_answer.emplace_back(TextBlockType::Text, block);
|
||||
}
|
||||
}
|
||||
} catch(...) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this->m_noAnswer = this->m_answer.empty();
|
||||
m_noAnswer = m_answer.empty();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,10 +31,10 @@ namespace hex::plugin::builtin {
|
|||
if (adjustedPath.empty())
|
||||
adjustedPath = path.filename();
|
||||
|
||||
this->m_files.push_back({ path, adjustedPath });
|
||||
m_files.push_back({ path, adjustedPath });
|
||||
}
|
||||
|
||||
std::sort(this->m_files.begin(), this->m_files.end(), [](const auto &a, const auto &b) {
|
||||
std::sort(m_files.begin(), m_files.end(), [](const auto &a, const auto &b) {
|
||||
return a.first < b.first;
|
||||
});
|
||||
}
|
||||
|
|
@ -44,19 +44,19 @@ namespace hex::plugin::builtin {
|
|||
|
||||
if (ImGui::BeginListBox("##files", scaled(ImVec2(500, 400)))) {
|
||||
u32 index = 0;
|
||||
for (auto &[path, pathName] : this->m_files) {
|
||||
for (auto &[path, pathName] : m_files) {
|
||||
ImGui::PushID(index);
|
||||
|
||||
bool selected = this->m_indices.contains(index);
|
||||
bool selected = m_indices.contains(index);
|
||||
if (ImGui::Selectable(wolv::util::toUTF8String(pathName).c_str(), selected, ImGuiSelectableFlags_DontClosePopups)) {
|
||||
if (!this->m_multiple) {
|
||||
this->m_indices.clear();
|
||||
this->m_indices.insert(index);
|
||||
if (!m_multiple) {
|
||||
m_indices.clear();
|
||||
m_indices.insert(index);
|
||||
} else {
|
||||
if (selected) {
|
||||
this->m_indices.erase(index);
|
||||
m_indices.erase(index);
|
||||
} else {
|
||||
this->m_indices.insert(index);
|
||||
m_indices.insert(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -74,18 +74,18 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
if (ImGui::Button("hex.builtin.common.open"_lang) || doubleClicked) {
|
||||
for (const auto &index : this->m_indices)
|
||||
this->m_openCallback(this->m_files[index].first);
|
||||
for (const auto &index : m_indices)
|
||||
m_openCallback(m_files[index].first);
|
||||
Popup::close();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("hex.builtin.common.browse"_lang)) {
|
||||
fs::openFileBrowser(fs::DialogMode::Open, this->m_validExtensions, [this](const auto &path) {
|
||||
this->m_openCallback(path);
|
||||
fs::openFileBrowser(fs::DialogMode::Open, m_validExtensions, [this](const auto &path) {
|
||||
m_openCallback(path);
|
||||
Popup::close();
|
||||
}, {}, this->m_multiple);
|
||||
}, {}, m_multiple);
|
||||
}
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Escape)))
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@ namespace hex::plugin::builtin {
|
|||
m_message(std::move(message)), m_function(std::move(function)) { }
|
||||
|
||||
void drawContent() override {
|
||||
ImGuiExt::TextFormattedWrapped("{}", this->m_message.c_str());
|
||||
ImGuiExt::TextFormattedWrapped("{}", m_message.c_str());
|
||||
ImGui::NewLine();
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("hex.builtin.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape))
|
||||
this->m_function();
|
||||
m_function();
|
||||
|
||||
ImGui::SetWindowPos((ImHexApi::System::getMainWindowSize() - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
|
||||
|
||||
|
|
|
|||
|
|
@ -17,20 +17,20 @@ namespace hex::plugin::builtin {
|
|||
m_yesFunction(std::move(yesFunction)), m_noFunction(std::move(noFunction)) { }
|
||||
|
||||
void drawContent() override {
|
||||
ImGuiExt::TextFormattedWrapped("{}", this->m_message.c_str());
|
||||
ImGuiExt::TextFormattedWrapped("{}", m_message.c_str());
|
||||
ImGui::NewLine();
|
||||
ImGui::Separator();
|
||||
|
||||
auto width = ImGui::GetWindowWidth();
|
||||
ImGui::SetCursorPosX(width / 9);
|
||||
if (ImGui::Button("hex.builtin.common.yes"_lang, ImVec2(width / 3, 0))) {
|
||||
this->m_yesFunction();
|
||||
m_yesFunction();
|
||||
this->close();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(width / 9 * 5);
|
||||
if (ImGui::Button("hex.builtin.common.no"_lang, ImVec2(width / 3, 0))) {
|
||||
this->m_noFunction();
|
||||
m_noFunction();
|
||||
this->close();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,12 +15,12 @@ namespace hex::plugin::builtin {
|
|||
PopupTelemetryRequest()
|
||||
: hex::Popup<PopupTelemetryRequest>("hex.builtin.common.question", false) {
|
||||
// Check if there is a telemetry uuid
|
||||
this->m_uuid = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.uuid", "").get<std::string>();
|
||||
if(this->m_uuid.empty()) {
|
||||
m_uuid = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.uuid", "").get<std::string>();
|
||||
if(m_uuid.empty()) {
|
||||
// Generate a new uuid
|
||||
this->m_uuid = wolv::hash::generateUUID();
|
||||
m_uuid = wolv::hash::generateUUID();
|
||||
// Save
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.uuid", this->m_uuid);
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.uuid", m_uuid);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted("hex.builtin.welcome.server_contact.data_collected.uuid"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextWrapped("%s", this->m_uuid.c_str());
|
||||
ImGui::TextWrapped("%s", m_uuid.c_str());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
|
|
|||
|
|
@ -19,17 +19,17 @@ namespace hex::plugin::builtin {
|
|||
m_message(std::move(message)), m_function(std::move(function)) { }
|
||||
|
||||
void drawContent() override {
|
||||
ImGuiExt::TextFormattedWrapped("{}", Lang(this->m_message));
|
||||
ImGuiExt::TextFormattedWrapped("{}", Lang(m_message));
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::PushItemWidth(-1);
|
||||
|
||||
if (this->m_justOpened) {
|
||||
if (m_justOpened) {
|
||||
ImGui::SetKeyboardFocusHere();
|
||||
this->m_justOpened = false;
|
||||
m_justOpened = false;
|
||||
}
|
||||
|
||||
ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_KEY, this->m_input);
|
||||
ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_KEY, m_input);
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
ImGui::NewLine();
|
||||
|
|
@ -38,7 +38,7 @@ namespace hex::plugin::builtin {
|
|||
auto width = ImGui::GetWindowWidth();
|
||||
ImGui::SetCursorPosX(width / 9);
|
||||
if (ImGui::Button("hex.builtin.common.okay"_lang, ImVec2(width / 3, 0)) || ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Enter))) {
|
||||
this->m_function(this->m_input);
|
||||
m_function(m_input);
|
||||
this->close();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace hex::plugin::builtin {
|
|||
m_yesFunction(std::move(yesFunction)), m_noFunction(std::move(noFunction)) { }
|
||||
|
||||
void drawContent() override {
|
||||
ImGuiExt::TextFormattedWrapped("{}", this->m_message.c_str());
|
||||
ImGuiExt::TextFormattedWrapped("{}", m_message.c_str());
|
||||
ImGui::NewLine();
|
||||
|
||||
if (ImGui::BeginTable("##unsaved_providers", 1, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * 4))) {
|
||||
|
|
@ -35,13 +35,13 @@ namespace hex::plugin::builtin {
|
|||
auto width = ImGui::GetWindowWidth();
|
||||
ImGui::SetCursorPosX(width / 9);
|
||||
if (ImGui::Button("hex.builtin.common.yes"_lang, ImVec2(width / 3, 0))) {
|
||||
this->m_yesFunction();
|
||||
m_yesFunction();
|
||||
this->close();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(width / 9 * 5);
|
||||
if (ImGui::Button("hex.builtin.common.no"_lang, ImVec2(width / 3, 0)) || ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Escape))) {
|
||||
this->m_noFunction();
|
||||
m_noFunction();
|
||||
this->close();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace hex::plugin::builtin {
|
|||
IntelHexProvider() = default;
|
||||
~IntelHexProvider() override = default;
|
||||
|
||||
[[nodiscard]] bool isAvailable() const override { return this->m_dataValid; }
|
||||
[[nodiscard]] bool isAvailable() const override { return m_dataValid; }
|
||||
[[nodiscard]] bool isReadable() const override { return true; }
|
||||
[[nodiscard]] bool isWritable() const override { return false; }
|
||||
[[nodiscard]] bool isResizable() const override { return false; }
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ namespace hex::plugin::builtin {
|
|||
|
||||
[[nodiscard]] bool isAvailable() const override { return true; }
|
||||
[[nodiscard]] bool isReadable() const override { return true; }
|
||||
[[nodiscard]] bool isWritable() const override { return !this->m_readOnly; }
|
||||
[[nodiscard]] bool isResizable() const override { return !this->m_readOnly; }
|
||||
[[nodiscard]] bool isSavable() const override { return this->m_name.empty(); }
|
||||
[[nodiscard]] bool isWritable() const override { return !m_readOnly; }
|
||||
[[nodiscard]] bool isResizable() const override { return !m_readOnly; }
|
||||
[[nodiscard]] bool isSavable() const override { return m_name.empty(); }
|
||||
[[nodiscard]] bool isSavableAsRecent() const override { return false; }
|
||||
|
||||
[[nodiscard]] bool open() override;
|
||||
|
|
@ -21,7 +21,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void readRaw(u64 offset, void *buffer, size_t size) override;
|
||||
void writeRaw(u64 offset, const void *buffer, size_t size) override;
|
||||
[[nodiscard]] u64 getActualSize() const override { return this->m_data.size(); }
|
||||
[[nodiscard]] u64 getActualSize() const override { return m_data.size(); }
|
||||
|
||||
void resizeRaw(u64 newSize) override;
|
||||
void insertRaw(u64 offset, u64 size) override;
|
||||
|
|
@ -43,7 +43,7 @@ namespace hex::plugin::builtin {
|
|||
void loadSettings(const nlohmann::json &settings) override;
|
||||
[[nodiscard]] nlohmann::json storeSettings(nlohmann::json settings) const override;
|
||||
|
||||
void setReadOnly(bool readOnly) { this->m_readOnly = readOnly; }
|
||||
void setReadOnly(bool readOnly) { m_readOnly = readOnly; }
|
||||
|
||||
private:
|
||||
void renameFile();
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ namespace hex::plugin::builtin {
|
|||
|
||||
[[nodiscard]] bool isAvailable() const override {
|
||||
#ifdef _WIN32
|
||||
return this->m_processHandle != nullptr;
|
||||
return m_processHandle != nullptr;
|
||||
#elif __linux__
|
||||
return this->m_processId != -1;
|
||||
return m_processId != -1;
|
||||
#endif
|
||||
}
|
||||
[[nodiscard]] bool isReadable() const override { return true; }
|
||||
|
|
@ -46,11 +46,11 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void save() override {}
|
||||
|
||||
[[nodiscard]] std::string getName() const override { return hex::format("hex.builtin.provider.process_memory.name"_lang, this->m_selectedProcess != nullptr ? this->m_selectedProcess->name : ""); }
|
||||
[[nodiscard]] std::string getName() const override { return hex::format("hex.builtin.provider.process_memory.name"_lang, m_selectedProcess != nullptr ? m_selectedProcess->name : ""); }
|
||||
[[nodiscard]] std::vector<Description> getDataDescription() const override {
|
||||
return {
|
||||
{ "hex.builtin.provider.process_memory.process_name"_lang, this->m_selectedProcess->name },
|
||||
{ "hex.builtin.provider.process_memory.process_id"_lang, std::to_string(this->m_selectedProcess->id) }
|
||||
{ "hex.builtin.provider.process_memory.process_name"_lang, m_selectedProcess->name },
|
||||
{ "hex.builtin.provider.process_memory.process_id"_lang, std::to_string(m_selectedProcess->id) }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,19 +14,19 @@ namespace hex::plugin::builtin::undo {
|
|||
void undo(prv::Provider *provider) override {
|
||||
hex::unused(provider);
|
||||
|
||||
ImHexApi::Bookmarks::remove(this->m_entry.id);
|
||||
ImHexApi::Bookmarks::remove(m_entry.id);
|
||||
}
|
||||
|
||||
void redo(prv::Provider *provider) override {
|
||||
hex::unused(provider);
|
||||
|
||||
auto &[region, name, comment, color, locked, id] = this->m_entry;
|
||||
auto &[region, name, comment, color, locked, id] = m_entry;
|
||||
|
||||
id = ImHexApi::Bookmarks::add(region, name, comment, color);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string format() const override {
|
||||
return hex::format("Bookmark {} created", this->m_entry.name);
|
||||
return hex::format("Bookmark {} created", m_entry.name);
|
||||
}
|
||||
|
||||
std::unique_ptr<Operation> clone() const override {
|
||||
|
|
@ -34,7 +34,7 @@ namespace hex::plugin::builtin::undo {
|
|||
}
|
||||
|
||||
[[nodiscard]] Region getRegion() const override {
|
||||
return this->m_entry.region;
|
||||
return m_entry.region;
|
||||
}
|
||||
|
||||
bool shouldHighlight() const override { return false; }
|
||||
|
|
|
|||
|
|
@ -13,15 +13,15 @@ namespace hex::plugin::builtin::undo {
|
|||
m_offset(offset), m_size(size) { }
|
||||
|
||||
void undo(prv::Provider *provider) override {
|
||||
provider->removeRaw(this->m_offset, this->m_size);
|
||||
provider->removeRaw(m_offset, m_size);
|
||||
}
|
||||
|
||||
void redo(prv::Provider *provider) override {
|
||||
provider->insertRaw(this->m_offset, this->m_size);
|
||||
provider->insertRaw(m_offset, m_size);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string format() const override {
|
||||
return hex::format("hex.builtin.undo_operation.insert"_lang, hex::toByteString(this->m_size), this->m_offset);
|
||||
return hex::format("hex.builtin.undo_operation.insert"_lang, hex::toByteString(m_size), m_offset);
|
||||
}
|
||||
|
||||
std::unique_ptr<Operation> clone() const override {
|
||||
|
|
@ -29,7 +29,7 @@ namespace hex::plugin::builtin::undo {
|
|||
}
|
||||
|
||||
[[nodiscard]] Region getRegion() const override {
|
||||
return { this->m_offset, this->m_size };
|
||||
return { m_offset, m_size };
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -13,20 +13,20 @@ namespace hex::plugin::builtin::undo {
|
|||
m_offset(offset), m_size(size) { }
|
||||
|
||||
void undo(prv::Provider *provider) override {
|
||||
provider->insertRaw(this->m_offset, this->m_size);
|
||||
provider->insertRaw(m_offset, m_size);
|
||||
|
||||
provider->writeRaw(this->m_offset, this->m_removedData.data(), this->m_removedData.size());
|
||||
provider->writeRaw(m_offset, m_removedData.data(), m_removedData.size());
|
||||
}
|
||||
|
||||
void redo(prv::Provider *provider) override {
|
||||
this->m_removedData.resize(this->m_size);
|
||||
provider->readRaw(this->m_offset, this->m_removedData.data(), this->m_removedData.size());
|
||||
m_removedData.resize(m_size);
|
||||
provider->readRaw(m_offset, m_removedData.data(), m_removedData.size());
|
||||
|
||||
provider->removeRaw(this->m_offset, this->m_size);
|
||||
provider->removeRaw(m_offset, m_size);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string format() const override {
|
||||
return hex::format("hex.builtin.undo_operation.remove"_lang, hex::toByteString(this->m_size), this->m_offset);
|
||||
return hex::format("hex.builtin.undo_operation.remove"_lang, hex::toByteString(m_size), m_offset);
|
||||
}
|
||||
|
||||
std::unique_ptr<Operation> clone() const override {
|
||||
|
|
@ -34,7 +34,7 @@ namespace hex::plugin::builtin::undo {
|
|||
}
|
||||
|
||||
[[nodiscard]] Region getRegion() const override {
|
||||
return { this->m_offset, this->m_size };
|
||||
return { m_offset, m_size };
|
||||
}
|
||||
|
||||
bool shouldHighlight() const override { return false; }
|
||||
|
|
|
|||
|
|
@ -16,20 +16,20 @@ namespace hex::plugin::builtin::undo {
|
|||
m_newData(newData, newData + size) { }
|
||||
|
||||
void undo(prv::Provider *provider) override {
|
||||
provider->writeRaw(this->m_offset, this->m_oldData.data(), this->m_oldData.size());
|
||||
provider->writeRaw(m_offset, m_oldData.data(), m_oldData.size());
|
||||
}
|
||||
|
||||
void redo(prv::Provider *provider) override {
|
||||
provider->writeRaw(this->m_offset, this->m_newData.data(), this->m_newData.size());
|
||||
provider->writeRaw(m_offset, m_newData.data(), m_newData.size());
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string format() const override {
|
||||
return hex::format("hex.builtin.undo_operation.write"_lang, hex::toByteString(this->m_newData.size()), this->m_offset);
|
||||
return hex::format("hex.builtin.undo_operation.write"_lang, hex::toByteString(m_newData.size()), m_offset);
|
||||
}
|
||||
|
||||
std::vector<std::string> formatContent() const override {
|
||||
return {
|
||||
hex::format("{} {} {}", hex::crypt::encode16(this->m_oldData), ICON_VS_ARROW_RIGHT, hex::crypt::encode16(this->m_newData)),
|
||||
hex::format("{} {} {}", hex::crypt::encode16(m_oldData), ICON_VS_ARROW_RIGHT, hex::crypt::encode16(m_newData)),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ namespace hex::plugin::builtin::undo {
|
|||
}
|
||||
|
||||
[[nodiscard]] Region getRegion() const override {
|
||||
return { this->m_offset, this->m_oldData.size() };
|
||||
return { m_offset, m_oldData.size() };
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace hex::plugin::builtin {
|
|||
public:
|
||||
explicit ViewProvider() {
|
||||
EventProviderClosing::subscribe(this, [this](const prv::Provider *provider, bool*) {
|
||||
if (this->m_provider == provider)
|
||||
if (m_provider == provider)
|
||||
ImHexApi::Provider::remove(this, false);
|
||||
});
|
||||
}
|
||||
|
|
@ -20,85 +20,85 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
[[nodiscard]] bool isAvailable() const override {
|
||||
if (this->m_provider == nullptr)
|
||||
if (m_provider == nullptr)
|
||||
return false;
|
||||
else
|
||||
return this->m_provider->isAvailable();
|
||||
return m_provider->isAvailable();
|
||||
}
|
||||
[[nodiscard]] bool isReadable() const override {
|
||||
if (this->m_provider == nullptr)
|
||||
if (m_provider == nullptr)
|
||||
return false;
|
||||
else
|
||||
return this->m_provider->isReadable();
|
||||
return m_provider->isReadable();
|
||||
}
|
||||
[[nodiscard]] bool isWritable() const override {
|
||||
if (this->m_provider == nullptr)
|
||||
if (m_provider == nullptr)
|
||||
return false;
|
||||
else
|
||||
return this->m_provider->isWritable();
|
||||
return m_provider->isWritable();
|
||||
}
|
||||
[[nodiscard]] bool isResizable() const override { return true; }
|
||||
|
||||
[[nodiscard]] bool isSavable() const override {
|
||||
if (this->m_provider == nullptr)
|
||||
if (m_provider == nullptr)
|
||||
return false;
|
||||
else
|
||||
return this->m_provider->isSavable();
|
||||
return m_provider->isSavable();
|
||||
}
|
||||
|
||||
void save() override {
|
||||
this->m_provider->save();
|
||||
m_provider->save();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool open() override { return true; }
|
||||
void close() override { }
|
||||
|
||||
void resizeRaw(u64 newSize) override {
|
||||
this->m_size = newSize;
|
||||
m_size = newSize;
|
||||
}
|
||||
void insertRaw(u64 offset, u64 size) override {
|
||||
if (this->m_provider == nullptr)
|
||||
if (m_provider == nullptr)
|
||||
return;
|
||||
|
||||
this->m_size += size;
|
||||
this->m_provider->insert(offset + this->m_startAddress, size);
|
||||
m_size += size;
|
||||
m_provider->insert(offset + m_startAddress, size);
|
||||
}
|
||||
|
||||
void removeRaw(u64 offset, u64 size) override {
|
||||
if (this->m_provider == nullptr)
|
||||
if (m_provider == nullptr)
|
||||
return;
|
||||
|
||||
this->m_size -= size;
|
||||
this->m_provider->remove(offset + this->m_startAddress, size);
|
||||
m_size -= size;
|
||||
m_provider->remove(offset + m_startAddress, size);
|
||||
}
|
||||
|
||||
void readRaw(u64 offset, void *buffer, size_t size) override {
|
||||
if (this->m_provider == nullptr)
|
||||
if (m_provider == nullptr)
|
||||
return;
|
||||
|
||||
this->m_provider->read(offset + this->m_startAddress, buffer, size);
|
||||
m_provider->read(offset + m_startAddress, buffer, size);
|
||||
}
|
||||
|
||||
void writeRaw(u64 offset, const void *buffer, size_t size) override {
|
||||
if (this->m_provider == nullptr)
|
||||
if (m_provider == nullptr)
|
||||
return;
|
||||
|
||||
this->m_provider->write(offset + this->m_startAddress, buffer, size);
|
||||
m_provider->write(offset + m_startAddress, buffer, size);
|
||||
}
|
||||
|
||||
[[nodiscard]] u64 getActualSize() const override { return this->m_size; }
|
||||
[[nodiscard]] u64 getActualSize() const override { return m_size; }
|
||||
|
||||
[[nodiscard]] std::string getName() const override {
|
||||
if (this->m_provider == nullptr)
|
||||
if (m_provider == nullptr)
|
||||
return "View";
|
||||
else
|
||||
return hex::format("{} View", this->m_provider->getName());
|
||||
return hex::format("{} View", m_provider->getName());
|
||||
}
|
||||
[[nodiscard]] std::vector<Description> getDataDescription() const override {
|
||||
if (this->m_provider == nullptr)
|
||||
if (m_provider == nullptr)
|
||||
return { };
|
||||
|
||||
return this->m_provider->getDataDescription();
|
||||
return m_provider->getDataDescription();
|
||||
}
|
||||
|
||||
void loadSettings(const nlohmann::json &settings) override { hex::unused(settings); }
|
||||
|
|
@ -109,9 +109,9 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
void setProvider(u64 startAddress, size_t size, hex::prv::Provider *provider) {
|
||||
this->m_startAddress = startAddress;
|
||||
this->m_size = size;
|
||||
this->m_provider = provider;
|
||||
m_startAddress = startAddress;
|
||||
m_size = size;
|
||||
m_provider = provider;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::pair<Region, bool> getRegionValidity(u64 address) const override {
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ namespace hex::plugin::builtin {
|
|||
std::string m_exactResult;
|
||||
|
||||
void focusInputTextBox() {
|
||||
this->m_focusInputTextBox = true;
|
||||
m_focusInputTextBox = true;
|
||||
}
|
||||
|
||||
std::vector<CommandResult> getCommandResults(const std::string &input);
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void reloadCustomNodes();
|
||||
|
||||
std::vector<Workspace*> &getWorkspaceStack() { return *this->m_workspaceStack; }
|
||||
std::vector<Workspace*> &getWorkspaceStack() { return *m_workspaceStack; }
|
||||
|
||||
private:
|
||||
void drawContextMenus(ViewDataProcessor::Workspace &workspace);
|
||||
|
|
|
|||
|
|
@ -23,42 +23,42 @@ namespace hex::plugin::builtin {
|
|||
};
|
||||
|
||||
[[nodiscard]] bool isAnyPopupOpen() const {
|
||||
return this->m_currPopup != nullptr;
|
||||
return m_currPopup != nullptr;
|
||||
}
|
||||
|
||||
template<std::derived_from<Popup> T>
|
||||
[[nodiscard]] bool isPopupOpen() const {
|
||||
return dynamic_cast<T*>(this->m_currPopup.get()) != nullptr;
|
||||
return dynamic_cast<T*>(m_currPopup.get()) != nullptr;
|
||||
}
|
||||
|
||||
template<std::derived_from<Popup> T, typename ... Args>
|
||||
void openPopup(Args && ...args) {
|
||||
this->m_currPopup = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
this->m_shouldOpenPopup = true;
|
||||
m_currPopup = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
m_shouldOpenPopup = true;
|
||||
}
|
||||
|
||||
void closePopup() {
|
||||
this->m_currPopup.reset();
|
||||
m_currPopup.reset();
|
||||
}
|
||||
|
||||
bool isSelectionValid() const {
|
||||
return this->m_hexEditor.isSelectionValid();
|
||||
return m_hexEditor.isSelectionValid();
|
||||
}
|
||||
|
||||
Region getSelection() const {
|
||||
return this->m_hexEditor.getSelection();
|
||||
return m_hexEditor.getSelection();
|
||||
}
|
||||
|
||||
void setSelection(const Region ®ion) {
|
||||
this->m_hexEditor.setSelection(region);
|
||||
m_hexEditor.setSelection(region);
|
||||
}
|
||||
|
||||
void setSelection(u128 start, u128 end) {
|
||||
this->m_hexEditor.setSelection(start, end);
|
||||
m_hexEditor.setSelection(start, end);
|
||||
}
|
||||
|
||||
void jumpToSelection() {
|
||||
this->m_hexEditor.jumpToSelection();
|
||||
m_hexEditor.jumpToSelection();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -52,20 +52,20 @@ namespace hex::plugin::builtin {
|
|||
ImGuiExt::TextFormattedWrapped("{}", static_cast<const char *>("hex.builtin.view.pattern_editor.accept_pattern.desc"_lang));
|
||||
|
||||
std::vector<std::string> entries;
|
||||
entries.resize(this->m_view->m_possiblePatternFiles.get(provider).size());
|
||||
entries.resize(m_view->m_possiblePatternFiles.get(provider).size());
|
||||
|
||||
for (u32 i = 0; i < entries.size(); i++) {
|
||||
entries[i] = wolv::util::toUTF8String(this->m_view->m_possiblePatternFiles.get(provider)[i].filename());
|
||||
entries[i] = wolv::util::toUTF8String(m_view->m_possiblePatternFiles.get(provider)[i].filename());
|
||||
}
|
||||
|
||||
if (ImGui::BeginListBox("##patterns_accept", ImVec2(-FLT_MIN, 0))) {
|
||||
u32 index = 0;
|
||||
for (auto &path : this->m_view->m_possiblePatternFiles.get(provider)) {
|
||||
if (ImGui::Selectable(wolv::util::toUTF8String(path.filename()).c_str(), index == this->m_selectedPatternFile, ImGuiSelectableFlags_DontClosePopups))
|
||||
this->m_selectedPatternFile = index;
|
||||
for (auto &path : m_view->m_possiblePatternFiles.get(provider)) {
|
||||
if (ImGui::Selectable(wolv::util::toUTF8String(path.filename()).c_str(), index == m_selectedPatternFile, ImGuiSelectableFlags_DontClosePopups))
|
||||
m_selectedPatternFile = index;
|
||||
|
||||
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0))
|
||||
this->m_view->loadPatternFile(this->m_view->m_possiblePatternFiles.get(provider)[this->m_selectedPatternFile], provider);
|
||||
m_view->loadPatternFile(m_view->m_possiblePatternFiles.get(provider)[m_selectedPatternFile], provider);
|
||||
|
||||
ImGuiExt::InfoTooltip(wolv::util::toUTF8String(path).c_str());
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
ImGuiExt::ConfirmButtons("hex.builtin.common.yes"_lang, "hex.builtin.common.no"_lang,
|
||||
[this, provider] {
|
||||
this->m_view->loadPatternFile(this->m_view->m_possiblePatternFiles.get(provider)[this->m_selectedPatternFile], provider);
|
||||
m_view->loadPatternFile(m_view->m_possiblePatternFiles.get(provider)[m_selectedPatternFile], provider);
|
||||
this->close();
|
||||
},
|
||||
[this] {
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ namespace hex::plugin::builtin::ui {
|
|||
void draw(float height = ImGui::GetContentRegionAvail().y);
|
||||
|
||||
void setProvider(prv::Provider *provider) {
|
||||
this->m_provider = provider;
|
||||
this->m_currValidRegion = { Region::Invalid(), false };
|
||||
m_provider = provider;
|
||||
m_currValidRegion = { Region::Invalid(), false };
|
||||
}
|
||||
void setUnknownDataCharacter(char character) { this->m_unknownDataCharacter = character; }
|
||||
void setUnknownDataCharacter(char character) { m_unknownDataCharacter = character; }
|
||||
private:
|
||||
enum class CellType { None, Hex, ASCII };
|
||||
|
||||
|
|
@ -36,36 +36,36 @@ namespace hex::plugin::builtin::ui {
|
|||
|
||||
public:
|
||||
void setSelectionUnchecked(std::optional<u64> start, std::optional<u64> end) {
|
||||
this->m_selectionStart = start;
|
||||
this->m_selectionEnd = end;
|
||||
this->m_cursorPosition = end;
|
||||
m_selectionStart = start;
|
||||
m_selectionEnd = end;
|
||||
m_cursorPosition = end;
|
||||
}
|
||||
void setSelection(const Region ®ion) { this->setSelection(region.getStartAddress(), region.getEndAddress()); }
|
||||
void setSelection(u128 start, u128 end) {
|
||||
if (!ImHexApi::Provider::isValid())
|
||||
return;
|
||||
|
||||
if (start > this->m_provider->getBaseAddress() + this->m_provider->getActualSize())
|
||||
if (start > m_provider->getBaseAddress() + m_provider->getActualSize())
|
||||
return;
|
||||
|
||||
if (start < this->m_provider->getBaseAddress())
|
||||
if (start < m_provider->getBaseAddress())
|
||||
return;
|
||||
|
||||
if (this->m_provider->getActualSize() == 0)
|
||||
if (m_provider->getActualSize() == 0)
|
||||
return;
|
||||
|
||||
const size_t maxAddress = this->m_provider->getActualSize() + this->m_provider->getBaseAddress() - 1;
|
||||
const size_t maxAddress = m_provider->getActualSize() + m_provider->getBaseAddress() - 1;
|
||||
|
||||
constexpr static auto alignDown = [](u128 value, u128 alignment) {
|
||||
return value & ~(alignment - 1);
|
||||
};
|
||||
|
||||
this->m_selectionChanged = this->m_selectionStart != start || this->m_selectionEnd != end;
|
||||
m_selectionChanged = m_selectionStart != start || m_selectionEnd != end;
|
||||
|
||||
if (!this->m_selectionStart.has_value()) this->m_selectionStart = start;
|
||||
if (!this->m_selectionEnd.has_value()) this->m_selectionEnd = end;
|
||||
if (!m_selectionStart.has_value()) m_selectionStart = start;
|
||||
if (!m_selectionEnd.has_value()) m_selectionEnd = end;
|
||||
|
||||
if (auto bytesPerCell = this->m_currDataVisualizer->getBytesPerCell(); bytesPerCell > 1) {
|
||||
if (auto bytesPerCell = m_currDataVisualizer->getBytesPerCell(); bytesPerCell > 1) {
|
||||
if (end > start) {
|
||||
start = alignDown(start, bytesPerCell);
|
||||
end = alignDown(end, bytesPerCell) + (bytesPerCell - 1);
|
||||
|
|
@ -75,14 +75,14 @@ namespace hex::plugin::builtin::ui {
|
|||
}
|
||||
}
|
||||
|
||||
this->m_selectionStart = std::clamp<u128>(start, 0, maxAddress);
|
||||
this->m_selectionEnd = std::clamp<u128>(end, 0, maxAddress);
|
||||
this->m_cursorPosition = this->m_selectionEnd;
|
||||
m_selectionStart = std::clamp<u128>(start, 0, maxAddress);
|
||||
m_selectionEnd = std::clamp<u128>(end, 0, maxAddress);
|
||||
m_cursorPosition = m_selectionEnd;
|
||||
|
||||
if (this->m_selectionChanged) {
|
||||
if (m_selectionChanged) {
|
||||
auto selection = this->getSelection();
|
||||
EventRegionSelected::post(ImHexApi::HexEditor::ProviderRegion{ { selection.address, selection.size }, this->m_provider });
|
||||
this->m_shouldModifyValue = true;
|
||||
EventRegionSelected::post(ImHexApi::HexEditor::ProviderRegion{ { selection.address, selection.size }, m_provider });
|
||||
m_shouldModifyValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -90,138 +90,138 @@ namespace hex::plugin::builtin::ui {
|
|||
if (!isSelectionValid())
|
||||
return Region::Invalid();
|
||||
|
||||
const auto start = std::min(this->m_selectionStart.value(), this->m_selectionEnd.value());
|
||||
const auto end = std::max(this->m_selectionStart.value(), this->m_selectionEnd.value());
|
||||
const auto start = std::min(m_selectionStart.value(), m_selectionEnd.value());
|
||||
const auto end = std::max(m_selectionStart.value(), m_selectionEnd.value());
|
||||
const size_t size = end - start + 1;
|
||||
|
||||
return { start, size };
|
||||
}
|
||||
|
||||
[[nodiscard]] std::optional<u64> getCursorPosition() const {
|
||||
return this->m_cursorPosition;
|
||||
return m_cursorPosition;
|
||||
}
|
||||
|
||||
void setCursorPosition(u64 cursorPosition) {
|
||||
this->m_cursorPosition = cursorPosition;
|
||||
m_cursorPosition = cursorPosition;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isSelectionValid() const {
|
||||
return this->m_selectionStart.has_value() && this->m_selectionEnd.has_value();
|
||||
return m_selectionStart.has_value() && m_selectionEnd.has_value();
|
||||
}
|
||||
|
||||
void jumpToSelection(bool center = true) {
|
||||
this->m_shouldJumpToSelection = true;
|
||||
m_shouldJumpToSelection = true;
|
||||
|
||||
if (center)
|
||||
this->m_centerOnJump = true;
|
||||
m_centerOnJump = true;
|
||||
}
|
||||
|
||||
void scrollToSelection() {
|
||||
this->m_shouldScrollToSelection = true;
|
||||
m_shouldScrollToSelection = true;
|
||||
}
|
||||
|
||||
void jumpIfOffScreen() {
|
||||
this->m_shouldJumpWhenOffScreen = true;
|
||||
m_shouldJumpWhenOffScreen = true;
|
||||
}
|
||||
|
||||
[[nodiscard]] u16 getBytesPerRow() const {
|
||||
return this->m_bytesPerRow;
|
||||
return m_bytesPerRow;
|
||||
}
|
||||
|
||||
[[nodiscard]] u16 getBytesPerCell() const {
|
||||
return this->m_currDataVisualizer->getBytesPerCell();
|
||||
return m_currDataVisualizer->getBytesPerCell();
|
||||
}
|
||||
|
||||
void setBytesPerRow(u16 bytesPerRow) {
|
||||
this->m_bytesPerRow = bytesPerRow;
|
||||
m_bytesPerRow = bytesPerRow;
|
||||
}
|
||||
|
||||
[[nodiscard]] u16 getVisibleRowCount() const {
|
||||
return this->m_visibleRowCount;
|
||||
return m_visibleRowCount;
|
||||
}
|
||||
|
||||
void setSelectionColor(color_t color) {
|
||||
this->m_selectionColor = color;
|
||||
m_selectionColor = color;
|
||||
}
|
||||
|
||||
void enableUpperCaseHex(bool upperCaseHex) {
|
||||
this->m_upperCaseHex = upperCaseHex;
|
||||
m_upperCaseHex = upperCaseHex;
|
||||
}
|
||||
|
||||
void enableGrayOutZeros(bool grayOutZeros) {
|
||||
this->m_grayOutZero = grayOutZeros;
|
||||
m_grayOutZero = grayOutZeros;
|
||||
}
|
||||
|
||||
void enableShowAscii(bool showAscii) {
|
||||
this->m_showAscii = showAscii;
|
||||
m_showAscii = showAscii;
|
||||
}
|
||||
|
||||
void enableShowHumanReadableUnits(bool showHumanReadableUnits) {
|
||||
this->m_showHumanReadableUnits = showHumanReadableUnits;
|
||||
m_showHumanReadableUnits = showHumanReadableUnits;
|
||||
}
|
||||
|
||||
void enableSyncScrolling(bool syncScrolling) {
|
||||
this->m_syncScrolling = syncScrolling;
|
||||
m_syncScrolling = syncScrolling;
|
||||
}
|
||||
|
||||
void setByteCellPadding(u32 byteCellPadding) {
|
||||
this->m_byteCellPadding = byteCellPadding;
|
||||
m_byteCellPadding = byteCellPadding;
|
||||
}
|
||||
|
||||
void setCharacterCellPadding(u32 characterCellPadding) {
|
||||
this->m_characterCellPadding = characterCellPadding;
|
||||
m_characterCellPadding = characterCellPadding;
|
||||
}
|
||||
|
||||
[[nodiscard]] const std::optional<EncodingFile>& getCustomEncoding() const {
|
||||
return this->m_currCustomEncoding;
|
||||
return m_currCustomEncoding;
|
||||
}
|
||||
|
||||
void setCustomEncoding(const EncodingFile &encoding) {
|
||||
this->m_currCustomEncoding = encoding;
|
||||
this->m_encodingLineStartAddresses.clear();
|
||||
m_currCustomEncoding = encoding;
|
||||
m_encodingLineStartAddresses.clear();
|
||||
}
|
||||
|
||||
void setCustomEncoding(EncodingFile &&encoding) {
|
||||
this->m_currCustomEncoding = std::move(encoding);
|
||||
this->m_encodingLineStartAddresses.clear();
|
||||
m_currCustomEncoding = std::move(encoding);
|
||||
m_encodingLineStartAddresses.clear();
|
||||
}
|
||||
|
||||
void forceUpdateScrollPosition() {
|
||||
this->m_shouldUpdateScrollPosition = true;
|
||||
m_shouldUpdateScrollPosition = true;
|
||||
}
|
||||
|
||||
void setForegroundHighlightCallback(const std::function<std::optional<color_t>(u64, const u8 *, size_t)> &callback) {
|
||||
this->m_foregroundColorCallback = callback;
|
||||
m_foregroundColorCallback = callback;
|
||||
}
|
||||
|
||||
void setBackgroundHighlightCallback(const std::function<std::optional<color_t>(u64, const u8 *, size_t)> &callback) {
|
||||
this->m_backgroundColorCallback = callback;
|
||||
m_backgroundColorCallback = callback;
|
||||
}
|
||||
|
||||
void setTooltipCallback(const std::function<void(u64, const u8 *, size_t)> &callback) {
|
||||
this->m_tooltipCallback = callback;
|
||||
m_tooltipCallback = callback;
|
||||
}
|
||||
|
||||
[[nodiscard]] float getScrollPosition() const {
|
||||
return this->m_scrollPosition;
|
||||
return m_scrollPosition;
|
||||
}
|
||||
|
||||
void setScrollPosition(float scrollPosition) {
|
||||
this->m_scrollPosition = scrollPosition;
|
||||
m_scrollPosition = scrollPosition;
|
||||
}
|
||||
|
||||
void setEditingAddress(u64 address) {
|
||||
this->m_editingAddress = address;
|
||||
this->m_shouldModifyValue = false;
|
||||
this->m_enteredEditingMode = true;
|
||||
m_editingAddress = address;
|
||||
m_shouldModifyValue = false;
|
||||
m_enteredEditingMode = true;
|
||||
|
||||
this->m_editingBytes.resize(this->m_currDataVisualizer->getBytesPerCell());
|
||||
this->m_provider->read(address + this->m_provider->getBaseAddress(), this->m_editingBytes.data(), this->m_editingBytes.size());
|
||||
this->m_editingCellType = CellType::Hex;
|
||||
m_editingBytes.resize(m_currDataVisualizer->getBytesPerCell());
|
||||
m_provider->read(address + m_provider->getBaseAddress(), m_editingBytes.data(), m_editingBytes.size());
|
||||
m_editingCellType = CellType::Hex;
|
||||
}
|
||||
|
||||
void clearEditingAddress() {
|
||||
this->m_editingAddress = std::nullopt;
|
||||
m_editingAddress = std::nullopt;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace hex::plugin::builtin::ui {
|
|||
class PatternDrawer : public pl::PatternVisitor {
|
||||
public:
|
||||
PatternDrawer() {
|
||||
this->m_formatters = pl::gen::fmt::createFormatters();
|
||||
m_formatters = pl::gen::fmt::createFormatters();
|
||||
}
|
||||
|
||||
virtual ~PatternDrawer() = default;
|
||||
|
|
@ -30,9 +30,9 @@ namespace hex::plugin::builtin::ui {
|
|||
Flattened = 2
|
||||
};
|
||||
|
||||
void setTreeStyle(TreeStyle style) { this->m_treeStyle = style; }
|
||||
void setSelectionCallback(std::function<void(Region)> callback) { this->m_selectionCallback = std::move(callback); }
|
||||
void enableRowColoring(bool enabled) { this->m_rowColoring = enabled; }
|
||||
void setTreeStyle(TreeStyle style) { m_treeStyle = style; }
|
||||
void setSelectionCallback(std::function<void(Region)> callback) { m_selectionCallback = std::move(callback); }
|
||||
void enableRowColoring(bool enabled) { m_rowColoring = enabled; }
|
||||
void reset();
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -180,12 +180,12 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
unitString = wolv::util::trim(unitString);
|
||||
this->m_unitString = unitString;
|
||||
m_unitString = unitString;
|
||||
if (unitString.empty()) {
|
||||
if (multiplier == 1)
|
||||
return { Unit::Unitless, 1 };
|
||||
else {
|
||||
this->m_unitString = unitStringCopy;
|
||||
m_unitString = unitStringCopy;
|
||||
return { Unit::Unitless, 1 };
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,27 +29,27 @@ namespace hex::plugin::builtin {
|
|||
constexpr static int StepSize = 1, FastStepSize = 10;
|
||||
|
||||
ImGui::PushItemWidth(100_scaled);
|
||||
ImGui::InputScalar("hex.builtin.nodes.constants.buffer.size"_lang, ImGuiDataType_U32, &this->m_size, &StepSize, &FastStepSize);
|
||||
ImGui::InputScalar("hex.builtin.nodes.constants.buffer.size"_lang, ImGuiDataType_U32, &m_size, &StepSize, &FastStepSize);
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
void process() override {
|
||||
if (this->m_buffer.size() != this->m_size)
|
||||
this->m_buffer.resize(this->m_size, 0x00);
|
||||
if (m_buffer.size() != m_size)
|
||||
m_buffer.resize(m_size, 0x00);
|
||||
|
||||
this->setBufferOnOutput(0, this->m_buffer);
|
||||
this->setBufferOnOutput(0, m_buffer);
|
||||
}
|
||||
|
||||
void store(nlohmann::json &j) const override {
|
||||
j = nlohmann::json::object();
|
||||
|
||||
j["size"] = this->m_size;
|
||||
j["data"] = this->m_buffer;
|
||||
j["size"] = m_size;
|
||||
j["data"] = m_buffer;
|
||||
}
|
||||
|
||||
void load(const nlohmann::json &j) override {
|
||||
this->m_size = j.at("size");
|
||||
this->m_buffer = j.at("data").get<std::vector<u8>>();
|
||||
m_size = j.at("size");
|
||||
m_buffer = j.at("data").get<std::vector<u8>>();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -64,21 +64,21 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
void drawNode() override {
|
||||
ImGui::InputTextMultiline("##string", this->m_value, ImVec2(150_scaled, 0), ImGuiInputTextFlags_AllowTabInput);
|
||||
ImGui::InputTextMultiline("##string", m_value, ImVec2(150_scaled, 0), ImGuiInputTextFlags_AllowTabInput);
|
||||
}
|
||||
|
||||
void process() override {
|
||||
this->setBufferOnOutput(0, hex::decodeByteString(this->m_value));
|
||||
this->setBufferOnOutput(0, hex::decodeByteString(m_value));
|
||||
}
|
||||
|
||||
void store(nlohmann::json &j) const override {
|
||||
j = nlohmann::json::object();
|
||||
|
||||
j["data"] = this->m_value;
|
||||
j["data"] = m_value;
|
||||
}
|
||||
|
||||
void load(const nlohmann::json &j) override {
|
||||
this->m_value = j.at("data").get<std::string>();
|
||||
m_value = j.at("data").get<std::string>();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -91,22 +91,22 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void drawNode() override {
|
||||
ImGui::PushItemWidth(100_scaled);
|
||||
ImGuiExt::InputHexadecimal("##integer_value", &this->m_value);
|
||||
ImGuiExt::InputHexadecimal("##integer_value", &m_value);
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
void process() override {
|
||||
this->setIntegerOnOutput(0, this->m_value);
|
||||
this->setIntegerOnOutput(0, m_value);
|
||||
}
|
||||
|
||||
void store(nlohmann::json &j) const override {
|
||||
j = nlohmann::json::object();
|
||||
|
||||
j["data"] = this->m_value;
|
||||
j["data"] = m_value;
|
||||
}
|
||||
|
||||
void load(const nlohmann::json &j) override {
|
||||
this->m_value = j.at("data");
|
||||
m_value = j.at("data");
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -119,22 +119,22 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void drawNode() override {
|
||||
ImGui::PushItemWidth(100_scaled);
|
||||
ImGui::InputScalar("##floatValue", ImGuiDataType_Float, &this->m_value, nullptr, nullptr, "%f", ImGuiInputTextFlags_CharsDecimal);
|
||||
ImGui::InputScalar("##floatValue", ImGuiDataType_Float, &m_value, nullptr, nullptr, "%f", ImGuiInputTextFlags_CharsDecimal);
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
void process() override {
|
||||
this->setFloatOnOutput(0, this->m_value);
|
||||
this->setFloatOnOutput(0, m_value);
|
||||
}
|
||||
|
||||
void store(nlohmann::json &j) const override {
|
||||
j = nlohmann::json::object();
|
||||
|
||||
j["data"] = this->m_value;
|
||||
j["data"] = m_value;
|
||||
}
|
||||
|
||||
void load(const nlohmann::json &j) override {
|
||||
this->m_value = j.at("data");
|
||||
m_value = j.at("data");
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -151,30 +151,30 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void drawNode() override {
|
||||
ImGui::PushItemWidth(200_scaled);
|
||||
ImGui::ColorPicker4("##colorPicker", &this->m_color.Value.x, ImGuiColorEditFlags_AlphaBar);
|
||||
ImGui::ColorPicker4("##colorPicker", &m_color.Value.x, ImGuiColorEditFlags_AlphaBar);
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
void process() override {
|
||||
this->setBufferOnOutput(0, wolv::util::toBytes<u8>(u8(this->m_color.Value.x * 0xFF)));
|
||||
this->setBufferOnOutput(1, wolv::util::toBytes<u8>(u8(this->m_color.Value.y * 0xFF)));
|
||||
this->setBufferOnOutput(2, wolv::util::toBytes<u8>(u8(this->m_color.Value.z * 0xFF)));
|
||||
this->setBufferOnOutput(3, wolv::util::toBytes<u8>(u8(this->m_color.Value.w * 0xFF)));
|
||||
this->setBufferOnOutput(0, wolv::util::toBytes<u8>(u8(m_color.Value.x * 0xFF)));
|
||||
this->setBufferOnOutput(1, wolv::util::toBytes<u8>(u8(m_color.Value.y * 0xFF)));
|
||||
this->setBufferOnOutput(2, wolv::util::toBytes<u8>(u8(m_color.Value.z * 0xFF)));
|
||||
this->setBufferOnOutput(3, wolv::util::toBytes<u8>(u8(m_color.Value.w * 0xFF)));
|
||||
}
|
||||
|
||||
void store(nlohmann::json &j) const override {
|
||||
j = nlohmann::json::object();
|
||||
|
||||
j["data"] = nlohmann::json::object();
|
||||
j["data"]["r"] = this->m_color.Value.x;
|
||||
j["data"]["g"] = this->m_color.Value.y;
|
||||
j["data"]["b"] = this->m_color.Value.z;
|
||||
j["data"]["a"] = this->m_color.Value.w;
|
||||
j["data"]["r"] = m_color.Value.x;
|
||||
j["data"]["g"] = m_color.Value.y;
|
||||
j["data"]["b"] = m_color.Value.z;
|
||||
j["data"]["a"] = m_color.Value.w;
|
||||
}
|
||||
|
||||
void load(const nlohmann::json &j) override {
|
||||
const auto &color = j.at("data");
|
||||
this->m_color = ImVec4(color.at("r"), color.at("g"), color.at("b"), color.at("a"));
|
||||
m_color = ImVec4(color.at("r"), color.at("g"), color.at("b"), color.at("a"));
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -188,7 +188,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
void drawNode() override {
|
||||
ImGui::InputTextMultiline("##string", this->m_comment, scaled(ImVec2(150, 100)));
|
||||
ImGui::InputTextMultiline("##string", m_comment, scaled(ImVec2(150, 100)));
|
||||
}
|
||||
|
||||
void process() override {
|
||||
|
|
@ -197,11 +197,11 @@ namespace hex::plugin::builtin {
|
|||
void store(nlohmann::json &j) const override {
|
||||
j = nlohmann::json::object();
|
||||
|
||||
j["comment"] = this->m_comment;
|
||||
j["comment"] = m_comment;
|
||||
}
|
||||
|
||||
void load(const nlohmann::json &j) override {
|
||||
this->m_comment = j["comment"].get<std::string>();
|
||||
m_comment = j["comment"].get<std::string>();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void drawNode() override {
|
||||
ImGui::PushItemWidth(100_scaled);
|
||||
ImGui::Combo("hex.builtin.nodes.crypto.aes.mode"_lang, &this->m_mode, "ECB\0CBC\0CFB128\0CTR\0GCM\0CCM\0OFB\0");
|
||||
ImGui::Combo("hex.builtin.nodes.crypto.aes.key_length"_lang, &this->m_keyLength, "128 Bits\000192 Bits\000256 Bits\000");
|
||||
ImGui::Combo("hex.builtin.nodes.crypto.aes.mode"_lang, &m_mode, "ECB\0CBC\0CFB128\0CTR\0GCM\0CCM\0OFB\0");
|
||||
ImGui::Combo("hex.builtin.nodes.crypto.aes.key_length"_lang, &m_keyLength, "128 Bits\000192 Bits\000256 Bits\000");
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ namespace hex::plugin::builtin {
|
|||
std::copy(iv.begin(), iv.end(), ivData.begin());
|
||||
std::copy(nonce.begin(), nonce.end(), nonceData.begin());
|
||||
|
||||
auto output = crypt::aesDecrypt(static_cast<crypt::AESMode>(this->m_mode), static_cast<crypt::KeyLength>(this->m_keyLength), key, nonceData, ivData, input);
|
||||
auto output = crypt::aesDecrypt(static_cast<crypt::AESMode>(m_mode), static_cast<crypt::KeyLength>(m_keyLength), key, nonceData, ivData, input);
|
||||
|
||||
this->setBufferOnOutput(4, output);
|
||||
}
|
||||
|
|
@ -50,13 +50,13 @@ namespace hex::plugin::builtin {
|
|||
j = nlohmann::json::object();
|
||||
|
||||
j["data"] = nlohmann::json::object();
|
||||
j["data"]["mode"] = this->m_mode;
|
||||
j["data"]["key_length"] = this->m_keyLength;
|
||||
j["data"]["mode"] = m_mode;
|
||||
j["data"]["key_length"] = m_keyLength;
|
||||
}
|
||||
|
||||
void load(const nlohmann::json &j) override {
|
||||
this->m_mode = j["data"]["mode"];
|
||||
this->m_keyLength = j["data"]["key_length"];
|
||||
m_mode = j["data"]["mode"];
|
||||
m_keyLength = j["data"]["key_length"];
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -61,8 +61,8 @@ namespace hex::plugin::builtin {
|
|||
public:
|
||||
NodeDataSelection() : Node("hex.builtin.nodes.data_access.selection.header", { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "hex.builtin.nodes.data_access.selection.address"), dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "hex.builtin.nodes.data_access.selection.size") }) {
|
||||
EventRegionSelected::subscribe(this, [this](const auto ®ion) {
|
||||
this->m_address = region.address;
|
||||
this->m_size = region.size;
|
||||
m_address = region.address;
|
||||
m_size = region.size;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -71,8 +71,8 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
void process() override {
|
||||
this->setIntegerOnOutput(0, this->m_address);
|
||||
this->setIntegerOnOutput(1, this->m_size);
|
||||
this->setIntegerOnOutput(0, m_address);
|
||||
this->setIntegerOnOutput(1, m_size);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -232,17 +232,17 @@ namespace hex::plugin::builtin {
|
|||
NodeVisualizerDigram() : Node("hex.builtin.nodes.visualizer.digram.header", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.input") }) { }
|
||||
|
||||
void drawNode() override {
|
||||
this->m_digram.draw(scaled({ 200, 200 }));
|
||||
m_digram.draw(scaled({ 200, 200 }));
|
||||
|
||||
if (ImGui::IsItemHovered() && ImGui::IsKeyDown(ImGuiKey_LeftShift)) {
|
||||
ImGui::BeginTooltip();
|
||||
this->m_digram.draw(scaled({ 600, 600 }));
|
||||
m_digram.draw(scaled({ 600, 600 }));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
void process() override {
|
||||
this->m_digram.process(this->getBufferOnInput(0));
|
||||
m_digram.process(this->getBufferOnInput(0));
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -254,16 +254,16 @@ namespace hex::plugin::builtin {
|
|||
NodeVisualizerLayeredDistribution() : Node("hex.builtin.nodes.visualizer.layered_dist.header", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.input") }) { }
|
||||
|
||||
void drawNode() override {
|
||||
this->m_layeredDistribution.draw(scaled({ 200, 200 }));
|
||||
m_layeredDistribution.draw(scaled({ 200, 200 }));
|
||||
if (ImGui::IsItemHovered() && ImGui::IsKeyDown(ImGuiKey_LeftShift)) {
|
||||
ImGui::BeginTooltip();
|
||||
this->m_layeredDistribution.draw(scaled({ 600, 600 }));
|
||||
m_layeredDistribution.draw(scaled({ 600, 600 }));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
void process() override {
|
||||
this->m_layeredDistribution.process(this->getBufferOnInput(0));
|
||||
m_layeredDistribution.process(this->getBufferOnInput(0));
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -275,10 +275,10 @@ namespace hex::plugin::builtin {
|
|||
NodeVisualizerImage() : Node("hex.builtin.nodes.visualizer.image.header", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.input") }) { }
|
||||
|
||||
void drawNode() override {
|
||||
ImGui::Image(this->m_texture, scaled(ImVec2(this->m_texture.getAspectRatio() * 200, 200)));
|
||||
ImGui::Image(m_texture, scaled(ImVec2(m_texture.getAspectRatio() * 200, 200)));
|
||||
if (ImGui::IsItemHovered() && ImGui::IsKeyDown(ImGuiKey_LeftShift)) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Image(this->m_texture, scaled(ImVec2(this->m_texture.getAspectRatio() * 600, 600)));
|
||||
ImGui::Image(m_texture, scaled(ImVec2(m_texture.getAspectRatio() * 600, 600)));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
|
@ -286,7 +286,7 @@ namespace hex::plugin::builtin {
|
|||
void process() override {
|
||||
const auto &rawData = this->getBufferOnInput(0);
|
||||
|
||||
this->m_texture = ImGuiExt::Texture(rawData.data(), rawData.size(), ImGuiExt::Texture::Filter::Nearest);
|
||||
m_texture = ImGuiExt::Texture(rawData.data(), rawData.size(), ImGuiExt::Texture::Filter::Nearest);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -298,16 +298,16 @@ namespace hex::plugin::builtin {
|
|||
NodeVisualizerImageRGBA() : Node("hex.builtin.nodes.visualizer.image_rgba.header", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.input"), dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.common.width"), dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.common.height") }) { }
|
||||
|
||||
void drawNode() override {
|
||||
ImGui::Image(this->m_texture, scaled(ImVec2(this->m_texture.getAspectRatio() * 200, 200)));
|
||||
ImGui::Image(m_texture, scaled(ImVec2(m_texture.getAspectRatio() * 200, 200)));
|
||||
if (ImGui::IsItemHovered() && ImGui::IsKeyDown(ImGuiKey_LeftShift)) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Image(this->m_texture, scaled(ImVec2(this->m_texture.getAspectRatio() * 600, 600)));
|
||||
ImGui::Image(m_texture, scaled(ImVec2(m_texture.getAspectRatio() * 600, 600)));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
void process() override {
|
||||
this->m_texture = { };
|
||||
m_texture = { };
|
||||
|
||||
const auto &rawData = this->getBufferOnInput(0);
|
||||
const auto &width = this->getIntegerOnInput(1);
|
||||
|
|
@ -317,7 +317,7 @@ namespace hex::plugin::builtin {
|
|||
if (requiredBytes > rawData.size())
|
||||
throwNodeError(hex::format("Image requires at least {} bytes of data, but only {} bytes are available", requiredBytes, rawData.size()));
|
||||
|
||||
this->m_texture = ImGuiExt::Texture(rawData.data(), rawData.size(), ImGuiExt::Texture::Filter::Nearest, width, height);
|
||||
m_texture = ImGuiExt::Texture(rawData.data(), rawData.size(), ImGuiExt::Texture::Filter::Nearest, width, height);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -342,7 +342,7 @@ namespace hex::plugin::builtin {
|
|||
if (ImPlot::BeginPlot("##distribution", viewSize, ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect)) {
|
||||
ImPlot::SetupAxes("Address", "Count", ImPlotAxisFlags_Lock, ImPlotAxisFlags_Lock);
|
||||
ImPlot::SetupAxisScale(ImAxis_Y1, ImPlotScale_Log10);
|
||||
ImPlot::SetupAxesLimits(0, 256, 1, double(*std::max_element(this->m_counts.begin(), this->m_counts.end())) * 1.1F, ImGuiCond_Always);
|
||||
ImPlot::SetupAxesLimits(0, 256, 1, double(*std::max_element(m_counts.begin(), m_counts.end())) * 1.1F, ImGuiCond_Always);
|
||||
|
||||
static auto x = [] {
|
||||
std::array<ImU64, 256> result { 0 };
|
||||
|
|
@ -351,7 +351,7 @@ namespace hex::plugin::builtin {
|
|||
}();
|
||||
|
||||
|
||||
ImPlot::PlotBars<ImU64>("##bytes", x.data(), this->m_counts.data(), x.size(), 1);
|
||||
ImPlot::PlotBars<ImU64>("##bytes", x.data(), m_counts.data(), x.size(), 1);
|
||||
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
|
|
@ -360,9 +360,9 @@ namespace hex::plugin::builtin {
|
|||
void process() override {
|
||||
const auto &buffer = this->getBufferOnInput(0);
|
||||
|
||||
this->m_counts.fill(0x00);
|
||||
m_counts.fill(0x00);
|
||||
for (const auto &byte : buffer) {
|
||||
this->m_counts[byte]++;
|
||||
m_counts[byte]++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -377,7 +377,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void drawNode() override {
|
||||
ImGui::PushItemWidth(100_scaled);
|
||||
ImGui::InputText("##name", this->m_name);
|
||||
ImGui::InputText("##name", m_name);
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
|
|
@ -387,7 +387,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
const auto &outVars = runtime.getOutVariables();
|
||||
|
||||
if (outVars.contains(this->m_name)) {
|
||||
if (outVars.contains(m_name)) {
|
||||
std::visit(wolv::util::overloaded {
|
||||
[](const std::string &) {},
|
||||
[](pl::ptrn::Pattern *) {},
|
||||
|
|
@ -397,20 +397,20 @@ namespace hex::plugin::builtin {
|
|||
|
||||
this->setBufferOnOutput(0, buffer);
|
||||
}
|
||||
}, outVars.at(this->m_name));
|
||||
}, outVars.at(m_name));
|
||||
} else {
|
||||
throwNodeError(hex::format("Out variable '{}' has not been defined!", this->m_name));
|
||||
throwNodeError(hex::format("Out variable '{}' has not been defined!", m_name));
|
||||
}
|
||||
}
|
||||
|
||||
void store(nlohmann::json &j) const override {
|
||||
j = nlohmann::json::object();
|
||||
|
||||
j["name"] = this->m_name;
|
||||
j["name"] = m_name;
|
||||
}
|
||||
|
||||
void load(const nlohmann::json &j) override {
|
||||
this->m_name = j["name"].get<std::string>();
|
||||
m_name = j["name"].get<std::string>();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -11,18 +11,18 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void drawNode() override {
|
||||
ImGui::PushItemWidth(150_scaled);
|
||||
if (this->m_value.has_value())
|
||||
ImGuiExt::TextFormatted("0x{0:X}", this->m_value.value());
|
||||
if (m_value.has_value())
|
||||
ImGuiExt::TextFormatted("0x{0:X}", m_value.value());
|
||||
else
|
||||
ImGui::TextUnformatted("???");
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
void process() override {
|
||||
this->m_value.reset();
|
||||
m_value.reset();
|
||||
const auto &input = this->getIntegerOnInput(0);
|
||||
|
||||
this->m_value = input;
|
||||
m_value = input;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -35,18 +35,18 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void drawNode() override {
|
||||
ImGui::PushItemWidth(150_scaled);
|
||||
if (this->m_value.has_value())
|
||||
ImGuiExt::TextFormatted("{0}", this->m_value.value());
|
||||
if (m_value.has_value())
|
||||
ImGuiExt::TextFormatted("{0}", m_value.value());
|
||||
else
|
||||
ImGui::TextUnformatted("???");
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
void process() override {
|
||||
this->m_value.reset();
|
||||
m_value.reset();
|
||||
const auto &input = this->getFloatOnInput(0);
|
||||
|
||||
this->m_value = input;
|
||||
m_value = input;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -63,7 +63,7 @@ namespace hex::plugin::builtin {
|
|||
if (ImGui::BeginChild("##hex_view", scaled(ImVec2(ImGui::CalcTextSize(Header.c_str()).x, 200)), true)) {
|
||||
ImGui::TextUnformatted(Header.c_str());
|
||||
|
||||
auto size = this->m_buffer.size();
|
||||
auto size = m_buffer.size();
|
||||
ImGuiListClipper clipper;
|
||||
|
||||
clipper.Begin((size + 0x0F) / 0x10);
|
||||
|
|
@ -75,7 +75,7 @@ namespace hex::plugin::builtin {
|
|||
std::string line = hex::format(" {:08X}: ", y * 0x10);
|
||||
for (u32 x = 0; x < 0x10; x++) {
|
||||
if (x < lineSize)
|
||||
line += hex::format("{:02X} ", this->m_buffer[y * 0x10 + x]);
|
||||
line += hex::format("{:02X} ", m_buffer[y * 0x10 + x]);
|
||||
else
|
||||
line += " ";
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ namespace hex::plugin::builtin {
|
|||
line += " ";
|
||||
|
||||
for (u32 x = 0; x < lineSize; x++) {
|
||||
auto c = char(this->m_buffer[y * 0x10 + x]);
|
||||
auto c = char(m_buffer[y * 0x10 + x]);
|
||||
if (std::isprint(c))
|
||||
line += c;
|
||||
else
|
||||
|
|
@ -100,7 +100,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
void process() override {
|
||||
this->m_buffer = this->getBufferOnInput(0);
|
||||
m_buffer = this->getBufferOnInput(0);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -114,7 +114,7 @@ namespace hex::plugin::builtin {
|
|||
void drawNode() override {
|
||||
constexpr static auto LineLength = 50;
|
||||
if (ImGui::BeginChild("##string_view", scaled(ImVec2(ImGui::CalcTextSize(" ").x * (LineLength + 4), 150)), true)) {
|
||||
std::string_view string = this->m_value;
|
||||
std::string_view string = m_value;
|
||||
|
||||
ImGuiListClipper clipper;
|
||||
clipper.Begin((string.length() + (LineLength - 1)) / LineLength);
|
||||
|
|
@ -135,7 +135,7 @@ namespace hex::plugin::builtin {
|
|||
void process() override {
|
||||
const auto &input = this->getBufferOnInput(0);
|
||||
|
||||
this->m_value = hex::encodeByteString(input);
|
||||
m_value = hex::encodeByteString(input);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -148,7 +148,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void drawNode() override {
|
||||
ImGui::PushItemWidth(100_scaled);
|
||||
ImGui::Text("%s", this->m_display.c_str());
|
||||
ImGui::Text("%s", m_display.c_str());
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
|
|
@ -165,7 +165,7 @@ namespace hex::plugin::builtin {
|
|||
display += (byte & (1 << i)) != 0 ? '1' : '0';
|
||||
}
|
||||
}
|
||||
this->m_display = wolv::util::trim(display);
|
||||
m_display = wolv::util::trim(display);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -236,16 +236,16 @@ namespace hex::plugin::builtin {
|
|||
hex::unused(address, data, size, upperCase);
|
||||
|
||||
if (startedEditing) {
|
||||
this->m_currColor = { float(data[0]) / 0xFF, float(data[1]) / 0xFF, float(data[2]) / 0xFF, float(data[3]) / 0xFF };
|
||||
m_currColor = { float(data[0]) / 0xFF, float(data[1]) / 0xFF, float(data[2]) / 0xFF, float(data[3]) / 0xFF };
|
||||
ImGui::OpenPopup("##color_popup");
|
||||
}
|
||||
|
||||
ImGui::ColorButton("##color", ImColor(this->m_currColor[0], this->m_currColor[1], this->m_currColor[2], this->m_currColor[3]), ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoDragDrop, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
|
||||
ImGui::ColorButton("##color", ImColor(m_currColor[0], m_currColor[1], m_currColor[2], m_currColor[3]), ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoDragDrop, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
|
||||
|
||||
if (ImGui::BeginPopup("##color_popup")) {
|
||||
if (ImGui::ColorPicker4("##picker", this->m_currColor.data(), ImGuiColorEditFlags_AlphaBar)) {
|
||||
if (ImGui::ColorPicker4("##picker", m_currColor.data(), ImGuiColorEditFlags_AlphaBar)) {
|
||||
for (u8 i = 0; i < 4; i++)
|
||||
data[i] = this->m_currColor[i] * 0xFF;
|
||||
data[i] = m_currColor[i] * 0xFF;
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
} else {
|
||||
|
|
@ -274,11 +274,11 @@ namespace hex::plugin::builtin {
|
|||
hex::unused(address, startedEditing);
|
||||
|
||||
if (startedEditing) {
|
||||
this->m_inputBuffer = hex::format("{:08b}", *data);
|
||||
m_inputBuffer = hex::format("{:08b}", *data);
|
||||
}
|
||||
|
||||
if (drawDefaultTextEditingTextBox(address, this->m_inputBuffer, ImGuiInputTextFlags_None)) {
|
||||
if (auto result = hex::parseBinaryString(wolv::util::trim(this->m_inputBuffer)); result.has_value()) {
|
||||
if (drawDefaultTextEditingTextBox(address, m_inputBuffer, ImGuiInputTextFlags_None)) {
|
||||
if (auto result = hex::parseBinaryString(wolv::util::trim(m_inputBuffer)); result.has_value()) {
|
||||
*data = result.value();
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,14 +112,14 @@ namespace hex::plugin::builtin {
|
|||
: Hash(name), m_crcFunction(crcFunction), m_polynomial(polynomial), m_initialValue(initialValue), m_xorOut(xorOut), m_reflectIn(reflectIn), m_reflectOut(reflectOut) {}
|
||||
|
||||
void draw() override {
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.hash.crc.poly"_lang, &this->m_polynomial);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.hash.crc.iv"_lang, &this->m_initialValue);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.hash.crc.xor_out"_lang, &this->m_xorOut);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.hash.crc.poly"_lang, &m_polynomial);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.hash.crc.iv"_lang, &m_initialValue);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.hash.crc.xor_out"_lang, &m_xorOut);
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::Checkbox("hex.builtin.hash.crc.refl_in"_lang, &this->m_reflectIn);
|
||||
ImGui::Checkbox("hex.builtin.hash.crc.refl_out"_lang, &this->m_reflectOut);
|
||||
ImGui::Checkbox("hex.builtin.hash.crc.refl_in"_lang, &m_reflectIn);
|
||||
ImGui::Checkbox("hex.builtin.hash.crc.refl_out"_lang, &m_reflectOut);
|
||||
}
|
||||
|
||||
Function create(std::string name) override {
|
||||
|
|
@ -139,22 +139,22 @@ namespace hex::plugin::builtin {
|
|||
[[nodiscard]] nlohmann::json store() const override {
|
||||
nlohmann::json result;
|
||||
|
||||
result["polynomial"] = this->m_polynomial;
|
||||
result["initialValue"] = this->m_initialValue;
|
||||
result["xorOut"] = this->m_xorOut;
|
||||
result["reflectIn"] = this->m_reflectIn;
|
||||
result["reflectOut"] = this->m_reflectOut;
|
||||
result["polynomial"] = m_polynomial;
|
||||
result["initialValue"] = m_initialValue;
|
||||
result["xorOut"] = m_xorOut;
|
||||
result["reflectIn"] = m_reflectIn;
|
||||
result["reflectOut"] = m_reflectOut;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void load(const nlohmann::json &json) override {
|
||||
try {
|
||||
this->m_polynomial = json.at("polynomial");
|
||||
this->m_initialValue = json.at("initialValue");
|
||||
this->m_xorOut = json.at("xorOut");
|
||||
this->m_reflectIn = json.at("reflectIn");
|
||||
this->m_reflectOut = json.at("reflectOut");
|
||||
m_polynomial = json.at("polynomial");
|
||||
m_initialValue = json.at("initialValue");
|
||||
m_xorOut = json.at("xorOut");
|
||||
m_reflectIn = json.at("reflectIn");
|
||||
m_reflectOut = json.at("reflectOut");
|
||||
} catch (std::exception&) { }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,21 +50,21 @@ namespace hex::plugin::builtin {
|
|||
bool DiskProvider::isAvailable() const {
|
||||
#if defined(OS_WINDOWS)
|
||||
|
||||
return this->m_diskHandle != INVALID_HANDLE_VALUE;
|
||||
return m_diskHandle != INVALID_HANDLE_VALUE;
|
||||
|
||||
#else
|
||||
|
||||
return this->m_diskHandle != -1;
|
||||
return m_diskHandle != -1;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
bool DiskProvider::isReadable() const {
|
||||
return this->m_readable;
|
||||
return m_readable;
|
||||
}
|
||||
|
||||
bool DiskProvider::isWritable() const {
|
||||
return this->m_writable;
|
||||
return m_writable;
|
||||
}
|
||||
|
||||
bool DiskProvider::isResizable() const {
|
||||
|
|
@ -77,7 +77,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
|
||||
void DiskProvider::setPath(const std::fs::path &path) {
|
||||
this->m_path = path;
|
||||
m_path = path;
|
||||
}
|
||||
|
||||
#if defined (OS_LINUX)
|
||||
|
|
@ -143,19 +143,19 @@ namespace hex::plugin::builtin {
|
|||
#endif
|
||||
|
||||
bool DiskProvider::open() {
|
||||
this->m_readable = true;
|
||||
this->m_writable = true;
|
||||
m_readable = true;
|
||||
m_writable = true;
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
|
||||
const auto &path = this->m_path.native();
|
||||
const auto &path = m_path.native();
|
||||
|
||||
this->m_diskHandle = CreateFileW(path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (this->m_diskHandle == INVALID_HANDLE_VALUE) {
|
||||
this->m_diskHandle = CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
this->m_writable = false;
|
||||
m_diskHandle = CreateFileW(path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (m_diskHandle == INVALID_HANDLE_VALUE) {
|
||||
m_diskHandle = CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
m_writable = false;
|
||||
|
||||
if (this->m_diskHandle == INVALID_HANDLE_VALUE)
|
||||
if (m_diskHandle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ namespace hex::plugin::builtin {
|
|||
DISK_GEOMETRY_EX diskGeometry = { };
|
||||
DWORD bytesRead = 0;
|
||||
if (DeviceIoControl(
|
||||
this->m_diskHandle,
|
||||
m_diskHandle,
|
||||
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
|
||||
nullptr,
|
||||
0,
|
||||
|
|
@ -171,45 +171,45 @@ namespace hex::plugin::builtin {
|
|||
sizeof(DISK_GEOMETRY_EX),
|
||||
&bytesRead,
|
||||
nullptr)) {
|
||||
this->m_diskSize = diskGeometry.DiskSize.QuadPart;
|
||||
this->m_sectorSize = diskGeometry.Geometry.BytesPerSector;
|
||||
this->m_sectorBuffer.resize(this->m_sectorSize);
|
||||
m_diskSize = diskGeometry.DiskSize.QuadPart;
|
||||
m_sectorSize = diskGeometry.Geometry.BytesPerSector;
|
||||
m_sectorBuffer.resize(m_sectorSize);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->m_diskHandle == nullptr || this->m_diskHandle == INVALID_HANDLE_VALUE) {
|
||||
this->m_readable = false;
|
||||
this->m_diskHandle = nullptr;
|
||||
CloseHandle(this->m_diskHandle);
|
||||
if (m_diskHandle == nullptr || m_diskHandle == INVALID_HANDLE_VALUE) {
|
||||
m_readable = false;
|
||||
m_diskHandle = nullptr;
|
||||
CloseHandle(m_diskHandle);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
const auto &path = this->m_path.native();
|
||||
const auto &path = m_path.native();
|
||||
|
||||
this->m_diskHandle = ::open(path.c_str(), O_RDWR);
|
||||
if (this->m_diskHandle == -1) {
|
||||
m_diskHandle = ::open(path.c_str(), O_RDWR);
|
||||
if (m_diskHandle == -1) {
|
||||
this->setErrorMessage(hex::format("hex.builtin.provider.disk.error.read_rw"_lang, path, ::strerror(errno)));
|
||||
log::warn(this->getErrorMessage());
|
||||
this->m_diskHandle = ::open(path.c_str(), O_RDONLY);
|
||||
this->m_writable = false;
|
||||
m_diskHandle = ::open(path.c_str(), O_RDONLY);
|
||||
m_writable = false;
|
||||
}
|
||||
|
||||
if (this->m_diskHandle == -1) {
|
||||
if (m_diskHandle == -1) {
|
||||
this->setErrorMessage(hex::format("hex.builtin.provider.disk.error.read_ro"_lang, path, ::strerror(errno)));
|
||||
log::warn(this->getErrorMessage());
|
||||
this->m_readable = false;
|
||||
m_readable = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 diskSize = 0;
|
||||
blkdev_get_size(this->m_diskHandle, &diskSize);
|
||||
this->m_diskSize = diskSize;
|
||||
blkdev_get_sector_size(this->m_diskHandle, reinterpret_cast<int *>(&this->m_sectorSize));
|
||||
blkdev_get_size(m_diskHandle, &diskSize);
|
||||
m_diskSize = diskSize;
|
||||
blkdev_get_sector_size(m_diskHandle, reinterpret_cast<int *>(&m_sectorSize));
|
||||
|
||||
this->m_sectorBuffer.resize(this->m_sectorSize);
|
||||
m_sectorBuffer.resize(m_sectorSize);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -219,17 +219,17 @@ namespace hex::plugin::builtin {
|
|||
void DiskProvider::close() {
|
||||
#if defined(OS_WINDOWS)
|
||||
|
||||
if (this->m_diskHandle != INVALID_HANDLE_VALUE)
|
||||
::CloseHandle(this->m_diskHandle);
|
||||
if (m_diskHandle != INVALID_HANDLE_VALUE)
|
||||
::CloseHandle(m_diskHandle);
|
||||
|
||||
this->m_diskHandle = INVALID_HANDLE_VALUE;
|
||||
m_diskHandle = INVALID_HANDLE_VALUE;
|
||||
|
||||
#else
|
||||
|
||||
if (this->m_diskHandle != -1)
|
||||
::close(this->m_diskHandle);
|
||||
if (m_diskHandle != -1)
|
||||
::close(m_diskHandle);
|
||||
|
||||
this->m_diskHandle = -1;
|
||||
m_diskHandle = -1;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
@ -243,19 +243,19 @@ namespace hex::plugin::builtin {
|
|||
|
||||
while (size > 0) {
|
||||
LARGE_INTEGER seekPosition;
|
||||
seekPosition.LowPart = (offset & 0xFFFF'FFFF) - (offset % this->m_sectorSize);
|
||||
seekPosition.LowPart = (offset & 0xFFFF'FFFF) - (offset % m_sectorSize);
|
||||
seekPosition.HighPart = LONG(offset >> 32);
|
||||
|
||||
if (this->m_sectorBufferAddress != static_cast<u64>(seekPosition.QuadPart)) {
|
||||
::SetFilePointer(this->m_diskHandle, seekPosition.LowPart, &seekPosition.HighPart, FILE_BEGIN);
|
||||
::ReadFile(this->m_diskHandle, this->m_sectorBuffer.data(), this->m_sectorBuffer.size(), &bytesRead, nullptr);
|
||||
this->m_sectorBufferAddress = seekPosition.QuadPart;
|
||||
if (m_sectorBufferAddress != static_cast<u64>(seekPosition.QuadPart)) {
|
||||
::SetFilePointer(m_diskHandle, seekPosition.LowPart, &seekPosition.HighPart, FILE_BEGIN);
|
||||
::ReadFile(m_diskHandle, m_sectorBuffer.data(), m_sectorBuffer.size(), &bytesRead, nullptr);
|
||||
m_sectorBufferAddress = seekPosition.QuadPart;
|
||||
}
|
||||
|
||||
std::memcpy(static_cast<u8 *>(buffer) + (offset - startOffset), this->m_sectorBuffer.data() + (offset & (this->m_sectorSize - 1)), std::min<u64>(this->m_sectorSize, size));
|
||||
std::memcpy(static_cast<u8 *>(buffer) + (offset - startOffset), m_sectorBuffer.data() + (offset & (m_sectorSize - 1)), std::min<u64>(m_sectorSize, size));
|
||||
|
||||
size = std::max<ssize_t>(static_cast<ssize_t>(size) - this->m_sectorSize, 0);
|
||||
offset += this->m_sectorSize;
|
||||
size = std::max<ssize_t>(static_cast<ssize_t>(size) - m_sectorSize, 0);
|
||||
offset += m_sectorSize;
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
@ -263,22 +263,22 @@ namespace hex::plugin::builtin {
|
|||
u64 startOffset = offset;
|
||||
|
||||
while (size > 0) {
|
||||
u64 seekPosition = offset - (offset % this->m_sectorSize);
|
||||
u64 seekPosition = offset - (offset % m_sectorSize);
|
||||
|
||||
if (this->m_sectorBufferAddress != seekPosition || this->m_sectorBufferAddress == 0) {
|
||||
::lseek(this->m_diskHandle, seekPosition, SEEK_SET);
|
||||
if (::read(this->m_diskHandle, this->m_sectorBuffer.data(), this->m_sectorBuffer.size()) == -1)
|
||||
if (m_sectorBufferAddress != seekPosition || m_sectorBufferAddress == 0) {
|
||||
::lseek(m_diskHandle, seekPosition, SEEK_SET);
|
||||
if (::read(m_diskHandle, m_sectorBuffer.data(), m_sectorBuffer.size()) == -1)
|
||||
break;
|
||||
|
||||
this->m_sectorBufferAddress = seekPosition;
|
||||
m_sectorBufferAddress = seekPosition;
|
||||
}
|
||||
|
||||
std::memcpy(reinterpret_cast<u8 *>(buffer) + (offset - startOffset),
|
||||
this->m_sectorBuffer.data() + (offset & (this->m_sectorSize - 1)),
|
||||
std::min<u64>(this->m_sectorSize, size));
|
||||
m_sectorBuffer.data() + (offset & (m_sectorSize - 1)),
|
||||
std::min<u64>(m_sectorSize, size));
|
||||
|
||||
size = std::max<ssize_t>(static_cast<ssize_t>(size) - this->m_sectorSize, 0);
|
||||
offset += this->m_sectorSize;
|
||||
size = std::max<ssize_t>(static_cast<ssize_t>(size) - m_sectorSize, 0);
|
||||
offset += m_sectorSize;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -292,21 +292,21 @@ namespace hex::plugin::builtin {
|
|||
u64 startOffset = offset;
|
||||
|
||||
std::vector<u8> modifiedSectorBuffer;
|
||||
modifiedSectorBuffer.resize(this->m_sectorSize);
|
||||
modifiedSectorBuffer.resize(m_sectorSize);
|
||||
|
||||
while (size > 0) {
|
||||
u64 sectorBase = offset - (offset % this->m_sectorSize);
|
||||
size_t currSize = std::min<u64>(size, this->m_sectorSize);
|
||||
u64 sectorBase = offset - (offset % m_sectorSize);
|
||||
size_t currSize = std::min<u64>(size, m_sectorSize);
|
||||
|
||||
this->readRaw(sectorBase, modifiedSectorBuffer.data(), modifiedSectorBuffer.size());
|
||||
std::memcpy(modifiedSectorBuffer.data() + ((offset - sectorBase) % this->m_sectorSize), reinterpret_cast<const u8 *>(buffer) + (startOffset - offset), currSize);
|
||||
std::memcpy(modifiedSectorBuffer.data() + ((offset - sectorBase) % m_sectorSize), reinterpret_cast<const u8 *>(buffer) + (startOffset - offset), currSize);
|
||||
|
||||
LARGE_INTEGER seekPosition;
|
||||
seekPosition.LowPart = (offset & 0xFFFF'FFFF) - (offset % this->m_sectorSize);
|
||||
seekPosition.LowPart = (offset & 0xFFFF'FFFF) - (offset % m_sectorSize);
|
||||
seekPosition.HighPart = offset >> 32;
|
||||
|
||||
::SetFilePointer(this->m_diskHandle, seekPosition.LowPart, &seekPosition.HighPart, FILE_BEGIN);
|
||||
::WriteFile(this->m_diskHandle, modifiedSectorBuffer.data(), modifiedSectorBuffer.size(), &bytesWritten, nullptr);
|
||||
::SetFilePointer(m_diskHandle, seekPosition.LowPart, &seekPosition.HighPart, FILE_BEGIN);
|
||||
::WriteFile(m_diskHandle, modifiedSectorBuffer.data(), modifiedSectorBuffer.size(), &bytesWritten, nullptr);
|
||||
|
||||
offset += currSize;
|
||||
size -= currSize;
|
||||
|
|
@ -317,17 +317,17 @@ namespace hex::plugin::builtin {
|
|||
u64 startOffset = offset;
|
||||
|
||||
std::vector<u8> modifiedSectorBuffer;
|
||||
modifiedSectorBuffer.resize(this->m_sectorSize);
|
||||
modifiedSectorBuffer.resize(m_sectorSize);
|
||||
|
||||
while (size > 0) {
|
||||
u64 sectorBase = offset - (offset % this->m_sectorSize);
|
||||
size_t currSize = std::min<u64>(size, this->m_sectorSize);
|
||||
u64 sectorBase = offset - (offset % m_sectorSize);
|
||||
size_t currSize = std::min<u64>(size, m_sectorSize);
|
||||
|
||||
this->readRaw(sectorBase, modifiedSectorBuffer.data(), modifiedSectorBuffer.size());
|
||||
std::memcpy(modifiedSectorBuffer.data() + ((offset - sectorBase) % this->m_sectorSize), reinterpret_cast<const u8 *>(buffer) + (startOffset - offset), currSize);
|
||||
std::memcpy(modifiedSectorBuffer.data() + ((offset - sectorBase) % m_sectorSize), reinterpret_cast<const u8 *>(buffer) + (startOffset - offset), currSize);
|
||||
|
||||
::lseek(this->m_diskHandle, sectorBase, SEEK_SET);
|
||||
if (::write(this->m_diskHandle, modifiedSectorBuffer.data(), modifiedSectorBuffer.size()) < 0)
|
||||
::lseek(m_diskHandle, sectorBase, SEEK_SET);
|
||||
if (::write(m_diskHandle, modifiedSectorBuffer.data(), modifiedSectorBuffer.size()) < 0)
|
||||
break;
|
||||
|
||||
offset += currSize;
|
||||
|
|
@ -338,21 +338,21 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
u64 DiskProvider::getActualSize() const {
|
||||
return this->m_diskSize;
|
||||
return m_diskSize;
|
||||
}
|
||||
|
||||
std::string DiskProvider::getName() const {
|
||||
if (this->m_friendlyName.empty())
|
||||
return wolv::util::toUTF8String(this->m_path);
|
||||
if (m_friendlyName.empty())
|
||||
return wolv::util::toUTF8String(m_path);
|
||||
else
|
||||
return this->m_friendlyName;
|
||||
return m_friendlyName;
|
||||
}
|
||||
|
||||
std::vector<DiskProvider::Description> DiskProvider::getDataDescription() const {
|
||||
return {
|
||||
{ "hex.builtin.provider.disk.selected_disk"_lang, wolv::util::toUTF8String(this->m_path) },
|
||||
{ "hex.builtin.provider.disk.disk_size"_lang, hex::toByteString(this->m_diskSize) },
|
||||
{ "hex.builtin.provider.disk.sector_size"_lang, hex::toByteString(this->m_sectorSize) }
|
||||
{ "hex.builtin.provider.disk.selected_disk"_lang, wolv::util::toUTF8String(m_path) },
|
||||
{ "hex.builtin.provider.disk.disk_size"_lang, hex::toByteString(m_diskSize) },
|
||||
{ "hex.builtin.provider.disk.sector_size"_lang, hex::toByteString(m_sectorSize) }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -360,7 +360,7 @@ namespace hex::plugin::builtin {
|
|||
void DiskProvider::reloadDrives() {
|
||||
#if defined(OS_WINDOWS)
|
||||
|
||||
this->m_availableDrives.clear();
|
||||
m_availableDrives.clear();
|
||||
|
||||
std::array<TCHAR, MAX_DEVICE_ID_LEN> deviceInstanceID = {};
|
||||
std::array<TCHAR, 1024> description = {};
|
||||
|
|
@ -412,7 +412,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
auto friendlyName = description.data();
|
||||
|
||||
this->m_availableDrives.insert({ path, friendlyName });
|
||||
m_availableDrives.insert({ path, friendlyName });
|
||||
}
|
||||
|
||||
// Add all logical drives
|
||||
|
|
@ -420,7 +420,7 @@ namespace hex::plugin::builtin {
|
|||
for (char i = 0; i < 26; i++) {
|
||||
if (drives[i]) {
|
||||
char letter = 'A' + i;
|
||||
this->m_availableDrives.insert({ hex::format(R"(\\.\{:c}:)", letter), hex::format(R"({:c}:/)", letter) });
|
||||
m_availableDrives.insert({ hex::format(R"(\\.\{:c}:)", letter), hex::format(R"({:c}:/)", letter) });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -430,12 +430,12 @@ namespace hex::plugin::builtin {
|
|||
bool DiskProvider::drawLoadInterface() {
|
||||
#if defined(OS_WINDOWS)
|
||||
|
||||
if (this->m_availableDrives.empty()) {
|
||||
if (m_availableDrives.empty()) {
|
||||
this->reloadDrives();
|
||||
this->m_elevated = hex::isProcessElevated();
|
||||
m_elevated = hex::isProcessElevated();
|
||||
}
|
||||
|
||||
if (!this->m_elevated) {
|
||||
if (!m_elevated) {
|
||||
ImGui::PushTextWrapPos(0);
|
||||
ImGuiExt::TextFormattedColored(ImGuiExt::GetCustomColorU32(ImGuiCustomCol_LoggerError), ICON_VS_SHIELD "{}", "hex.builtin.provider.disk.elevation"_lang);
|
||||
ImGui::PopTextWrapPos();
|
||||
|
|
@ -445,10 +445,10 @@ namespace hex::plugin::builtin {
|
|||
ImGui::PushItemWidth(300_scaled);
|
||||
if (ImGui::BeginListBox("hex.builtin.provider.disk.selected_disk"_lang)) {
|
||||
ImGui::PushID(1);
|
||||
for (const auto &[path, friendlyName] : this->m_availableDrives) {
|
||||
if (ImGui::Selectable(friendlyName.c_str(), this->m_path == path)) {
|
||||
this->m_path = path;
|
||||
this->m_friendlyName = friendlyName;
|
||||
for (const auto &[path, friendlyName] : m_availableDrives) {
|
||||
if (ImGui::Selectable(friendlyName.c_str(), m_path == path)) {
|
||||
m_path = path;
|
||||
m_friendlyName = friendlyName;
|
||||
}
|
||||
|
||||
ImGuiExt::InfoTooltip(path.c_str());
|
||||
|
|
@ -467,20 +467,20 @@ namespace hex::plugin::builtin {
|
|||
|
||||
#else
|
||||
|
||||
if (ImGui::InputText("hex.builtin.provider.disk.selected_disk"_lang, this->m_pathBuffer.data(), this->m_pathBuffer.size(), ImGuiInputTextFlags_CallbackResize, ImGuiExt::UpdateStringSizeCallback, &this->m_pathBuffer)) {
|
||||
this->m_path = this->m_pathBuffer;
|
||||
this->m_friendlyName = this->m_pathBuffer;
|
||||
if (ImGui::InputText("hex.builtin.provider.disk.selected_disk"_lang, m_pathBuffer.data(), m_pathBuffer.size(), ImGuiInputTextFlags_CallbackResize, ImGuiExt::UpdateStringSizeCallback, &m_pathBuffer)) {
|
||||
m_path = m_pathBuffer;
|
||||
m_friendlyName = m_pathBuffer;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return !this->m_path.empty();
|
||||
return !m_path.empty();
|
||||
}
|
||||
|
||||
nlohmann::json DiskProvider::storeSettings(nlohmann::json settings) const {
|
||||
settings["path"] = wolv::util::toUTF8String(this->m_path);
|
||||
settings["path"] = wolv::util::toUTF8String(m_path);
|
||||
|
||||
settings["friendly_name"] = this->m_friendlyName;
|
||||
settings["friendly_name"] = m_friendlyName;
|
||||
|
||||
return Provider::storeSettings(settings);
|
||||
}
|
||||
|
|
@ -491,7 +491,7 @@ namespace hex::plugin::builtin {
|
|||
auto path = settings.at("path").get<std::string>();
|
||||
|
||||
if (settings.contains("friendly_name"))
|
||||
this->m_friendlyName = settings.at("friendly_name").get<std::string>();
|
||||
m_friendlyName = settings.at("friendly_name").get<std::string>();
|
||||
|
||||
this->setPath(std::u8string(path.begin(), path.end()));
|
||||
this->reloadDrives();
|
||||
|
|
@ -508,11 +508,11 @@ namespace hex::plugin::builtin {
|
|||
|
||||
std::variant<std::string, i128> DiskProvider::queryInformation(const std::string &category, const std::string &argument) {
|
||||
if (category == "file_path")
|
||||
return wolv::util::toUTF8String(this->m_path);
|
||||
return wolv::util::toUTF8String(m_path);
|
||||
else if (category == "sector_size")
|
||||
return this->m_sectorSize;
|
||||
return m_sectorSize;
|
||||
else if (category == "friendly_name")
|
||||
return this->m_friendlyName;
|
||||
return m_friendlyName;
|
||||
else
|
||||
return Provider::queryInformation(category, argument);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,11 +27,11 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
bool FileProvider::isReadable() const {
|
||||
return isAvailable() && this->m_readable;
|
||||
return isAvailable() && m_readable;
|
||||
}
|
||||
|
||||
bool FileProvider::isWritable() const {
|
||||
return isAvailable() && this->m_writable;
|
||||
return isAvailable() && m_writable;
|
||||
}
|
||||
|
||||
bool FileProvider::isResizable() const {
|
||||
|
|
@ -39,7 +39,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
bool FileProvider::isSavable() const {
|
||||
return this->m_undoRedoStack.canUndo();
|
||||
return m_undoRedoStack.canUndo();
|
||||
}
|
||||
|
||||
void FileProvider::readRaw(u64 offset, void *buffer, size_t size) {
|
||||
|
|
@ -47,14 +47,14 @@ namespace hex::plugin::builtin {
|
|||
if (actualSize == 0 || (offset + size) > actualSize || buffer == nullptr || size == 0)
|
||||
return;
|
||||
|
||||
std::memcpy(buffer, this->m_file.getMapping() + offset, size);
|
||||
std::memcpy(buffer, m_file.getMapping() + offset, size);
|
||||
}
|
||||
|
||||
void FileProvider::writeRaw(u64 offset, const void *buffer, size_t size) {
|
||||
if ((offset + size) > this->getActualSize() || buffer == nullptr || size == 0)
|
||||
return;
|
||||
|
||||
std::memcpy(this->m_file.getMapping() + offset, buffer, size);
|
||||
std::memcpy(m_file.getMapping() + offset, buffer, size);
|
||||
}
|
||||
|
||||
void FileProvider::save() {
|
||||
|
|
@ -62,7 +62,7 @@ namespace hex::plugin::builtin {
|
|||
FILETIME ft;
|
||||
SYSTEMTIME st;
|
||||
|
||||
wolv::io::File file(this->m_path, wolv::io::File::Mode::Write);
|
||||
wolv::io::File file(m_path, wolv::io::File::Mode::Write);
|
||||
if (file.isValid()) {
|
||||
GetSystemTime(&st);
|
||||
if (SystemTimeToFileTime(&st, &ft)) {
|
||||
|
|
@ -76,7 +76,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
void FileProvider::saveAs(const std::fs::path &path) {
|
||||
if (path == this->m_path)
|
||||
if (path == m_path)
|
||||
this->save();
|
||||
else
|
||||
Provider::saveAs(path);
|
||||
|
|
@ -86,7 +86,7 @@ namespace hex::plugin::builtin {
|
|||
this->close();
|
||||
|
||||
{
|
||||
wolv::io::File file(this->m_path, wolv::io::File::Mode::Write);
|
||||
wolv::io::File file(m_path, wolv::io::File::Mode::Write);
|
||||
|
||||
file.setSize(newSize);
|
||||
}
|
||||
|
|
@ -139,29 +139,29 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
u64 FileProvider::getActualSize() const {
|
||||
return this->m_fileSize;
|
||||
return m_fileSize;
|
||||
}
|
||||
|
||||
std::string FileProvider::getName() const {
|
||||
return wolv::util::toUTF8String(this->m_path.filename());
|
||||
return wolv::util::toUTF8String(m_path.filename());
|
||||
}
|
||||
|
||||
std::vector<FileProvider::Description> FileProvider::getDataDescription() const {
|
||||
std::vector<Description> result;
|
||||
|
||||
result.emplace_back("hex.builtin.provider.file.path"_lang, wolv::util::toUTF8String(this->m_path));
|
||||
result.emplace_back("hex.builtin.provider.file.path"_lang, wolv::util::toUTF8String(m_path));
|
||||
result.emplace_back("hex.builtin.provider.file.size"_lang, hex::toByteString(this->getActualSize()));
|
||||
|
||||
if (this->m_fileStats.has_value()) {
|
||||
if (m_fileStats.has_value()) {
|
||||
std::string creationTime, accessTime, modificationTime;
|
||||
|
||||
try { creationTime = hex::format("{:%Y-%m-%d %H:%M:%S}", fmt::localtime(this->m_fileStats->st_ctime)); }
|
||||
try { creationTime = hex::format("{:%Y-%m-%d %H:%M:%S}", fmt::localtime(m_fileStats->st_ctime)); }
|
||||
catch (const std::exception&) { creationTime = "???"; }
|
||||
|
||||
try { accessTime = hex::format("{:%Y-%m-%d %H:%M:%S}", fmt::localtime(this->m_fileStats->st_atime)); }
|
||||
try { accessTime = hex::format("{:%Y-%m-%d %H:%M:%S}", fmt::localtime(m_fileStats->st_atime)); }
|
||||
catch (const std::exception&) { accessTime = "???"; }
|
||||
|
||||
try { modificationTime = hex::format("{:%Y-%m-%d %H:%M:%S}", fmt::localtime(this->m_fileStats->st_mtime)); }
|
||||
try { modificationTime = hex::format("{:%Y-%m-%d %H:%M:%S}", fmt::localtime(m_fileStats->st_mtime)); }
|
||||
catch (const std::exception&) { modificationTime = "???"; }
|
||||
|
||||
result.emplace_back("hex.builtin.provider.file.creation"_lang, creationTime);
|
||||
|
|
@ -174,19 +174,19 @@ namespace hex::plugin::builtin {
|
|||
|
||||
std::variant<std::string, i128> FileProvider::queryInformation(const std::string &category, const std::string &argument) {
|
||||
if (category == "file_path")
|
||||
return wolv::util::toUTF8String(this->m_path);
|
||||
return wolv::util::toUTF8String(m_path);
|
||||
else if (category == "file_name")
|
||||
return wolv::util::toUTF8String(this->m_path.filename());
|
||||
return wolv::util::toUTF8String(m_path.filename());
|
||||
else if (category == "file_extension")
|
||||
return wolv::util::toUTF8String(this->m_path.extension());
|
||||
return wolv::util::toUTF8String(m_path.extension());
|
||||
else if (category == "creation_time")
|
||||
return this->m_fileStats->st_ctime;
|
||||
return m_fileStats->st_ctime;
|
||||
else if (category == "access_time")
|
||||
return this->m_fileStats->st_atime;
|
||||
return m_fileStats->st_atime;
|
||||
else if (category == "modification_time")
|
||||
return this->m_fileStats->st_mtime;
|
||||
return m_fileStats->st_mtime;
|
||||
else if (category == "permissions")
|
||||
return this->m_fileStats->st_mode & 0777;
|
||||
return m_fileStats->st_mode & 0777;
|
||||
else
|
||||
return Provider::queryInformation(category, argument);
|
||||
}
|
||||
|
|
@ -199,50 +199,50 @@ namespace hex::plugin::builtin {
|
|||
|
||||
std::vector<FileProvider::MenuEntry> FileProvider::getMenuEntries(){
|
||||
return {
|
||||
{ "hex.builtin.provider.file.menu.open_folder"_lang, [this] { fs::openFolderWithSelectionExternal(this->m_path); } },
|
||||
{ "hex.builtin.provider.file.menu.open_file"_lang, [this] { fs::openFileExternal(this->m_path); } },
|
||||
{ "hex.builtin.provider.file.menu.open_folder"_lang, [this] { fs::openFolderWithSelectionExternal(m_path); } },
|
||||
{ "hex.builtin.provider.file.menu.open_file"_lang, [this] { fs::openFileExternal(m_path); } },
|
||||
{ "hex.builtin.provider.file.menu.into_memory"_lang, [this] { this->convertToMemoryFile(); } }
|
||||
};
|
||||
}
|
||||
|
||||
void FileProvider::setPath(const std::fs::path &path) {
|
||||
this->m_path = path;
|
||||
m_path = path;
|
||||
}
|
||||
|
||||
bool FileProvider::open() {
|
||||
this->m_readable = true;
|
||||
this->m_writable = true;
|
||||
m_readable = true;
|
||||
m_writable = true;
|
||||
|
||||
if (!std::fs::exists(this->m_path)) {
|
||||
this->setErrorMessage(hex::format("hex.builtin.provider.file.error.open"_lang, this->m_path.string(), ::strerror(ENOENT)));
|
||||
if (!std::fs::exists(m_path)) {
|
||||
this->setErrorMessage(hex::format("hex.builtin.provider.file.error.open"_lang, m_path.string(), ::strerror(ENOENT)));
|
||||
return false;
|
||||
}
|
||||
|
||||
wolv::io::File file(this->m_path, wolv::io::File::Mode::Write);
|
||||
wolv::io::File file(m_path, wolv::io::File::Mode::Write);
|
||||
if (!file.isValid()) {
|
||||
this->m_writable = false;
|
||||
m_writable = false;
|
||||
|
||||
file = wolv::io::File(this->m_path, wolv::io::File::Mode::Read);
|
||||
file = wolv::io::File(m_path, wolv::io::File::Mode::Read);
|
||||
if (!file.isValid()) {
|
||||
this->m_readable = false;
|
||||
this->setErrorMessage(hex::format("hex.builtin.provider.file.error.open"_lang, this->m_path.string(), ::strerror(errno)));
|
||||
m_readable = false;
|
||||
this->setErrorMessage(hex::format("hex.builtin.provider.file.error.open"_lang, m_path.string(), ::strerror(errno)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
this->m_fileStats = file.getFileInfo();
|
||||
this->m_file = std::move(file);
|
||||
m_fileStats = file.getFileInfo();
|
||||
m_file = std::move(file);
|
||||
|
||||
this->m_file.map();
|
||||
this->m_fileSize = this->m_file.getSize();
|
||||
m_file.map();
|
||||
m_fileSize = m_file.getSize();
|
||||
|
||||
this->m_file.close();
|
||||
m_file.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileProvider::close() {
|
||||
this->m_file.unmap();
|
||||
m_file.unmap();
|
||||
}
|
||||
|
||||
void FileProvider::loadSettings(const nlohmann::json &settings) {
|
||||
|
|
@ -258,7 +258,7 @@ namespace hex::plugin::builtin {
|
|||
try {
|
||||
this->setPath(projectPath.parent_path() / path);
|
||||
} catch (const std::fs::filesystem_error &e) {
|
||||
this->setErrorMessage(hex::format("hex.builtin.provider.file.error.open"_lang, this->m_path.string(), e.what()));
|
||||
this->setErrorMessage(hex::format("hex.builtin.provider.file.error.open"_lang, m_path.string(), e.what()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -269,9 +269,9 @@ namespace hex::plugin::builtin {
|
|||
nlohmann::json FileProvider::storeSettings(nlohmann::json settings) const {
|
||||
std::string path;
|
||||
if (auto projectPath = ProjectFile::getPath(); !projectPath.empty())
|
||||
path = wolv::util::toUTF8String(std::fs::proximate(this->m_path, projectPath.parent_path()));
|
||||
path = wolv::util::toUTF8String(std::fs::proximate(m_path, projectPath.parent_path()));
|
||||
if (path.empty())
|
||||
path = wolv::util::toUTF8String(this->m_path);
|
||||
path = wolv::util::toUTF8String(m_path);
|
||||
|
||||
settings["path"] = path;
|
||||
|
||||
|
|
|
|||
|
|
@ -127,11 +127,11 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
bool GDBProvider::isAvailable() const {
|
||||
return this->m_socket.isConnected();
|
||||
return m_socket.isConnected();
|
||||
}
|
||||
|
||||
bool GDBProvider::isReadable() const {
|
||||
return this->m_socket.isConnected();
|
||||
return m_socket.isConnected();
|
||||
}
|
||||
|
||||
bool GDBProvider::isWritable() const {
|
||||
|
|
@ -155,28 +155,28 @@ namespace hex::plugin::builtin {
|
|||
u64 alignedOffset = offset - (offset % CacheLineSize);
|
||||
|
||||
if (size <= CacheLineSize) {
|
||||
std::scoped_lock lock(this->m_cacheLock);
|
||||
std::scoped_lock lock(m_cacheLock);
|
||||
|
||||
const auto &cacheLine = std::find_if(this->m_cache.begin(), this->m_cache.end(), [&](auto &line) {
|
||||
const auto &cacheLine = std::find_if(m_cache.begin(), m_cache.end(), [&](auto &line) {
|
||||
return line.address == alignedOffset;
|
||||
});
|
||||
|
||||
if (cacheLine != this->m_cache.end()) {
|
||||
if (cacheLine != m_cache.end()) {
|
||||
// Cache hit
|
||||
|
||||
} else {
|
||||
// Cache miss
|
||||
|
||||
this->m_cache.push_back({ alignedOffset, { 0 } });
|
||||
m_cache.push_back({ alignedOffset, { 0 } });
|
||||
}
|
||||
|
||||
if (cacheLine != this->m_cache.end())
|
||||
if (cacheLine != m_cache.end())
|
||||
std::memcpy(buffer, &cacheLine->data[0] + (offset % CacheLineSize), std::min<u64>(size, cacheLine->data.size()));
|
||||
} else {
|
||||
while (size > 0) {
|
||||
size_t readSize = std::min<u64>(size, CacheLineSize);
|
||||
|
||||
auto data = gdb::readMemory(this->m_socket, offset, size);
|
||||
auto data = gdb::readMemory(m_socket, offset, size);
|
||||
if (!data.empty())
|
||||
std::memcpy(buffer, &data[0], data.size());
|
||||
|
||||
|
|
@ -192,7 +192,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
offset -= this->getBaseAddress();
|
||||
|
||||
gdb::writeMemory(this->m_socket, offset, buffer, size);
|
||||
gdb::writeMemory(m_socket, offset, buffer, size);
|
||||
}
|
||||
|
||||
void GDBProvider::save() {
|
||||
|
|
@ -200,7 +200,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
u64 GDBProvider::getActualSize() const {
|
||||
return this->m_size;
|
||||
return m_size;
|
||||
}
|
||||
|
||||
std::string GDBProvider::getName() const {
|
||||
|
|
@ -208,8 +208,8 @@ namespace hex::plugin::builtin {
|
|||
std::string port = "-";
|
||||
|
||||
if (this->isConnected()) {
|
||||
address = this->m_ipAddress;
|
||||
port = std::to_string(this->m_port);
|
||||
address = m_ipAddress;
|
||||
port = std::to_string(m_port);
|
||||
}
|
||||
|
||||
return hex::format("hex.builtin.provider.gdb.name"_lang, address, port);
|
||||
|
|
@ -217,46 +217,46 @@ namespace hex::plugin::builtin {
|
|||
|
||||
std::vector<GDBProvider::Description> GDBProvider::getDataDescription() const {
|
||||
return {
|
||||
{"hex.builtin.provider.gdb.server"_lang, hex::format("{}:{}", this->m_ipAddress, this->m_port)},
|
||||
{"hex.builtin.provider.gdb.server"_lang, hex::format("{}:{}", m_ipAddress, m_port)},
|
||||
};
|
||||
}
|
||||
|
||||
bool GDBProvider::open() {
|
||||
this->m_socket = wolv::net::SocketClient(wolv::net::SocketClient::Type::TCP);
|
||||
this->m_socket.connect(this->m_ipAddress, this->m_port);
|
||||
if (!gdb::enableNoAckMode(this->m_socket)) {
|
||||
this->m_socket.disconnect();
|
||||
m_socket = wolv::net::SocketClient(wolv::net::SocketClient::Type::TCP);
|
||||
m_socket.connect(m_ipAddress, m_port);
|
||||
if (!gdb::enableNoAckMode(m_socket)) {
|
||||
m_socket.disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->m_socket.isConnected()) {
|
||||
gdb::continueExecution(this->m_socket);
|
||||
if (m_socket.isConnected()) {
|
||||
gdb::continueExecution(m_socket);
|
||||
|
||||
this->m_cacheUpdateThread = std::thread([this] {
|
||||
auto cacheLine = this->m_cache.begin();
|
||||
m_cacheUpdateThread = std::thread([this] {
|
||||
auto cacheLine = m_cache.begin();
|
||||
while (this->isConnected()) {
|
||||
{
|
||||
std::scoped_lock lock(this->m_cacheLock);
|
||||
std::scoped_lock lock(m_cacheLock);
|
||||
|
||||
if (this->m_resetCache) {
|
||||
this->m_cache.clear();
|
||||
this->m_resetCache = false;
|
||||
cacheLine = this->m_cache.begin();
|
||||
if (m_resetCache) {
|
||||
m_cache.clear();
|
||||
m_resetCache = false;
|
||||
cacheLine = m_cache.begin();
|
||||
}
|
||||
|
||||
if (cacheLine != this->m_cache.end()) {
|
||||
std::vector<u8> data = gdb::readMemory(this->m_socket, cacheLine->address, CacheLineSize);
|
||||
if (cacheLine != m_cache.end()) {
|
||||
std::vector<u8> data = gdb::readMemory(m_socket, cacheLine->address, CacheLineSize);
|
||||
|
||||
while (std::count_if(this->m_cache.begin(), this->m_cache.end(), [&](auto &line) { return !line.data.empty(); }) > 100) {
|
||||
this->m_cache.pop_front();
|
||||
cacheLine = this->m_cache.begin();
|
||||
while (std::count_if(m_cache.begin(), m_cache.end(), [&](auto &line) { return !line.data.empty(); }) > 100) {
|
||||
m_cache.pop_front();
|
||||
cacheLine = m_cache.begin();
|
||||
}
|
||||
|
||||
std::memcpy(cacheLine->data.data(), data.data(), data.size());
|
||||
}
|
||||
|
||||
if (cacheLine == this->m_cache.end())
|
||||
cacheLine = this->m_cache.begin();
|
||||
if (cacheLine == m_cache.end())
|
||||
cacheLine = m_cache.begin();
|
||||
else
|
||||
++cacheLine;
|
||||
}
|
||||
|
|
@ -271,46 +271,46 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
void GDBProvider::close() {
|
||||
this->m_socket.disconnect();
|
||||
m_socket.disconnect();
|
||||
|
||||
if (this->m_cacheUpdateThread.joinable()) {
|
||||
this->m_cacheUpdateThread.join();
|
||||
if (m_cacheUpdateThread.joinable()) {
|
||||
m_cacheUpdateThread.join();
|
||||
}
|
||||
}
|
||||
|
||||
bool GDBProvider::isConnected() const {
|
||||
return this->m_socket.isConnected();
|
||||
return m_socket.isConnected();
|
||||
}
|
||||
|
||||
|
||||
bool GDBProvider::drawLoadInterface() {
|
||||
ImGui::InputText("hex.builtin.provider.gdb.ip"_lang, this->m_ipAddress);
|
||||
ImGui::InputInt("hex.builtin.provider.gdb.port"_lang, &this->m_port, 0, 0);
|
||||
ImGui::InputText("hex.builtin.provider.gdb.ip"_lang, m_ipAddress);
|
||||
ImGui::InputInt("hex.builtin.provider.gdb.port"_lang, &m_port, 0, 0);
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.common.size"_lang, &this->m_size, ImGuiInputTextFlags_CharsHexadecimal);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.common.size"_lang, &m_size, ImGuiInputTextFlags_CharsHexadecimal);
|
||||
|
||||
if (this->m_port < 0)
|
||||
this->m_port = 0;
|
||||
else if (this->m_port > 0xFFFF)
|
||||
this->m_port = 0xFFFF;
|
||||
if (m_port < 0)
|
||||
m_port = 0;
|
||||
else if (m_port > 0xFFFF)
|
||||
m_port = 0xFFFF;
|
||||
|
||||
return !this->m_ipAddress.empty() && this->m_port != 0;
|
||||
return !m_ipAddress.empty() && m_port != 0;
|
||||
}
|
||||
|
||||
void GDBProvider::loadSettings(const nlohmann::json &settings) {
|
||||
Provider::loadSettings(settings);
|
||||
|
||||
this->m_ipAddress = settings.at("ip").get<std::string>();
|
||||
this->m_port = settings.at("port").get<int>();
|
||||
this->m_size = settings.at("size").get<size_t>();
|
||||
m_ipAddress = settings.at("ip").get<std::string>();
|
||||
m_port = settings.at("port").get<int>();
|
||||
m_size = settings.at("size").get<size_t>();
|
||||
}
|
||||
|
||||
nlohmann::json GDBProvider::storeSettings(nlohmann::json settings) const {
|
||||
settings["ip"] = this->m_ipAddress;
|
||||
settings["port"] = this->m_port;
|
||||
settings["size"] = this->m_size;
|
||||
settings["ip"] = m_ipAddress;
|
||||
settings["port"] = m_port;
|
||||
settings["size"] = m_size;
|
||||
|
||||
return Provider::storeSettings(settings);
|
||||
}
|
||||
|
|
@ -326,9 +326,9 @@ namespace hex::plugin::builtin {
|
|||
|
||||
std::variant<std::string, i128> GDBProvider::queryInformation(const std::string &category, const std::string &argument) {
|
||||
if (category == "ip")
|
||||
return this->m_ipAddress;
|
||||
return m_ipAddress;
|
||||
else if (category == "port")
|
||||
return this->m_port;
|
||||
return m_port;
|
||||
else
|
||||
return Provider::queryInformation(category, argument);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,19 +160,19 @@ namespace hex::plugin::builtin {
|
|||
void IntelHexProvider::setBaseAddress(u64 address) {
|
||||
auto oldBase = this->getBaseAddress();
|
||||
|
||||
auto regions = this->m_data.overlapping({ oldBase, oldBase + this->getActualSize() });
|
||||
auto regions = m_data.overlapping({ oldBase, oldBase + this->getActualSize() });
|
||||
|
||||
decltype(this->m_data) newIntervals;
|
||||
decltype(m_data) newIntervals;
|
||||
for (auto &[interval, data] : regions) {
|
||||
newIntervals.insert({ interval.start - oldBase + address, interval.end - oldBase + address }, *data);
|
||||
}
|
||||
this->m_data = newIntervals;
|
||||
m_data = newIntervals;
|
||||
|
||||
Provider::setBaseAddress(address);
|
||||
}
|
||||
|
||||
void IntelHexProvider::readRaw(u64 offset, void *buffer, size_t size) {
|
||||
auto intervals = this->m_data.overlapping({ offset, (offset + size) - 1 });
|
||||
auto intervals = m_data.overlapping({ offset, (offset + size) - 1 });
|
||||
|
||||
std::memset(buffer, 0x00, size);
|
||||
auto bytes = static_cast<u8*>(buffer);
|
||||
|
|
@ -188,11 +188,11 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
u64 IntelHexProvider::getActualSize() const {
|
||||
return this->m_dataSize;
|
||||
return m_dataSize;
|
||||
}
|
||||
|
||||
bool IntelHexProvider::open() {
|
||||
auto file = wolv::io::File(this->m_sourceFilePath, wolv::io::File::Mode::Read);
|
||||
auto file = wolv::io::File(m_sourceFilePath, wolv::io::File::Mode::Read);
|
||||
if (!file.isValid())
|
||||
return false;
|
||||
|
||||
|
|
@ -203,14 +203,14 @@ namespace hex::plugin::builtin {
|
|||
u64 maxAddress = 0x00;
|
||||
for (auto &[address, bytes] : data) {
|
||||
auto endAddress = (address + bytes.size()) - 1;
|
||||
this->m_data.emplace({ address, endAddress }, std::move(bytes));
|
||||
m_data.emplace({ address, endAddress }, std::move(bytes));
|
||||
|
||||
if (endAddress > maxAddress)
|
||||
maxAddress = endAddress;
|
||||
}
|
||||
|
||||
this->m_dataSize = maxAddress + 1;
|
||||
this->m_dataValid = true;
|
||||
m_dataSize = maxAddress + 1;
|
||||
m_dataValid = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -220,13 +220,13 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
[[nodiscard]] std::string IntelHexProvider::getName() const {
|
||||
return hex::format("hex.builtin.provider.intel_hex.name"_lang, wolv::util::toUTF8String(this->m_sourceFilePath.filename()));
|
||||
return hex::format("hex.builtin.provider.intel_hex.name"_lang, wolv::util::toUTF8String(m_sourceFilePath.filename()));
|
||||
}
|
||||
|
||||
[[nodiscard]] std::vector<IntelHexProvider::Description> IntelHexProvider::getDataDescription() const {
|
||||
std::vector<Description> result;
|
||||
|
||||
result.emplace_back("hex.builtin.provider.file.path"_lang, wolv::util::toUTF8String(this->m_sourceFilePath));
|
||||
result.emplace_back("hex.builtin.provider.file.path"_lang, wolv::util::toUTF8String(m_sourceFilePath));
|
||||
result.emplace_back("hex.builtin.provider.file.size"_lang, hex::toByteString(this->getActualSize()));
|
||||
|
||||
return result;
|
||||
|
|
@ -247,25 +247,25 @@ namespace hex::plugin::builtin {
|
|||
{ "Intel Hex File", "a43" },
|
||||
{ "Intel Hex File", "a90" }
|
||||
}, [this](const std::fs::path &path) {
|
||||
this->m_sourceFilePath = path;
|
||||
m_sourceFilePath = path;
|
||||
}
|
||||
);
|
||||
|
||||
if (!picked)
|
||||
return false;
|
||||
if (!wolv::io::fs::isRegularFile(this->m_sourceFilePath))
|
||||
if (!wolv::io::fs::isRegularFile(m_sourceFilePath))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::pair<Region, bool> IntelHexProvider::getRegionValidity(u64 address) const {
|
||||
auto intervals = this->m_data.overlapping({ address, address });
|
||||
auto intervals = m_data.overlapping({ address, address });
|
||||
if (intervals.empty()) {
|
||||
return Provider::getRegionValidity(address);
|
||||
}
|
||||
|
||||
decltype(this->m_data)::Interval closestInterval = { 0, 0 };
|
||||
decltype(m_data)::Interval closestInterval = { 0, 0 };
|
||||
for (const auto &[interval, data] : intervals) {
|
||||
if (interval.start <= closestInterval.end)
|
||||
closestInterval = interval;
|
||||
|
|
@ -278,11 +278,11 @@ namespace hex::plugin::builtin {
|
|||
Provider::loadSettings(settings);
|
||||
|
||||
auto path = settings.at("path").get<std::string>();
|
||||
this->m_sourceFilePath = std::u8string(path.begin(), path.end());
|
||||
m_sourceFilePath = std::u8string(path.begin(), path.end());
|
||||
}
|
||||
|
||||
nlohmann::json IntelHexProvider::storeSettings(nlohmann::json settings) const {
|
||||
settings["path"] = wolv::util::toUTF8String(this->m_sourceFilePath);
|
||||
settings["path"] = wolv::util::toUTF8String(m_sourceFilePath);
|
||||
|
||||
return Provider::storeSettings(settings);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@
|
|||
namespace hex::plugin::builtin {
|
||||
|
||||
bool MemoryFileProvider::open() {
|
||||
if (this->m_data.empty()) {
|
||||
this->m_data.resize(1);
|
||||
if (m_data.empty()) {
|
||||
m_data.resize(1);
|
||||
this->markDirty();
|
||||
}
|
||||
|
||||
|
|
@ -28,18 +28,18 @@ namespace hex::plugin::builtin {
|
|||
if (actualSize == 0 || (offset + size) > actualSize || buffer == nullptr || size == 0)
|
||||
return;
|
||||
|
||||
std::memcpy(buffer, &this->m_data.front() + offset, size);
|
||||
std::memcpy(buffer, &m_data.front() + offset, size);
|
||||
}
|
||||
|
||||
void MemoryFileProvider::writeRaw(u64 offset, const void *buffer, size_t size) {
|
||||
if ((offset + size) > this->getActualSize() || buffer == nullptr || size == 0)
|
||||
return;
|
||||
|
||||
std::memcpy(&this->m_data.front() + offset, buffer, size);
|
||||
std::memcpy(&m_data.front() + offset, buffer, size);
|
||||
}
|
||||
|
||||
void MemoryFileProvider::save() {
|
||||
if (!this->m_name.empty())
|
||||
if (!m_name.empty())
|
||||
return;
|
||||
|
||||
fs::openFileBrowser(fs::DialogMode::Save, { }, [this](const std::fs::path &path) {
|
||||
|
|
@ -67,7 +67,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
void MemoryFileProvider::resizeRaw(u64 newSize) {
|
||||
this->m_data.resize(newSize);
|
||||
m_data.resize(newSize);
|
||||
}
|
||||
|
||||
void MemoryFileProvider::insertRaw(u64 offset, u64 size) {
|
||||
|
|
@ -108,10 +108,10 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
[[nodiscard]] std::string MemoryFileProvider::getName() const {
|
||||
if (this->m_name.empty())
|
||||
if (m_name.empty())
|
||||
return Lang("hex.builtin.provider.mem_file.unsaved");
|
||||
else
|
||||
return this->m_name;
|
||||
return m_name;
|
||||
}
|
||||
|
||||
std::vector<MemoryFileProvider::MenuEntry> MemoryFileProvider::getMenuEntries() {
|
||||
|
|
@ -132,22 +132,22 @@ namespace hex::plugin::builtin {
|
|||
void MemoryFileProvider::loadSettings(const nlohmann::json &settings) {
|
||||
Provider::loadSettings(settings);
|
||||
|
||||
this->m_data = settings["data"].get<std::vector<u8>>();
|
||||
this->m_name = settings["name"].get<std::string>();
|
||||
this->m_readOnly = settings["readOnly"].get<bool>();
|
||||
m_data = settings["data"].get<std::vector<u8>>();
|
||||
m_name = settings["name"].get<std::string>();
|
||||
m_readOnly = settings["readOnly"].get<bool>();
|
||||
}
|
||||
|
||||
[[nodiscard]] nlohmann::json MemoryFileProvider::storeSettings(nlohmann::json settings) const {
|
||||
settings["data"] = this->m_data;
|
||||
settings["name"] = this->m_name;
|
||||
settings["readOnly"] = this->m_readOnly;
|
||||
settings["data"] = m_data;
|
||||
settings["name"] = m_name;
|
||||
settings["readOnly"] = m_readOnly;
|
||||
|
||||
return Provider::storeSettings(settings);
|
||||
}
|
||||
|
||||
void MemoryFileProvider::renameFile() {
|
||||
PopupTextInput::open("hex.builtin.provider.mem_file.rename", "hex.builtin.provider.mem_file.rename.desc", [this](const std::string &name) {
|
||||
this->m_name = name;
|
||||
m_name = name;
|
||||
RequestUpdateWindowTitle::post();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
bool MotorolaSRECProvider::open() {
|
||||
auto file = wolv::io::File(this->m_sourceFilePath, wolv::io::File::Mode::Read);
|
||||
auto file = wolv::io::File(m_sourceFilePath, wolv::io::File::Mode::Read);
|
||||
if (!file.isValid())
|
||||
return false;
|
||||
|
||||
|
|
@ -182,14 +182,14 @@ namespace hex::plugin::builtin {
|
|||
u64 maxAddress = 0x00;
|
||||
for (auto &[address, bytes] : data) {
|
||||
auto endAddress = (address + bytes.size()) - 1;
|
||||
this->m_data.emplace({ address, endAddress }, std::move(bytes));
|
||||
m_data.emplace({ address, endAddress }, std::move(bytes));
|
||||
|
||||
if (endAddress > maxAddress)
|
||||
maxAddress = endAddress;
|
||||
}
|
||||
|
||||
this->m_dataSize = maxAddress + 1;
|
||||
this->m_dataValid = true;
|
||||
m_dataSize = maxAddress + 1;
|
||||
m_dataValid = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -199,14 +199,14 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
[[nodiscard]] std::string MotorolaSRECProvider::getName() const {
|
||||
return hex::format("hex.builtin.provider.motorola_srec.name"_lang, wolv::util::toUTF8String(this->m_sourceFilePath.filename()));
|
||||
return hex::format("hex.builtin.provider.motorola_srec.name"_lang, wolv::util::toUTF8String(m_sourceFilePath.filename()));
|
||||
}
|
||||
|
||||
|
||||
[[nodiscard]] std::vector<MotorolaSRECProvider::Description> MotorolaSRECProvider::getDataDescription() const {
|
||||
std::vector<Description> result;
|
||||
|
||||
result.emplace_back("hex.builtin.provider.file.path"_lang, wolv::util::toUTF8String(this->m_sourceFilePath));
|
||||
result.emplace_back("hex.builtin.provider.file.path"_lang, wolv::util::toUTF8String(m_sourceFilePath));
|
||||
result.emplace_back("hex.builtin.provider.file.size"_lang, hex::toByteString(this->getActualSize()));
|
||||
|
||||
return result;
|
||||
|
|
@ -228,13 +228,13 @@ namespace hex::plugin::builtin {
|
|||
{ "Motorola SREC File", "mxt" }
|
||||
},
|
||||
[this](const std::fs::path &path) {
|
||||
this->m_sourceFilePath = path;
|
||||
m_sourceFilePath = path;
|
||||
}
|
||||
);
|
||||
|
||||
if (!picked)
|
||||
return false;
|
||||
if (!wolv::io::fs::isRegularFile(this->m_sourceFilePath))
|
||||
if (!wolv::io::fs::isRegularFile(m_sourceFilePath))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -24,11 +24,11 @@ namespace hex::plugin::builtin {
|
|||
|
||||
bool ProcessMemoryProvider::open() {
|
||||
#if defined(OS_WINDOWS)
|
||||
this->m_processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, this->m_selectedProcess->id);
|
||||
if (this->m_processHandle == nullptr)
|
||||
m_processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_selectedProcess->id);
|
||||
if (m_processHandle == nullptr)
|
||||
return false;
|
||||
#elif defined(OS_LINUX)
|
||||
this->m_processId = pid_t(this->m_selectedProcess->id);
|
||||
m_processId = pid_t(m_selectedProcess->id);
|
||||
#endif
|
||||
|
||||
this->reloadProcessModules();
|
||||
|
|
@ -38,16 +38,16 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void ProcessMemoryProvider::close() {
|
||||
#if defined(OS_WINDOWS)
|
||||
CloseHandle(this->m_processHandle);
|
||||
this->m_processHandle = nullptr;
|
||||
CloseHandle(m_processHandle);
|
||||
m_processHandle = nullptr;
|
||||
#elif defined(OS_LINUX)
|
||||
this->m_processId = -1;
|
||||
m_processId = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ProcessMemoryProvider::readRaw(u64 address, void *buffer, size_t size) {
|
||||
#if defined(OS_WINDOWS)
|
||||
ReadProcessMemory(this->m_processHandle, reinterpret_cast<LPCVOID>(address), buffer, size, nullptr);
|
||||
ReadProcessMemory(m_processHandle, reinterpret_cast<LPCVOID>(address), buffer, size, nullptr);
|
||||
#elif defined(OS_LINUX)
|
||||
const iovec local {
|
||||
.iov_base = buffer,
|
||||
|
|
@ -58,7 +58,7 @@ namespace hex::plugin::builtin {
|
|||
.iov_len = size,
|
||||
};
|
||||
|
||||
auto read = process_vm_readv(this->m_processId, &local, 1, &remote, 1, 0);
|
||||
auto read = process_vm_readv(m_processId, &local, 1, &remote, 1, 0);
|
||||
|
||||
if (read == -1) {
|
||||
// TODO error handling strerror(errno)
|
||||
|
|
@ -67,7 +67,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
void ProcessMemoryProvider::writeRaw(u64 address, const void *buffer, size_t size) {
|
||||
#if defined(OS_WINDOWS)
|
||||
WriteProcessMemory(this->m_processHandle, reinterpret_cast<LPVOID>(address), buffer, size, nullptr);
|
||||
WriteProcessMemory(m_processHandle, reinterpret_cast<LPVOID>(address), buffer, size, nullptr);
|
||||
#elif defined(OS_LINUX)
|
||||
const iovec local {
|
||||
.iov_base = const_cast<void*>(buffer),
|
||||
|
|
@ -78,7 +78,7 @@ namespace hex::plugin::builtin {
|
|||
.iov_len = size,
|
||||
};
|
||||
|
||||
auto read = process_vm_writev(this->m_processId, &local, 1, &remote, 1, 0);
|
||||
auto read = process_vm_writev(m_processId, &local, 1, &remote, 1, 0);
|
||||
if (read == -1) {
|
||||
// TODO error handling strerror(errno)
|
||||
}
|
||||
|
|
@ -86,13 +86,13 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
std::pair<Region, bool> ProcessMemoryProvider::getRegionValidity(u64 address) const {
|
||||
for (const auto &memoryRegion : this->m_memoryRegions) {
|
||||
for (const auto &memoryRegion : m_memoryRegions) {
|
||||
if (memoryRegion.region.overlaps({ address, 1 }))
|
||||
return { memoryRegion.region, true };
|
||||
}
|
||||
|
||||
Region lastRegion = Region::Invalid();
|
||||
for (const auto &memoryRegion : this->m_memoryRegions) {
|
||||
for (const auto &memoryRegion : m_memoryRegions) {
|
||||
|
||||
if (address < memoryRegion.region.getStartAddress())
|
||||
return { Region { lastRegion.getEndAddress() + 1, memoryRegion.region.getStartAddress() - lastRegion.getEndAddress() }, false };
|
||||
|
|
@ -104,7 +104,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
bool ProcessMemoryProvider::drawLoadInterface() {
|
||||
if (this->m_processes.empty() && !this->m_enumerationFailed) {
|
||||
if (m_processes.empty() && !m_enumerationFailed) {
|
||||
#if defined(OS_WINDOWS)
|
||||
DWORD numProcesses = 0;
|
||||
std::vector<DWORD> processIds;
|
||||
|
|
@ -113,7 +113,7 @@ namespace hex::plugin::builtin {
|
|||
processIds.resize(processIds.size() + 1024);
|
||||
if (EnumProcesses(processIds.data(), processIds.size() * sizeof(DWORD), &numProcesses) == FALSE) {
|
||||
processIds.clear();
|
||||
this->m_enumerationFailed = true;
|
||||
m_enumerationFailed = true;
|
||||
break;
|
||||
}
|
||||
} while (numProcesses == processIds.size() * sizeof(DWORD));
|
||||
|
|
@ -172,7 +172,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
}
|
||||
|
||||
this->m_processes.push_back({ u32(processId), processName, std::move(texture) });
|
||||
m_processes.push_back({ u32(processId), processName, std::move(texture) });
|
||||
}
|
||||
#elif defined(OS_LINUX)
|
||||
for (const auto& entry : std::fs::directory_iterator("/proc")) {
|
||||
|
|
@ -192,16 +192,16 @@ namespace hex::plugin::builtin {
|
|||
|
||||
std::string processName = file.readString(0xF'FFFF);
|
||||
|
||||
this->m_processes.emplace_back(processId, processName, ImGuiExt::Texture());
|
||||
m_processes.emplace_back(processId, processName, ImGuiExt::Texture());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (this->m_enumerationFailed) {
|
||||
if (m_enumerationFailed) {
|
||||
ImGui::TextUnformatted("hex.builtin.provider.process_memory.enumeration_failed"_lang);
|
||||
} else {
|
||||
ImGui::PushItemWidth(500_scaled);
|
||||
const auto &filtered = this->m_processSearchWidget.draw(this->m_processes);
|
||||
const auto &filtered = m_processSearchWidget.draw(m_processes);
|
||||
ImGui::PopItemWidth();
|
||||
if (ImGui::BeginTable("##process_table", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollY, ImVec2(500_scaled, 500_scaled))) {
|
||||
ImGui::TableSetupColumn("##icon");
|
||||
|
|
@ -222,8 +222,8 @@ namespace hex::plugin::builtin {
|
|||
ImGui::Text("%d", process->id);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Selectable(process->name.c_str(), this->m_selectedProcess != nullptr && process->id == this->m_selectedProcess->id, ImGuiSelectableFlags_SpanAllColumns, ImVec2(0, process->icon.getSize().y)))
|
||||
this->m_selectedProcess = process;
|
||||
if (ImGui::Selectable(process->name.c_str(), m_selectedProcess != nullptr && process->id == m_selectedProcess->id, ImGuiSelectableFlags_SpanAllColumns, ImVec2(0, process->icon.getSize().y)))
|
||||
m_selectedProcess = process;
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
|
@ -233,7 +233,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
}
|
||||
|
||||
return this->m_selectedProcess != nullptr;
|
||||
return m_selectedProcess != nullptr;
|
||||
}
|
||||
|
||||
void ProcessMemoryProvider::drawInterface() {
|
||||
|
|
@ -241,7 +241,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
auto availableX = ImGui::GetContentRegionAvail().x;
|
||||
ImGui::PushItemWidth(availableX);
|
||||
const auto &filtered = this->m_regionSearchWidget.draw(this->m_memoryRegions);
|
||||
const auto &filtered = m_regionSearchWidget.draw(m_memoryRegions);
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
|
|
@ -288,11 +288,11 @@ namespace hex::plugin::builtin {
|
|||
const auto &dllPath = path.native();
|
||||
const auto dllPathLength = (dllPath.length() + 1) * sizeof(std::fs::path::value_type);
|
||||
|
||||
if (auto pathAddress = VirtualAllocEx(this->m_processHandle, nullptr, dllPathLength, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); pathAddress != nullptr) {
|
||||
if (WriteProcessMemory(this->m_processHandle, pathAddress, dllPath.c_str(), dllPathLength, nullptr) != FALSE) {
|
||||
if (auto pathAddress = VirtualAllocEx(m_processHandle, nullptr, dllPathLength, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); pathAddress != nullptr) {
|
||||
if (WriteProcessMemory(m_processHandle, pathAddress, dllPath.c_str(), dllPathLength, nullptr) != FALSE) {
|
||||
auto loadLibraryW = reinterpret_cast<LPTHREAD_START_ROUTINE>(reinterpret_cast<void*>(GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryW")));
|
||||
if (loadLibraryW != nullptr) {
|
||||
if (auto threadHandle = CreateRemoteThread(this->m_processHandle, nullptr, 0, loadLibraryW, pathAddress, 0, nullptr); threadHandle != nullptr) {
|
||||
if (auto threadHandle = CreateRemoteThread(m_processHandle, nullptr, 0, loadLibraryW, pathAddress, 0, nullptr); threadHandle != nullptr) {
|
||||
WaitForSingleObject(threadHandle, INFINITE);
|
||||
RequestOpenErrorPopup::post(hex::format("hex.builtin.provider.process_memory.utils.inject_dll.success"_lang, path.filename().string()));
|
||||
this->reloadProcessModules();
|
||||
|
|
@ -310,7 +310,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
void ProcessMemoryProvider::reloadProcessModules() {
|
||||
this->m_memoryRegions.clear();
|
||||
m_memoryRegions.clear();
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
DWORD numModules = 0;
|
||||
|
|
@ -318,7 +318,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
do {
|
||||
modules.resize(modules.size() + 1024);
|
||||
if (EnumProcessModules(this->m_processHandle, modules.data(), modules.size() * sizeof(HMODULE), &numModules) == FALSE) {
|
||||
if (EnumProcessModules(m_processHandle, modules.data(), modules.size() * sizeof(HMODULE), &numModules) == FALSE) {
|
||||
modules.clear();
|
||||
break;
|
||||
}
|
||||
|
|
@ -328,19 +328,19 @@ namespace hex::plugin::builtin {
|
|||
|
||||
for (auto &module : modules) {
|
||||
MODULEINFO moduleInfo;
|
||||
if (GetModuleInformation(this->m_processHandle, module, &moduleInfo, sizeof(MODULEINFO)) == FALSE)
|
||||
if (GetModuleInformation(m_processHandle, module, &moduleInfo, sizeof(MODULEINFO)) == FALSE)
|
||||
continue;
|
||||
|
||||
char moduleName[MAX_PATH];
|
||||
if (GetModuleFileNameExA(this->m_processHandle, module, moduleName, MAX_PATH) == FALSE)
|
||||
if (GetModuleFileNameExA(m_processHandle, module, moduleName, MAX_PATH) == FALSE)
|
||||
continue;
|
||||
|
||||
this->m_memoryRegions.insert({ { u64(moduleInfo.lpBaseOfDll), size_t(moduleInfo.SizeOfImage) }, std::fs::path(moduleName).filename().string() });
|
||||
m_memoryRegions.insert({ { u64(moduleInfo.lpBaseOfDll), size_t(moduleInfo.SizeOfImage) }, std::fs::path(moduleName).filename().string() });
|
||||
}
|
||||
|
||||
MEMORY_BASIC_INFORMATION memoryInfo;
|
||||
for (u64 address = 0; address < this->getActualSize(); address += memoryInfo.RegionSize) {
|
||||
if (VirtualQueryEx(this->m_processHandle, reinterpret_cast<LPCVOID>(address), &memoryInfo, sizeof(MEMORY_BASIC_INFORMATION)) == 0)
|
||||
if (VirtualQueryEx(m_processHandle, reinterpret_cast<LPCVOID>(address), &memoryInfo, sizeof(MEMORY_BASIC_INFORMATION)) == 0)
|
||||
break;
|
||||
|
||||
std::string name;
|
||||
|
|
@ -351,12 +351,12 @@ namespace hex::plugin::builtin {
|
|||
if (memoryInfo.State & MEM_PRIVATE) name += hex::format("{} ", "hex.builtin.provider.process_memory.region.private"_lang);
|
||||
if (memoryInfo.State & MEM_MAPPED) name += hex::format("{} ", "hex.builtin.provider.process_memory.region.mapped"_lang);
|
||||
|
||||
this->m_memoryRegions.insert({ { reinterpret_cast<u64>(memoryInfo.BaseAddress), reinterpret_cast<u64>(memoryInfo.BaseAddress) + memoryInfo.RegionSize }, name });
|
||||
m_memoryRegions.insert({ { reinterpret_cast<u64>(memoryInfo.BaseAddress), reinterpret_cast<u64>(memoryInfo.BaseAddress) + memoryInfo.RegionSize }, name });
|
||||
}
|
||||
|
||||
#elif defined(OS_LINUX)
|
||||
|
||||
wolv::io::File file(std::fs::path("/proc") / std::to_string(this->m_processId) / "maps", wolv::io::File::Mode::Read);
|
||||
wolv::io::File file(std::fs::path("/proc") / std::to_string(m_processId) / "maps", wolv::io::File::Mode::Read);
|
||||
|
||||
if (!file.isValid())
|
||||
return;
|
||||
|
|
@ -370,7 +370,7 @@ namespace hex::plugin::builtin {
|
|||
const u64 end = std::stoull(split[0].substr(split[0].find('-') + 1), nullptr, 16);
|
||||
const auto &name = split[5];
|
||||
|
||||
this->m_memoryRegions.insert({ { start, end - start }, name });
|
||||
m_memoryRegions.insert({ { start, end - start }, name });
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -378,26 +378,26 @@ namespace hex::plugin::builtin {
|
|||
|
||||
std::variant<std::string, i128> ProcessMemoryProvider::queryInformation(const std::string &category, const std::string &argument) {
|
||||
auto findRegionByName = [this](const std::string &name) {
|
||||
return std::find_if(this->m_memoryRegions.begin(), this->m_memoryRegions.end(),
|
||||
return std::find_if(m_memoryRegions.begin(), m_memoryRegions.end(),
|
||||
[name](const auto ®ion) {
|
||||
return region.name == name;
|
||||
});
|
||||
};
|
||||
|
||||
if (category == "region_address") {
|
||||
if (auto iter = findRegionByName(argument); iter != this->m_memoryRegions.end())
|
||||
if (auto iter = findRegionByName(argument); iter != m_memoryRegions.end())
|
||||
return iter->region.getStartAddress();
|
||||
else
|
||||
return 0;
|
||||
} else if (category == "region_size") {
|
||||
if (auto iter = findRegionByName(argument); iter != this->m_memoryRegions.end())
|
||||
if (auto iter = findRegionByName(argument); iter != m_memoryRegions.end())
|
||||
return iter->region.getSize();
|
||||
else
|
||||
return 0;
|
||||
} else if (category == "process_id") {
|
||||
return this->m_selectedProcess->id;
|
||||
return m_selectedProcess->id;
|
||||
} else if (category == "process_name") {
|
||||
return this->m_selectedProcess->name;
|
||||
return m_selectedProcess->name;
|
||||
} else
|
||||
return Provider::queryInformation(category, argument);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ namespace hex::plugin::builtin::recent {
|
|||
if (entry.is_regular_file() && entry.path().extension() == ".hexproj") {
|
||||
wolv::io::File backupFile(entry.path(), wolv::io::File::Mode::Read);
|
||||
|
||||
this->m_backups.emplace_back(
|
||||
m_backups.emplace_back(
|
||||
hex::format("hex.builtin.welcome.start.recent.auto_backups.backup"_lang, fmt::gmtime(backupFile.getFileInfo()->st_ctime)),
|
||||
entry.path()
|
||||
);
|
||||
|
|
@ -54,7 +54,7 @@ namespace hex::plugin::builtin::recent {
|
|||
|
||||
void drawContent() override {
|
||||
if (ImGui::BeginTable("AutoBackups", 1, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersInnerV, ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * 5))) {
|
||||
for (const auto &backup : this->m_backups | std::views::reverse | std::views::take(10)) {
|
||||
for (const auto &backup : m_backups | std::views::reverse | std::views::take(10)) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Selectable(backup.displayName.c_str())) {
|
||||
|
|
|
|||
|
|
@ -31,10 +31,10 @@ namespace hex::plugin::builtin {
|
|||
class ServerContactWidget : public ContentRegistry::Settings::Widgets::Widget {
|
||||
public:
|
||||
bool draw(const std::string &name) override {
|
||||
bool enabled = this->m_value == 1;
|
||||
bool enabled = m_value == 1;
|
||||
|
||||
if (ImGui::Checkbox(name.data(), &enabled)) {
|
||||
this->m_value = enabled ? 1 : 0;
|
||||
m_value = enabled ? 1 : 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -43,11 +43,11 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void load(const nlohmann::json &data) override {
|
||||
if (data.is_number())
|
||||
this->m_value = data.get<int>();
|
||||
m_value = data.get<int>();
|
||||
}
|
||||
|
||||
nlohmann::json store() override {
|
||||
return this->m_value;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -58,15 +58,15 @@ namespace hex::plugin::builtin {
|
|||
public:
|
||||
bool draw(const std::string &name) override {
|
||||
auto format = [this] -> std::string {
|
||||
if (this->m_value > 200)
|
||||
if (m_value > 200)
|
||||
return "hex.builtin.setting.interface.fps.unlocked"_lang;
|
||||
else if (this->m_value < 15)
|
||||
else if (m_value < 15)
|
||||
return "hex.builtin.setting.interface.fps.native"_lang;
|
||||
else
|
||||
return "%d FPS";
|
||||
}();
|
||||
|
||||
if (ImGui::SliderInt(name.data(), &this->m_value, 14, 201, format.c_str(), ImGuiSliderFlags_AlwaysClamp)) {
|
||||
if (ImGui::SliderInt(name.data(), &m_value, 14, 201, format.c_str(), ImGuiSliderFlags_AlwaysClamp)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -75,11 +75,11 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void load(const nlohmann::json &data) override {
|
||||
if (data.is_number())
|
||||
this->m_value = data.get<int>();
|
||||
m_value = data.get<int>();
|
||||
}
|
||||
|
||||
nlohmann::json store() override {
|
||||
return this->m_value;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -94,10 +94,10 @@ namespace hex::plugin::builtin {
|
|||
if (!ImGui::BeginListBox("", ImVec2(-40_scaled, 280_scaled))) {
|
||||
return false;
|
||||
} else {
|
||||
for (size_t n = 0; n < this->m_paths.size(); n++) {
|
||||
const bool isSelected = (this->m_itemIndex == n);
|
||||
if (ImGui::Selectable(wolv::util::toUTF8String(this->m_paths[n]).c_str(), isSelected)) {
|
||||
this->m_itemIndex = n;
|
||||
for (size_t n = 0; n < m_paths.size(); n++) {
|
||||
const bool isSelected = (m_itemIndex == n);
|
||||
if (ImGui::Selectable(wolv::util::toUTF8String(m_paths[n]).c_str(), isSelected)) {
|
||||
m_itemIndex = n;
|
||||
}
|
||||
|
||||
if (isSelected) {
|
||||
|
|
@ -111,9 +111,9 @@ namespace hex::plugin::builtin {
|
|||
|
||||
if (ImGuiExt::IconButton(ICON_VS_NEW_FOLDER, ImGui::GetStyleColorVec4(ImGuiCol_Text), ImVec2(30, 30))) {
|
||||
fs::openFileBrowser(fs::DialogMode::Folder, {}, [&](const std::fs::path &path) {
|
||||
if (std::find(this->m_paths.begin(), this->m_paths.end(), path) == this->m_paths.end()) {
|
||||
this->m_paths.emplace_back(path);
|
||||
ImHexApi::System::setAdditionalFolderPaths(this->m_paths);
|
||||
if (std::find(m_paths.begin(), m_paths.end(), path) == m_paths.end()) {
|
||||
m_paths.emplace_back(path);
|
||||
ImHexApi::System::setAdditionalFolderPaths(m_paths);
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
|
@ -122,9 +122,9 @@ namespace hex::plugin::builtin {
|
|||
ImGuiExt::InfoTooltip("hex.builtin.setting.folders.add_folder"_lang);
|
||||
|
||||
if (ImGuiExt::IconButton(ICON_VS_REMOVE_CLOSE, ImGui::GetStyleColorVec4(ImGuiCol_Text), ImVec2(30, 30))) {
|
||||
if (!this->m_paths.empty()) {
|
||||
this->m_paths.erase(std::next(this->m_paths.begin(), this->m_itemIndex));
|
||||
ImHexApi::System::setAdditionalFolderPaths(this->m_paths);
|
||||
if (!m_paths.empty()) {
|
||||
m_paths.erase(std::next(m_paths.begin(), m_itemIndex));
|
||||
ImHexApi::System::setAdditionalFolderPaths(m_paths);
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ namespace hex::plugin::builtin {
|
|||
std::vector<std::string> pathStrings = data;
|
||||
|
||||
for (const auto &pathString : pathStrings) {
|
||||
this->m_paths.emplace_back(pathString);
|
||||
m_paths.emplace_back(pathString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -149,7 +149,7 @@ namespace hex::plugin::builtin {
|
|||
nlohmann::json store() override {
|
||||
std::vector<std::string> pathStrings;
|
||||
|
||||
for (const auto &path : this->m_paths) {
|
||||
for (const auto &path : m_paths) {
|
||||
pathStrings.push_back(wolv::util::toUTF8String(path));
|
||||
}
|
||||
|
||||
|
|
@ -165,13 +165,13 @@ namespace hex::plugin::builtin {
|
|||
public:
|
||||
bool draw(const std::string &name) override {
|
||||
auto format = [this] -> std::string {
|
||||
if (this->m_value == 0)
|
||||
if (m_value == 0)
|
||||
return "hex.builtin.setting.interface.scaling.native"_lang;
|
||||
else
|
||||
return "x%.1f";
|
||||
}();
|
||||
|
||||
if (ImGui::SliderFloat(name.data(), &this->m_value, 0, 10, format.c_str(), ImGuiSliderFlags_AlwaysClamp)) {
|
||||
if (ImGui::SliderFloat(name.data(), &m_value, 0, 10, format.c_str(), ImGuiSliderFlags_AlwaysClamp)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -180,11 +180,11 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void load(const nlohmann::json &data) override {
|
||||
if (data.is_number())
|
||||
this->m_value = data.get<float>();
|
||||
m_value = data.get<float>();
|
||||
}
|
||||
|
||||
nlohmann::json store() override {
|
||||
return this->m_value;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -195,7 +195,7 @@ namespace hex::plugin::builtin {
|
|||
public:
|
||||
bool draw(const std::string &name) override {
|
||||
auto format = [this] -> std::string {
|
||||
auto value = this->m_value * 30;
|
||||
auto value = m_value * 30;
|
||||
if (value == 0)
|
||||
return "hex.builtin.common.off"_lang;
|
||||
else if (value < 60)
|
||||
|
|
@ -204,7 +204,7 @@ namespace hex::plugin::builtin {
|
|||
return hex::format("hex.builtin.setting.general.auto_backup_time.format.extended"_lang, value / 60, value % 60);
|
||||
}();
|
||||
|
||||
if (ImGui::SliderInt(name.data(), &this->m_value, 0, (30 * 60) / 30, format.c_str(), ImGuiSliderFlags_AlwaysClamp | ImGuiSliderFlags_NoInput)) {
|
||||
if (ImGui::SliderInt(name.data(), &m_value, 0, (30 * 60) / 30, format.c_str(), ImGuiSliderFlags_AlwaysClamp | ImGuiSliderFlags_NoInput)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -213,11 +213,11 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void load(const nlohmann::json &data) override {
|
||||
if (data.is_number())
|
||||
this->m_value = data.get<int>();
|
||||
m_value = data.get<int>();
|
||||
}
|
||||
|
||||
nlohmann::json store() override {
|
||||
return this->m_value;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -231,8 +231,8 @@ namespace hex::plugin::builtin {
|
|||
bool draw(const std::string &name) override {
|
||||
std::string label;
|
||||
|
||||
if (!this->m_editing)
|
||||
label = this->m_drawShortcut.toString();
|
||||
if (!m_editing)
|
||||
label = m_drawShortcut.toString();
|
||||
else
|
||||
label = "...";
|
||||
|
||||
|
|
@ -240,14 +240,14 @@ namespace hex::plugin::builtin {
|
|||
label = "???";
|
||||
|
||||
|
||||
if (this->m_hasDuplicate)
|
||||
if (m_hasDuplicate)
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_LoggerError));
|
||||
|
||||
ImGui::PushID(this);
|
||||
if (ImGui::Button(label.c_str(), ImVec2(250_scaled, 0))) {
|
||||
this->m_editing = !this->m_editing;
|
||||
m_editing = !m_editing;
|
||||
|
||||
if (this->m_editing)
|
||||
if (m_editing)
|
||||
ShortcutManager::pauseShortcuts();
|
||||
else
|
||||
ShortcutManager::resumeShortcuts();
|
||||
|
|
@ -255,18 +255,18 @@ namespace hex::plugin::builtin {
|
|||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (this->m_hasDuplicate)
|
||||
if (m_hasDuplicate)
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
bool settingChanged = false;
|
||||
|
||||
ImGui::BeginDisabled(this->m_drawShortcut == this->m_defaultShortcut);
|
||||
ImGui::BeginDisabled(m_drawShortcut == m_defaultShortcut);
|
||||
if (ImGuiExt::IconButton(ICON_VS_X, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
|
||||
this->m_hasDuplicate = !ShortcutManager::updateShortcut(this->m_shortcut, this->m_defaultShortcut, this->m_view);
|
||||
m_hasDuplicate = !ShortcutManager::updateShortcut(m_shortcut, m_defaultShortcut, m_view);
|
||||
|
||||
this->m_drawShortcut = this->m_defaultShortcut;
|
||||
if (!this->m_hasDuplicate) {
|
||||
this->m_shortcut = this->m_defaultShortcut;
|
||||
m_drawShortcut = m_defaultShortcut;
|
||||
if (!m_hasDuplicate) {
|
||||
m_shortcut = m_defaultShortcut;
|
||||
settingChanged = true;
|
||||
}
|
||||
|
||||
|
|
@ -274,7 +274,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::EndDisabled();
|
||||
|
||||
if (!ImGui::IsItemHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
|
||||
this->m_editing = false;
|
||||
m_editing = false;
|
||||
ShortcutManager::resumeShortcuts();
|
||||
}
|
||||
|
||||
|
|
@ -284,13 +284,13 @@ namespace hex::plugin::builtin {
|
|||
|
||||
ImGui::PopID();
|
||||
|
||||
if (this->m_editing) {
|
||||
if (m_editing) {
|
||||
if (this->detectShortcut()) {
|
||||
this->m_editing = false;
|
||||
m_editing = false;
|
||||
ShortcutManager::resumeShortcuts();
|
||||
|
||||
settingChanged = true;
|
||||
if (!this->m_hasDuplicate) {
|
||||
if (!m_hasDuplicate) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -308,15 +308,15 @@ namespace hex::plugin::builtin {
|
|||
return;
|
||||
|
||||
auto newShortcut = Shortcut(keys);
|
||||
this->m_hasDuplicate = !ShortcutManager::updateShortcut(this->m_shortcut, newShortcut, this->m_view);
|
||||
this->m_shortcut = std::move(newShortcut);
|
||||
this->m_drawShortcut = this->m_shortcut;
|
||||
m_hasDuplicate = !ShortcutManager::updateShortcut(m_shortcut, newShortcut, m_view);
|
||||
m_shortcut = std::move(newShortcut);
|
||||
m_drawShortcut = m_shortcut;
|
||||
}
|
||||
|
||||
nlohmann::json store() override {
|
||||
std::vector<u32> keys;
|
||||
|
||||
for (const auto &key : this->m_shortcut.getKeys()) {
|
||||
for (const auto &key : m_shortcut.getKeys()) {
|
||||
if (key != CurrentView)
|
||||
keys.push_back(key.getKeyCode());
|
||||
}
|
||||
|
|
@ -327,7 +327,7 @@ namespace hex::plugin::builtin {
|
|||
private:
|
||||
bool detectShortcut() {
|
||||
if (const auto &shortcut = ShortcutManager::getPreviousShortcut(); shortcut.has_value()) {
|
||||
auto keys = this->m_shortcut.getKeys();
|
||||
auto keys = m_shortcut.getKeys();
|
||||
std::erase_if(keys, [](Key key) {
|
||||
return key != AllowWhileTyping && key != CurrentView;
|
||||
});
|
||||
|
|
@ -337,11 +337,11 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
auto newShortcut = Shortcut(std::move(keys));
|
||||
this->m_hasDuplicate = !ShortcutManager::updateShortcut(this->m_shortcut, newShortcut, this->m_view);
|
||||
this->m_drawShortcut = std::move(newShortcut);
|
||||
m_hasDuplicate = !ShortcutManager::updateShortcut(m_shortcut, newShortcut, m_view);
|
||||
m_drawShortcut = std::move(newShortcut);
|
||||
|
||||
if (!this->m_hasDuplicate) {
|
||||
this->m_shortcut = this->m_drawShortcut;
|
||||
if (!m_hasDuplicate) {
|
||||
m_shortcut = m_drawShortcut;
|
||||
log::info("Changed shortcut to {}", shortcut->toString());
|
||||
} else {
|
||||
log::warn("Changing shortcut failed as it overlapped with another one", shortcut->toString());
|
||||
|
|
|
|||
|
|
@ -100,18 +100,18 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TableNextColumn();
|
||||
|
||||
// Draw the ImHex icon
|
||||
if (!this->m_logoTexture.isValid())
|
||||
this->m_logoTexture = ImGuiExt::Texture(romfs::get("assets/common/logo.png").span(), ImGuiExt::Texture::Filter::Linear);
|
||||
if (!m_logoTexture.isValid())
|
||||
m_logoTexture = ImGuiExt::Texture(romfs::get("assets/common/logo.png").span(), ImGuiExt::Texture::Filter::Linear);
|
||||
|
||||
ImGui::Image(this->m_logoTexture, scaled({ 100, 100 }));
|
||||
ImGui::Image(m_logoTexture, scaled({ 100, 100 }));
|
||||
if (ImGui::IsItemClicked()) {
|
||||
this->m_clickCount += 1;
|
||||
m_clickCount += 1;
|
||||
}
|
||||
|
||||
if (this->m_clickCount >= (2 * 3 + 4)) {
|
||||
if (m_clickCount >= (2 * 3 + 4)) {
|
||||
this->getWindowOpenState() = false;
|
||||
PopupEE::open();
|
||||
this->m_clickCount = 0;
|
||||
m_clickCount = 0;
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
|
@ -451,13 +451,13 @@ namespace hex::plugin::builtin {
|
|||
AT_FIRST_TIME {
|
||||
static HttpRequest request("GET", GitHubApiURL + std::string("/releases/tags/v") + ImHexApi::System::getImHexVersion(false));
|
||||
|
||||
this->m_releaseNoteRequest = request.execute();
|
||||
m_releaseNoteRequest = request.execute();
|
||||
};
|
||||
|
||||
// Wait for the request to finish and parse the response
|
||||
if (this->m_releaseNoteRequest.valid()) {
|
||||
if (this->m_releaseNoteRequest.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
|
||||
auto response = this->m_releaseNoteRequest.get();
|
||||
if (m_releaseNoteRequest.valid()) {
|
||||
if (m_releaseNoteRequest.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
|
||||
auto response = m_releaseNoteRequest.get();
|
||||
nlohmann::json json;
|
||||
|
||||
if (response.isSuccess()) {
|
||||
|
|
@ -553,13 +553,13 @@ namespace hex::plugin::builtin {
|
|||
// Set up the request to get the commit history the first time the page is opened
|
||||
AT_FIRST_TIME {
|
||||
static HttpRequest request("GET", GitHubApiURL + std::string("/commits?per_page=100"));
|
||||
this->m_commitHistoryRequest = request.execute();
|
||||
m_commitHistoryRequest = request.execute();
|
||||
};
|
||||
|
||||
// Wait for the request to finish and parse the response
|
||||
if (this->m_commitHistoryRequest.valid()) {
|
||||
if (this->m_commitHistoryRequest.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
|
||||
auto response = this->m_commitHistoryRequest.get();
|
||||
if (m_commitHistoryRequest.valid()) {
|
||||
if (m_commitHistoryRequest.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
|
||||
auto response = m_commitHistoryRequest.get();
|
||||
nlohmann::json json;
|
||||
|
||||
if (response.isSuccess()) {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
// Add newly unlocked achievements to the display queue
|
||||
EventAchievementUnlocked::subscribe(this, [this](const Achievement &achievement) {
|
||||
this->m_achievementUnlockQueue.push_back(&achievement);
|
||||
m_achievementUnlockQueue.push_back(&achievement);
|
||||
});
|
||||
|
||||
RequestOpenWindow::subscribe(this, [this](const std::string &name) {
|
||||
|
|
@ -29,7 +29,7 @@ namespace hex::plugin::builtin {
|
|||
});
|
||||
|
||||
// Load settings
|
||||
this->m_showPopup = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.achievement_popup", true);
|
||||
m_showPopup = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.achievement_popup", true);
|
||||
}
|
||||
|
||||
ViewAchievements::~ViewAchievements() {
|
||||
|
|
@ -273,9 +273,9 @@ namespace hex::plugin::builtin {
|
|||
drawList->AddBezierQuadratic(start, middle, end, color, 2_scaled);
|
||||
|
||||
// Handle jumping to an achievement
|
||||
if (this->m_achievementToGoto != nullptr) {
|
||||
if (this->m_achievementToGoto == node->achievement) {
|
||||
this->m_offset = position - scaled({ 100, 100 });
|
||||
if (m_achievementToGoto != nullptr) {
|
||||
if (m_achievementToGoto == node->achievement) {
|
||||
m_offset = position - scaled({ 100, 100 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -331,8 +331,8 @@ namespace hex::plugin::builtin {
|
|||
ImGuiTabItemFlags flags = ImGuiTabItemFlags_None;
|
||||
|
||||
// Handle jumping to the category of an achievement
|
||||
if (this->m_achievementToGoto != nullptr) {
|
||||
if (this->m_achievementToGoto->getUnlocalizedCategory() == categoryName) {
|
||||
if (m_achievementToGoto != nullptr) {
|
||||
if (m_achievementToGoto->getUnlocalizedCategory() == categoryName) {
|
||||
flags |= ImGuiTabItemFlags_SetSelected;
|
||||
}
|
||||
}
|
||||
|
|
@ -358,10 +358,10 @@ namespace hex::plugin::builtin {
|
|||
drawList->ChannelsSetCurrent(0);
|
||||
|
||||
// Draw achievement background
|
||||
drawBackground(drawList, innerWindowPos, innerWindowPos + innerWindowSize, this->m_offset);
|
||||
drawBackground(drawList, innerWindowPos, innerWindowPos + innerWindowSize, m_offset);
|
||||
|
||||
// Draw the achievement tree
|
||||
auto maxPos = drawAchievementTree(drawList, nullptr, achievements, innerWindowPos + scaled({ 100, 100 }) + this->m_offset);
|
||||
auto maxPos = drawAchievementTree(drawList, nullptr, achievements, innerWindowPos + scaled({ 100, 100 }) + m_offset);
|
||||
|
||||
drawList->ChannelsSetCurrent(3);
|
||||
|
||||
|
|
@ -373,12 +373,12 @@ namespace hex::plugin::builtin {
|
|||
// Handle dragging the achievement tree around
|
||||
if (ImGui::IsMouseHoveringRect(innerWindowPos, innerWindowPos + innerWindowSize)) {
|
||||
auto dragDelta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Left);
|
||||
this->m_offset += dragDelta;
|
||||
m_offset += dragDelta;
|
||||
ImGui::ResetMouseDragDelta(ImGuiMouseButton_Left);
|
||||
}
|
||||
|
||||
// Clamp the achievement tree to the window
|
||||
this->m_offset = -ImClamp(-this->m_offset, { 0, 0 }, ImMax(maxPos - innerWindowPos - innerWindowSize, { 0, 0 }));
|
||||
m_offset = -ImClamp(-m_offset, { 0, 0 }, ImMax(maxPos - innerWindowPos - innerWindowSize, { 0, 0 }));
|
||||
|
||||
drawList->PopClipRect();
|
||||
|
||||
|
|
@ -386,8 +386,8 @@ namespace hex::plugin::builtin {
|
|||
ImGui::SetCursorScreenPos(innerWindowPos + ImVec2(0, innerWindowSize.y + windowPadding.y));
|
||||
ImGui::BeginGroup();
|
||||
{
|
||||
if (ImGui::Checkbox("Show popup", &this->m_showPopup))
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.achievement_popup", this->m_showPopup);
|
||||
if (ImGui::Checkbox("Show popup", &m_showPopup))
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.achievement_popup", m_showPopup);
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
|
||||
|
|
@ -398,17 +398,17 @@ namespace hex::plugin::builtin {
|
|||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
this->m_achievementToGoto = nullptr;
|
||||
m_achievementToGoto = nullptr;
|
||||
}
|
||||
|
||||
void ViewAchievements::drawAlwaysVisibleContent() {
|
||||
|
||||
// Handle showing the achievement unlock popup
|
||||
if (this->m_achievementUnlockQueueTimer >= 0 && this->m_showPopup) {
|
||||
this->m_achievementUnlockQueueTimer -= ImGui::GetIO().DeltaTime;
|
||||
if (m_achievementUnlockQueueTimer >= 0 && m_showPopup) {
|
||||
m_achievementUnlockQueueTimer -= ImGui::GetIO().DeltaTime;
|
||||
|
||||
// Check if there's an achievement that can be drawn
|
||||
if (this->m_currAchievement != nullptr) {
|
||||
if (m_currAchievement != nullptr) {
|
||||
|
||||
const ImVec2 windowSize = scaled({ 200, 55 });
|
||||
ImGui::SetNextWindowPos(ImHexApi::System::getMainWindowPosition() + ImVec2 { ImHexApi::System::getMainWindowSize().x - windowSize.x - 100_scaled, 0 });
|
||||
|
|
@ -420,34 +420,34 @@ namespace hex::plugin::builtin {
|
|||
ImGuiExt::TextFormattedColored(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_AchievementUnlocked), "{}", "hex.builtin.view.achievements.unlocked"_lang);
|
||||
|
||||
// Draw achievement icon
|
||||
ImGui::Image(this->m_currAchievement->getIcon(), scaled({ 20, 20 }));
|
||||
ImGui::Image(m_currAchievement->getIcon(), scaled({ 20, 20 }));
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||
ImGui::SameLine();
|
||||
|
||||
// Draw name of achievement
|
||||
ImGuiExt::TextFormattedWrapped("{}", Lang(this->m_currAchievement->getUnlocalizedName()));
|
||||
ImGuiExt::TextFormattedWrapped("{}", Lang(m_currAchievement->getUnlocalizedName()));
|
||||
|
||||
// Handle clicking on the popup
|
||||
if (ImGui::IsWindowHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) {
|
||||
// Open the achievement window and jump to the achievement
|
||||
this->getWindowOpenState() = true;
|
||||
this->m_achievementToGoto = this->m_currAchievement;
|
||||
m_achievementToGoto = m_currAchievement;
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
} else {
|
||||
// Reset the achievement unlock queue timer
|
||||
this->m_achievementUnlockQueueTimer = -1.0F;
|
||||
this->m_currAchievement = nullptr;
|
||||
m_achievementUnlockQueueTimer = -1.0F;
|
||||
m_currAchievement = nullptr;
|
||||
|
||||
// If there are more achievements to draw, draw the next one
|
||||
if (!this->m_achievementUnlockQueue.empty()) {
|
||||
this->m_currAchievement = this->m_achievementUnlockQueue.front();
|
||||
this->m_achievementUnlockQueue.pop_front();
|
||||
this->m_achievementUnlockQueueTimer = 5.0F;
|
||||
if (!m_achievementUnlockQueue.empty()) {
|
||||
m_currAchievement = m_achievementUnlockQueue.front();
|
||||
m_achievementUnlockQueue.pop_front();
|
||||
m_achievementUnlockQueueTimer = 5.0F;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ namespace hex::plugin::builtin {
|
|||
if (color == 0x00)
|
||||
color = ImGui::GetColorU32(ImGuiCol_Header);
|
||||
|
||||
this->m_currBookmarkId += 1;
|
||||
u64 bookmarkId = this->m_currBookmarkId;
|
||||
m_currBookmarkId += 1;
|
||||
u64 bookmarkId = m_currBookmarkId;
|
||||
if (id != nullptr)
|
||||
*id = bookmarkId;
|
||||
|
||||
|
|
@ -42,16 +42,16 @@ namespace hex::plugin::builtin {
|
|||
bookmarkId
|
||||
};
|
||||
|
||||
this->m_bookmarks->emplace_back(std::move(bookmark), TextEditor());
|
||||
m_bookmarks->emplace_back(std::move(bookmark), TextEditor());
|
||||
|
||||
ImHexApi::Provider::markDirty();
|
||||
|
||||
EventBookmarkCreated::post(this->m_bookmarks->back().entry);
|
||||
EventBookmarkCreated::post(m_bookmarks->back().entry);
|
||||
EventHighlightingChanged::post();
|
||||
});
|
||||
|
||||
RequestRemoveBookmark::subscribe([this](u64 id) {
|
||||
std::erase_if(this->m_bookmarks.get(), [id](const auto &bookmark) {
|
||||
std::erase_if(m_bookmarks.get(), [id](const auto &bookmark) {
|
||||
return bookmark.entry.id == id;
|
||||
});
|
||||
});
|
||||
|
|
@ -61,7 +61,7 @@ namespace hex::plugin::builtin {
|
|||
hex::unused(data);
|
||||
|
||||
// Check all bookmarks for potential overlaps with the current address
|
||||
for (const auto &bookmark : *this->m_bookmarks) {
|
||||
for (const auto &bookmark : *m_bookmarks) {
|
||||
if (Region { address, size }.isWithin(bookmark.entry.region))
|
||||
return bookmark.entry.color;
|
||||
}
|
||||
|
|
@ -74,7 +74,7 @@ namespace hex::plugin::builtin {
|
|||
hex::unused(data);
|
||||
|
||||
// Loop over all bookmarks
|
||||
for (const auto &[bookmark, editor] : *this->m_bookmarks) {
|
||||
for (const auto &[bookmark, editor] : *m_bookmarks) {
|
||||
// Make sure the bookmark overlaps the currently hovered address
|
||||
if (!Region { address, size }.isWithin(bookmark.region))
|
||||
continue;
|
||||
|
|
@ -147,7 +147,7 @@ namespace hex::plugin::builtin {
|
|||
return true;
|
||||
|
||||
auto data = nlohmann::json::parse(fileContent.begin(), fileContent.end());
|
||||
this->m_bookmarks.get(provider).clear();
|
||||
m_bookmarks.get(provider).clear();
|
||||
return this->importBookmarks(provider, data);
|
||||
},
|
||||
.store = [this](prv::Provider *provider, const std::fs::path &basePath, Tar &tar) -> bool {
|
||||
|
|
@ -163,7 +163,7 @@ namespace hex::plugin::builtin {
|
|||
ContentRegistry::Reports::addReportProvider([this](prv::Provider *provider) -> std::string {
|
||||
std::string result;
|
||||
|
||||
const auto &bookmarks = this->m_bookmarks.get(provider);
|
||||
const auto &bookmarks = m_bookmarks.get(provider);
|
||||
if (bookmarks.empty())
|
||||
return "";
|
||||
|
||||
|
|
@ -243,27 +243,27 @@ namespace hex::plugin::builtin {
|
|||
|
||||
// Draw filter input
|
||||
ImGui::PushItemWidth(-1);
|
||||
ImGuiExt::InputTextIcon("##filter", ICON_VS_FILTER, this->m_currFilter);
|
||||
ImGuiExt::InputTextIcon("##filter", ICON_VS_FILTER, m_currFilter);
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
if (ImGui::BeginChild("##bookmarks")) {
|
||||
if (this->m_bookmarks->empty()) {
|
||||
if (m_bookmarks->empty()) {
|
||||
ImGuiExt::TextFormattedCentered("hex.builtin.view.bookmarks.no_bookmarks"_lang);
|
||||
}
|
||||
|
||||
int id = 1;
|
||||
auto bookmarkToRemove = this->m_bookmarks->end();
|
||||
auto bookmarkToRemove = m_bookmarks->end();
|
||||
|
||||
// Draw all bookmarks
|
||||
for (auto it = this->m_bookmarks->begin(); it != this->m_bookmarks->end(); ++it) {
|
||||
for (auto it = m_bookmarks->begin(); it != m_bookmarks->end(); ++it) {
|
||||
auto &[bookmark, editor] = *it;
|
||||
auto &[region, name, comment, color, locked, bookmarkId] = bookmark;
|
||||
|
||||
// Apply filter
|
||||
if (!this->m_currFilter.empty()) {
|
||||
if (!name.contains(this->m_currFilter) && !comment.contains(this->m_currFilter))
|
||||
if (!m_currFilter.empty()) {
|
||||
if (!name.contains(m_currFilter) && !comment.contains(m_currFilter))
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -288,18 +288,18 @@ namespace hex::plugin::builtin {
|
|||
// Handle dragging bookmarks up and down when they're collapsed
|
||||
|
||||
// Set the currently held bookmark as the one being dragged
|
||||
if (ImGui::IsMouseClicked(0) && ImGui::IsItemActivated() && this->m_dragStartIterator == this->m_bookmarks->end())
|
||||
this->m_dragStartIterator = it;
|
||||
if (ImGui::IsMouseClicked(0) && ImGui::IsItemActivated() && m_dragStartIterator == m_bookmarks->end())
|
||||
m_dragStartIterator = it;
|
||||
|
||||
// When the mouse moved away from the current bookmark, swap the dragged bookmark with the current one
|
||||
if (ImGui::IsItemHovered() && this->m_dragStartIterator != this->m_bookmarks->end()) {
|
||||
std::iter_swap(it, this->m_dragStartIterator);
|
||||
this->m_dragStartIterator = it;
|
||||
if (ImGui::IsItemHovered() && m_dragStartIterator != m_bookmarks->end()) {
|
||||
std::iter_swap(it, m_dragStartIterator);
|
||||
m_dragStartIterator = it;
|
||||
}
|
||||
|
||||
// When the mouse is released, reset the dragged bookmark
|
||||
if (!ImGui::IsMouseDown(0))
|
||||
this->m_dragStartIterator = this->m_bookmarks->end();
|
||||
m_dragStartIterator = m_bookmarks->end();
|
||||
} else {
|
||||
const auto rowHeight = ImGui::GetTextLineHeightWithSpacing() + 2 * ImGui::GetStyle().FramePadding.y;
|
||||
if (ImGui::BeginTable("##bookmark_table", 3, ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit)) {
|
||||
|
|
@ -436,8 +436,8 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
// Remove the bookmark that was marked for removal
|
||||
if (bookmarkToRemove != this->m_bookmarks->end()) {
|
||||
this->m_bookmarks->erase(bookmarkToRemove);
|
||||
if (bookmarkToRemove != m_bookmarks->end()) {
|
||||
m_bookmarks->erase(bookmarkToRemove);
|
||||
EventHighlightingChanged::post();
|
||||
}
|
||||
}
|
||||
|
|
@ -458,22 +458,22 @@ namespace hex::plugin::builtin {
|
|||
|
||||
TextEditor editor;
|
||||
editor.SetText(bookmark["comment"]);
|
||||
this->m_bookmarks.get(provider).push_back({
|
||||
m_bookmarks.get(provider).push_back({
|
||||
{
|
||||
.region = { region["address"], region["size"] },
|
||||
.name = bookmark["name"],
|
||||
.comment = bookmark["comment"],
|
||||
.color = bookmark["color"],
|
||||
.locked = bookmark["locked"],
|
||||
.id = bookmark.contains("id") ? bookmark["id"].get<u64>() : *this->m_currBookmarkId
|
||||
.id = bookmark.contains("id") ? bookmark["id"].get<u64>() : *m_currBookmarkId
|
||||
},
|
||||
editor
|
||||
});
|
||||
|
||||
if (bookmark.contains("id"))
|
||||
this->m_currBookmarkId = std::max<u64>(this->m_currBookmarkId, bookmark["id"].get<i64>() + 1);
|
||||
m_currBookmarkId = std::max<u64>(m_currBookmarkId, bookmark["id"].get<i64>() + 1);
|
||||
else
|
||||
this->m_currBookmarkId += 1;
|
||||
m_currBookmarkId += 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -482,7 +482,7 @@ namespace hex::plugin::builtin {
|
|||
bool ViewBookmarks::exportBookmarks(prv::Provider *provider, nlohmann::json &json) {
|
||||
json["bookmarks"] = nlohmann::json::array();
|
||||
size_t index = 0;
|
||||
for (const auto &[bookmark, editor] : this->m_bookmarks.get(provider)) {
|
||||
for (const auto &[bookmark, editor] : m_bookmarks.get(provider)) {
|
||||
json["bookmarks"][index] = {
|
||||
{ "name", bookmark.name },
|
||||
{ "comment", editor.GetText() },
|
||||
|
|
@ -536,7 +536,7 @@ namespace hex::plugin::builtin {
|
|||
wolv::io::File(path, wolv::io::File::Mode::Create).writeString(json.dump(4));
|
||||
});
|
||||
}, [this]{
|
||||
return ImHexApi::Provider::isValid() && !this->m_bookmarks->empty();
|
||||
return ImHexApi::Provider::isValid() && !m_bookmarks->empty();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,22 +9,22 @@ namespace hex::plugin::builtin {
|
|||
// Add global shortcut to open the command palette
|
||||
ShortcutManager::addGlobalShortcut(CTRLCMD + SHIFT + Keys::P, "hex.builtin.view.command_palette.name", [this] {
|
||||
RequestOpenPopup::post("hex.builtin.view.command_palette.name"_lang);
|
||||
this->m_commandPaletteOpen = true;
|
||||
this->m_justOpened = true;
|
||||
m_commandPaletteOpen = true;
|
||||
m_justOpened = true;
|
||||
});
|
||||
|
||||
EventSearchBoxClicked::subscribe([this](ImGuiMouseButton button) {
|
||||
if (button == ImGuiMouseButton_Left) {
|
||||
RequestOpenPopup::post("hex.builtin.view.command_palette.name"_lang);
|
||||
this->m_commandPaletteOpen = true;
|
||||
this->m_justOpened = true;
|
||||
m_commandPaletteOpen = true;
|
||||
m_justOpened = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ViewCommandPalette::drawAlwaysVisibleContent() {
|
||||
// If the command palette is hidden, don't draw it
|
||||
if (!this->m_commandPaletteOpen) return;
|
||||
if (!m_commandPaletteOpen) return;
|
||||
|
||||
auto windowPos = ImHexApi::System::getMainWindowPosition();
|
||||
auto windowSize = ImHexApi::System::getMainWindowSize();
|
||||
|
|
@ -52,8 +52,8 @@ namespace hex::plugin::builtin {
|
|||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0_scaled);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4_scaled);
|
||||
|
||||
if (ImGui::InputText("##command_input", this->m_commandBuffer)) {
|
||||
this->m_lastResults = this->getCommandResults(this->m_commandBuffer);
|
||||
if (ImGui::InputText("##command_input", m_commandBuffer)) {
|
||||
m_lastResults = this->getCommandResults(m_commandBuffer);
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
|
|
@ -61,40 +61,40 @@ namespace hex::plugin::builtin {
|
|||
ImGui::PopItemWidth();
|
||||
ImGui::SetItemDefaultFocus();
|
||||
|
||||
if (this->m_moveCursorToEnd) {
|
||||
if (m_moveCursorToEnd) {
|
||||
auto textState = ImGui::GetInputTextState(ImGui::GetID("##command_input"));
|
||||
if (textState != nullptr) {
|
||||
textState->Stb.cursor =
|
||||
textState->Stb.select_start =
|
||||
textState->Stb.select_end = this->m_commandBuffer.size();
|
||||
textState->Stb.select_end = m_commandBuffer.size();
|
||||
}
|
||||
this->m_moveCursorToEnd = false;
|
||||
m_moveCursorToEnd = false;
|
||||
}
|
||||
|
||||
// Handle giving back focus to the input text box
|
||||
if (this->m_focusInputTextBox) {
|
||||
if (m_focusInputTextBox) {
|
||||
ImGui::SetKeyboardFocusHere(-1);
|
||||
ImGui::ActivateItemByID(ImGui::GetID("##command_input"));
|
||||
|
||||
this->m_focusInputTextBox = false;
|
||||
this->m_moveCursorToEnd = true;
|
||||
m_focusInputTextBox = false;
|
||||
m_moveCursorToEnd = true;
|
||||
}
|
||||
|
||||
// Execute the currently selected command when pressing enter
|
||||
if (ImGui::IsItemFocused() && (ImGui::IsKeyPressed(ImGuiKey_Enter, false) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter, false))) {
|
||||
if (!this->m_lastResults.empty()) {
|
||||
auto &[displayResult, matchedCommand, callback] = this->m_lastResults.front();
|
||||
if (!m_lastResults.empty()) {
|
||||
auto &[displayResult, matchedCommand, callback] = m_lastResults.front();
|
||||
callback(matchedCommand);
|
||||
}
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
// Focus the input text box when the popup is opened
|
||||
if (this->m_justOpened) {
|
||||
if (m_justOpened) {
|
||||
focusInputTextBox();
|
||||
this->m_lastResults = this->getCommandResults("");
|
||||
this->m_commandBuffer.clear();
|
||||
this->m_justOpened = false;
|
||||
m_lastResults = this->getCommandResults("");
|
||||
m_commandBuffer.clear();
|
||||
m_justOpened = false;
|
||||
}
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetStyle().FramePadding.y);
|
||||
|
|
@ -103,7 +103,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
// Draw the results
|
||||
if (ImGui::BeginChild("##results", ImGui::GetContentRegionAvail(), false, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_NavFlattened)) {
|
||||
for (const auto &[displayResult, matchedCommand, callback] : this->m_lastResults) {
|
||||
for (const auto &[displayResult, matchedCommand, callback] : m_lastResults) {
|
||||
ImGui::PushTabStop(true);
|
||||
ON_SCOPE_EXIT { ImGui::PopTabStop(); };
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
ImGui::EndPopup();
|
||||
} else {
|
||||
this->m_commandPaletteOpen = false;
|
||||
m_commandPaletteOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -155,8 +155,8 @@ namespace hex::plugin::builtin {
|
|||
|
||||
auto AutoComplete = [this, currCommand = command](auto) {
|
||||
this->focusInputTextBox();
|
||||
this->m_commandBuffer = currCommand + " ";
|
||||
this->m_lastResults = this->getCommandResults(currCommand);
|
||||
m_commandBuffer = currCommand + " ";
|
||||
m_lastResults = this->getCommandResults(currCommand);
|
||||
};
|
||||
|
||||
if (type == ContentRegistry::CommandPaletteCommands::Type::SymbolCommand) {
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
void ViewConstants::reloadConstants() {
|
||||
this->m_constants.clear();
|
||||
this->m_filterIndices.clear();
|
||||
m_constants.clear();
|
||||
m_filterIndices.clear();
|
||||
|
||||
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Constants)) {
|
||||
if (!wolv::io::fs::exists(path)) continue;
|
||||
|
|
@ -52,8 +52,8 @@ namespace hex::plugin::builtin {
|
|||
else
|
||||
throw std::runtime_error("Invalid type");
|
||||
|
||||
this->m_filterIndices.push_back(this->m_constants.size());
|
||||
this->m_constants.push_back(constant);
|
||||
m_filterIndices.push_back(m_constants.size());
|
||||
m_constants.push_back(constant);
|
||||
}
|
||||
} catch (...) {
|
||||
log::error("Failed to parse constants file {}", wolv::util::toUTF8String(file.path()));
|
||||
|
|
@ -65,17 +65,17 @@ namespace hex::plugin::builtin {
|
|||
void ViewConstants::drawContent() {
|
||||
ImGui::PushItemWidth(-1);
|
||||
|
||||
if (ImGuiExt::InputTextIcon("##search", ICON_VS_FILTER, this->m_filter)) {
|
||||
this->m_filterIndices.clear();
|
||||
if (ImGuiExt::InputTextIcon("##search", ICON_VS_FILTER, m_filter)) {
|
||||
m_filterIndices.clear();
|
||||
|
||||
// Filter the constants according to the entered value
|
||||
for (u64 i = 0; i < this->m_constants.size(); i++) {
|
||||
auto &constant = this->m_constants[i];
|
||||
if (hex::containsIgnoreCase(constant.name, this->m_filter) ||
|
||||
hex::containsIgnoreCase(constant.category, this->m_filter) ||
|
||||
hex::containsIgnoreCase(constant.description, this->m_filter) ||
|
||||
hex::containsIgnoreCase(constant.value, this->m_filter))
|
||||
this->m_filterIndices.push_back(i);
|
||||
for (u64 i = 0; i < m_constants.size(); i++) {
|
||||
auto &constant = m_constants[i];
|
||||
if (hex::containsIgnoreCase(constant.name, m_filter) ||
|
||||
hex::containsIgnoreCase(constant.category, m_filter) ||
|
||||
hex::containsIgnoreCase(constant.description, m_filter) ||
|
||||
hex::containsIgnoreCase(constant.value, m_filter))
|
||||
m_filterIndices.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
// Handle table sorting
|
||||
if (sortSpecs->SpecsDirty) {
|
||||
std::sort(this->m_constants.begin(), this->m_constants.end(), [&sortSpecs](const Constant &left, const Constant &right) -> bool {
|
||||
std::sort(m_constants.begin(), m_constants.end(), [&sortSpecs](const Constant &left, const Constant &right) -> bool {
|
||||
if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("category")) {
|
||||
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
|
||||
return left.category > right.category;
|
||||
|
|
@ -124,12 +124,12 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TableHeadersRow();
|
||||
|
||||
ImGuiListClipper clipper;
|
||||
clipper.Begin(this->m_filterIndices.size());
|
||||
clipper.Begin(m_filterIndices.size());
|
||||
|
||||
// Draw the constants table
|
||||
while (clipper.Step()) {
|
||||
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
|
||||
auto &constant = this->m_constants[this->m_filterIndices[i]];
|
||||
auto &constant = m_constants[m_filterIndices[i]];
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted(constant.category.c_str());
|
||||
|
|
|
|||
|
|
@ -25,26 +25,26 @@ namespace hex::plugin::builtin {
|
|||
|
||||
// Save current selection
|
||||
if (!ImHexApi::Provider::isValid() || region == Region::Invalid()) {
|
||||
this->m_validBytes = 0;
|
||||
this->m_selectedProvider = nullptr;
|
||||
m_validBytes = 0;
|
||||
m_selectedProvider = nullptr;
|
||||
} else {
|
||||
this->m_validBytes = u64(region.getProvider()->getActualSize() - region.address);
|
||||
this->m_startAddress = region.address;
|
||||
this->m_selectedProvider = region.getProvider();
|
||||
m_validBytes = u64(region.getProvider()->getActualSize() - region.address);
|
||||
m_startAddress = region.address;
|
||||
m_selectedProvider = region.getProvider();
|
||||
}
|
||||
|
||||
// Invalidate inspector rows
|
||||
this->m_shouldInvalidate = true;
|
||||
m_shouldInvalidate = true;
|
||||
});
|
||||
|
||||
EventProviderClosed::subscribe(this, [this](const auto*) {
|
||||
this->m_selectedProvider = nullptr;
|
||||
m_selectedProvider = nullptr;
|
||||
});
|
||||
|
||||
EventSettingsChanged::subscribe(this, [this] {
|
||||
auto filterValues = ContentRegistry::Settings::read("hex.builtin.setting.data_inspector", "hex.builtin.setting.data_inspector.hidden_rows", nlohmann::json::array()).get<std::vector<std::string>>();
|
||||
|
||||
this->m_hiddenValues = std::set(filterValues.begin(), filterValues.end());
|
||||
m_hiddenValues = std::set(filterValues.begin(), filterValues.end());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -56,10 +56,10 @@ namespace hex::plugin::builtin {
|
|||
|
||||
|
||||
void ViewDataInspector::updateInspectorRows() {
|
||||
this->m_updateTask = TaskManager::createBackgroundTask("Update Inspector", [this, validBytes = this->m_validBytes, startAddress = this->m_startAddress, endian = this->m_endian, invert = this->m_invert, numberDisplayStyle = this->m_numberDisplayStyle](auto &) {
|
||||
this->m_workData.clear();
|
||||
m_updateTask = TaskManager::createBackgroundTask("Update Inspector", [this, validBytes = m_validBytes, startAddress = m_startAddress, endian = m_endian, invert = m_invert, numberDisplayStyle = m_numberDisplayStyle](auto &) {
|
||||
m_workData.clear();
|
||||
|
||||
if (this->m_selectedProvider == nullptr)
|
||||
if (m_selectedProvider == nullptr)
|
||||
return;
|
||||
|
||||
// Decode bytes using registered inspectors
|
||||
|
|
@ -69,7 +69,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
// Try to read as many bytes as requested and possible
|
||||
std::vector<u8> buffer(validBytes > entry.maxSize ? entry.maxSize : validBytes);
|
||||
this->m_selectedProvider->read(startAddress, buffer.data(), buffer.size());
|
||||
m_selectedProvider->read(startAddress, buffer.data(), buffer.size());
|
||||
|
||||
// Handle invert setting
|
||||
if (invert) {
|
||||
|
|
@ -78,7 +78,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
// Insert processed data into the inspector list
|
||||
this->m_workData.push_back({
|
||||
m_workData.push_back({
|
||||
entry.unlocalizedName,
|
||||
entry.generatorFunction(buffer, endian, numberDisplayStyle),
|
||||
entry.editingFunction,
|
||||
|
|
@ -94,13 +94,13 @@ namespace hex::plugin::builtin {
|
|||
};
|
||||
|
||||
// Setup a new pattern language runtime
|
||||
ContentRegistry::PatternLanguage::configureRuntime(this->m_runtime, this->m_selectedProvider);
|
||||
ContentRegistry::PatternLanguage::configureRuntime(m_runtime, m_selectedProvider);
|
||||
|
||||
// Setup the runtime to read from the selected provider
|
||||
this->m_runtime.setDataSource(this->m_selectedProvider->getBaseAddress(), this->m_selectedProvider->getActualSize(),
|
||||
m_runtime.setDataSource(m_selectedProvider->getBaseAddress(), m_selectedProvider->getActualSize(),
|
||||
[this, invert](u64 offset, u8 *buffer, size_t size) {
|
||||
// Read bytes from the selected provider
|
||||
this->m_selectedProvider->read(offset, buffer, size);
|
||||
m_selectedProvider->read(offset, buffer, size);
|
||||
|
||||
// Handle invert setting
|
||||
if (invert) {
|
||||
|
|
@ -110,13 +110,13 @@ namespace hex::plugin::builtin {
|
|||
});
|
||||
|
||||
// Prevent dangerous function calls
|
||||
this->m_runtime.setDangerousFunctionCallHandler([] { return false; });
|
||||
m_runtime.setDangerousFunctionCallHandler([] { return false; });
|
||||
|
||||
// Set the default endianness based on the endian setting
|
||||
this->m_runtime.setDefaultEndian(endian);
|
||||
m_runtime.setDefaultEndian(endian);
|
||||
|
||||
// Set start address to the selected address
|
||||
this->m_runtime.setStartAddress(startAddress);
|
||||
m_runtime.setStartAddress(startAddress);
|
||||
|
||||
// Loop over all files in the inspectors folder and execute them
|
||||
for (const auto &folderPath : fs::getDefaultPaths(fs::ImHexPath::Inspectors)) {
|
||||
|
|
@ -133,10 +133,10 @@ namespace hex::plugin::builtin {
|
|||
|
||||
// Execute the inspector file
|
||||
if (!inspectorCode.empty()) {
|
||||
if (this->m_runtime.executeString(inspectorCode, {}, inVariables, true)) {
|
||||
if (m_runtime.executeString(inspectorCode, {}, inVariables, true)) {
|
||||
|
||||
// Loop over patterns produced by the runtime
|
||||
const auto &patterns = this->m_runtime.getPatterns();
|
||||
const auto &patterns = m_runtime.getPatterns();
|
||||
for (const auto &pattern : patterns) {
|
||||
// Skip hidden patterns
|
||||
if (pattern->getVisibility() == pl::ptrn::Visibility::Hidden)
|
||||
|
|
@ -166,7 +166,7 @@ namespace hex::plugin::builtin {
|
|||
};
|
||||
|
||||
// Insert the inspector into the list
|
||||
this->m_workData.push_back({
|
||||
m_workData.push_back({
|
||||
pattern->getDisplayName(),
|
||||
displayFunction,
|
||||
editingFunction,
|
||||
|
|
@ -180,7 +180,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
const auto& error = this->m_runtime.getError();
|
||||
const auto& error = m_runtime.getError();
|
||||
|
||||
log::error("Failed to execute custom inspector file '{}'!", wolv::util::toUTF8String(filePath));
|
||||
if (error.has_value())
|
||||
|
|
@ -191,46 +191,46 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
}
|
||||
|
||||
this->m_dataValid = true;
|
||||
m_dataValid = true;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
void ViewDataInspector::drawContent() {
|
||||
if (this->m_dataValid && !this->m_updateTask.isRunning()) {
|
||||
this->m_dataValid = false;
|
||||
this->m_cachedData = std::move(this->m_workData);
|
||||
if (m_dataValid && !m_updateTask.isRunning()) {
|
||||
m_dataValid = false;
|
||||
m_cachedData = std::move(m_workData);
|
||||
}
|
||||
|
||||
if (this->m_shouldInvalidate && !this->m_updateTask.isRunning()) {
|
||||
this->m_shouldInvalidate = false;
|
||||
if (m_shouldInvalidate && !m_updateTask.isRunning()) {
|
||||
m_shouldInvalidate = false;
|
||||
|
||||
this->updateInspectorRows();
|
||||
}
|
||||
|
||||
if (this->m_selectedProvider != nullptr && this->m_selectedProvider->isReadable() && this->m_validBytes > 0) {
|
||||
u32 validLineCount = this->m_cachedData.size();
|
||||
if (!this->m_tableEditingModeEnabled) {
|
||||
validLineCount = std::count_if(this->m_cachedData.begin(), this->m_cachedData.end(), [this](const auto &entry) {
|
||||
return !this->m_hiddenValues.contains(entry.filterValue);
|
||||
if (m_selectedProvider != nullptr && m_selectedProvider->isReadable() && m_validBytes > 0) {
|
||||
u32 validLineCount = m_cachedData.size();
|
||||
if (!m_tableEditingModeEnabled) {
|
||||
validLineCount = std::count_if(m_cachedData.begin(), m_cachedData.end(), [this](const auto &entry) {
|
||||
return !m_hiddenValues.contains(entry.filterValue);
|
||||
});
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("##datainspector", this->m_tableEditingModeEnabled ? 3 : 2, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg, ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * (validLineCount + 1)))) {
|
||||
if (ImGui::BeginTable("##datainspector", m_tableEditingModeEnabled ? 3 : 2, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg, ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * (validLineCount + 1)))) {
|
||||
ImGui::TableSetupScrollFreeze(0, 1);
|
||||
ImGui::TableSetupColumn("hex.builtin.view.data_inspector.table.name"_lang, ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("hex.builtin.view.data_inspector.table.value"_lang, ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
if (this->m_tableEditingModeEnabled)
|
||||
if (m_tableEditingModeEnabled)
|
||||
ImGui::TableSetupColumn("##favorite", ImGuiTableColumnFlags_WidthFixed, ImGui::GetTextLineHeight());
|
||||
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
int inspectorRowId = 1;
|
||||
for (auto &[unlocalizedName, displayFunction, editingFunction, editing, filterValue] : this->m_cachedData) {
|
||||
for (auto &[unlocalizedName, displayFunction, editingFunction, editing, filterValue] : m_cachedData) {
|
||||
bool grayedOut = false;
|
||||
if (this->m_hiddenValues.contains(filterValue)) {
|
||||
if (!this->m_tableEditingModeEnabled)
|
||||
if (m_hiddenValues.contains(filterValue)) {
|
||||
if (!m_tableEditingModeEnabled)
|
||||
continue;
|
||||
else
|
||||
grayedOut = true;
|
||||
|
|
@ -262,7 +262,7 @@ namespace hex::plugin::builtin {
|
|||
// Enter editing mode when double-clicking the row
|
||||
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) && editingFunction.has_value()) {
|
||||
editing = true;
|
||||
this->m_editingValue = copyValue;
|
||||
m_editingValue = copyValue;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -273,49 +273,49 @@ namespace hex::plugin::builtin {
|
|||
ImGui::SetKeyboardFocusHere();
|
||||
|
||||
// Draw input text box
|
||||
if (ImGui::InputText("##InspectorLineEditing", this->m_editingValue, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
|
||||
if (ImGui::InputText("##InspectorLineEditing", m_editingValue, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
|
||||
// Turn the entered value into bytes
|
||||
auto bytes = editingFunction.value()(this->m_editingValue, this->m_endian);
|
||||
auto bytes = editingFunction.value()(m_editingValue, m_endian);
|
||||
|
||||
if (this->m_invert)
|
||||
if (m_invert)
|
||||
std::ranges::transform(bytes, bytes.begin(), [](auto byte) { return byte ^ 0xFF; });
|
||||
|
||||
// Write those bytes to the selected provider at the current address
|
||||
this->m_selectedProvider->write(this->m_startAddress, bytes.data(), bytes.size());
|
||||
m_selectedProvider->write(m_startAddress, bytes.data(), bytes.size());
|
||||
|
||||
// Disable editing mode
|
||||
this->m_editingValue.clear();
|
||||
m_editingValue.clear();
|
||||
editing = false;
|
||||
|
||||
// Reload all inspector rows
|
||||
this->m_shouldInvalidate = true;
|
||||
m_shouldInvalidate = true;
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
// Disable editing mode when clicking outside the input text box
|
||||
if (!ImGui::IsItemHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
|
||||
this->m_editingValue.clear();
|
||||
m_editingValue.clear();
|
||||
editing = false;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (this->m_tableEditingModeEnabled) {
|
||||
if (m_tableEditingModeEnabled) {
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetStyleColorVec4(ImGuiCol_Text));
|
||||
|
||||
bool hidden = this->m_hiddenValues.contains(filterValue);
|
||||
bool hidden = m_hiddenValues.contains(filterValue);
|
||||
if (ImGuiExt::DimmedButton(hidden ? ICON_VS_EYE : ICON_VS_EYE_CLOSED)) {
|
||||
if (hidden)
|
||||
this->m_hiddenValues.erase(filterValue);
|
||||
m_hiddenValues.erase(filterValue);
|
||||
else
|
||||
this->m_hiddenValues.insert(filterValue);
|
||||
m_hiddenValues.insert(filterValue);
|
||||
|
||||
{
|
||||
std::vector filterValues(this->m_hiddenValues.begin(), this->m_hiddenValues.end());
|
||||
std::vector filterValues(m_hiddenValues.begin(), m_hiddenValues.end());
|
||||
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.data_inspector", "hex.builtin.setting.data_inspector.hidden_rows", filterValues);
|
||||
}
|
||||
|
|
@ -332,7 +332,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGuiExt::DimmedButtonToggle("hex.builtin.common.edit"_lang, &this->m_tableEditingModeEnabled, ImVec2(ImGui::GetContentRegionAvail().x, 0));
|
||||
ImGuiExt::DimmedButtonToggle("hex.builtin.common.edit"_lang, &m_tableEditingModeEnabled, ImVec2(ImGui::GetContentRegionAvail().x, 0));
|
||||
|
||||
ImGui::NewLine();
|
||||
ImGui::Separator();
|
||||
|
|
@ -343,7 +343,7 @@ namespace hex::plugin::builtin {
|
|||
// Draw endian setting
|
||||
{
|
||||
int selection = [this] {
|
||||
switch (this->m_endian) {
|
||||
switch (m_endian) {
|
||||
default:
|
||||
case std::endian::little: return 0;
|
||||
case std::endian::big: return 1;
|
||||
|
|
@ -353,12 +353,12 @@ namespace hex::plugin::builtin {
|
|||
std::array options = { "hex.builtin.common.little"_lang, "hex.builtin.common.big"_lang };
|
||||
|
||||
if (ImGui::SliderInt("hex.builtin.common.endian"_lang, &selection, 0, options.size() - 1, options[selection], ImGuiSliderFlags_NoInput)) {
|
||||
this->m_shouldInvalidate = true;
|
||||
m_shouldInvalidate = true;
|
||||
|
||||
switch (selection) {
|
||||
default:
|
||||
case 0: this->m_endian = std::endian::little; break;
|
||||
case 1: this->m_endian = std::endian::big; break;
|
||||
case 0: m_endian = std::endian::little; break;
|
||||
case 1: m_endian = std::endian::big; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -366,7 +366,7 @@ namespace hex::plugin::builtin {
|
|||
// Draw radix setting
|
||||
{
|
||||
int selection = [this] {
|
||||
switch (this->m_numberDisplayStyle) {
|
||||
switch (m_numberDisplayStyle) {
|
||||
default:
|
||||
case NumberDisplayStyle::Decimal: return 0;
|
||||
case NumberDisplayStyle::Hexadecimal: return 1;
|
||||
|
|
@ -376,26 +376,26 @@ namespace hex::plugin::builtin {
|
|||
std::array options = { "hex.builtin.common.decimal"_lang, "hex.builtin.common.hexadecimal"_lang, "hex.builtin.common.octal"_lang };
|
||||
|
||||
if (ImGui::SliderInt("hex.builtin.common.number_format"_lang, &selection, 0, options.size() - 1, options[selection], ImGuiSliderFlags_NoInput)) {
|
||||
this->m_shouldInvalidate = true;
|
||||
m_shouldInvalidate = true;
|
||||
|
||||
switch (selection) {
|
||||
default:
|
||||
case 0: this->m_numberDisplayStyle = NumberDisplayStyle::Decimal; break;
|
||||
case 1: this->m_numberDisplayStyle = NumberDisplayStyle::Hexadecimal; break;
|
||||
case 2: this->m_numberDisplayStyle = NumberDisplayStyle::Octal; break;
|
||||
case 0: m_numberDisplayStyle = NumberDisplayStyle::Decimal; break;
|
||||
case 1: m_numberDisplayStyle = NumberDisplayStyle::Hexadecimal; break;
|
||||
case 2: m_numberDisplayStyle = NumberDisplayStyle::Octal; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw invert setting
|
||||
{
|
||||
int selection = this->m_invert ? 1 : 0;
|
||||
int selection = m_invert ? 1 : 0;
|
||||
std::array options = { "hex.builtin.common.no"_lang, "hex.builtin.common.yes"_lang };
|
||||
|
||||
if (ImGui::SliderInt("hex.builtin.view.data_inspector.invert"_lang, &selection, 0, options.size() - 1, options[selection], ImGuiSliderFlags_NoInput)) {
|
||||
this->m_shouldInvalidate = true;
|
||||
m_shouldInvalidate = true;
|
||||
|
||||
this->m_invert = selection == 1;
|
||||
m_invert = selection == 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -29,26 +29,26 @@ namespace hex::plugin::builtin {
|
|||
void drawNode() override {
|
||||
ImGui::PushItemWidth(100_scaled);
|
||||
// Draw combo box to select the type of the input
|
||||
if (ImGui::Combo("##type", &this->m_type, "Integer\0Float\0Buffer\0")) {
|
||||
if (ImGui::Combo("##type", &m_type, "Integer\0Float\0Buffer\0")) {
|
||||
this->setAttributes({
|
||||
{ dp::Attribute(dp::Attribute::IOType::Out, this->getType(), "hex.builtin.nodes.common.input") }
|
||||
});
|
||||
}
|
||||
|
||||
// Draw text input to set the name of the input
|
||||
if (ImGui::InputText("##name", this->m_name)) {
|
||||
this->setUnlocalizedTitle(this->m_name);
|
||||
if (ImGui::InputText("##name", m_name)) {
|
||||
this->setUnlocalizedTitle(m_name);
|
||||
}
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
void setValue(auto value) { this->m_value = std::move(value); }
|
||||
void setValue(auto value) { m_value = std::move(value); }
|
||||
|
||||
const std::string &getName() const { return this->m_name; }
|
||||
const std::string &getName() const { return m_name; }
|
||||
|
||||
dp::Attribute::Type getType() const {
|
||||
switch (this->m_type) {
|
||||
switch (m_type) {
|
||||
default:
|
||||
case 0: return dp::Attribute::Type::Integer;
|
||||
case 1: return dp::Attribute::Type::Float;
|
||||
|
|
@ -61,21 +61,21 @@ namespace hex::plugin::builtin {
|
|||
[this](i128 value) { this->setIntegerOnOutput(0, value); },
|
||||
[this](long double value) { this->setFloatOnOutput(0, value); },
|
||||
[this](const std::vector<u8> &value) { this->setBufferOnOutput(0, value); }
|
||||
}, this->m_value);
|
||||
}, m_value);
|
||||
}
|
||||
|
||||
void store(nlohmann::json &j) const override {
|
||||
j = nlohmann::json::object();
|
||||
|
||||
j["name"] = this->m_name;
|
||||
j["type"] = this->m_type;
|
||||
j["name"] = m_name;
|
||||
j["type"] = m_type;
|
||||
}
|
||||
|
||||
void load(const nlohmann::json &j) override {
|
||||
this->m_name = j.at("name").get<std::string>();
|
||||
this->m_type = j.at("type");
|
||||
m_name = j.at("name").get<std::string>();
|
||||
m_type = j.at("type");
|
||||
|
||||
this->setUnlocalizedTitle(this->m_name);
|
||||
this->setUnlocalizedTitle(m_name);
|
||||
this->setAttributes({
|
||||
{ dp::Attribute(dp::Attribute::IOType::Out, this->getType(), "hex.builtin.nodes.common.input") }
|
||||
});
|
||||
|
|
@ -100,23 +100,23 @@ namespace hex::plugin::builtin {
|
|||
ImGui::PushItemWidth(100_scaled);
|
||||
|
||||
// Draw combo box to select the type of the output
|
||||
if (ImGui::Combo("##type", &this->m_type, "Integer\0Float\0Buffer\0")) {
|
||||
if (ImGui::Combo("##type", &m_type, "Integer\0Float\0Buffer\0")) {
|
||||
this->setAttributes({
|
||||
{ dp::Attribute(dp::Attribute::IOType::In, this->getType(), "hex.builtin.nodes.common.output") }
|
||||
});
|
||||
}
|
||||
|
||||
// Draw text input to set the name of the output
|
||||
if (ImGui::InputText("##name", this->m_name)) {
|
||||
this->setUnlocalizedTitle(this->m_name);
|
||||
if (ImGui::InputText("##name", m_name)) {
|
||||
this->setUnlocalizedTitle(m_name);
|
||||
}
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
const std::string &getName() const { return this->m_name; }
|
||||
const std::string &getName() const { return m_name; }
|
||||
dp::Attribute::Type getType() const {
|
||||
switch (this->m_type) {
|
||||
switch (m_type) {
|
||||
case 0: return dp::Attribute::Type::Integer;
|
||||
case 1: return dp::Attribute::Type::Float;
|
||||
case 2: return dp::Attribute::Type::Buffer;
|
||||
|
|
@ -126,26 +126,26 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void process() override {
|
||||
switch (this->getType()) {
|
||||
case dp::Attribute::Type::Integer: this->m_value = this->getIntegerOnInput(0); break;
|
||||
case dp::Attribute::Type::Float: this->m_value = this->getFloatOnInput(0); break;
|
||||
case dp::Attribute::Type::Buffer: this->m_value = this->getBufferOnInput(0); break;
|
||||
case dp::Attribute::Type::Integer: m_value = this->getIntegerOnInput(0); break;
|
||||
case dp::Attribute::Type::Float: m_value = this->getFloatOnInput(0); break;
|
||||
case dp::Attribute::Type::Buffer: m_value = this->getBufferOnInput(0); break;
|
||||
}
|
||||
}
|
||||
|
||||
const auto& getValue() const { return this->m_value; }
|
||||
const auto& getValue() const { return m_value; }
|
||||
|
||||
void store(nlohmann::json &j) const override {
|
||||
j = nlohmann::json::object();
|
||||
|
||||
j["name"] = this->m_name;
|
||||
j["type"] = this->m_type;
|
||||
j["name"] = m_name;
|
||||
j["type"] = m_type;
|
||||
}
|
||||
|
||||
void load(const nlohmann::json &j) override {
|
||||
this->m_name = j.at("name").get<std::string>();
|
||||
this->m_type = j.at("type");
|
||||
m_name = j.at("name").get<std::string>();
|
||||
m_type = j.at("type");
|
||||
|
||||
this->setUnlocalizedTitle(this->m_name);
|
||||
this->setUnlocalizedTitle(m_name);
|
||||
this->setAttributes({
|
||||
{ dp::Attribute(dp::Attribute::IOType::In, this->getType(), "hex.builtin.nodes.common.output") }
|
||||
});
|
||||
|
|
@ -168,8 +168,8 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void drawNode() override {
|
||||
// Update attributes if we have to
|
||||
if (this->m_requiresAttributeUpdate) {
|
||||
this->m_requiresAttributeUpdate = false;
|
||||
if (m_requiresAttributeUpdate) {
|
||||
m_requiresAttributeUpdate = false;
|
||||
|
||||
// Find all input and output nodes that are used by the workspace of this node
|
||||
// and set the attributes of this node to the attributes of the input and output nodes
|
||||
|
|
@ -179,9 +179,9 @@ namespace hex::plugin::builtin {
|
|||
ImGui::PushItemWidth(200_scaled);
|
||||
|
||||
bool editing = false;
|
||||
if (this->m_editable) {
|
||||
if (m_editable) {
|
||||
// Draw name input field
|
||||
ImGuiExt::InputTextIcon("##name", ICON_VS_SYMBOL_KEY, this->m_name);
|
||||
ImGuiExt::InputTextIcon("##name", ICON_VS_SYMBOL_KEY, m_name);
|
||||
|
||||
// Prevent editing mode from deactivating when the input field is focused
|
||||
editing = ImGui::IsItemActive();
|
||||
|
|
@ -191,12 +191,12 @@ namespace hex::plugin::builtin {
|
|||
AchievementManager::unlockAchievement("hex.builtin.achievement.data_processor", "hex.builtin.achievement.data_processor.custom_node.name");
|
||||
|
||||
// Open the custom node's workspace
|
||||
this->m_dataProcessor->getWorkspaceStack().push_back(&this->m_workspace);
|
||||
m_dataProcessor->getWorkspaceStack().push_back(&m_workspace);
|
||||
|
||||
this->m_requiresAttributeUpdate = true;
|
||||
m_requiresAttributeUpdate = true;
|
||||
}
|
||||
} else {
|
||||
this->setUnlocalizedTitle(this->m_name);
|
||||
this->setUnlocalizedTitle(m_name);
|
||||
|
||||
if (this->getAttributes().empty()) {
|
||||
ImGui::TextUnformatted("hex.builtin.nodes.custom.custom.edit_hint"_lang);
|
||||
|
|
@ -204,7 +204,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
// Enable editing mode when the shift button is pressed
|
||||
this->m_editable = ImGui::GetIO().KeyShift || editing;
|
||||
m_editable = ImGui::GetIO().KeyShift || editing;
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
|
@ -220,7 +220,7 @@ namespace hex::plugin::builtin {
|
|||
};
|
||||
|
||||
auto prevContext = ImNodes::GetCurrentContext();
|
||||
ImNodes::SetCurrentContext(this->m_workspace.context.get());
|
||||
ImNodes::SetCurrentContext(m_workspace.context.get());
|
||||
ON_SCOPE_EXIT { ImNodes::SetCurrentContext(prevContext); };
|
||||
|
||||
// Forward inputs to input nodes values
|
||||
|
|
@ -251,11 +251,11 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
// Process all nodes in our workspace
|
||||
for (auto &endNode : this->m_workspace.endNodes) {
|
||||
for (auto &endNode : m_workspace.endNodes) {
|
||||
endNode->resetOutputData();
|
||||
|
||||
// Reset processed inputs of all nodes
|
||||
for (auto &node : this->m_workspace.nodes)
|
||||
for (auto &node : m_workspace.nodes)
|
||||
node->resetProcessedInputs();
|
||||
|
||||
endNode->process();
|
||||
|
|
@ -294,14 +294,14 @@ namespace hex::plugin::builtin {
|
|||
void store(nlohmann::json &j) const override {
|
||||
j = nlohmann::json::object();
|
||||
|
||||
j["nodes"] = this->m_dataProcessor->saveNodes(this->m_workspace);
|
||||
j["nodes"] = m_dataProcessor->saveNodes(m_workspace);
|
||||
}
|
||||
|
||||
void load(const nlohmann::json &j) override {
|
||||
this->m_dataProcessor->loadNodes(this->m_workspace, j.at("nodes"));
|
||||
m_dataProcessor->loadNodes(m_workspace, j.at("nodes"));
|
||||
|
||||
this->m_name = Lang(this->getUnlocalizedTitle()).get();
|
||||
this->m_requiresAttributeUpdate = true;
|
||||
m_name = Lang(this->getUnlocalizedTitle()).get();
|
||||
m_requiresAttributeUpdate = true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -309,7 +309,7 @@ namespace hex::plugin::builtin {
|
|||
std::vector<dp::Attribute> result;
|
||||
|
||||
// Search through all nodes in the workspace and add all input and output nodes to the result
|
||||
for (auto &node : this->m_workspace.nodes) {
|
||||
for (auto &node : m_workspace.nodes) {
|
||||
if (auto *inputNode = dynamic_cast<NodeCustomInput*>(node.get()); inputNode != nullptr)
|
||||
result.emplace_back(dp::Attribute::IOType::In, inputNode->getType(), inputNode->getName());
|
||||
else if (auto *outputNode = dynamic_cast<NodeCustomOutput*>(node.get()); outputNode != nullptr)
|
||||
|
|
@ -320,7 +320,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
NodeCustomInput* findInput(const std::string &name) const {
|
||||
for (auto &node : this->m_workspace.nodes) {
|
||||
for (auto &node : m_workspace.nodes) {
|
||||
if (auto *inputNode = dynamic_cast<NodeCustomInput*>(node.get()); inputNode != nullptr && inputNode->getName() == name)
|
||||
return inputNode;
|
||||
}
|
||||
|
|
@ -329,7 +329,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
NodeCustomOutput* findOutput(const std::string &name) const {
|
||||
for (auto &node : this->m_workspace.nodes) {
|
||||
for (auto &node : m_workspace.nodes) {
|
||||
if (auto *outputNode = dynamic_cast<NodeCustomOutput*>(node.get()); outputNode != nullptr && outputNode->getName() == name)
|
||||
return outputNode;
|
||||
}
|
||||
|
|
@ -358,25 +358,25 @@ namespace hex::plugin::builtin {
|
|||
.load = [this](prv::Provider *provider, const std::fs::path &basePath, Tar &tar) {
|
||||
std::string save = tar.readString(basePath);
|
||||
|
||||
ViewDataProcessor::loadNodes(this->m_mainWorkspace.get(provider), nlohmann::json::parse(save));
|
||||
this->m_updateNodePositions = true;
|
||||
ViewDataProcessor::loadNodes(m_mainWorkspace.get(provider), nlohmann::json::parse(save));
|
||||
m_updateNodePositions = true;
|
||||
|
||||
return true;
|
||||
},
|
||||
.store = [this](prv::Provider *provider, const std::fs::path &basePath, Tar &tar) {
|
||||
tar.writeString(basePath, ViewDataProcessor::saveNodes(this->m_mainWorkspace.get(provider)).dump(4));
|
||||
tar.writeString(basePath, ViewDataProcessor::saveNodes(m_mainWorkspace.get(provider)).dump(4));
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
EventProviderCreated::subscribe(this, [this](auto *provider) {
|
||||
this->m_mainWorkspace.get(provider) = { };
|
||||
this->m_workspaceStack.get(provider).push_back(&this->m_mainWorkspace.get(provider));
|
||||
m_mainWorkspace.get(provider) = { };
|
||||
m_workspaceStack.get(provider).push_back(&m_mainWorkspace.get(provider));
|
||||
});
|
||||
|
||||
EventProviderChanged::subscribe(this, [this](const auto *, const auto *) {
|
||||
for (auto *workspace : *this->m_workspaceStack) {
|
||||
for (auto *workspace : *m_workspaceStack) {
|
||||
for (auto &node : workspace->nodes) {
|
||||
node->setCurrentOverlay(nullptr);
|
||||
}
|
||||
|
|
@ -384,11 +384,11 @@ namespace hex::plugin::builtin {
|
|||
workspace->dataOverlays.clear();
|
||||
}
|
||||
|
||||
this->m_updateNodePositions = true;
|
||||
m_updateNodePositions = true;
|
||||
});
|
||||
|
||||
EventDataChanged::subscribe(this, [this] {
|
||||
ViewDataProcessor::processNodes(*this->m_workspaceStack->back());
|
||||
ViewDataProcessor::processNodes(*m_workspaceStack->back());
|
||||
});
|
||||
|
||||
/* Import Nodes */
|
||||
|
|
@ -397,8 +397,8 @@ namespace hex::plugin::builtin {
|
|||
[&](const std::fs::path &path) {
|
||||
wolv::io::File file(path, wolv::io::File::Mode::Read);
|
||||
if (file.isValid()) {
|
||||
ViewDataProcessor::loadNodes(*this->m_mainWorkspace, nlohmann::json::parse(file.readString()));
|
||||
this->m_updateNodePositions = true;
|
||||
ViewDataProcessor::loadNodes(*m_mainWorkspace, nlohmann::json::parse(file.readString()));
|
||||
m_updateNodePositions = true;
|
||||
}
|
||||
});
|
||||
}, ImHexApi::Provider::isValid);
|
||||
|
|
@ -409,18 +409,18 @@ namespace hex::plugin::builtin {
|
|||
[&, this](const std::fs::path &path) {
|
||||
wolv::io::File file(path, wolv::io::File::Mode::Create);
|
||||
if (file.isValid())
|
||||
file.writeString(ViewDataProcessor::saveNodes(*this->m_mainWorkspace).dump(4));
|
||||
file.writeString(ViewDataProcessor::saveNodes(*m_mainWorkspace).dump(4));
|
||||
});
|
||||
}, [this]{
|
||||
return !this->m_workspaceStack->empty() && !this->m_workspaceStack->back()->nodes.empty() && ImHexApi::Provider::isValid();
|
||||
return !m_workspaceStack->empty() && !m_workspaceStack->back()->nodes.empty() && ImHexApi::Provider::isValid();
|
||||
});
|
||||
|
||||
ContentRegistry::FileHandler::add({ ".hexnode" }, [this](const auto &path) {
|
||||
wolv::io::File file(path, wolv::io::File::Mode::Read);
|
||||
if (!file.isValid()) return false;
|
||||
|
||||
ViewDataProcessor::loadNodes(*this->m_mainWorkspace, file.readString());
|
||||
this->m_updateNodePositions = true;
|
||||
ViewDataProcessor::loadNodes(*m_mainWorkspace, file.readString());
|
||||
m_updateNodePositions = true;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
|
@ -563,7 +563,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void ViewDataProcessor::reloadCustomNodes() {
|
||||
// Delete all custom nodes
|
||||
this->m_customNodes.clear();
|
||||
m_customNodes.clear();
|
||||
|
||||
// Loop over all custom node folders
|
||||
for (const auto &basePath : fs::getDefaultPaths(fs::ImHexPath::Nodes)) {
|
||||
|
|
@ -579,7 +579,7 @@ namespace hex::plugin::builtin {
|
|||
nlohmann::json nodeJson = nlohmann::json::parse(file.readString());
|
||||
|
||||
// Add the loaded node to the list of custom nodes
|
||||
this->m_customNodes.push_back(CustomNode { Lang(nodeJson.at("name").get<std::string>()), nodeJson });
|
||||
m_customNodes.push_back(CustomNode { Lang(nodeJson.at("name").get<std::string>()), nodeJson });
|
||||
} catch (nlohmann::json::exception &e) {
|
||||
log::warn("Failed to load custom node '{}': {}", entry.path().string(), e.what());
|
||||
}
|
||||
|
|
@ -595,13 +595,13 @@ namespace hex::plugin::builtin {
|
|||
ImNodes::ClearLinkSelection();
|
||||
|
||||
// Save the current mouse position
|
||||
this->m_rightClickedCoords = ImGui::GetMousePos();
|
||||
m_rightClickedCoords = ImGui::GetMousePos();
|
||||
|
||||
// Show a different context menu depending on if a node, a link
|
||||
// or the background was right-clicked
|
||||
if (ImNodes::IsNodeHovered(&this->m_rightClickedId))
|
||||
if (ImNodes::IsNodeHovered(&m_rightClickedId))
|
||||
ImGui::OpenPopup("Node Menu");
|
||||
else if (ImNodes::IsLinkHovered(&this->m_rightClickedId))
|
||||
else if (ImNodes::IsLinkHovered(&m_rightClickedId))
|
||||
ImGui::OpenPopup("Link Menu");
|
||||
else {
|
||||
ImGui::OpenPopup("Context Menu");
|
||||
|
|
@ -665,7 +665,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::Separator();
|
||||
|
||||
// Draw entries for each custom node
|
||||
for (auto &customNode : this->m_customNodes) {
|
||||
for (auto &customNode : m_customNodes) {
|
||||
if (ImGui::MenuItem(customNode.name.c_str())) {
|
||||
node = loadNode(customNode.data);
|
||||
}
|
||||
|
|
@ -694,7 +694,7 @@ namespace hex::plugin::builtin {
|
|||
workspace.endNodes.push_back(node.get());
|
||||
|
||||
// Set the position of the node to the position where the user right-clicked
|
||||
ImNodes::SetNodeScreenSpacePos(node->getId(), this->m_rightClickedCoords);
|
||||
ImNodes::SetNodeScreenSpacePos(node->getId(), m_rightClickedCoords);
|
||||
workspace.nodes.push_back(std::move(node));
|
||||
|
||||
ImHexApi::Provider::markDirty();
|
||||
|
|
@ -710,7 +710,7 @@ namespace hex::plugin::builtin {
|
|||
// Find the node that was right-clicked
|
||||
auto it = std::find_if(workspace.nodes.begin(), workspace.nodes.end(),
|
||||
[this](const auto &node) {
|
||||
return node->getId() == this->m_rightClickedId;
|
||||
return node->getId() == m_rightClickedId;
|
||||
});
|
||||
|
||||
// Check if the node was found
|
||||
|
|
@ -728,7 +728,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.view.data_processor.menu.remove_node"_lang))
|
||||
this->eraseNodes(workspace, { this->m_rightClickedId });
|
||||
this->eraseNodes(workspace, { m_rightClickedId });
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
|
@ -736,7 +736,7 @@ namespace hex::plugin::builtin {
|
|||
// Draw link right click menu
|
||||
if (ImGui::BeginPopup("Link Menu")) {
|
||||
if (ImGui::MenuItem("hex.builtin.view.data_processor.menu.remove_link"_lang))
|
||||
this->eraseLink(workspace, this->m_rightClickedId);
|
||||
this->eraseLink(workspace, m_rightClickedId);
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
|
@ -745,7 +745,7 @@ namespace hex::plugin::builtin {
|
|||
void ViewDataProcessor::drawNode(dp::Node &node) const {
|
||||
// If a node position update is pending, update the node position
|
||||
int nodeId = node.getId();
|
||||
if (this->m_updateNodePositions) {
|
||||
if (m_updateNodePositions) {
|
||||
ImNodes::SetNodeGridSpacePos(nodeId, node.getPosition());
|
||||
} else {
|
||||
if (ImNodes::ObjectPoolFind(ImNodes::EditorContextGet().Nodes, nodeId) >= 0)
|
||||
|
|
@ -839,7 +839,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
void ViewDataProcessor::drawContent() {
|
||||
auto &workspace = *this->m_workspaceStack->back();
|
||||
auto &workspace = *m_workspaceStack->back();
|
||||
|
||||
bool popWorkspace = false;
|
||||
// Set the ImNodes context to the current workspace context
|
||||
|
|
@ -879,7 +879,7 @@ namespace hex::plugin::builtin {
|
|||
ImNodes::PopColorStyle();
|
||||
}
|
||||
|
||||
this->m_updateNodePositions = false;
|
||||
m_updateNodePositions = false;
|
||||
|
||||
// Handle removing links that are connected to attributes that don't exist anymore
|
||||
{
|
||||
|
|
@ -908,7 +908,7 @@ namespace hex::plugin::builtin {
|
|||
ImGuiExt::TextFormattedCentered("{}", "hex.builtin.view.data_processor.help_text"_lang);
|
||||
|
||||
// Draw a close button if there is more than one workspace on the stack
|
||||
if (this->m_workspaceStack->size() > 1) {
|
||||
if (m_workspaceStack->size() > 1) {
|
||||
ImGui::SetCursorPos(ImVec2(ImGui::GetContentRegionAvail().x - ImGui::GetTextLineHeightWithSpacing() * 1.5F, ImGui::GetTextLineHeightWithSpacing() * 0.2F));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4.0F, 4.0F));
|
||||
if (ImGuiExt::DimmedIconButton(ICON_VS_CLOSE, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) {
|
||||
|
|
@ -923,12 +923,12 @@ namespace hex::plugin::builtin {
|
|||
|
||||
// Draw the control bar at the bottom
|
||||
{
|
||||
if (ImGuiExt::IconButton(ICON_VS_DEBUG_START, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen)) || this->m_continuousEvaluation)
|
||||
if (ImGuiExt::IconButton(ICON_VS_DEBUG_START, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen)) || m_continuousEvaluation)
|
||||
this->processNodes(workspace);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::Checkbox("Continuous evaluation", &this->m_continuousEvaluation);
|
||||
ImGui::Checkbox("Continuous evaluation", &m_continuousEvaluation);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1016,8 +1016,8 @@ namespace hex::plugin::builtin {
|
|||
|
||||
// Remove the top-most workspace from the stack if requested
|
||||
if (popWorkspace) {
|
||||
this->m_workspaceStack->pop_back();
|
||||
this->m_updateNodePositions = true;
|
||||
m_workspaceStack->pop_back();
|
||||
m_updateNodePositions = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1192,7 +1192,7 @@ namespace hex::plugin::builtin {
|
|||
dp::Attribute::setIdCounter(maxAttrId + 1);
|
||||
dp::Link::setIdCounter(maxLinkId + 1);
|
||||
|
||||
this->m_updateNodePositions = true;
|
||||
m_updateNodePositions = true;
|
||||
} catch (nlohmann::json::exception &e) {
|
||||
PopupError::open(hex::format("Failed to load nodes: {}", e.what()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,16 +20,16 @@ namespace hex::plugin::builtin {
|
|||
// Clear the selected diff providers when a provider is closed
|
||||
EventProviderClosed::subscribe(this, [this](prv::Provider *) {
|
||||
for (u8 i = 0; i < 2; i++) {
|
||||
this->m_columns[i].provider = -1;
|
||||
this->m_columns[i].hexEditor.setSelectionUnchecked(std::nullopt, std::nullopt);
|
||||
m_columns[i].provider = -1;
|
||||
m_columns[i].hexEditor.setSelectionUnchecked(std::nullopt, std::nullopt);
|
||||
}
|
||||
|
||||
this->m_diffs.clear();
|
||||
m_diffs.clear();
|
||||
});
|
||||
|
||||
// Set the background highlight callbacks for the two hex editor columns
|
||||
this->m_columns[0].hexEditor.setBackgroundHighlightCallback(this->createCompareFunction(1));
|
||||
this->m_columns[1].hexEditor.setBackgroundHighlightCallback(this->createCompareFunction(0));
|
||||
m_columns[0].hexEditor.setBackgroundHighlightCallback(this->createCompareFunction(1));
|
||||
m_columns[1].hexEditor.setBackgroundHighlightCallback(this->createCompareFunction(0));
|
||||
}
|
||||
|
||||
ViewDiff::~ViewDiff() {
|
||||
|
|
@ -102,7 +102,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
return [this, otherIndex](u64 address, const u8 *data, size_t) -> std::optional<color_t> {
|
||||
const auto &providers = ImHexApi::Provider::getProviders();
|
||||
auto otherId = this->m_columns[otherIndex].provider;
|
||||
auto otherId = m_columns[otherIndex].provider;
|
||||
|
||||
// Check if the other provider is valid
|
||||
if (otherId < 0 || size_t(otherId) >= providers.size())
|
||||
|
|
@ -133,7 +133,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void ViewDiff::analyze(prv::Provider *providerA, prv::Provider *providerB) {
|
||||
auto commonSize = std::min(providerA->getActualSize(), providerB->getActualSize());
|
||||
this->m_diffTask = TaskManager::createTask("Diffing...", commonSize, [this, providerA, providerB](Task &task) {
|
||||
m_diffTask = TaskManager::createTask("Diffing...", commonSize, [this, providerA, providerB](Task &task) {
|
||||
std::vector<Diff> differences;
|
||||
|
||||
// Set up readers for both providers
|
||||
|
|
@ -177,13 +177,13 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
// Move the calculated differences over so they can be displayed
|
||||
this->m_diffs = std::move(differences);
|
||||
this->m_analyzed = true;
|
||||
m_diffs = std::move(differences);
|
||||
m_analyzed = true;
|
||||
});
|
||||
}
|
||||
|
||||
void ViewDiff::drawContent() {
|
||||
auto &[a, b] = this->m_columns;
|
||||
auto &[a, b] = m_columns;
|
||||
|
||||
a.hexEditor.enableSyncScrolling(false);
|
||||
b.hexEditor.enableSyncScrolling(false);
|
||||
|
|
@ -206,7 +206,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
// Analyze the providers if they are valid and the user selected a new provider
|
||||
if (!this->m_analyzed && a.provider != -1 && b.provider != -1 && !this->m_diffTask.isRunning()) {
|
||||
if (!m_analyzed && a.provider != -1 && b.provider != -1 && !m_diffTask.isRunning()) {
|
||||
const auto &providers = ImHexApi::Provider::getProviders();
|
||||
auto providerA = providers[a.provider];
|
||||
auto providerB = providers[b.provider];
|
||||
|
|
@ -222,15 +222,15 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TableSetupColumn("hex.builtin.view.diff.provider_b"_lang);
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
ImGui::BeginDisabled(this->m_diffTask.isRunning());
|
||||
ImGui::BeginDisabled(m_diffTask.isRunning());
|
||||
{
|
||||
// Draw first provider selector
|
||||
ImGui::TableNextColumn();
|
||||
if (drawProviderSelector(a)) this->m_analyzed = false;
|
||||
if (drawProviderSelector(a)) m_analyzed = false;
|
||||
|
||||
// Draw second provider selector
|
||||
ImGui::TableNextColumn();
|
||||
if (drawProviderSelector(b)) this->m_analyzed = false;
|
||||
if (drawProviderSelector(b)) m_analyzed = false;
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
|
|
@ -268,21 +268,21 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TableHeadersRow();
|
||||
|
||||
// Draw the differences if the providers have been analyzed
|
||||
if (this->m_analyzed) {
|
||||
if (m_analyzed) {
|
||||
ImGuiListClipper clipper;
|
||||
clipper.Begin(int(this->m_diffs.size()));
|
||||
clipper.Begin(int(m_diffs.size()));
|
||||
|
||||
while (clipper.Step())
|
||||
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
|
||||
ImGui::TableNextRow();
|
||||
|
||||
// Prevent the list from trying to access non-existing diffs
|
||||
if (size_t(i) >= this->m_diffs.size())
|
||||
if (size_t(i) >= m_diffs.size())
|
||||
break;
|
||||
|
||||
ImGui::PushID(i);
|
||||
|
||||
const auto &diff = this->m_diffs[i];
|
||||
const auto &diff = m_diffs[i];
|
||||
|
||||
// Draw a clickable row for each difference that will select the difference in both hex editors
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
ViewDisassembler::ViewDisassembler() : View::Window("hex.builtin.view.disassembler.name") {
|
||||
EventProviderDeleted::subscribe(this, [this](const auto*) {
|
||||
this->m_disassembly.clear();
|
||||
m_disassembly.clear();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -22,23 +22,23 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
void ViewDisassembler::disassemble() {
|
||||
this->m_disassembly.clear();
|
||||
m_disassembly.clear();
|
||||
|
||||
this->m_disassemblerTask = TaskManager::createTask("hex.builtin.view.disassembler.disassembling", this->m_codeRegion.getSize(), [this](auto &task) {
|
||||
m_disassemblerTask = TaskManager::createTask("hex.builtin.view.disassembler.disassembling", m_codeRegion.getSize(), [this](auto &task) {
|
||||
csh capstoneHandle;
|
||||
cs_insn *instructions = nullptr;
|
||||
|
||||
cs_mode mode = this->m_mode;
|
||||
cs_mode mode = m_mode;
|
||||
|
||||
// Create a capstone disassembler instance
|
||||
if (cs_open(Disassembler::toCapstoneArchitecture(this->m_architecture), mode, &capstoneHandle) == CS_ERR_OK) {
|
||||
if (cs_open(Disassembler::toCapstoneArchitecture(m_architecture), mode, &capstoneHandle) == CS_ERR_OK) {
|
||||
|
||||
// Tell capstone to skip data bytes
|
||||
cs_option(capstoneHandle, CS_OPT_SKIPDATA, CS_OPT_ON);
|
||||
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
std::vector<u8> buffer(2048, 0x00);
|
||||
size_t size = this->m_codeRegion.getSize();
|
||||
size_t size = m_codeRegion.getSize();
|
||||
|
||||
// Read the data in chunks and disassemble it
|
||||
for (u64 address = 0; address < size; address += 2048) {
|
||||
|
|
@ -46,15 +46,15 @@ namespace hex::plugin::builtin {
|
|||
|
||||
// Read a chunk of data
|
||||
size_t bufferSize = std::min(u64(2048), (size - address));
|
||||
provider->read(this->m_codeRegion.getStartAddress() + address, buffer.data(), bufferSize);
|
||||
provider->read(m_codeRegion.getStartAddress() + address, buffer.data(), bufferSize);
|
||||
|
||||
// Ask capstone to disassemble the data
|
||||
size_t instructionCount = cs_disasm(capstoneHandle, buffer.data(), bufferSize, this->m_baseAddress + address, 0, &instructions);
|
||||
size_t instructionCount = cs_disasm(capstoneHandle, buffer.data(), bufferSize, m_baseAddress + address, 0, &instructions);
|
||||
if (instructionCount == 0)
|
||||
break;
|
||||
|
||||
// Reserve enough space for the disassembly
|
||||
this->m_disassembly.reserve(this->m_disassembly.size() + instructionCount);
|
||||
m_disassembly.reserve(m_disassembly.size() + instructionCount);
|
||||
|
||||
// Convert the capstone instructions to our disassembly format
|
||||
u64 usedBytes = 0;
|
||||
|
|
@ -62,7 +62,7 @@ namespace hex::plugin::builtin {
|
|||
const auto &instr = instructions[i];
|
||||
Disassembly disassembly = { };
|
||||
disassembly.address = instr.address;
|
||||
disassembly.offset = this->m_codeRegion.getStartAddress() + address + usedBytes;
|
||||
disassembly.offset = m_codeRegion.getStartAddress() + address + usedBytes;
|
||||
disassembly.size = instr.size;
|
||||
disassembly.mnemonic = instr.mnemonic;
|
||||
disassembly.operators = instr.op_str;
|
||||
|
|
@ -71,7 +71,7 @@ namespace hex::plugin::builtin {
|
|||
disassembly.bytes += hex::format("{0:02X} ", instr.bytes[j]);
|
||||
disassembly.bytes.pop_back();
|
||||
|
||||
this->m_disassembly.push_back(disassembly);
|
||||
m_disassembly.push_back(disassembly);
|
||||
|
||||
usedBytes += instr.size;
|
||||
}
|
||||
|
|
@ -96,18 +96,18 @@ namespace hex::plugin::builtin {
|
|||
ImGuiExt::Header("hex.builtin.view.disassembler.position"_lang, true);
|
||||
|
||||
// Draw base address input
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.view.disassembler.base"_lang, &this->m_baseAddress, ImGuiInputTextFlags_CharsHexadecimal);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.view.disassembler.base"_lang, &m_baseAddress, ImGuiInputTextFlags_CharsHexadecimal);
|
||||
|
||||
// Draw region selection picker
|
||||
ui::regionSelectionPicker(&this->m_codeRegion, provider, &this->m_range);
|
||||
ui::regionSelectionPicker(&m_codeRegion, provider, &m_range);
|
||||
|
||||
// Draw settings
|
||||
{
|
||||
ImGuiExt::Header("hex.builtin.common.settings"_lang);
|
||||
|
||||
// Draw architecture selector
|
||||
if (ImGui::Combo("hex.builtin.view.disassembler.arch"_lang, reinterpret_cast<int *>(&this->m_architecture), Disassembler::ArchitectureNames.data(), Disassembler::getArchitectureSupportedCount()))
|
||||
this->m_mode = cs_mode(0);
|
||||
if (ImGui::Combo("hex.builtin.view.disassembler.arch"_lang, reinterpret_cast<int *>(&m_architecture), Disassembler::ArchitectureNames.data(), Disassembler::getArchitectureSupportedCount()))
|
||||
m_mode = cs_mode(0);
|
||||
|
||||
// Draw sub-settings for each architecture
|
||||
if (ImGuiExt::BeginBox()) {
|
||||
|
|
@ -121,7 +121,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::NewLine();
|
||||
|
||||
// Draw architecture specific settings
|
||||
switch (this->m_architecture) {
|
||||
switch (m_architecture) {
|
||||
case Architecture::ARM:
|
||||
{
|
||||
static int mode = CS_MODE_ARM;
|
||||
|
|
@ -136,7 +136,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::SameLine();
|
||||
ImGui::RadioButton("hex.builtin.view.disassembler.arm.armv8"_lang, &extraMode, CS_MODE_V8);
|
||||
|
||||
this->m_mode = cs_mode(mode | extraMode);
|
||||
m_mode = cs_mode(mode | extraMode);
|
||||
}
|
||||
break;
|
||||
case Architecture::MIPS:
|
||||
|
|
@ -155,7 +155,7 @@ namespace hex::plugin::builtin {
|
|||
static bool microMode;
|
||||
ImGui::Checkbox("hex.builtin.view.disassembler.mips.micro"_lang, µMode);
|
||||
|
||||
this->m_mode = cs_mode(mode | (microMode ? CS_MODE_MICRO : cs_mode(0)));
|
||||
m_mode = cs_mode(mode | (microMode ? CS_MODE_MICRO : cs_mode(0)));
|
||||
}
|
||||
break;
|
||||
case Architecture::X86:
|
||||
|
|
@ -167,7 +167,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::SameLine();
|
||||
ImGui::RadioButton("hex.builtin.view.disassembler.64bit"_lang, &mode, CS_MODE_64);
|
||||
|
||||
this->m_mode = cs_mode(mode);
|
||||
m_mode = cs_mode(mode);
|
||||
}
|
||||
break;
|
||||
case Architecture::PPC:
|
||||
|
|
@ -186,9 +186,9 @@ namespace hex::plugin::builtin {
|
|||
static bool booke = false;
|
||||
ImGui::Checkbox("hex.builtin.view.disassembler.ppc.booke"_lang, &booke);
|
||||
|
||||
this->m_mode = cs_mode(mode | (qpx ? CS_MODE_QPX : cs_mode(0)) | (spe ? CS_MODE_SPE : cs_mode(0)) | (booke ? CS_MODE_BOOKE : cs_mode(0)));
|
||||
m_mode = cs_mode(mode | (qpx ? CS_MODE_QPX : cs_mode(0)) | (spe ? CS_MODE_SPE : cs_mode(0)) | (booke ? CS_MODE_BOOKE : cs_mode(0)));
|
||||
#else
|
||||
this->m_mode = cs_mode(mode | (qpx ? CS_MODE_QPX : cs_mode(0)));
|
||||
m_mode = cs_mode(mode | (qpx ? CS_MODE_QPX : cs_mode(0)));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
|
@ -197,7 +197,7 @@ namespace hex::plugin::builtin {
|
|||
static bool v9Mode = false;
|
||||
ImGui::Checkbox("hex.builtin.view.disassembler.sparc.v9"_lang, &v9Mode);
|
||||
|
||||
this->m_mode = cs_mode(v9Mode ? CS_MODE_V9 : cs_mode(0));
|
||||
m_mode = cs_mode(v9Mode ? CS_MODE_V9 : cs_mode(0));
|
||||
}
|
||||
break;
|
||||
#if CS_API_MAJOR >= 5
|
||||
|
|
@ -211,7 +211,7 @@ namespace hex::plugin::builtin {
|
|||
static bool compressed = false;
|
||||
ImGui::Checkbox("hex.builtin.view.disassembler.riscv.compressed"_lang, &compressed);
|
||||
|
||||
this->m_mode = cs_mode(mode | (compressed ? CS_MODE_RISCVC : cs_mode(0)));
|
||||
m_mode = cs_mode(mode | (compressed ? CS_MODE_RISCVC : cs_mode(0)));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
|
@ -236,7 +236,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
this->m_mode = cs_mode(modes[selectedMode].second);
|
||||
m_mode = cs_mode(modes[selectedMode].second);
|
||||
}
|
||||
break;
|
||||
case Architecture::M680X:
|
||||
|
|
@ -264,7 +264,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
this->m_mode = cs_mode(modes[selectedMode].second);
|
||||
m_mode = cs_mode(modes[selectedMode].second);
|
||||
}
|
||||
break;
|
||||
#if CS_API_MAJOR >= 5
|
||||
|
|
@ -290,7 +290,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
this->m_mode = cs_mode(modes[selectedMode].second);
|
||||
m_mode = cs_mode(modes[selectedMode].second);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
|
@ -302,7 +302,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::SameLine();
|
||||
ImGui::RadioButton("hex.builtin.view.disassembler.bpf.extended"_lang, &mode, CS_MODE_BPF_EXTENDED);
|
||||
|
||||
this->m_mode = cs_mode(mode);
|
||||
m_mode = cs_mode(mode);
|
||||
}
|
||||
break;
|
||||
case Architecture::SH:
|
||||
|
|
@ -331,7 +331,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::SameLine();
|
||||
ImGui::Checkbox("hex.builtin.view.disassembler.sh.dsp"_lang, &dsp);
|
||||
|
||||
this->m_mode = cs_mode(modes[selectionMode].second | (fpu ? CS_MODE_SHFPU : cs_mode(0)) | (dsp ? CS_MODE_SHDSP : cs_mode(0)));
|
||||
m_mode = cs_mode(modes[selectionMode].second | (fpu ? CS_MODE_SHFPU : cs_mode(0)) | (dsp ? CS_MODE_SHDSP : cs_mode(0)));
|
||||
}
|
||||
break;
|
||||
case Architecture::TRICORE:
|
||||
|
|
@ -356,7 +356,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
this->m_mode = cs_mode(modes[selectionMode].second);
|
||||
m_mode = cs_mode(modes[selectionMode].second);
|
||||
}
|
||||
break;
|
||||
case Architecture::WASM:
|
||||
|
|
@ -366,7 +366,7 @@ namespace hex::plugin::builtin {
|
|||
case Architecture::ARM64:
|
||||
case Architecture::SYSZ:
|
||||
case Architecture::XCORE:
|
||||
this->m_mode = cs_mode(0);
|
||||
m_mode = cs_mode(0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -375,7 +375,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
// Draw disassemble button
|
||||
ImGui::BeginDisabled(this->m_disassemblerTask.isRunning());
|
||||
ImGui::BeginDisabled(m_disassemblerTask.isRunning());
|
||||
{
|
||||
if (ImGui::Button("hex.builtin.view.disassembler.disassemble"_lang))
|
||||
this->disassemble();
|
||||
|
|
@ -383,7 +383,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::EndDisabled();
|
||||
|
||||
// Draw a spinner if the disassembler is running
|
||||
if (this->m_disassemblerTask.isRunning()) {
|
||||
if (m_disassemblerTask.isRunning()) {
|
||||
ImGui::SameLine();
|
||||
ImGuiExt::TextSpinner("hex.builtin.view.disassembler.disassembling"_lang);
|
||||
}
|
||||
|
|
@ -401,14 +401,14 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TableSetupColumn("hex.builtin.view.disassembler.disassembly.bytes"_lang);
|
||||
ImGui::TableSetupColumn("hex.builtin.view.disassembler.disassembly.title"_lang);
|
||||
|
||||
if (!this->m_disassemblerTask.isRunning()) {
|
||||
if (!m_disassemblerTask.isRunning()) {
|
||||
ImGuiListClipper clipper;
|
||||
clipper.Begin(this->m_disassembly.size());
|
||||
clipper.Begin(m_disassembly.size());
|
||||
|
||||
ImGui::TableHeadersRow();
|
||||
while (clipper.Step()) {
|
||||
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
|
||||
const auto &instruction = this->m_disassembly[i];
|
||||
const auto &instruction = m_disassembly[i];
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ namespace hex::plugin::builtin {
|
|||
ImHexApi::HexEditor::addBackgroundHighlightingProvider([this](u64 address, const u8* data, size_t size, bool) -> std::optional<color_t> {
|
||||
hex::unused(data, size);
|
||||
|
||||
if (this->m_searchTask.isRunning())
|
||||
if (m_searchTask.isRunning())
|
||||
return { };
|
||||
|
||||
if (!this->m_occurrenceTree->overlapping({ address, address + size }).empty())
|
||||
if (!m_occurrenceTree->overlapping({ address, address + size }).empty())
|
||||
return HighlightColor();
|
||||
else
|
||||
return std::nullopt;
|
||||
|
|
@ -32,10 +32,10 @@ namespace hex::plugin::builtin {
|
|||
ImHexApi::HexEditor::addTooltipProvider([this](u64 address, const u8* data, size_t size) {
|
||||
hex::unused(data, size);
|
||||
|
||||
if (this->m_searchTask.isRunning())
|
||||
if (m_searchTask.isRunning())
|
||||
return;
|
||||
|
||||
auto occurrences = this->m_occurrenceTree->overlapping({ address, address + size });
|
||||
auto occurrences = m_occurrenceTree->overlapping({ address, address + size });
|
||||
if (occurrences.empty())
|
||||
return;
|
||||
|
||||
|
|
@ -94,12 +94,12 @@ namespace hex::plugin::builtin {
|
|||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRLCMD + Keys::A, "hex.builtin.view.find.shortcut.select_all", [this] {
|
||||
if (this->m_filterTask.isRunning())
|
||||
if (m_filterTask.isRunning())
|
||||
return;
|
||||
if (this->m_searchTask.isRunning())
|
||||
if (m_searchTask.isRunning())
|
||||
return;
|
||||
|
||||
for (auto &occurrence : *this->m_sortedOccurrences)
|
||||
for (auto &occurrence : *m_sortedOccurrences)
|
||||
occurrence.selected = true;
|
||||
});
|
||||
}
|
||||
|
|
@ -440,46 +440,46 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
void ViewFind::runSearch() {
|
||||
Region searchRegion = this->m_searchSettings.region;
|
||||
Region searchRegion = m_searchSettings.region;
|
||||
|
||||
if (this->m_searchSettings.mode == SearchSettings::Mode::Strings)
|
||||
if (m_searchSettings.mode == SearchSettings::Mode::Strings)
|
||||
AchievementManager::unlockAchievement("hex.builtin.achievement.find", "hex.builtin.achievement.find.find_strings.name");
|
||||
else if (this->m_searchSettings.mode == SearchSettings::Mode::Sequence)
|
||||
else if (m_searchSettings.mode == SearchSettings::Mode::Sequence)
|
||||
AchievementManager::unlockAchievement("hex.builtin.achievement.find", "hex.builtin.achievement.find.find_specific_string.name");
|
||||
else if (this->m_searchSettings.mode == SearchSettings::Mode::Value) {
|
||||
if (this->m_searchSettings.value.inputMin == "250" && this->m_searchSettings.value.inputMax == "1000")
|
||||
else if (m_searchSettings.mode == SearchSettings::Mode::Value) {
|
||||
if (m_searchSettings.value.inputMin == "250" && m_searchSettings.value.inputMax == "1000")
|
||||
AchievementManager::unlockAchievement("hex.builtin.achievement.find", "hex.builtin.achievement.find.find_numeric.name");
|
||||
}
|
||||
|
||||
this->m_occurrenceTree->clear();
|
||||
m_occurrenceTree->clear();
|
||||
EventHighlightingChanged::post();
|
||||
|
||||
this->m_searchTask = TaskManager::createTask("hex.builtin.view.find.searching", searchRegion.getSize(), [this, settings = this->m_searchSettings, searchRegion](auto &task) {
|
||||
m_searchTask = TaskManager::createTask("hex.builtin.view.find.searching", searchRegion.getSize(), [this, settings = m_searchSettings, searchRegion](auto &task) {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
|
||||
switch (settings.mode) {
|
||||
using enum SearchSettings::Mode;
|
||||
case Strings:
|
||||
this->m_foundOccurrences.get(provider) = searchStrings(task, provider, searchRegion, settings.strings);
|
||||
m_foundOccurrences.get(provider) = searchStrings(task, provider, searchRegion, settings.strings);
|
||||
break;
|
||||
case Sequence:
|
||||
this->m_foundOccurrences.get(provider) = searchSequence(task, provider, searchRegion, settings.bytes);
|
||||
m_foundOccurrences.get(provider) = searchSequence(task, provider, searchRegion, settings.bytes);
|
||||
break;
|
||||
case Regex:
|
||||
this->m_foundOccurrences.get(provider) = searchRegex(task, provider, searchRegion, settings.regex);
|
||||
m_foundOccurrences.get(provider) = searchRegex(task, provider, searchRegion, settings.regex);
|
||||
break;
|
||||
case BinaryPattern:
|
||||
this->m_foundOccurrences.get(provider) = searchBinaryPattern(task, provider, searchRegion, settings.binaryPattern);
|
||||
m_foundOccurrences.get(provider) = searchBinaryPattern(task, provider, searchRegion, settings.binaryPattern);
|
||||
break;
|
||||
case Value:
|
||||
this->m_foundOccurrences.get(provider) = searchValue(task, provider, searchRegion, settings.value);
|
||||
m_foundOccurrences.get(provider) = searchValue(task, provider, searchRegion, settings.value);
|
||||
break;
|
||||
}
|
||||
|
||||
this->m_sortedOccurrences.get(provider) = this->m_foundOccurrences.get(provider);
|
||||
m_sortedOccurrences.get(provider) = m_foundOccurrences.get(provider);
|
||||
|
||||
for (const auto &occurrence : this->m_foundOccurrences.get(provider))
|
||||
this->m_occurrenceTree->insert({ occurrence.region.getStartAddress(), occurrence.region.getEndAddress() }, occurrence);
|
||||
for (const auto &occurrence : m_foundOccurrences.get(provider))
|
||||
m_occurrenceTree->insert({ occurrence.region.getStartAddress(), occurrence.region.getEndAddress() }, occurrence);
|
||||
|
||||
TaskManager::doLater([] {
|
||||
EventHighlightingChanged::post();
|
||||
|
|
@ -492,7 +492,7 @@ namespace hex::plugin::builtin {
|
|||
provider->read(occurrence.region.getStartAddress(), bytes.data(), bytes.size());
|
||||
|
||||
std::string result;
|
||||
switch (this->m_decodeSettings.mode) {
|
||||
switch (m_decodeSettings.mode) {
|
||||
using enum SearchSettings::Mode;
|
||||
|
||||
case Value:
|
||||
|
|
@ -540,7 +540,7 @@ namespace hex::plugin::builtin {
|
|||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right) && ImGui::IsItemHovered()) {
|
||||
ImGui::OpenPopup("FindContextMenu");
|
||||
target.selected = true;
|
||||
this->m_replaceBuffer.clear();
|
||||
m_replaceBuffer.clear();
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopup("FindContextMenu")) {
|
||||
|
|
@ -551,14 +551,14 @@ namespace hex::plugin::builtin {
|
|||
if (ImGui::BeginMenu("hex.builtin.view.find.context.replace"_lang)) {
|
||||
if (ImGui::BeginTabBar("##replace_tabs")) {
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.find.context.replace.hex"_lang)) {
|
||||
ImGuiExt::InputTextIcon("##replace_input", ICON_VS_SYMBOL_NAMESPACE, this->m_replaceBuffer);
|
||||
ImGuiExt::InputTextIcon("##replace_input", ICON_VS_SYMBOL_NAMESPACE, m_replaceBuffer);
|
||||
|
||||
ImGui::BeginDisabled(this->m_replaceBuffer.empty());
|
||||
ImGui::BeginDisabled(m_replaceBuffer.empty());
|
||||
if (ImGui::Button("hex.builtin.view.find.context.replace"_lang)) {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
auto bytes = parseHexString(this->m_replaceBuffer);
|
||||
auto bytes = parseHexString(m_replaceBuffer);
|
||||
|
||||
for (const auto &occurrence : *this->m_sortedOccurrences) {
|
||||
for (const auto &occurrence : *m_sortedOccurrences) {
|
||||
if (occurrence.selected) {
|
||||
size_t size = std::min<size_t>(occurrence.region.size, bytes.size());
|
||||
provider->write(occurrence.region.getStartAddress(), bytes.data(), size);
|
||||
|
|
@ -571,14 +571,14 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.find.context.replace.ascii"_lang)) {
|
||||
ImGuiExt::InputTextIcon("##replace_input", ICON_VS_SYMBOL_KEY, this->m_replaceBuffer);
|
||||
ImGuiExt::InputTextIcon("##replace_input", ICON_VS_SYMBOL_KEY, m_replaceBuffer);
|
||||
|
||||
ImGui::BeginDisabled(this->m_replaceBuffer.empty());
|
||||
ImGui::BeginDisabled(m_replaceBuffer.empty());
|
||||
if (ImGui::Button("hex.builtin.view.find.context.replace"_lang)) {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
auto bytes = decodeByteString(this->m_replaceBuffer);
|
||||
auto bytes = decodeByteString(m_replaceBuffer);
|
||||
|
||||
for (const auto &occurrence : *this->m_sortedOccurrences) {
|
||||
for (const auto &occurrence : *m_sortedOccurrences) {
|
||||
if (occurrence.selected) {
|
||||
size_t size = std::min<size_t>(occurrence.region.size, bytes.size());
|
||||
provider->write(occurrence.region.getStartAddress(), bytes.data(), size);
|
||||
|
|
@ -603,9 +603,9 @@ namespace hex::plugin::builtin {
|
|||
void ViewFind::drawContent() {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
|
||||
ImGui::BeginDisabled(this->m_searchTask.isRunning());
|
||||
ImGui::BeginDisabled(m_searchTask.isRunning());
|
||||
{
|
||||
ui::regionSelectionPicker(&this->m_searchSettings.region, provider, &this->m_searchSettings.range, true, true);
|
||||
ui::regionSelectionPicker(&m_searchSettings.region, provider, &m_searchSettings.range, true, true);
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
|
|
@ -618,9 +618,9 @@ namespace hex::plugin::builtin {
|
|||
hex::format("{} + {}", "hex.builtin.common.encoding.ascii"_lang, "hex.builtin.common.encoding.utf16be"_lang)
|
||||
};
|
||||
|
||||
auto &mode = this->m_searchSettings.mode;
|
||||
auto &mode = m_searchSettings.mode;
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.find.strings"_lang)) {
|
||||
auto &settings = this->m_searchSettings.strings;
|
||||
auto &settings = m_searchSettings.strings;
|
||||
mode = SearchSettings::Mode::Strings;
|
||||
|
||||
ImGui::InputInt("hex.builtin.view.find.strings.min_length"_lang, &settings.minLength, 1, 1);
|
||||
|
|
@ -650,23 +650,23 @@ namespace hex::plugin::builtin {
|
|||
ImGui::Checkbox(hex::format("{} [\\r\\n]", "hex.builtin.view.find.strings.line_feeds"_lang.get()).c_str(), &settings.lineFeeds);
|
||||
}
|
||||
|
||||
this->m_settingsValid = true;
|
||||
m_settingsValid = true;
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.find.sequences"_lang)) {
|
||||
auto &settings = this->m_searchSettings.bytes;
|
||||
auto &settings = m_searchSettings.bytes;
|
||||
|
||||
mode = SearchSettings::Mode::Sequence;
|
||||
|
||||
ImGuiExt::InputTextIcon("hex.builtin.common.value"_lang, ICON_VS_SYMBOL_KEY, settings.sequence);
|
||||
|
||||
this->m_settingsValid = !settings.sequence.empty() && !hex::decodeByteString(settings.sequence).empty();
|
||||
m_settingsValid = !settings.sequence.empty() && !hex::decodeByteString(settings.sequence).empty();
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.find.regex"_lang)) {
|
||||
auto &settings = this->m_searchSettings.regex;
|
||||
auto &settings = m_searchSettings.regex;
|
||||
|
||||
mode = SearchSettings::Mode::Regex;
|
||||
|
||||
|
|
@ -692,20 +692,20 @@ namespace hex::plugin::builtin {
|
|||
|
||||
try {
|
||||
std::regex regex(settings.pattern);
|
||||
this->m_settingsValid = true;
|
||||
m_settingsValid = true;
|
||||
} catch (const std::regex_error &) {
|
||||
this->m_settingsValid = false;
|
||||
m_settingsValid = false;
|
||||
}
|
||||
|
||||
if (settings.pattern.empty())
|
||||
this->m_settingsValid = false;
|
||||
m_settingsValid = false;
|
||||
|
||||
ImGui::Checkbox("hex.builtin.view.find.regex.full_match"_lang, &settings.fullMatch);
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.find.binary_pattern"_lang)) {
|
||||
auto &settings = this->m_searchSettings.binaryPattern;
|
||||
auto &settings = m_searchSettings.binaryPattern;
|
||||
|
||||
mode = SearchSettings::Mode::BinaryPattern;
|
||||
|
||||
|
|
@ -715,12 +715,12 @@ namespace hex::plugin::builtin {
|
|||
ImGui::SliderScalar("hex.builtin.view.find.binary_pattern.alignment"_lang, ImGuiDataType_U32, &settings.alignment, &min, &max);
|
||||
|
||||
settings.pattern = hex::BinaryPattern(settings.input);
|
||||
this->m_settingsValid = settings.pattern.isValid() && settings.alignment > 0;
|
||||
m_settingsValid = settings.pattern.isValid() && settings.alignment > 0;
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.find.value"_lang)) {
|
||||
auto &settings = this->m_searchSettings.value;
|
||||
auto &settings = m_searchSettings.value;
|
||||
|
||||
mode = SearchSettings::Mode::Value;
|
||||
|
||||
|
|
@ -796,11 +796,11 @@ namespace hex::plugin::builtin {
|
|||
auto [minValid, min, minSize] = parseNumericValueInput(settings.inputMin, settings.type);
|
||||
auto [maxValid, max, maxSize] = parseNumericValueInput(settings.inputMax, settings.type);
|
||||
|
||||
this->m_settingsValid = minValid && maxValid && minSize == maxSize;
|
||||
m_settingsValid = minValid && maxValid && minSize == maxSize;
|
||||
}
|
||||
|
||||
if (settings.inputMin.empty())
|
||||
this->m_settingsValid = false;
|
||||
m_settingsValid = false;
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
|
@ -810,25 +810,25 @@ namespace hex::plugin::builtin {
|
|||
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::BeginDisabled(!this->m_settingsValid);
|
||||
ImGui::BeginDisabled(!m_settingsValid);
|
||||
{
|
||||
if (ImGui::Button("hex.builtin.view.find.search"_lang)) {
|
||||
this->runSearch();
|
||||
|
||||
this->m_decodeSettings = this->m_searchSettings;
|
||||
m_decodeSettings = m_searchSettings;
|
||||
}
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGuiExt::TextFormatted("hex.builtin.view.find.search.entries"_lang, this->m_foundOccurrences->size());
|
||||
ImGuiExt::TextFormatted("hex.builtin.view.find.search.entries"_lang, m_foundOccurrences->size());
|
||||
|
||||
ImGui::BeginDisabled(this->m_foundOccurrences->empty());
|
||||
ImGui::BeginDisabled(m_foundOccurrences->empty());
|
||||
{
|
||||
if (ImGui::Button("hex.builtin.view.find.search.reset"_lang)) {
|
||||
this->m_foundOccurrences->clear();
|
||||
this->m_sortedOccurrences->clear();
|
||||
this->m_occurrenceTree->clear();
|
||||
m_foundOccurrences->clear();
|
||||
m_sortedOccurrences->clear();
|
||||
m_occurrenceTree->clear();
|
||||
|
||||
EventHighlightingChanged::post();
|
||||
}
|
||||
|
|
@ -841,25 +841,25 @@ namespace hex::plugin::builtin {
|
|||
ImGui::Separator();
|
||||
ImGui::NewLine();
|
||||
|
||||
auto &currOccurrences = *this->m_sortedOccurrences;
|
||||
auto &currOccurrences = *m_sortedOccurrences;
|
||||
|
||||
ImGui::PushItemWidth(-1);
|
||||
auto prevFilterLength = this->m_currFilter->length();
|
||||
if (ImGuiExt::InputTextIcon("##filter", ICON_VS_FILTER, *this->m_currFilter)) {
|
||||
if (prevFilterLength > this->m_currFilter->length())
|
||||
*this->m_sortedOccurrences = *this->m_foundOccurrences;
|
||||
auto prevFilterLength = m_currFilter->length();
|
||||
if (ImGuiExt::InputTextIcon("##filter", ICON_VS_FILTER, *m_currFilter)) {
|
||||
if (prevFilterLength > m_currFilter->length())
|
||||
*m_sortedOccurrences = *m_foundOccurrences;
|
||||
|
||||
if (this->m_filterTask.isRunning())
|
||||
this->m_filterTask.interrupt();
|
||||
if (m_filterTask.isRunning())
|
||||
m_filterTask.interrupt();
|
||||
|
||||
if (!this->m_currFilter->empty()) {
|
||||
this->m_filterTask = TaskManager::createTask("Filtering", currOccurrences.size(), [this, provider, &currOccurrences](Task &task) {
|
||||
if (!m_currFilter->empty()) {
|
||||
m_filterTask = TaskManager::createTask("Filtering", currOccurrences.size(), [this, provider, &currOccurrences](Task &task) {
|
||||
u64 progress = 0;
|
||||
std::erase_if(currOccurrences, [this, provider, &task, &progress](const auto ®ion) {
|
||||
task.update(progress);
|
||||
progress += 1;
|
||||
|
||||
return !hex::containsIgnoreCase(this->decodeValue(provider, region), this->m_currFilter.get(provider));
|
||||
return !hex::containsIgnoreCase(this->decodeValue(provider, region), m_currFilter.get(provider));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -925,7 +925,7 @@ namespace hex::plugin::builtin {
|
|||
if (ImGui::GetIO().KeyCtrl) {
|
||||
foundItem.selected = !foundItem.selected;
|
||||
} else {
|
||||
for (auto &occurrence : *this->m_sortedOccurrences)
|
||||
for (auto &occurrence : *m_sortedOccurrences)
|
||||
occurrence.selected = false;
|
||||
foundItem.selected = true;
|
||||
ImHexApi::HexEditor::setSelection(foundItem.region.getStartAddress(), foundItem.region.getSize());
|
||||
|
|
|
|||
|
|
@ -22,19 +22,19 @@ namespace hex::plugin::builtin {
|
|||
ImGuiExt::Header(this->getUnlocalizedName(), true);
|
||||
|
||||
ImGui::PushItemWidth(-1);
|
||||
if (ImGui::InputTextMultiline("##input", this->m_input)) {
|
||||
if (ImGui::InputTextMultiline("##input", m_input)) {
|
||||
auto provider = std::make_unique<MemoryFileProvider>();
|
||||
provider->resize(this->m_input.size());
|
||||
provider->writeRaw(0x00, this->m_input.data(), this->m_input.size());
|
||||
provider->resize(m_input.size());
|
||||
provider->writeRaw(0x00, m_input.data(), m_input.size());
|
||||
|
||||
this->m_hash.reset();
|
||||
auto bytes = this->m_hash.get(Region { 0x00, provider->getActualSize() }, provider.get());
|
||||
m_hash.reset();
|
||||
auto bytes = m_hash.get(Region { 0x00, provider->getActualSize() }, provider.get());
|
||||
|
||||
this->m_result = crypt::encode16(bytes);
|
||||
m_result = crypt::encode16(bytes);
|
||||
}
|
||||
|
||||
ImGui::NewLine();
|
||||
ImGui::InputText("##result", this->m_result, ImGuiInputTextFlags_ReadOnly);
|
||||
ImGui::InputText("##result", m_result, ImGuiInputTextFlags_ReadOnly);
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Escape)))
|
||||
|
|
@ -59,7 +59,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
ViewHashes::ViewHashes() : View::Window("hex.builtin.view.hashes.name") {
|
||||
EventRegionSelected::subscribe(this, [this](const auto &providerRegion) {
|
||||
for (auto &function : this->m_hashFunctions.get(providerRegion.getProvider()))
|
||||
for (auto &function : m_hashFunctions.get(providerRegion.getProvider()))
|
||||
function.reset();
|
||||
});
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ namespace hex::plugin::builtin {
|
|||
auto selection = ImHexApi::HexEditor::getSelection();
|
||||
|
||||
if (selection.has_value() && ImGui::GetIO().KeyShift) {
|
||||
auto &hashFunctions = this->m_hashFunctions.get(selection->getProvider());
|
||||
auto &hashFunctions = m_hashFunctions.get(selection->getProvider());
|
||||
if (!hashFunctions.empty() && selection.has_value() && selection->overlaps(Region { address, size })) {
|
||||
ImGui::BeginTooltip();
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ namespace hex::plugin::builtin {
|
|||
return true;
|
||||
|
||||
auto data = nlohmann::json::parse(fileContent.begin(), fileContent.end());
|
||||
this->m_hashFunctions->clear();
|
||||
m_hashFunctions->clear();
|
||||
|
||||
return this->importHashes(provider, data);
|
||||
},
|
||||
|
|
@ -140,29 +140,29 @@ namespace hex::plugin::builtin {
|
|||
void ViewHashes::drawContent() {
|
||||
const auto &hashes = ContentRegistry::Hashes::impl::getHashes();
|
||||
|
||||
if (this->m_selectedHash == nullptr && !hashes.empty()) {
|
||||
this->m_selectedHash = hashes.front().get();
|
||||
if (m_selectedHash == nullptr && !hashes.empty()) {
|
||||
m_selectedHash = hashes.front().get();
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo("hex.builtin.view.hashes.function"_lang, this->m_selectedHash != nullptr ? Lang(this->m_selectedHash->getUnlocalizedName()) : "")) {
|
||||
if (ImGui::BeginCombo("hex.builtin.view.hashes.function"_lang, m_selectedHash != nullptr ? Lang(m_selectedHash->getUnlocalizedName()) : "")) {
|
||||
|
||||
for (const auto &hash : hashes) {
|
||||
if (ImGui::Selectable(Lang(hash->getUnlocalizedName()), this->m_selectedHash == hash.get())) {
|
||||
this->m_selectedHash = hash.get();
|
||||
this->m_newHashName.clear();
|
||||
if (ImGui::Selectable(Lang(hash->getUnlocalizedName()), m_selectedHash == hash.get())) {
|
||||
m_selectedHash = hash.get();
|
||||
m_newHashName.clear();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (this->m_newHashName.empty() && this->m_selectedHash != nullptr)
|
||||
this->m_newHashName = hex::format("{} {}", Lang(this->m_selectedHash->getUnlocalizedName()), static_cast<const char *>("hex.builtin.view.hashes.hash"_lang));
|
||||
if (m_newHashName.empty() && m_selectedHash != nullptr)
|
||||
m_newHashName = hex::format("{} {}", Lang(m_selectedHash->getUnlocalizedName()), static_cast<const char *>("hex.builtin.view.hashes.hash"_lang));
|
||||
|
||||
if (ImGui::BeginChild("##settings", ImVec2(ImGui::GetContentRegionAvail().x, 200_scaled), true)) {
|
||||
if (this->m_selectedHash != nullptr) {
|
||||
if (m_selectedHash != nullptr) {
|
||||
auto startPos = ImGui::GetCursorPosY();
|
||||
this->m_selectedHash->draw();
|
||||
m_selectedHash->draw();
|
||||
|
||||
// Check if no elements have been added
|
||||
if (startPos == ImGui::GetCursorPosY()) {
|
||||
|
|
@ -173,13 +173,13 @@ namespace hex::plugin::builtin {
|
|||
ImGui::EndChild();
|
||||
|
||||
|
||||
ImGuiExt::InputTextIcon("##hash_name", ICON_VS_SYMBOL_KEY, this->m_newHashName);
|
||||
ImGuiExt::InputTextIcon("##hash_name", ICON_VS_SYMBOL_KEY, m_newHashName);
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginDisabled(this->m_newHashName.empty() || this->m_selectedHash == nullptr);
|
||||
ImGui::BeginDisabled(m_newHashName.empty() || m_selectedHash == nullptr);
|
||||
if (ImGuiExt::IconButton(ICON_VS_ADD, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
|
||||
if (this->m_selectedHash != nullptr) {
|
||||
this->m_hashFunctions->push_back(this->m_selectedHash->create(this->m_newHashName));
|
||||
if (m_selectedHash != nullptr) {
|
||||
m_hashFunctions->push_back(m_selectedHash->create(m_newHashName));
|
||||
AchievementManager::unlockAchievement("hex.builtin.achievement.misc", "hex.builtin.achievement.misc.create_hash.name");
|
||||
}
|
||||
}
|
||||
|
|
@ -200,8 +200,8 @@ namespace hex::plugin::builtin {
|
|||
auto selection = ImHexApi::HexEditor::getSelection();
|
||||
|
||||
std::optional<u32> indexToRemove;
|
||||
for (u32 i = 0; i < this->m_hashFunctions->size(); i++) {
|
||||
auto &function = (*this->m_hashFunctions)[i];
|
||||
for (u32 i = 0; i < m_hashFunctions->size(); i++) {
|
||||
auto &function = (*m_hashFunctions)[i];
|
||||
|
||||
ImGui::PushID(i);
|
||||
|
||||
|
|
@ -242,7 +242,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
if (indexToRemove.has_value()) {
|
||||
this->m_hashFunctions->erase(this->m_hashFunctions->begin() + indexToRemove.value());
|
||||
m_hashFunctions->erase(m_hashFunctions->begin() + indexToRemove.value());
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
|
|
@ -265,7 +265,7 @@ namespace hex::plugin::builtin {
|
|||
auto newFunction = newHash->create(hash["name"]);
|
||||
newFunction.getType()->load(hash["settings"]);
|
||||
|
||||
this->m_hashFunctions.get(provider).push_back(std::move(newFunction));
|
||||
m_hashFunctions.get(provider).push_back(std::move(newFunction));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -277,7 +277,7 @@ namespace hex::plugin::builtin {
|
|||
bool ViewHashes::exportHashes(prv::Provider *provider, nlohmann::json &json) {
|
||||
json["hashes"] = nlohmann::json::array();
|
||||
size_t index = 0;
|
||||
for (const auto &hashFunction : this->m_hashFunctions.get(provider)) {
|
||||
for (const auto &hashFunction : m_hashFunctions.get(provider)) {
|
||||
json["hashes"][index] = {
|
||||
{ "name", hashFunction.getName() },
|
||||
{ "type", hashFunction.getType()->getUnlocalizedName() },
|
||||
|
|
|
|||
|
|
@ -30,39 +30,39 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.file.goto"_lang);
|
||||
if (ImGui::BeginTabBar("goto_tabs")) {
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.goto.offset.absolute"_lang)) {
|
||||
this->m_mode = Mode::Absolute;
|
||||
m_mode = Mode::Absolute;
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
ImGui::BeginDisabled(!editor->isSelectionValid());
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.goto.offset.relative"_lang)) {
|
||||
this->m_mode = Mode::Relative;
|
||||
m_mode = Mode::Relative;
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.goto.offset.begin"_lang)) {
|
||||
this->m_mode = Mode::Begin;
|
||||
m_mode = Mode::Begin;
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.goto.offset.end"_lang)) {
|
||||
this->m_mode = Mode::End;
|
||||
m_mode = Mode::End;
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (this->m_requestFocus){
|
||||
if (m_requestFocus){
|
||||
ImGui::SetKeyboardFocusHere();
|
||||
this->m_requestFocus = false;
|
||||
m_requestFocus = false;
|
||||
}
|
||||
if (ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_OPERATOR, this->m_input, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
|
||||
if (auto result = this->m_evaluator.evaluate(this->m_input); result.has_value()) {
|
||||
if (ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_OPERATOR, m_input, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
|
||||
if (auto result = m_evaluator.evaluate(m_input); result.has_value()) {
|
||||
const auto inputResult = result.value();
|
||||
u64 newAddress = 0x00;
|
||||
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
|
||||
switch (this->m_mode) {
|
||||
switch (m_mode) {
|
||||
case Mode::Absolute: {
|
||||
newAddress = inputResult;
|
||||
}
|
||||
|
|
@ -115,34 +115,34 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.file.select"_lang);
|
||||
if (ImGui::BeginTabBar("select_tabs")) {
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.select.offset.region"_lang)) {
|
||||
u64 inputA = this->m_region.getStartAddress();
|
||||
u64 inputB = this->m_region.getEndAddress();
|
||||
u64 inputA = m_region.getStartAddress();
|
||||
u64 inputB = m_region.getEndAddress();
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.view.hex_editor.select.offset.begin"_lang, &inputA, ImGuiInputTextFlags_AutoSelectAll);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.view.hex_editor.select.offset.end"_lang, &inputB, ImGuiInputTextFlags_AutoSelectAll);
|
||||
|
||||
if (inputB < inputA)
|
||||
inputB = inputA;
|
||||
|
||||
this->m_region = { inputA, (inputB - inputA) + 1 };
|
||||
m_region = { inputA, (inputB - inputA) + 1 };
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.select.offset.size"_lang)) {
|
||||
u64 inputA = this->m_region.getStartAddress();
|
||||
u64 inputB = this->m_region.getSize();
|
||||
u64 inputA = m_region.getStartAddress();
|
||||
u64 inputB = m_region.getSize();
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.view.hex_editor.select.offset.begin"_lang, &inputA, ImGuiInputTextFlags_AutoSelectAll);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.view.hex_editor.select.offset.size"_lang, &inputB, ImGuiInputTextFlags_AutoSelectAll);
|
||||
|
||||
if (inputB <= 0)
|
||||
inputB = 1;
|
||||
|
||||
this->m_region = { inputA, inputB };
|
||||
m_region = { inputA, inputB };
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::Button("hex.builtin.view.hex_editor.select.select"_lang) || (ImGui::IsItemFocused() && (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_Enter)))) {
|
||||
editor->setSelection(this->m_region.getStartAddress(), this->m_region.getEndAddress());
|
||||
editor->setSelection(m_region.getStartAddress(), m_region.getEndAddress());
|
||||
editor->jumpToSelection();
|
||||
}
|
||||
|
||||
|
|
@ -158,8 +158,8 @@ namespace hex::plugin::builtin {
|
|||
public:
|
||||
PopupFind() {
|
||||
EventRegionSelected::subscribe(this, [this](Region region) {
|
||||
this->m_searchPosition = this->m_nextSearchPosition.value_or(region.getStartAddress());
|
||||
this->m_nextSearchPosition.reset();
|
||||
m_searchPosition = m_nextSearchPosition.value_or(region.getStartAddress());
|
||||
m_nextSearchPosition.reset();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -173,35 +173,35 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.file.search"_lang);
|
||||
if (ImGui::BeginTabBar("##find_tabs")) {
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.search.hex"_lang)) {
|
||||
if (ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_NUMERIC, this->m_input, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_CharsHexadecimal)) {
|
||||
if (!this->m_input.empty()) {
|
||||
this->m_shouldSearch = true;
|
||||
this->m_backwards = false;
|
||||
if (ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_NUMERIC, m_input, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_CharsHexadecimal)) {
|
||||
if (!m_input.empty()) {
|
||||
m_shouldSearch = true;
|
||||
m_backwards = false;
|
||||
}
|
||||
}
|
||||
|
||||
this->drawButtons();
|
||||
|
||||
if (this->m_shouldSearch) {
|
||||
searchSequence = crypt::decode16(this->m_input);
|
||||
if (m_shouldSearch) {
|
||||
searchSequence = crypt::decode16(m_input);
|
||||
}
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.search.string"_lang)) {
|
||||
if (ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_KEY, this->m_input, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
|
||||
if (!this->m_input.empty()) {
|
||||
this->m_shouldSearch = true;
|
||||
this->m_backwards = false;
|
||||
if (ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_KEY, m_input, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
|
||||
if (!m_input.empty()) {
|
||||
m_shouldSearch = true;
|
||||
m_backwards = false;
|
||||
}
|
||||
}
|
||||
|
||||
this->drawButtons();
|
||||
|
||||
if (this->m_shouldSearch) {
|
||||
if (m_shouldSearch) {
|
||||
searchSequence.clear();
|
||||
std::copy(this->m_input.begin(), this->m_input.end(), std::back_inserter(searchSequence));
|
||||
std::copy(m_input.begin(), m_input.end(), std::back_inserter(searchSequence));
|
||||
|
||||
if (!searchSequence.empty() && searchSequence.back() == 0x00)
|
||||
searchSequence.pop_back();
|
||||
|
|
@ -213,16 +213,16 @@ namespace hex::plugin::builtin {
|
|||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
if (!this->m_searchTask.isRunning() && !searchSequence.empty() && this->m_shouldSearch) {
|
||||
this->m_searchTask = TaskManager::createTask("hex.builtin.common.processing", ImHexApi::Provider::get()->getActualSize(), [this, editor, searchSequence](auto &) {
|
||||
if (!m_searchTask.isRunning() && !searchSequence.empty() && m_shouldSearch) {
|
||||
m_searchTask = TaskManager::createTask("hex.builtin.common.processing", ImHexApi::Provider::get()->getActualSize(), [this, editor, searchSequence](auto &) {
|
||||
for (u8 retry = 0; retry < 2; retry++) {
|
||||
auto region = this->findSequence(searchSequence, this->m_backwards);
|
||||
auto region = this->findSequence(searchSequence, m_backwards);
|
||||
|
||||
if (region.has_value()) {
|
||||
if (editor->getSelection() == region) {
|
||||
if (this->m_nextSearchPosition.has_value())
|
||||
this->m_searchPosition = this->m_nextSearchPosition.value();
|
||||
this->m_nextSearchPosition.reset();
|
||||
if (m_nextSearchPosition.has_value())
|
||||
m_searchPosition = m_nextSearchPosition.value();
|
||||
m_nextSearchPosition.reset();
|
||||
} else {
|
||||
TaskManager::doLater([editor, region]{
|
||||
editor->setSelection(region->getStartAddress(), region->getEndAddress());
|
||||
|
|
@ -232,12 +232,12 @@ namespace hex::plugin::builtin {
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
this->m_reachedEnd = true;
|
||||
m_reachedEnd = true;
|
||||
}
|
||||
}
|
||||
|
||||
this->m_shouldSearch = false;
|
||||
this->m_requestFocus = true;
|
||||
m_shouldSearch = false;
|
||||
m_requestFocus = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -247,42 +247,42 @@ namespace hex::plugin::builtin {
|
|||
const auto ButtonSize = ImVec2(ImGui::CalcTextSize(ICON_VS_SEARCH).x, ImGui::GetTextLineHeight()) + ImGui::GetStyle().CellPadding * 2;
|
||||
const auto ButtonColor = ImGui::GetStyleColorVec4(ImGuiCol_Text);
|
||||
|
||||
if (this->m_requestFocus) {
|
||||
if (m_requestFocus) {
|
||||
ImGui::SetKeyboardFocusHere(-1);
|
||||
this->m_requestFocus = false;
|
||||
m_requestFocus = false;
|
||||
}
|
||||
|
||||
ImGui::BeginDisabled(this->m_searchTask.isRunning());
|
||||
ImGui::BeginDisabled(m_searchTask.isRunning());
|
||||
{
|
||||
ImGui::SameLine();
|
||||
if (ImGuiExt::IconButton(ICON_VS_SEARCH "##search", ButtonColor, ButtonSize)) {
|
||||
this->m_shouldSearch = true;
|
||||
this->m_backwards = false;
|
||||
this->m_reachedEnd = false;
|
||||
this->m_searchPosition.reset();
|
||||
this->m_nextSearchPosition.reset();
|
||||
m_shouldSearch = true;
|
||||
m_backwards = false;
|
||||
m_reachedEnd = false;
|
||||
m_searchPosition.reset();
|
||||
m_nextSearchPosition.reset();
|
||||
}
|
||||
|
||||
ImGui::BeginDisabled(!this->m_searchPosition.has_value());
|
||||
ImGui::BeginDisabled(!m_searchPosition.has_value());
|
||||
{
|
||||
ImGui::BeginDisabled(this->m_reachedEnd && this->m_backwards);
|
||||
ImGui::BeginDisabled(m_reachedEnd && m_backwards);
|
||||
{
|
||||
if (ImGuiExt::IconButton(ICON_VS_ARROW_UP "##up", ButtonColor, ButtonSize)) {
|
||||
this->m_shouldSearch = true;
|
||||
this->m_backwards = true;
|
||||
this->m_reachedEnd = false;
|
||||
m_shouldSearch = true;
|
||||
m_backwards = true;
|
||||
m_reachedEnd = false;
|
||||
}
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginDisabled(this->m_reachedEnd && !this->m_backwards);
|
||||
ImGui::BeginDisabled(m_reachedEnd && !m_backwards);
|
||||
{
|
||||
if (ImGuiExt::IconButton(ICON_VS_ARROW_DOWN "##down", ButtonColor, ButtonSize)) {
|
||||
this->m_shouldSearch = true;
|
||||
this->m_backwards = false;
|
||||
this->m_reachedEnd = false;
|
||||
m_shouldSearch = true;
|
||||
m_backwards = false;
|
||||
m_reachedEnd = false;
|
||||
}
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
|
@ -298,7 +298,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
prv::ProviderReader reader(provider);
|
||||
|
||||
reader.seek(this->m_searchPosition.value_or(provider->getBaseAddress()));
|
||||
reader.seek(m_searchPosition.value_or(provider->getBaseAddress()));
|
||||
|
||||
constexpr static auto searchFunction = [](const auto &haystackBegin, const auto &haystackEnd, const auto &needleBegin, const auto &needleEnd) {
|
||||
return std::search(haystackBegin, haystackEnd, std::boyer_moore_horspool_searcher(needleBegin, needleEnd));
|
||||
|
|
@ -307,16 +307,16 @@ namespace hex::plugin::builtin {
|
|||
if (!backwards) {
|
||||
auto occurrence = searchFunction(reader.begin(), reader.end(), sequence.begin(), sequence.end());
|
||||
if (occurrence != reader.end()) {
|
||||
this->m_nextSearchPosition = occurrence.getAddress() + sequence.size();
|
||||
m_nextSearchPosition = occurrence.getAddress() + sequence.size();
|
||||
return Region { occurrence.getAddress(), sequence.size() };
|
||||
}
|
||||
} else {
|
||||
auto occurrence = searchFunction(reader.rbegin(), reader.rend(), sequence.rbegin(), sequence.rend());
|
||||
if (occurrence != reader.rend()) {
|
||||
if (occurrence.getAddress() < sequence.size())
|
||||
this->m_nextSearchPosition = 0x00;
|
||||
m_nextSearchPosition = 0x00;
|
||||
else
|
||||
this->m_nextSearchPosition = occurrence.getAddress() - sequence.size();
|
||||
m_nextSearchPosition = occurrence.getAddress() - sequence.size();
|
||||
|
||||
return Region { occurrence.getAddress() - (sequence.size() - 1), sequence.size() };
|
||||
}
|
||||
|
|
@ -343,15 +343,15 @@ namespace hex::plugin::builtin {
|
|||
void draw(ViewHexEditor *editor) override {
|
||||
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.set_base"_lang);
|
||||
|
||||
ImGuiExt::InputHexadecimal("##base_address", &this->m_baseAddress);
|
||||
ImGuiExt::InputHexadecimal("##base_address", &m_baseAddress);
|
||||
if (ImGui::IsItemFocused() && (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter))) {
|
||||
setBaseAddress(this->m_baseAddress);
|
||||
setBaseAddress(m_baseAddress);
|
||||
editor->closePopup();
|
||||
}
|
||||
|
||||
ImGuiExt::ConfirmButtons("hex.builtin.common.set"_lang, "hex.builtin.common.cancel"_lang,
|
||||
[&, this]{
|
||||
setBaseAddress(this->m_baseAddress);
|
||||
setBaseAddress(m_baseAddress);
|
||||
editor->closePopup();
|
||||
},
|
||||
[&]{
|
||||
|
|
@ -377,15 +377,15 @@ namespace hex::plugin::builtin {
|
|||
void draw(ViewHexEditor *editor) override {
|
||||
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.set_page_size"_lang);
|
||||
|
||||
ImGuiExt::InputHexadecimal("##page_size", &this->m_pageSize);
|
||||
ImGuiExt::InputHexadecimal("##page_size", &m_pageSize);
|
||||
if (ImGui::IsItemFocused() && (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter))) {
|
||||
setPageSize(this->m_pageSize);
|
||||
setPageSize(m_pageSize);
|
||||
editor->closePopup();
|
||||
}
|
||||
|
||||
ImGuiExt::ConfirmButtons("hex.builtin.common.set"_lang, "hex.builtin.common.cancel"_lang,
|
||||
[&, this]{
|
||||
setPageSize(this->m_pageSize);
|
||||
setPageSize(m_pageSize);
|
||||
editor->closePopup();
|
||||
},
|
||||
[&]{
|
||||
|
|
@ -415,15 +415,15 @@ namespace hex::plugin::builtin {
|
|||
void draw(ViewHexEditor *editor) override {
|
||||
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.resize"_lang);
|
||||
|
||||
ImGuiExt::InputHexadecimal("##resize", &this->m_size);
|
||||
ImGuiExt::InputHexadecimal("##resize", &m_size);
|
||||
if (ImGui::IsItemFocused() && (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter))) {
|
||||
this->resize(this->m_size);
|
||||
this->resize(m_size);
|
||||
editor->closePopup();
|
||||
}
|
||||
|
||||
ImGuiExt::ConfirmButtons("hex.builtin.common.set"_lang, "hex.builtin.common.cancel"_lang,
|
||||
[&, this]{
|
||||
this->resize(this->m_size);
|
||||
this->resize(m_size);
|
||||
editor->closePopup();
|
||||
},
|
||||
[&]{
|
||||
|
|
@ -448,12 +448,12 @@ namespace hex::plugin::builtin {
|
|||
void draw(ViewHexEditor *editor) override {
|
||||
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.insert"_lang);
|
||||
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.common.address"_lang, &this->m_address);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.common.size"_lang, &this->m_size);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.common.address"_lang, &m_address);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.common.size"_lang, &m_size);
|
||||
|
||||
ImGuiExt::ConfirmButtons("hex.builtin.common.set"_lang, "hex.builtin.common.cancel"_lang,
|
||||
[&, this]{
|
||||
insert(this->m_address, this->m_size);
|
||||
insert(m_address, m_size);
|
||||
editor->closePopup();
|
||||
},
|
||||
[&]{
|
||||
|
|
@ -479,12 +479,12 @@ namespace hex::plugin::builtin {
|
|||
void draw(ViewHexEditor *editor) override {
|
||||
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.remove"_lang);
|
||||
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.common.address"_lang, &this->m_address);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.common.size"_lang, &this->m_size);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.common.address"_lang, &m_address);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.common.size"_lang, &m_size);
|
||||
|
||||
ImGuiExt::ConfirmButtons("hex.builtin.common.set"_lang, "hex.builtin.common.cancel"_lang,
|
||||
[&, this]{
|
||||
remove(this->m_address, this->m_size);
|
||||
remove(m_address, m_size);
|
||||
editor->closePopup();
|
||||
},
|
||||
[&]{
|
||||
|
|
@ -510,16 +510,16 @@ namespace hex::plugin::builtin {
|
|||
void draw(ViewHexEditor *editor) override {
|
||||
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.fill"_lang);
|
||||
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.common.address"_lang, &this->m_address);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.common.size"_lang, &this->m_size);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.common.address"_lang, &m_address);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.common.size"_lang, &m_size);
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGuiExt::InputTextIcon("hex.builtin.common.bytes"_lang, ICON_VS_SYMBOL_NAMESPACE, this->m_input);
|
||||
ImGuiExt::InputTextIcon("hex.builtin.common.bytes"_lang, ICON_VS_SYMBOL_NAMESPACE, m_input);
|
||||
|
||||
ImGuiExt::ConfirmButtons("hex.builtin.common.set"_lang, "hex.builtin.common.cancel"_lang,
|
||||
[&, this] {
|
||||
fill(this->m_address, this->m_size, this->m_input);
|
||||
fill(m_address, m_size, m_input);
|
||||
editor->closePopup();
|
||||
},
|
||||
[&] {
|
||||
|
|
@ -558,8 +558,8 @@ namespace hex::plugin::builtin {
|
|||
/* Hex Editor */
|
||||
|
||||
ViewHexEditor::ViewHexEditor() : View::Window("hex.builtin.view.hex_editor.name") {
|
||||
this->m_hexEditor.setForegroundHighlightCallback([this](u64 address, const u8 *data, size_t size) -> std::optional<color_t> {
|
||||
if (auto highlight = this->m_foregroundHighlights->find(address); highlight != this->m_foregroundHighlights->end())
|
||||
m_hexEditor.setForegroundHighlightCallback([this](u64 address, const u8 *data, size_t size) -> std::optional<color_t> {
|
||||
if (auto highlight = m_foregroundHighlights->find(address); highlight != m_foregroundHighlights->end())
|
||||
return highlight->second;
|
||||
|
||||
std::optional<color_t> result;
|
||||
|
|
@ -576,13 +576,13 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
if (result.has_value())
|
||||
this->m_foregroundHighlights->insert({ address, result.value() });
|
||||
m_foregroundHighlights->insert({ address, result.value() });
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
this->m_hexEditor.setBackgroundHighlightCallback([this](u64 address, const u8 *data, size_t size) -> std::optional<color_t> {
|
||||
if (auto highlight = this->m_backgroundHighlights->find(address); highlight != this->m_backgroundHighlights->end())
|
||||
m_hexEditor.setBackgroundHighlightCallback([this](u64 address, const u8 *data, size_t size) -> std::optional<color_t> {
|
||||
if (auto highlight = m_backgroundHighlights->find(address); highlight != m_backgroundHighlights->end())
|
||||
return highlight->second;
|
||||
|
||||
std::optional<color_t> result;
|
||||
|
|
@ -599,12 +599,12 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
if (result.has_value())
|
||||
this->m_backgroundHighlights->insert({ address, result.value() });
|
||||
m_backgroundHighlights->insert({ address, result.value() });
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
this->m_hexEditor.setTooltipCallback([](u64 address, const u8 *data, size_t size) {
|
||||
m_hexEditor.setTooltipCallback([](u64 address, const u8 *data, size_t size) {
|
||||
for (const auto &[id, callback] : ImHexApi::HexEditor::impl::getTooltipFunctions()) {
|
||||
callback(address, data, size);
|
||||
}
|
||||
|
|
@ -644,8 +644,8 @@ namespace hex::plugin::builtin {
|
|||
|
||||
void ViewHexEditor::drawPopup() {
|
||||
// Popup windows
|
||||
if (this->m_shouldOpenPopup) {
|
||||
this->m_shouldOpenPopup = false;
|
||||
if (m_shouldOpenPopup) {
|
||||
m_shouldOpenPopup = false;
|
||||
ImGui::OpenPopup("##hex_editor_popup");
|
||||
}
|
||||
|
||||
|
|
@ -663,8 +663,8 @@ namespace hex::plugin::builtin {
|
|||
justOpened = false;
|
||||
}
|
||||
|
||||
if (this->m_currPopup != nullptr)
|
||||
this->m_currPopup->draw(this);
|
||||
if (m_currPopup != nullptr)
|
||||
m_currPopup->draw(this);
|
||||
else
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
|
|
@ -680,9 +680,9 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
void ViewHexEditor::drawContent() {
|
||||
this->m_hexEditor.setProvider(ImHexApi::Provider::get());
|
||||
m_hexEditor.setProvider(ImHexApi::Provider::get());
|
||||
|
||||
this->m_hexEditor.draw();
|
||||
m_hexEditor.draw();
|
||||
|
||||
this->drawPopup();
|
||||
}
|
||||
|
|
@ -771,185 +771,185 @@ namespace hex::plugin::builtin {
|
|||
// Remove selection
|
||||
ShortcutManager::addShortcut(this, Keys::Escape, "hex.builtin.view.hex_editor.shortcut.remove_selection", [this] {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
this->m_selectionStart->reset();
|
||||
this->m_selectionEnd->reset();
|
||||
m_selectionStart->reset();
|
||||
m_selectionEnd->reset();
|
||||
|
||||
this->m_hexEditor.setSelectionUnchecked(std::nullopt, std::nullopt);
|
||||
m_hexEditor.setSelectionUnchecked(std::nullopt, std::nullopt);
|
||||
|
||||
EventRegionSelected::post(ImHexApi::HexEditor::ProviderRegion{ Region::Invalid(), provider });
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, Keys::Enter, "hex.builtin.view.hex_editor.shortcut.enter_editing", [this] {
|
||||
if (auto cursor = this->m_hexEditor.getCursorPosition(); cursor.has_value())
|
||||
this->m_hexEditor.setEditingAddress(cursor.value());
|
||||
if (auto cursor = m_hexEditor.getCursorPosition(); cursor.has_value())
|
||||
m_hexEditor.setEditingAddress(cursor.value());
|
||||
});
|
||||
|
||||
// Move cursor around
|
||||
ShortcutManager::addShortcut(this, Keys::Up, "hex.builtin.view.hex_editor.shortcut.cursor_up", [this] {
|
||||
auto selection = getSelection();
|
||||
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||
auto cursor = m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||
|
||||
if (cursor >= this->m_hexEditor.getBytesPerRow()) {
|
||||
auto pos = cursor - this->m_hexEditor.getBytesPerRow();
|
||||
if (cursor >= m_hexEditor.getBytesPerRow()) {
|
||||
auto pos = cursor - m_hexEditor.getBytesPerRow();
|
||||
this->setSelection(pos, pos);
|
||||
this->m_hexEditor.scrollToSelection();
|
||||
this->m_hexEditor.jumpIfOffScreen();
|
||||
m_hexEditor.scrollToSelection();
|
||||
m_hexEditor.jumpIfOffScreen();
|
||||
}
|
||||
});
|
||||
ShortcutManager::addShortcut(this, Keys::Down, "hex.builtin.view.hex_editor.shortcut.cursor_down", [this] {
|
||||
auto selection = getSelection();
|
||||
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||
auto cursor = m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||
|
||||
auto pos = cursor + this->m_hexEditor.getBytesPerRow();
|
||||
auto pos = cursor + m_hexEditor.getBytesPerRow();
|
||||
this->setSelection(pos, pos);
|
||||
this->m_hexEditor.scrollToSelection();
|
||||
this->m_hexEditor.jumpIfOffScreen();
|
||||
m_hexEditor.scrollToSelection();
|
||||
m_hexEditor.jumpIfOffScreen();
|
||||
});
|
||||
ShortcutManager::addShortcut(this, Keys::Left, "hex.builtin.view.hex_editor.shortcut.cursor_left", [this] {
|
||||
auto selection = getSelection();
|
||||
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||
auto cursor = m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||
|
||||
if (cursor > 0) {
|
||||
auto pos = cursor - this->m_hexEditor.getBytesPerCell();
|
||||
auto pos = cursor - m_hexEditor.getBytesPerCell();
|
||||
this->setSelection(pos, pos);
|
||||
this->m_hexEditor.scrollToSelection();
|
||||
this->m_hexEditor.jumpIfOffScreen();
|
||||
m_hexEditor.scrollToSelection();
|
||||
m_hexEditor.jumpIfOffScreen();
|
||||
}
|
||||
});
|
||||
ShortcutManager::addShortcut(this, Keys::Right, "hex.builtin.view.hex_editor.shortcut.cursor_right", [this] {
|
||||
auto selection = getSelection();
|
||||
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||
auto cursor = m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||
|
||||
auto pos = cursor + this->m_hexEditor.getBytesPerCell();
|
||||
auto pos = cursor + m_hexEditor.getBytesPerCell();
|
||||
this->setSelection(pos, pos);
|
||||
this->m_hexEditor.scrollToSelection();
|
||||
this->m_hexEditor.jumpIfOffScreen();
|
||||
m_hexEditor.scrollToSelection();
|
||||
m_hexEditor.jumpIfOffScreen();
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, Keys::PageUp, "hex.builtin.view.hex_editor.shortcut.cursor_page_up", [this] {
|
||||
auto selection = getSelection();
|
||||
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||
auto cursor = m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||
|
||||
u64 visibleByteCount = this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount();
|
||||
u64 visibleByteCount = m_hexEditor.getBytesPerRow() * m_hexEditor.getVisibleRowCount();
|
||||
if (cursor >= visibleByteCount) {
|
||||
auto pos = cursor - visibleByteCount;
|
||||
this->setSelection(pos, (pos + this->m_hexEditor.getBytesPerCell()) - 1);
|
||||
this->m_hexEditor.scrollToSelection();
|
||||
this->m_hexEditor.jumpIfOffScreen();
|
||||
this->setSelection(pos, (pos + m_hexEditor.getBytesPerCell()) - 1);
|
||||
m_hexEditor.scrollToSelection();
|
||||
m_hexEditor.jumpIfOffScreen();
|
||||
}
|
||||
});
|
||||
ShortcutManager::addShortcut(this, Keys::PageDown, "hex.builtin.view.hex_editor.shortcut.cursor_page_down", [this] {
|
||||
auto selection = getSelection();
|
||||
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||
auto cursor = m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||
|
||||
auto pos = cursor + (this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount());
|
||||
this->setSelection(pos, (pos + this->m_hexEditor.getBytesPerCell()) - 1);
|
||||
this->m_hexEditor.scrollToSelection();
|
||||
this->m_hexEditor.jumpIfOffScreen();
|
||||
auto pos = cursor + (m_hexEditor.getBytesPerRow() * m_hexEditor.getVisibleRowCount());
|
||||
this->setSelection(pos, (pos + m_hexEditor.getBytesPerCell()) - 1);
|
||||
m_hexEditor.scrollToSelection();
|
||||
m_hexEditor.jumpIfOffScreen();
|
||||
});
|
||||
|
||||
// Move selection around
|
||||
ShortcutManager::addShortcut(this, SHIFT + Keys::Up, "hex.builtin.view.hex_editor.shortcut.selection_up", [this] {
|
||||
auto selection = getSelection();
|
||||
auto cursor = this->m_hexEditor.getCursorPosition();
|
||||
auto cursor = m_hexEditor.getCursorPosition();
|
||||
|
||||
if (cursor != selection.getStartAddress()) {
|
||||
auto newCursor = std::max<u64>(cursor.value_or(selection.getEndAddress()), this->m_hexEditor.getBytesPerRow()) - this->m_hexEditor.getBytesPerRow();
|
||||
auto newCursor = std::max<u64>(cursor.value_or(selection.getEndAddress()), m_hexEditor.getBytesPerRow()) - m_hexEditor.getBytesPerRow();
|
||||
setSelection(selection.getStartAddress(), newCursor);
|
||||
this->m_hexEditor.setCursorPosition(newCursor);
|
||||
m_hexEditor.setCursorPosition(newCursor);
|
||||
} else {
|
||||
auto newCursor = std::max<u64>(cursor.value_or(selection.getEndAddress()), this->m_hexEditor.getBytesPerRow()) - this->m_hexEditor.getBytesPerRow();
|
||||
auto newCursor = std::max<u64>(cursor.value_or(selection.getEndAddress()), m_hexEditor.getBytesPerRow()) - m_hexEditor.getBytesPerRow();
|
||||
setSelection(newCursor, selection.getEndAddress());
|
||||
this->m_hexEditor.setCursorPosition(newCursor);
|
||||
m_hexEditor.setCursorPosition(newCursor);
|
||||
}
|
||||
|
||||
this->m_hexEditor.scrollToSelection();
|
||||
this->m_hexEditor.jumpIfOffScreen();
|
||||
m_hexEditor.scrollToSelection();
|
||||
m_hexEditor.jumpIfOffScreen();
|
||||
});
|
||||
ShortcutManager::addShortcut(this, SHIFT + Keys::Down, "hex.builtin.view.hex_editor.shortcut.selection_down", [this] {
|
||||
auto selection = getSelection();
|
||||
auto cursor = this->m_hexEditor.getCursorPosition();
|
||||
auto cursor = m_hexEditor.getCursorPosition();
|
||||
|
||||
if (cursor != selection.getStartAddress()) {
|
||||
auto newCursor = cursor.value_or(selection.getEndAddress()) + this->m_hexEditor.getBytesPerRow();
|
||||
auto newCursor = cursor.value_or(selection.getEndAddress()) + m_hexEditor.getBytesPerRow();
|
||||
setSelection(selection.getStartAddress(), newCursor);
|
||||
this->m_hexEditor.setCursorPosition(newCursor);
|
||||
m_hexEditor.setCursorPosition(newCursor);
|
||||
} else {
|
||||
auto newCursor = cursor.value_or(selection.getEndAddress()) + this->m_hexEditor.getBytesPerRow();
|
||||
auto newCursor = cursor.value_or(selection.getEndAddress()) + m_hexEditor.getBytesPerRow();
|
||||
setSelection(newCursor, selection.getEndAddress());
|
||||
this->m_hexEditor.setCursorPosition(newCursor);
|
||||
m_hexEditor.setCursorPosition(newCursor);
|
||||
}
|
||||
|
||||
this->m_hexEditor.scrollToSelection();
|
||||
this->m_hexEditor.jumpIfOffScreen();
|
||||
m_hexEditor.scrollToSelection();
|
||||
m_hexEditor.jumpIfOffScreen();
|
||||
});
|
||||
ShortcutManager::addShortcut(this, SHIFT + Keys::Left, "hex.builtin.view.hex_editor.shortcut.selection_left", [this] {
|
||||
auto selection = getSelection();
|
||||
auto cursor = this->m_hexEditor.getCursorPosition();
|
||||
auto cursor = m_hexEditor.getCursorPosition();
|
||||
|
||||
if (cursor != selection.getStartAddress()) {
|
||||
auto newCursor = cursor.value_or(selection.getEndAddress()) - this->m_hexEditor.getBytesPerCell();
|
||||
auto newCursor = cursor.value_or(selection.getEndAddress()) - m_hexEditor.getBytesPerCell();
|
||||
setSelection(selection.getStartAddress(), newCursor);
|
||||
this->m_hexEditor.setCursorPosition(newCursor);
|
||||
m_hexEditor.setCursorPosition(newCursor);
|
||||
} else {
|
||||
auto newCursor = cursor.value_or(selection.getEndAddress()) - this->m_hexEditor.getBytesPerCell();
|
||||
auto newCursor = cursor.value_or(selection.getEndAddress()) - m_hexEditor.getBytesPerCell();
|
||||
setSelection(newCursor, selection.getEndAddress());
|
||||
this->m_hexEditor.setCursorPosition(newCursor);
|
||||
m_hexEditor.setCursorPosition(newCursor);
|
||||
}
|
||||
|
||||
this->m_hexEditor.scrollToSelection();
|
||||
this->m_hexEditor.jumpIfOffScreen();
|
||||
m_hexEditor.scrollToSelection();
|
||||
m_hexEditor.jumpIfOffScreen();
|
||||
});
|
||||
ShortcutManager::addShortcut(this, SHIFT + Keys::Right, "hex.builtin.view.hex_editor.shortcut.selection_right", [this] {
|
||||
auto selection = getSelection();
|
||||
auto cursor = this->m_hexEditor.getCursorPosition();
|
||||
auto cursor = m_hexEditor.getCursorPosition();
|
||||
|
||||
if (cursor != selection.getStartAddress()) {
|
||||
auto newCursor = cursor.value_or(selection.getEndAddress()) + this->m_hexEditor.getBytesPerCell();
|
||||
auto newCursor = cursor.value_or(selection.getEndAddress()) + m_hexEditor.getBytesPerCell();
|
||||
setSelection(selection.getStartAddress(), newCursor);
|
||||
this->m_hexEditor.setCursorPosition(newCursor);
|
||||
m_hexEditor.setCursorPosition(newCursor);
|
||||
} else {
|
||||
auto newCursor = cursor.value_or(selection.getEndAddress()) + this->m_hexEditor.getBytesPerCell();
|
||||
auto newCursor = cursor.value_or(selection.getEndAddress()) + m_hexEditor.getBytesPerCell();
|
||||
setSelection(newCursor, selection.getEndAddress());
|
||||
this->m_hexEditor.setCursorPosition(newCursor);
|
||||
m_hexEditor.setCursorPosition(newCursor);
|
||||
}
|
||||
|
||||
this->m_hexEditor.scrollToSelection();
|
||||
this->m_hexEditor.jumpIfOffScreen();
|
||||
m_hexEditor.scrollToSelection();
|
||||
m_hexEditor.jumpIfOffScreen();
|
||||
});
|
||||
ShortcutManager::addShortcut(this, SHIFT + Keys::PageUp, "hex.builtin.view.hex_editor.shortcut.selection_page_up", [this] {
|
||||
auto selection = getSelection();
|
||||
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||
auto cursor = m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||
|
||||
if (cursor != selection.getStartAddress()) {
|
||||
auto newCursor = std::max<u64>(cursor, this->m_hexEditor.getBytesPerRow()) - this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount();
|
||||
auto newCursor = std::max<u64>(cursor, m_hexEditor.getBytesPerRow()) - m_hexEditor.getBytesPerRow() * m_hexEditor.getVisibleRowCount();
|
||||
setSelection(selection.getStartAddress(), newCursor);
|
||||
this->m_hexEditor.setCursorPosition(newCursor);
|
||||
m_hexEditor.setCursorPosition(newCursor);
|
||||
} else {
|
||||
auto newCursor = std::max<u64>(cursor, this->m_hexEditor.getBytesPerRow()) - this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount();
|
||||
auto newCursor = std::max<u64>(cursor, m_hexEditor.getBytesPerRow()) - m_hexEditor.getBytesPerRow() * m_hexEditor.getVisibleRowCount();
|
||||
setSelection(newCursor, selection.getEndAddress());
|
||||
this->m_hexEditor.setCursorPosition(newCursor);
|
||||
m_hexEditor.setCursorPosition(newCursor);
|
||||
}
|
||||
|
||||
this->m_hexEditor.scrollToSelection();
|
||||
this->m_hexEditor.jumpIfOffScreen();
|
||||
m_hexEditor.scrollToSelection();
|
||||
m_hexEditor.jumpIfOffScreen();
|
||||
});
|
||||
ShortcutManager::addShortcut(this, SHIFT + Keys::PageDown, "hex.builtin.view.hex_editor.shortcut.selection_page_down", [this] {
|
||||
auto selection = getSelection();
|
||||
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||
auto cursor = m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
|
||||
|
||||
if (cursor != selection.getStartAddress()) {
|
||||
auto newCursor = cursor + (this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount());
|
||||
auto newCursor = cursor + (m_hexEditor.getBytesPerRow() * m_hexEditor.getVisibleRowCount());
|
||||
setSelection(selection.getStartAddress(), newCursor);
|
||||
this->m_hexEditor.setCursorPosition(newCursor);
|
||||
m_hexEditor.setCursorPosition(newCursor);
|
||||
} else {
|
||||
auto newCursor = cursor + (this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount());
|
||||
auto newCursor = cursor + (m_hexEditor.getBytesPerRow() * m_hexEditor.getVisibleRowCount());
|
||||
setSelection(newCursor, selection.getEndAddress());
|
||||
this->m_hexEditor.setCursorPosition(newCursor);
|
||||
m_hexEditor.setCursorPosition(newCursor);
|
||||
}
|
||||
|
||||
this->m_hexEditor.scrollToSelection();
|
||||
this->m_hexEditor.jumpIfOffScreen();
|
||||
m_hexEditor.scrollToSelection();
|
||||
m_hexEditor.jumpIfOffScreen();
|
||||
});
|
||||
|
||||
}
|
||||
|
|
@ -959,8 +959,8 @@ namespace hex::plugin::builtin {
|
|||
auto provider = ImHexApi::Provider::get();
|
||||
|
||||
if (region == Region::Invalid()) {
|
||||
this->m_selectionStart->reset();
|
||||
this->m_selectionEnd->reset();
|
||||
m_selectionStart->reset();
|
||||
m_selectionEnd->reset();
|
||||
EventRegionSelected::post(ImHexApi::HexEditor::ProviderRegion({ Region::Invalid(), nullptr }));
|
||||
|
||||
return;
|
||||
|
|
@ -979,26 +979,26 @@ namespace hex::plugin::builtin {
|
|||
|
||||
EventProviderChanged::subscribe(this, [this](auto *oldProvider, auto *newProvider) {
|
||||
if (oldProvider != nullptr) {
|
||||
auto selection = this->m_hexEditor.getSelection();
|
||||
auto selection = m_hexEditor.getSelection();
|
||||
|
||||
if (selection != Region::Invalid()) {
|
||||
this->m_selectionStart.get(oldProvider) = selection.getStartAddress();
|
||||
this->m_selectionEnd.get(oldProvider) = selection.getEndAddress();
|
||||
this->m_scrollPosition.get(oldProvider) = this->m_hexEditor.getScrollPosition();
|
||||
m_selectionStart.get(oldProvider) = selection.getStartAddress();
|
||||
m_selectionEnd.get(oldProvider) = selection.getEndAddress();
|
||||
m_scrollPosition.get(oldProvider) = m_hexEditor.getScrollPosition();
|
||||
}
|
||||
}
|
||||
|
||||
this->m_hexEditor.setSelectionUnchecked(std::nullopt, std::nullopt);
|
||||
this->m_hexEditor.setScrollPosition(0);
|
||||
m_hexEditor.setSelectionUnchecked(std::nullopt, std::nullopt);
|
||||
m_hexEditor.setScrollPosition(0);
|
||||
|
||||
if (newProvider != nullptr) {
|
||||
this->m_hexEditor.setSelectionUnchecked(this->m_selectionStart.get(newProvider), this->m_selectionEnd.get(newProvider));
|
||||
this->m_hexEditor.setScrollPosition(this->m_scrollPosition.get(newProvider));
|
||||
m_hexEditor.setSelectionUnchecked(m_selectionStart.get(newProvider), m_selectionEnd.get(newProvider));
|
||||
m_hexEditor.setScrollPosition(m_scrollPosition.get(newProvider));
|
||||
} else {
|
||||
ImHexApi::HexEditor::clearSelection();
|
||||
}
|
||||
|
||||
this->m_hexEditor.forceUpdateScrollPosition();
|
||||
m_hexEditor.forceUpdateScrollPosition();
|
||||
if (isSelectionValid()) {
|
||||
EventRegionSelected::post(ImHexApi::HexEditor::ProviderRegion{ this->getSelection(), newProvider });
|
||||
}
|
||||
|
|
@ -1009,8 +1009,8 @@ namespace hex::plugin::builtin {
|
|||
});
|
||||
|
||||
EventHighlightingChanged::subscribe(this, [this]{
|
||||
this->m_foregroundHighlights->clear();
|
||||
this->m_backgroundHighlights->clear();
|
||||
m_foregroundHighlights->clear();
|
||||
m_backgroundHighlights->clear();
|
||||
});
|
||||
|
||||
ProjectFile::registerPerProviderHandler({
|
||||
|
|
@ -1022,12 +1022,12 @@ namespace hex::plugin::builtin {
|
|||
|
||||
auto content = tar.readString(basePath);
|
||||
if (!content.empty())
|
||||
this->m_hexEditor.setCustomEncoding(EncodingFile(hex::EncodingFile::Type::Thingy, content));
|
||||
m_hexEditor.setCustomEncoding(EncodingFile(hex::EncodingFile::Type::Thingy, content));
|
||||
|
||||
return true;
|
||||
},
|
||||
.store = [this](prv::Provider *, const std::fs::path &basePath, Tar &tar) {
|
||||
if (const auto &encoding = this->m_hexEditor.getCustomEncoding(); encoding.has_value()) {
|
||||
if (const auto &encoding = m_hexEditor.getCustomEncoding(); encoding.has_value()) {
|
||||
auto content = encoding->getTableContent();
|
||||
|
||||
if (!content.empty())
|
||||
|
|
@ -1086,7 +1086,7 @@ namespace hex::plugin::builtin {
|
|||
ImHexApi::Provider::markDirty();
|
||||
|
||||
TaskManager::doLater([this, encoding = std::move(encoding)] mutable {
|
||||
this->m_hexEditor.setCustomEncoding(std::move(encoding));
|
||||
m_hexEditor.setCustomEncoding(std::move(encoding));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1161,12 +1161,12 @@ namespace hex::plugin::builtin {
|
|||
Shortcut::None,
|
||||
[this] {
|
||||
auto selection = ImHexApi::HexEditor::getSelection();
|
||||
auto customEncoding = this->m_hexEditor.getCustomEncoding();
|
||||
auto customEncoding = m_hexEditor.getCustomEncoding();
|
||||
if (customEncoding.has_value() && selection.has_value() && selection != Region::Invalid())
|
||||
copyCustomEncoding(*customEncoding, *selection);
|
||||
},
|
||||
[this] {
|
||||
return ImHexApi::HexEditor::isSelectionValid() && this->m_hexEditor.getCustomEncoding().has_value();
|
||||
return ImHexApi::HexEditor::isSelectionValid() && m_hexEditor.getCustomEncoding().has_value();
|
||||
});
|
||||
|
||||
ContentRegistry::Interface::addMenuItemSeparator({ "hex.builtin.menu.edit", "hex.builtin.view.hex_editor.menu.edit.copy_as" }, 1350);
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ namespace hex::plugin::builtin {
|
|||
.load = [this](prv::Provider *provider, const std::fs::path &basePath, Tar &tar) -> bool {
|
||||
const auto json = nlohmann::json::parse(tar.readString(basePath));
|
||||
|
||||
auto &rules = this->m_rules.get(provider);
|
||||
auto &rules = m_rules.get(provider);
|
||||
rules.clear();
|
||||
|
||||
for (const auto &entry : json) {
|
||||
|
|
@ -140,7 +140,7 @@ namespace hex::plugin::builtin {
|
|||
},
|
||||
.store = [this](prv::Provider *provider, const std::fs::path &basePath, Tar &tar) -> bool {
|
||||
nlohmann::json result = nlohmann::json::array();
|
||||
for (const auto &rule : this->m_rules.get(provider)) {
|
||||
for (const auto &rule : m_rules.get(provider)) {
|
||||
nlohmann::json content;
|
||||
|
||||
content["name"] = rule.name;
|
||||
|
|
@ -163,9 +163,9 @@ namespace hex::plugin::builtin {
|
|||
});
|
||||
|
||||
// Initialize the selected rule iterators to point to the end of the rules lists
|
||||
this->m_selectedRule = this->m_rules->end();
|
||||
m_selectedRule = m_rules->end();
|
||||
EventProviderCreated::subscribe([this](prv::Provider *provider) {
|
||||
this->m_selectedRule.get(provider) = this->m_rules.get(provider).end();
|
||||
m_selectedRule.get(provider) = m_rules.get(provider).end();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch, 1);
|
||||
ImGui::TableSetupColumn("Enabled", ImGuiTableColumnFlags_WidthFixed, 10_scaled);
|
||||
|
||||
for (auto it = this->m_rules->begin(); it != this->m_rules->end(); ++it) {
|
||||
for (auto it = m_rules->begin(); it != m_rules->end(); ++it) {
|
||||
auto &rule = *it;
|
||||
|
||||
ImGui::TableNextRow();
|
||||
|
|
@ -184,8 +184,8 @@ namespace hex::plugin::builtin {
|
|||
// Add a selectable for each rule to be able to switch between them
|
||||
ImGui::PushID(&rule);
|
||||
ImGui::BeginDisabled(!rule.enabled);
|
||||
if (ImGui::Selectable(rule.name.c_str(), this->m_selectedRule == it, ImGuiSelectableFlags_SpanAvailWidth)) {
|
||||
this->m_selectedRule = it;
|
||||
if (ImGui::Selectable(rule.name.c_str(), m_selectedRule == it, ImGuiSelectableFlags_SpanAvailWidth)) {
|
||||
m_selectedRule = it;
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
|
|
@ -205,21 +205,21 @@ namespace hex::plugin::builtin {
|
|||
|
||||
// Draw button to add a new rule
|
||||
if (ImGuiExt::DimmedIconButton(ICON_VS_ADD, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
|
||||
this->m_rules->emplace_back("hex.builtin.view.highlight_rules.new_rule"_lang);
|
||||
m_rules->emplace_back("hex.builtin.view.highlight_rules.new_rule"_lang);
|
||||
|
||||
if (this->m_selectedRule == this->m_rules->end())
|
||||
this->m_selectedRule = this->m_rules->begin();
|
||||
if (m_selectedRule == m_rules->end())
|
||||
m_selectedRule = m_rules->begin();
|
||||
}
|
||||
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
// Draw button to remove the selected rule
|
||||
ImGui::BeginDisabled(this->m_selectedRule == this->m_rules->end());
|
||||
ImGui::BeginDisabled(m_selectedRule == m_rules->end());
|
||||
if (ImGuiExt::DimmedIconButton(ICON_VS_REMOVE, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
|
||||
auto next = std::next(*this->m_selectedRule);
|
||||
this->m_rules->erase(*this->m_selectedRule);
|
||||
this->m_selectedRule = next;
|
||||
auto next = std::next(*m_selectedRule);
|
||||
m_rules->erase(*m_selectedRule);
|
||||
m_selectedRule = next;
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
|
@ -228,14 +228,14 @@ namespace hex::plugin::builtin {
|
|||
void ViewHighlightRules::drawRulesConfig() {
|
||||
ImGuiExt::BeginSubWindow("hex.builtin.view.highlight_rules.config"_lang, ImGui::GetContentRegionAvail());
|
||||
{
|
||||
if (this->m_selectedRule != this->m_rules->end()) {
|
||||
if (m_selectedRule != m_rules->end()) {
|
||||
|
||||
// Draw text input field for the rule name
|
||||
ImGui::PushItemWidth(-1);
|
||||
ImGui::InputTextWithHint("##name", "Name", this->m_selectedRule.get()->name);
|
||||
ImGui::InputTextWithHint("##name", "Name", m_selectedRule.get()->name);
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
auto &rule = *this->m_selectedRule;
|
||||
auto &rule = *m_selectedRule;
|
||||
|
||||
// Draw a table containing all the expressions for the selected rule
|
||||
ImGui::PushID(&rule);
|
||||
|
|
@ -282,7 +282,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
// Draw button to add a new expression
|
||||
if (ImGuiExt::DimmedIconButton(ICON_VS_ADD, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
|
||||
this->m_selectedRule.get()->addExpression(Rule::Expression("", {}));
|
||||
m_selectedRule.get()->addExpression(Rule::Expression("", {}));
|
||||
ImHexApi::Provider::markDirty();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,27 +22,27 @@ namespace hex::plugin::builtin {
|
|||
|
||||
ViewInformation::ViewInformation() : View::Window("hex.builtin.view.information.name") {
|
||||
EventDataChanged::subscribe(this, [this] {
|
||||
this->m_dataValid = false;
|
||||
this->m_plainTextCharacterPercentage = -1.0;
|
||||
this->m_averageEntropy = -1.0;
|
||||
this->m_highestBlockEntropy = -1.0;
|
||||
this->m_blockSize = 0;
|
||||
this->m_dataMimeType.clear();
|
||||
this->m_dataDescription.clear();
|
||||
this->m_analyzedRegion = { 0, 0 };
|
||||
m_dataValid = false;
|
||||
m_plainTextCharacterPercentage = -1.0;
|
||||
m_averageEntropy = -1.0;
|
||||
m_highestBlockEntropy = -1.0;
|
||||
m_blockSize = 0;
|
||||
m_dataMimeType.clear();
|
||||
m_dataDescription.clear();
|
||||
m_analyzedRegion = { 0, 0 };
|
||||
});
|
||||
|
||||
EventRegionSelected::subscribe(this, [this](Region region) {
|
||||
// Set the position of the diagram relative to the place where
|
||||
// the user clicked inside the hex editor view
|
||||
if (this->m_blockSize != 0) {
|
||||
this->m_byteTypesDistribution.setHandlePosition(region.getStartAddress());
|
||||
this->m_chunkBasedEntropy.setHandlePosition(region.getStartAddress());
|
||||
if (m_blockSize != 0) {
|
||||
m_byteTypesDistribution.setHandlePosition(region.getStartAddress());
|
||||
m_chunkBasedEntropy.setHandlePosition(region.getStartAddress());
|
||||
}
|
||||
});
|
||||
|
||||
EventProviderDeleted::subscribe(this, [this](const auto*) {
|
||||
this->m_dataValid = false;
|
||||
m_dataValid = false;
|
||||
});
|
||||
|
||||
ContentRegistry::FileHandler::add({ ".mgc" }, [](const auto &path) {
|
||||
|
|
@ -66,72 +66,72 @@ namespace hex::plugin::builtin {
|
|||
void ViewInformation::analyze() {
|
||||
AchievementManager::unlockAchievement("hex.builtin.achievement.misc", "hex.builtin.achievement.misc.analyze_file.name");
|
||||
|
||||
this->m_analyzerTask = TaskManager::createTask("hex.builtin.view.information.analyzing", 0, [this](auto &task) {
|
||||
m_analyzerTask = TaskManager::createTask("hex.builtin.view.information.analyzing", 0, [this](auto &task) {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
|
||||
if ((this->m_analyzedRegion.getStartAddress() >= this->m_analyzedRegion.getEndAddress()) || (this->m_analyzedRegion.getEndAddress() > provider->getActualSize())) {
|
||||
this->m_analyzedRegion = { provider->getBaseAddress(), provider->getActualSize() };
|
||||
if ((m_analyzedRegion.getStartAddress() >= m_analyzedRegion.getEndAddress()) || (m_analyzedRegion.getEndAddress() > provider->getActualSize())) {
|
||||
m_analyzedRegion = { provider->getBaseAddress(), provider->getActualSize() };
|
||||
}
|
||||
|
||||
if (this->m_inputChunkSize == 0) {
|
||||
this->m_inputChunkSize = 256;
|
||||
if (m_inputChunkSize == 0) {
|
||||
m_inputChunkSize = 256;
|
||||
}
|
||||
|
||||
task.setMaxValue(this->m_analyzedRegion.getSize());
|
||||
task.setMaxValue(m_analyzedRegion.getSize());
|
||||
|
||||
{
|
||||
magic::compile();
|
||||
|
||||
this->m_dataDescription = magic::getDescription(provider);
|
||||
this->m_dataMimeType = magic::getMIMEType(provider);
|
||||
m_dataDescription = magic::getDescription(provider);
|
||||
m_dataMimeType = magic::getMIMEType(provider);
|
||||
}
|
||||
|
||||
{
|
||||
this->m_blockSize = std::max<u32>(std::ceil(provider->getActualSize() / 2048.0F), 256);
|
||||
m_blockSize = std::max<u32>(std::ceil(provider->getActualSize() / 2048.0F), 256);
|
||||
|
||||
this->m_averageEntropy = -1.0;
|
||||
this->m_highestBlockEntropy = -1.0;
|
||||
this->m_plainTextCharacterPercentage = -1.0;
|
||||
m_averageEntropy = -1.0;
|
||||
m_highestBlockEntropy = -1.0;
|
||||
m_plainTextCharacterPercentage = -1.0;
|
||||
|
||||
// Setup / start each analysis
|
||||
|
||||
this->m_byteDistribution.reset();
|
||||
this->m_digram.reset(this->m_analysisRegion.getSize());
|
||||
this->m_layeredDistribution.reset(this->m_analysisRegion.getSize());
|
||||
this->m_byteTypesDistribution.reset(this->m_analysisRegion.getStartAddress(), this->m_analysisRegion.getEndAddress(), provider->getBaseAddress(), provider->getActualSize());
|
||||
this->m_chunkBasedEntropy.reset(this->m_inputChunkSize, this->m_analysisRegion.getStartAddress(), this->m_analysisRegion.getEndAddress(),
|
||||
m_byteDistribution.reset();
|
||||
m_digram.reset(m_analysisRegion.getSize());
|
||||
m_layeredDistribution.reset(m_analysisRegion.getSize());
|
||||
m_byteTypesDistribution.reset(m_analysisRegion.getStartAddress(), m_analysisRegion.getEndAddress(), provider->getBaseAddress(), provider->getActualSize());
|
||||
m_chunkBasedEntropy.reset(m_inputChunkSize, m_analysisRegion.getStartAddress(), m_analysisRegion.getEndAddress(),
|
||||
provider->getBaseAddress(), provider->getActualSize());
|
||||
|
||||
// Create a handle to the file
|
||||
auto reader = prv::ProviderReader(provider);
|
||||
reader.seek(this->m_analysisRegion.getStartAddress());
|
||||
reader.setEndAddress(this->m_analysisRegion.getEndAddress());
|
||||
reader.seek(m_analysisRegion.getStartAddress());
|
||||
reader.setEndAddress(m_analysisRegion.getEndAddress());
|
||||
|
||||
this->m_analyzedRegion = this->m_analysisRegion;
|
||||
m_analyzedRegion = m_analysisRegion;
|
||||
|
||||
u64 count = 0;
|
||||
|
||||
// Loop over each byte of the selection and update each analysis
|
||||
// one byte at a time to process the file only once
|
||||
for (u8 byte : reader) {
|
||||
this->m_byteDistribution.update(byte);
|
||||
this->m_byteTypesDistribution.update(byte);
|
||||
this->m_chunkBasedEntropy.update(byte);
|
||||
this->m_layeredDistribution.update(byte);
|
||||
this->m_digram.update(byte);
|
||||
m_byteDistribution.update(byte);
|
||||
m_byteTypesDistribution.update(byte);
|
||||
m_chunkBasedEntropy.update(byte);
|
||||
m_layeredDistribution.update(byte);
|
||||
m_digram.update(byte);
|
||||
++count;
|
||||
task.update(count);
|
||||
}
|
||||
|
||||
this->m_averageEntropy = this->m_chunkBasedEntropy.calculateEntropy(this->m_byteDistribution.get(), this->m_analyzedRegion.getSize());
|
||||
this->m_highestBlockEntropy = this->m_chunkBasedEntropy.getHighestEntropyBlockValue();
|
||||
this->m_highestBlockEntropyAddress = this->m_chunkBasedEntropy.getHighestEntropyBlockAddress();
|
||||
this->m_lowestBlockEntropy = this->m_chunkBasedEntropy.getLowestEntropyBlockValue();
|
||||
this->m_lowestBlockEntropyAddress = this->m_chunkBasedEntropy.getLowestEntropyBlockAddress();
|
||||
this->m_plainTextCharacterPercentage = this->m_byteTypesDistribution.getPlainTextCharacterPercentage();
|
||||
m_averageEntropy = m_chunkBasedEntropy.calculateEntropy(m_byteDistribution.get(), m_analyzedRegion.getSize());
|
||||
m_highestBlockEntropy = m_chunkBasedEntropy.getHighestEntropyBlockValue();
|
||||
m_highestBlockEntropyAddress = m_chunkBasedEntropy.getHighestEntropyBlockAddress();
|
||||
m_lowestBlockEntropy = m_chunkBasedEntropy.getLowestEntropyBlockValue();
|
||||
m_lowestBlockEntropyAddress = m_chunkBasedEntropy.getLowestEntropyBlockAddress();
|
||||
m_plainTextCharacterPercentage = m_byteTypesDistribution.getPlainTextCharacterPercentage();
|
||||
}
|
||||
|
||||
this->m_dataValid = true;
|
||||
m_dataValid = true;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -140,7 +140,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
if (ImHexApi::Provider::isValid() && provider->isReadable()) {
|
||||
ImGui::BeginDisabled(this->m_analyzerTask.isRunning());
|
||||
ImGui::BeginDisabled(m_analyzerTask.isRunning());
|
||||
ImGuiExt::BeginSubWindow("hex.builtin.common.settings"_lang);
|
||||
{
|
||||
if (ImGui::BeginTable("SettingsTable", 2, ImGuiTableFlags_BordersInner | ImGuiTableFlags_SizingFixedSame, ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
|
||||
|
|
@ -148,10 +148,10 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TableSetupColumn("Right", ImGuiTableColumnFlags_WidthStretch, 0.5F);
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ui::regionSelectionPicker(&this->m_analysisRegion, provider, &this->m_selectionType, false);
|
||||
ui::regionSelectionPicker(&m_analysisRegion, provider, &m_selectionType, false);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.view.information.block_size"_lang, &this->m_inputChunkSize);
|
||||
ImGuiExt::InputHexadecimal("hex.builtin.view.information.block_size"_lang, &m_inputChunkSize);
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
|
@ -164,13 +164,13 @@ namespace hex::plugin::builtin {
|
|||
ImGuiExt::EndSubWindow();
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (this->m_analyzerTask.isRunning()) {
|
||||
if (m_analyzerTask.isRunning()) {
|
||||
ImGuiExt::TextSpinner("hex.builtin.view.information.analyzing"_lang);
|
||||
} else {
|
||||
ImGui::NewLine();
|
||||
}
|
||||
|
||||
if (!this->m_analyzerTask.isRunning() && this->m_dataValid) {
|
||||
if (!m_analyzerTask.isRunning() && m_dataValid) {
|
||||
|
||||
// Provider information
|
||||
ImGuiExt::Header("hex.builtin.view.information.provider_information"_lang, true);
|
||||
|
|
@ -191,13 +191,13 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.region"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormatted("0x{:X} - 0x{:X}", this->m_analyzedRegion.getStartAddress(), this->m_analyzedRegion.getEndAddress());
|
||||
ImGuiExt::TextFormatted("0x{:X} - 0x{:X}", m_analyzedRegion.getStartAddress(), m_analyzedRegion.getEndAddress());
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
// Magic information
|
||||
if (!(this->m_dataDescription.empty() && this->m_dataMimeType.empty())) {
|
||||
if (!(m_dataDescription.empty() && m_dataMimeType.empty())) {
|
||||
ImGuiExt::Header("hex.builtin.view.information.magic"_lang);
|
||||
|
||||
if (ImGui::BeginTable("magic", 2, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg)) {
|
||||
|
|
@ -206,31 +206,31 @@ namespace hex::plugin::builtin {
|
|||
|
||||
ImGui::TableNextRow();
|
||||
|
||||
if (!this->m_dataDescription.empty()) {
|
||||
if (!m_dataDescription.empty()) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted("hex.builtin.view.information.description"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (this->m_dataDescription == "data") {
|
||||
ImGuiExt::TextFormattedColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F), "{} ({})", "hex.builtin.view.information.octet_stream_text"_lang, this->m_dataDescription);
|
||||
if (m_dataDescription == "data") {
|
||||
ImGuiExt::TextFormattedColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F), "{} ({})", "hex.builtin.view.information.octet_stream_text"_lang, m_dataDescription);
|
||||
} else {
|
||||
ImGuiExt::TextFormattedWrapped("{}", this->m_dataDescription);
|
||||
ImGuiExt::TextFormattedWrapped("{}", m_dataDescription);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->m_dataMimeType.empty()) {
|
||||
if (!m_dataMimeType.empty()) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted("hex.builtin.view.information.mime"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (this->m_dataMimeType == "application/octet-stream") {
|
||||
ImGuiExt::TextFormattedColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F), "{} ({})", "hex.builtin.view.information.octet_stream_text"_lang, this->m_dataMimeType);
|
||||
if (m_dataMimeType == "application/octet-stream") {
|
||||
ImGuiExt::TextFormattedColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F), "{} ({})", "hex.builtin.view.information.octet_stream_text"_lang, m_dataMimeType);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
||||
ImGuiExt::HelpHover("hex.builtin.view.information.octet_stream_warning"_lang);
|
||||
ImGui::PopStyleVar();
|
||||
} else {
|
||||
ImGuiExt::TextFormatted("{}", this->m_dataMimeType);
|
||||
ImGuiExt::TextFormatted("{}", m_dataMimeType);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -241,7 +241,7 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
|
||||
// Information analysis
|
||||
if (this->m_analyzedRegion.getSize() > 0) {
|
||||
if (m_analyzedRegion.getSize() > 0) {
|
||||
|
||||
ImGuiExt::Header("hex.builtin.view.information.info_analysis"_lang);
|
||||
|
||||
|
|
@ -250,14 +250,14 @@ namespace hex::plugin::builtin {
|
|||
|
||||
// Display byte distribution analysis
|
||||
ImGui::TextUnformatted("hex.builtin.view.information.distribution"_lang);
|
||||
this->m_byteDistribution.draw(
|
||||
m_byteDistribution.draw(
|
||||
ImVec2(-1, 0),
|
||||
ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect
|
||||
);
|
||||
|
||||
// Display byte types distribution analysis
|
||||
ImGui::TextUnformatted("hex.builtin.view.information.byte_types"_lang);
|
||||
this->m_byteTypesDistribution.draw(
|
||||
m_byteTypesDistribution.draw(
|
||||
ImVec2(-1, 0),
|
||||
ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect,
|
||||
true
|
||||
|
|
@ -265,7 +265,7 @@ namespace hex::plugin::builtin {
|
|||
|
||||
// Display chunk-based entropy analysis
|
||||
ImGui::TextUnformatted("hex.builtin.view.information.entropy"_lang);
|
||||
this->m_chunkBasedEntropy.draw(
|
||||
m_chunkBasedEntropy.draw(
|
||||
ImVec2(-1, 0),
|
||||
ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect,
|
||||
true
|
||||
|
|
@ -287,15 +287,15 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.block_size"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormatted("hex.builtin.view.information.block_size.desc"_lang, this->m_chunkBasedEntropy.getSize(), this->m_chunkBasedEntropy.getChunkSize());
|
||||
ImGuiExt::TextFormatted("hex.builtin.view.information.block_size.desc"_lang, m_chunkBasedEntropy.getSize(), m_chunkBasedEntropy.getChunkSize());
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.file_entropy"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
if (this->m_averageEntropy < 0)
|
||||
if (m_averageEntropy < 0)
|
||||
ImGui::TextUnformatted("???");
|
||||
else {
|
||||
auto entropy = std::abs(this->m_averageEntropy);
|
||||
auto entropy = std::abs(m_averageEntropy);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.1F);
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGui::GetColorU32(ImGuiCol_TableRowBgAlt));
|
||||
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImColor::HSV(0.3F - (0.3F * entropy), 0.6F, 0.8F, 1.0F).Value);
|
||||
|
|
@ -307,12 +307,12 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.highest_entropy"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormatted("{:.5f} @", this->m_highestBlockEntropy);
|
||||
ImGuiExt::TextFormatted("{:.5f} @", m_highestBlockEntropy);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
||||
if (ImGui::Button(hex::format("0x{:06X}", this->m_highestBlockEntropyAddress).c_str())) {
|
||||
ImHexApi::HexEditor::setSelection(this->m_highestBlockEntropyAddress, this->m_inputChunkSize);
|
||||
if (ImGui::Button(hex::format("0x{:06X}", m_highestBlockEntropyAddress).c_str())) {
|
||||
ImHexApi::HexEditor::setSelection(m_highestBlockEntropyAddress, m_inputChunkSize);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopStyleVar();
|
||||
|
|
@ -320,12 +320,12 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.lowest_entropy"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormatted("{:.5f} @", this->m_lowestBlockEntropy);
|
||||
ImGuiExt::TextFormatted("{:.5f} @", m_lowestBlockEntropy);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
||||
if (ImGui::Button(hex::format("0x{:06X}", this->m_lowestBlockEntropyAddress).c_str())) {
|
||||
ImHexApi::HexEditor::setSelection(this->m_lowestBlockEntropyAddress, this->m_inputChunkSize);
|
||||
if (ImGui::Button(hex::format("0x{:06X}", m_lowestBlockEntropyAddress).c_str())) {
|
||||
ImHexApi::HexEditor::setSelection(m_lowestBlockEntropyAddress, m_inputChunkSize);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopStyleVar();
|
||||
|
|
@ -333,13 +333,13 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.plain_text_percentage"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
if (this->m_plainTextCharacterPercentage < 0)
|
||||
if (m_plainTextCharacterPercentage < 0)
|
||||
ImGui::TextUnformatted("???");
|
||||
else {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.1F);
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGui::GetColorU32(ImGuiCol_TableRowBgAlt));
|
||||
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImColor::HSV(0.3F * (this->m_plainTextCharacterPercentage / 100.0F), 0.8F, 0.6F, 1.0F).Value);
|
||||
ImGui::ProgressBar(this->m_plainTextCharacterPercentage / 100.0F, ImVec2(200_scaled, ImGui::GetTextLineHeight()));
|
||||
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImColor::HSV(0.3F * (m_plainTextCharacterPercentage / 100.0F), 0.8F, 0.6F, 1.0F).Value);
|
||||
ImGui::ProgressBar(m_plainTextCharacterPercentage / 100.0F, ImVec2(200_scaled, ImGui::GetTextLineHeight()));
|
||||
ImGui::PopStyleColor(2);
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
|
@ -354,12 +354,12 @@ namespace hex::plugin::builtin {
|
|||
ImGui::TableSetupColumn("value", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableNextRow();
|
||||
|
||||
if (this->m_averageEntropy > 0.83 && this->m_highestBlockEntropy > 0.9) {
|
||||
if (m_averageEntropy > 0.83 && m_highestBlockEntropy > 0.9) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormattedColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F), "{}", "hex.builtin.view.information.encrypted"_lang);
|
||||
}
|
||||
|
||||
if (this->m_plainTextCharacterPercentage > 95) {
|
||||
if (m_plainTextCharacterPercentage > 95) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormattedColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F), "{}", "hex.builtin.view.information.plain_text"_lang);
|
||||
}
|
||||
|
|
@ -370,7 +370,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::BeginGroup();
|
||||
{
|
||||
ImGui::TextUnformatted("hex.builtin.view.information.digram"_lang);
|
||||
this->m_digram.draw(scaled(ImVec2(300, 300)));
|
||||
m_digram.draw(scaled(ImVec2(300, 300)));
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
|
||||
|
|
@ -379,7 +379,7 @@ namespace hex::plugin::builtin {
|
|||
ImGui::BeginGroup();
|
||||
{
|
||||
ImGui::TextUnformatted("hex.builtin.view.information.layered_distribution"_lang);
|
||||
this->m_layeredDistribution.draw(scaled(ImVec2(300, 300)));
|
||||
m_layeredDistribution.draw(scaled(ImVec2(300, 300)));
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue