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