yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
memory_editor.cc
Go to the documentation of this file.
2
3#include "absl/strings/str_format.h"
9#include "imgui/imgui.h"
10
11namespace yaze {
12namespace editor {
13
14absl::Status MemoryEditor::Update() {
15 if (!active_) {
16 return absl::OkStatus();
17 }
18
20 ImGui::Separator();
21
22 ImGui::Begin("Hex Editor", &active_);
23 if (ImGui::Button("Compare Rom")) {
26 show_compare_rom_ = true;
27 }
28
29 static uint64_t convert_address = 0;
30 gui::InputHex("SNES to PC", (int*)&convert_address, 6, 200.f);
31 SameLine();
32 Text("%x", SnesToPc(convert_address));
33
34 BEGIN_TABLE("Memory Comparison", 2, ImGuiTableFlags_Resizable);
35 SETUP_COLUMN("Source")
36 SETUP_COLUMN("Dest")
37
39 Text("%s", rom()->filename().data());
40 memory_widget_.DrawContents(rom()->mutable_data(), rom()->size());
41
45 ImGui::BeginGroup();
46 ImGui::BeginChild("Comparison ROM");
47 Text("%s", comparison_rom_.filename().data());
50 ImGui::EndChild();
51 ImGui::EndGroup();
52 }
53 END_TABLE()
54
55 ImGui::End();
56
57 return absl::OkStatus();
58}
59
61 // Modern compact toolbar with icon-only buttons
62 {
63 const float pad = gui::LayoutHelpers::GetButtonPadding();
64 gui::StyleVarGuard toolbar_vars(
65 {{ImGuiStyleVar_FramePadding, ImVec2(pad, pad * 0.67f)},
66 {ImGuiStyleVar_ItemSpacing, ImVec2(pad * 0.67f, pad * 0.67f)}});
67
68 if (ImGui::Button(ICON_MD_LOCATION_SEARCHING " Jump")) {
69 ImGui::OpenPopup("JumpToAddress");
70 }
71 if (ImGui::IsItemHovered()) {
72 ImGui::SetTooltip("Jump to specific address");
73 }
74
75 ImGui::SameLine();
76 if (ImGui::Button(ICON_MD_SEARCH " Search")) {
77 ImGui::OpenPopup("SearchPattern");
78 }
79 if (ImGui::IsItemHovered()) {
80 ImGui::SetTooltip("Search for hex pattern");
81 }
82
83 ImGui::SameLine();
84 if (ImGui::Button(ICON_MD_BOOKMARK " Bookmarks")) {
85 ImGui::OpenPopup("Bookmarks");
86 }
87 if (ImGui::IsItemHovered()) {
88 ImGui::SetTooltip("Manage address bookmarks");
89 }
90
91 ImGui::SameLine();
92 ImGui::Text(ICON_MD_MORE_VERT);
93 ImGui::SameLine();
94
95 // Show current address
96 if (current_address_ != 0) {
97 ImGui::TextColored(gui::GetInfoColor(),
99 }
100 }
101
102 ImGui::Separator();
103
107}
108
110 if (ImGui::BeginPopupModal("JumpToAddress", nullptr,
111 ImGuiWindowFlags_AlwaysAutoResize)) {
112 ImGui::TextColored(gui::GetInfoColor(),
113 ICON_MD_LOCATION_SEARCHING " Jump to Address");
114 ImGui::Separator();
115 ImGui::Spacing();
116
117 ImGui::SetNextItemWidth(200);
118 if (ImGui::InputText("##jump_addr", jump_address_,
119 IM_ARRAYSIZE(jump_address_),
120 ImGuiInputTextFlags_CharsHexadecimal |
121 ImGuiInputTextFlags_EnterReturnsTrue)) {
122 // Parse and jump on Enter key
123 unsigned int addr;
124 if (sscanf(jump_address_, "%X", &addr) == 1) {
125 current_address_ = addr;
126 memory_widget_.GotoAddrAndHighlight(addr, addr + 1);
127 ImGui::CloseCurrentPopup();
128 }
129 }
130 ImGui::TextDisabled("Format: 0x1C800 or 1C800");
131
132 ImGui::Spacing();
133 ImGui::Separator();
134 ImGui::Spacing();
135
136 if (ImGui::Button(ICON_MD_CHECK " Go", ImVec2(120, 0))) {
137 unsigned int addr;
138 if (sscanf(jump_address_, "%X", &addr) == 1) {
139 current_address_ = addr;
140 memory_widget_.GotoAddrAndHighlight(addr, addr + 1);
141 }
142 ImGui::CloseCurrentPopup();
143 }
144 ImGui::SameLine();
145 if (ImGui::Button(ICON_MD_CANCEL " Cancel", ImVec2(120, 0))) {
146 ImGui::CloseCurrentPopup();
147 }
148 ImGui::EndPopup();
149 }
150}
151
153 if (ImGui::BeginPopupModal("SearchPattern", nullptr,
154 ImGuiWindowFlags_AlwaysAutoResize)) {
155 ImGui::TextColored(gui::GetSuccessColor(),
156 ICON_MD_SEARCH " Search Hex Pattern");
157 ImGui::Separator();
158 ImGui::Spacing();
159
160 ImGui::SetNextItemWidth(300);
161 if (ImGui::InputText("##search_pattern", search_pattern_,
162 IM_ARRAYSIZE(search_pattern_),
163 ImGuiInputTextFlags_EnterReturnsTrue)) {
164 // TODO: Implement search
165 ImGui::CloseCurrentPopup();
166 }
167 ImGui::TextDisabled("Use ?? for wildcard (e.g. FF 00 ?? 12)");
168 ImGui::Spacing();
169
170 // Quick preset patterns
171 ImGui::Text(ICON_MD_LIST " Quick Patterns:");
172 if (ImGui::SmallButton("LDA")) {
173 snprintf(search_pattern_, sizeof(search_pattern_), "A9 ??");
174 }
175 ImGui::SameLine();
176 if (ImGui::SmallButton("STA")) {
177 snprintf(search_pattern_, sizeof(search_pattern_), "8D ?? ??");
178 }
179 ImGui::SameLine();
180 if (ImGui::SmallButton("JSR")) {
181 snprintf(search_pattern_, sizeof(search_pattern_), "20 ?? ??");
182 }
183
184 ImGui::Spacing();
185 ImGui::Separator();
186 ImGui::Spacing();
187
188 if (ImGui::Button(ICON_MD_SEARCH " Search", ImVec2(120, 0))) {
189 // TODO: Implement search using hex-search handler
190 ImGui::CloseCurrentPopup();
191 }
192 ImGui::SameLine();
193 if (ImGui::Button(ICON_MD_CANCEL " Cancel", ImVec2(120, 0))) {
194 ImGui::CloseCurrentPopup();
195 }
196 ImGui::EndPopup();
197 }
198}
199
201 if (ImGui::BeginPopupModal("Bookmarks", nullptr,
202 ImGuiWindowFlags_AlwaysAutoResize)) {
203 ImGui::TextColored(gui::GetWarningColor(),
204 ICON_MD_BOOKMARK " Memory Bookmarks");
205 ImGui::Separator();
206 ImGui::Spacing();
207
208 if (bookmarks_.empty()) {
209 ImGui::TextDisabled(ICON_MD_INFO " No bookmarks yet");
210 ImGui::Spacing();
211 ImGui::Separator();
212 ImGui::Spacing();
213
214 if (ImGui::Button(ICON_MD_ADD " Add Current Address", ImVec2(250, 0))) {
215 Bookmark new_bookmark;
216 new_bookmark.address = current_address_;
217 new_bookmark.name =
218 absl::StrFormat("Bookmark %zu", bookmarks_.size() + 1);
219 new_bookmark.description = "User-defined bookmark";
220 bookmarks_.push_back(new_bookmark);
221 }
222 } else {
223 // Bookmarks table
224 ImGui::BeginChild("##bookmarks_list", ImVec2(0, 300), true);
225 if (ImGui::BeginTable("##bookmarks_table", 3,
226 ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg |
227 ImGuiTableFlags_Resizable)) {
228 ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 150);
229 ImGui::TableSetupColumn("Address", ImGuiTableColumnFlags_WidthFixed,
230 100);
231 ImGui::TableSetupColumn("Description",
232 ImGuiTableColumnFlags_WidthStretch);
233 ImGui::TableHeadersRow();
234
235 for (size_t i = 0; i < bookmarks_.size(); ++i) {
236 const auto& bm = bookmarks_[i];
237 ImGui::PushID(static_cast<int>(i));
238
239 ImGui::TableNextRow();
240 ImGui::TableNextColumn();
241 if (ImGui::Selectable(bm.name.c_str(), false,
242 ImGuiSelectableFlags_SpanAllColumns)) {
243 current_address_ = bm.address;
244 memory_widget_.GotoAddrAndHighlight(bm.address, bm.address + 1);
245 ImGui::CloseCurrentPopup();
246 }
247
248 ImGui::TableNextColumn();
249 ImGui::TextColored(gui::GetInfoColor(), "0x%06X",
250 bm.address);
251
252 ImGui::TableNextColumn();
253 ImGui::TextDisabled("%s", bm.description.c_str());
254
255 ImGui::PopID();
256 }
257 ImGui::EndTable();
258 }
259 ImGui::EndChild();
260
261 ImGui::Spacing();
262 if (ImGui::Button(ICON_MD_ADD " Add Bookmark", ImVec2(150, 0))) {
263 Bookmark new_bookmark;
264 new_bookmark.address = current_address_;
265 new_bookmark.name =
266 absl::StrFormat("Bookmark %zu", bookmarks_.size() + 1);
267 new_bookmark.description = "User-defined bookmark";
268 bookmarks_.push_back(new_bookmark);
269 }
270 ImGui::SameLine();
271 if (ImGui::Button(ICON_MD_CLEAR_ALL " Clear All", ImVec2(150, 0))) {
272 bookmarks_.clear();
273 }
274 }
275
276 ImGui::Spacing();
277 ImGui::Separator();
278 ImGui::Spacing();
279
280 if (ImGui::Button(ICON_MD_CLOSE " Close", ImVec2(250, 0))) {
281 ImGui::CloseCurrentPopup();
282 }
283
284 ImGui::EndPopup();
285 }
286}
287
288} // namespace editor
289} // namespace yaze
absl::Status LoadFromFile(const std::string &filename, const LoadOptions &options=LoadOptions::Defaults())
Definition rom.cc:155
auto filename() const
Definition rom.h:145
auto mutable_data()
Definition rom.h:140
auto size() const
Definition rom.h:138
std::vector< Bookmark > bookmarks_
gui::MemoryEditorWidget memory_widget_
absl::Status Update() override
gui::MemoryEditorWidget comparison_widget_
static float GetButtonPadding()
RAII guard for ImGui style vars.
Definition style_guard.h:68
static std::string ShowOpenFileDialog()
ShowOpenFileDialog opens a file dialog and returns the selected filepath. Uses global feature flag to...
#define ICON_MD_LOCATION_ON
Definition icons.h:1137
#define ICON_MD_LOCATION_SEARCHING
Definition icons.h:1139
#define ICON_MD_INFO
Definition icons.h:993
#define ICON_MD_CANCEL
Definition icons.h:364
#define ICON_MD_MORE_VERT
Definition icons.h:1243
#define ICON_MD_SEARCH
Definition icons.h:1673
#define ICON_MD_CHECK
Definition icons.h:397
#define ICON_MD_LIST
Definition icons.h:1094
#define ICON_MD_CLEAR_ALL
Definition icons.h:417
#define ICON_MD_ADD
Definition icons.h:86
#define ICON_MD_BOOKMARK
Definition icons.h:285
#define ICON_MD_CLOSE
Definition icons.h:418
#define SETUP_COLUMN(l)
Definition macro.h:12
#define END_TABLE()
Definition macro.h:20
#define BEGIN_TABLE(l, n, f)
Definition macro.h:11
#define PRINT_IF_ERROR(expression)
Definition macro.h:28
#define NEXT_COLUMN()
Definition macro.h:18
ImVec4 GetSuccessColor()
Definition ui_helpers.cc:48
bool InputHex(const char *label, uint64_t *data)
Definition input.cc:325
ImVec4 GetWarningColor()
Definition ui_helpers.cc:53
ImVec4 GetInfoColor()
Definition ui_helpers.cc:63
uint32_t SnesToPc(uint32_t addr) noexcept
Definition snes.h:8
void SetComparisonData(const void *data)
void GotoAddrAndHighlight(size_t addr_min, size_t addr_max)
void DrawContents(void *mem_data_void, size_t mem_size, size_t base_display_addr=0x0000)