yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
overworld_sidebar.cc
Go to the documentation of this file.
3#include "util/i18n/tr.h"
4
5#include <algorithm>
6#include <cfloat>
7#include <cstring>
8
9#include "absl/strings/str_format.h"
12#include "app/gui/core/icons.h"
13#include "app/gui/core/input.h"
16#include "imgui/imgui.h"
17#include "zelda3/common.h"
20
21namespace yaze {
22namespace editor {
23
24namespace {
25
26constexpr float kFieldLabelWidth = 118.0f;
27constexpr const char* kLabelPopupId = "OverworldPropertyLabelPopup";
28
29// Music bytes are indexed by story progress, not by the preview game state.
30constexpr const char* kMusicLabels[] = {"Music: start", "Music: Zelda saved",
31 "Music: Master Sword",
32 "Music: Agahnim"};
33constexpr const char* kMusicTooltips[] = {
34 "Track before rescuing Zelda",
35 "Track after rescuing Zelda from Hyrule Castle",
36 "Track after drawing the Master Sword", "Track after defeating Agahnim"};
37
38std::string FormatId(int id, int width) {
39 return width <= 2 ? absl::StrFormat("0x%02X", id)
40 : absl::StrFormat("0x%04X", id);
41}
42
43} // namespace
44
46 MapPropertiesSystem* map_properties_system)
47 : overworld_(overworld),
48 rom_(rom),
49 map_properties_system_(map_properties_system) {}
50
51void OverworldSidebar::Draw(int& current_world, int& current_map,
52 bool& current_map_lock, int& game_state,
53 bool& show_custom_bg_color_editor,
54 bool& show_overlay_editor,
55 project::YazeProject* project) {
57 return;
58 }
59 project_ = project;
60
61 if (ImGui::BeginChild("OverworldSidebar", ImVec2(0, 0), false,
62 ImGuiWindowFlags_None)) {
63 ImGui::PushID("OverworldSidebar");
64 const auto* selected = overworld_->overworld_map(current_map);
65 if (!selected) {
66 ImGui::TextDisabled(tr("Current map selection is invalid."));
67 ImGui::TextDisabled(
68 tr("Hover or jump to a valid overworld map to continue."));
69 ImGui::PopID();
70 ImGui::EndChild();
71 return;
72 }
73
74 // Multi-area maps store their properties on the parent.
75 const int parent = selected->parent();
76 const int property_map =
77 (parent >= 0 && parent < zelda3::kNumOverworldMaps &&
79 ? parent
80 : current_map;
81 if (edit_error_map_ != property_map) {
82 edit_error_map_ = property_map;
83 edit_error_.clear();
84 }
85
86 DrawHeader(current_world, current_map, property_map, current_map_lock,
87 game_state);
88
89 if (ImGui::CollapsingHeader(tr("Area"), ImGuiTreeNodeFlags_DefaultOpen)) {
90 DrawAreaSection(property_map, game_state);
91 }
92 if (ImGui::CollapsingHeader(tr("Graphics"),
93 ImGuiTreeNodeFlags_DefaultOpen)) {
94 DrawGraphicsSection(property_map, game_state);
95 }
96 if (ImGui::CollapsingHeader(tr("Palettes"),
97 ImGuiTreeNodeFlags_DefaultOpen)) {
98 DrawPaletteSection(property_map, game_state, show_custom_bg_color_editor);
99 }
100 if (ImGui::CollapsingHeader(tr("Music"))) {
101 DrawMusicSection(property_map);
102 }
103 if (ImGui::CollapsingHeader(tr("Effects"))) {
104 DrawEffectsSection(property_map, show_overlay_editor);
105 }
106
107 if (!edit_error_.empty()) {
108 ImGui::Spacing();
109 ImGui::TextColored(gui::GetErrorColor(), "%s", edit_error_.c_str());
110 }
112 ImGui::PopID();
113 }
114 ImGui::EndChild();
115}
116
118 bool current_map_lock,
119 project::YazeProject* project,
120 bool compact) {
121 if (!overworld_ || !overworld_->is_loaded() || !rom_ ||
123 return;
124 }
125 const auto* selected = overworld_->overworld_map(current_map);
126 if (!selected) {
127 return;
128 }
129 project_ = project;
130 const int parent = selected->parent();
131 const int property_map = parent >= 0 && parent < zelda3::kNumOverworldMaps &&
133 ? parent
134 : current_map;
135 const auto* map = overworld_->overworld_map(property_map);
136 if (edit_error_map_ != property_map) {
137 edit_error_map_ = property_map;
138 edit_error_.clear();
139 }
140
141 ImGui::PushID("OverworldAppearance");
142 // Include the target in widget IDs: an unfinished text edit must not migrate
143 // to another area when cursor-follow changes the current map.
144 ImGui::PushID(property_map);
145 if (!compact) {
146 ImGui::AlignTextToFramePadding();
147 ImGui::Text("Area %02X%s", property_map,
148 current_map_lock ? " (pinned)" : " (follow)");
149 if (ImGui::IsItemHovered()) {
150 ImGui::SetTooltip(
151 "Appearance edits apply to area %02X and its shared screens.\n"
152 "Unpinned controls follow the cursor over the canvas.\n"
153 "Pin the map to keep editing this area while navigating.",
154 property_map);
155 }
156 }
157 const float row_start = ImGui::GetCursorPosX();
158 const float right = row_start + ImGui::GetContentRegionAvail().x;
159 const float input_width =
160 ImGui::CalcTextSize("FF").x + ImGui::GetStyle().FramePadding.x * 2.0f;
161 bool first_field = true;
162 const auto field = [&](const char* label, const char* tip,
163 OverworldPropertyField kind, uint8_t value) {
164 const float width = ImGui::CalcTextSize(label).x + input_width +
165 ImGui::GetStyle().ItemInnerSpacing.x;
166 if (compact ? !first_field
167 : ImGui::GetItemRectMax().x - ImGui::GetWindowPos().x +
168 ImGui::GetScrollX() +
169 ImGui::GetStyle().ItemSpacing.x + width <=
170 right) {
171 ImGui::SameLine();
172 }
173 first_field = false;
174 ImGui::BeginGroup();
175 ImGui::AlignTextToFramePadding();
176 ImGui::TextUnformatted(
177 compact
178 ? (kind == OverworldPropertyField::kAreaGraphics ? "GFX" : "Pal")
179 : label);
180 ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x);
181 ImGui::PushID(label);
182 if (gui::InputHexByte("##Value", &value, input_width, /*no_step=*/true)) {
183 Apply(kind, 0, property_map, value);
184 }
186 std::string("OverworldToolbar/field:") + label, "input",
187 ImGui::GetItemID());
188 ImGui::PopID();
189 ImGui::EndGroup();
190 if (ImGui::IsItemHovered()) {
191 ImGui::SetTooltip(
192 "%s\nHexadecimal ID. Changes refresh the canvas and "
193 "Tile16 preview; undo restores the previous value.%s%s",
194 tip,
195 edit_error_.empty() ? "" : "\nEdit failed: ", edit_error_.c_str());
196 }
197 };
198 field("Graphics", "Tile graphics group assigned to this area",
199 OverworldPropertyField::kAreaGraphics, map->area_graphics());
200 field("Palette", "Area palette set assigned to this area",
201 OverworldPropertyField::kAreaPalette, map->area_palette());
203 if (!compact &&
205 field("Main palette", "Extended main palette assigned to this area",
206 OverworldPropertyField::kMainPalette, map->main_palette());
207 }
208 if (!edit_error_.empty() && !compact) {
209 ImGui::TextWrapped("%s", edit_error_.c_str());
210 }
211 ImGui::PopID();
212 ImGui::PopID();
213}
214
215void OverworldSidebar::DrawHeader(int current_world, int current_map,
216 int property_map, bool& current_map_lock,
217 int game_state) {
218 const auto metadata = BuildOverworldMapMetadata(*overworld_, rom_, project_,
219 current_map, game_state);
220 // Title on its own line (map names can be long); actions below it.
221 ImGui::TextWrapped(ICON_MD_MAP " %s", metadata.map_title.c_str());
222
224 current_map_lock ? ICON_MD_PUSH_PIN : ICON_MD_GPS_FIXED,
225 current_map_lock ? "Pinned: properties stay on this map.\n"
226 "Click to follow the cursor again."
227 : "Following the cursor.\n"
228 "Click to pin properties to this map.",
229 current_map_lock)) {
230 current_map_lock = !current_map_lock;
231 }
232 ImGui::SameLine(0, 2);
233 ImGui::AlignTextToFramePadding();
234 ImGui::TextDisabled("%s", current_map_lock ? "Pinned" : "Follow");
235 ImGui::SameLine(0, 6);
236 ImGui::BeginDisabled(project_ == nullptr);
238 project_ ? "Rename this map in the project"
239 : "Open a project to name maps")) {
240 label_target_ = {"Map name", "overworld_map", current_map, 2};
241 open_label_popup_ = true;
242 }
243 ImGui::EndDisabled();
244 ImGui::SameLine();
245 ImGui::AlignTextToFramePadding();
246 ImGui::TextDisabled("%s", metadata.area_size_label.c_str());
247
248 (void)current_world; // The title already names the world.
249 if (property_map != current_map) {
250 // Multi-screen areas: values below belong to the parent screen.
251 ImGui::TextDisabled("%s", metadata.parent_label.c_str());
252 ImGui::SameLine();
253 }
254 ImGui::TextDisabled(ICON_MD_INFO " %s", metadata.version_label.c_str());
255 if (ImGui::IsItemHovered()) {
256 ImGui::SetTooltip(
257 "%s", tr("ROM version determines available overworld features.\n"
258 "v2+: custom BG colors, main palettes\n"
259 "v3+: wide/tall areas, custom tile GFX, animated GFX"));
260 }
261 ImGui::Spacing();
262}
263
265 if (!ImGui::BeginTable(id, 2, ImGuiTableFlags_SizingFixedFit)) {
266 return false;
267 }
268 ImGui::TableSetupColumn("Label", ImGuiTableColumnFlags_WidthFixed,
269 kFieldLabelWidth);
270 ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
271 return true;
272}
273
274void OverworldSidebar::FieldLabel(const char* label, const char* tooltip) {
275 ImGui::TableNextRow();
276 ImGui::TableNextColumn();
277 ImGui::AlignTextToFramePadding();
278 ImGui::TextUnformatted(label);
279 if (tooltip && ImGui::IsItemHovered()) {
280 ImGui::SetTooltip("%s", tooltip);
281 }
282 ImGui::TableNextColumn();
283}
284
286 int property_map, int value) {
287 const auto status = map_properties_system_->ApplyPropertyEdit(
288 {property_map, field, index, value});
289 edit_error_ = status.ok() ? "" : std::string(status.message());
290}
291
292bool OverworldSidebar::HexByteField(const char* id, const char* label,
293 const char* tooltip,
294 OverworldPropertyField field, int index,
295 int property_map, uint8_t value,
296 const LabelTarget* label_target) {
297 FieldLabel(label, tooltip);
298 ImGui::PushID(id);
299 const bool changed =
300 gui::InputHexByte("##Value", &value, ImGui::GetContentRegionAvail().x,
301 /*no_step=*/true);
302 if (changed) {
303 Apply(field, index, property_map, value);
304 }
305 if (label_target) {
306 if (ImGui::IsItemHovered()) {
307 const std::string project_label = GetProjectResourceLabel(
308 project_, label_target->type, label_target->id);
309 ImGui::SetTooltip(
310 "%s\n%s\n%s", tooltip ? tooltip : label,
311 project_label.empty()
312 ? tr("No project label")
313 : absl::StrFormat("Label: %s", project_label).c_str(),
314 tr("Right-click to rename the label"));
315 }
316 LabelContextMenu(*label_target);
317 }
318 ImGui::PopID();
319 return changed;
320}
321
323 if (ImGui::BeginPopupContextItem("##LabelMenu")) {
324 ImGui::BeginDisabled(project_ == nullptr);
325 if (ImGui::MenuItem(ICON_MD_LABEL " Rename label...")) {
326 label_target_ = target;
327 open_label_popup_ = true;
328 }
329 ImGui::EndDisabled();
330 if (!project_) {
331 ImGui::TextDisabled("%s", tr("Open a project to store labels"));
332 }
333 ImGui::EndPopup();
334 }
335}
336
338 if (open_label_popup_) {
339 open_label_popup_ = false;
340 label_error_.clear();
341 const std::string current =
343 std::strncpy(label_buffer_.data(), current.c_str(),
344 label_buffer_.size() - 1);
345 label_buffer_[label_buffer_.size() - 1] = '\0';
346 ImGui::OpenPopup(kLabelPopupId);
347 }
348 if (!ImGui::BeginPopup(kLabelPopupId)) {
349 return;
350 }
351 ImGui::Text("%s %s %s", ICON_MD_LABEL, label_target_.title.c_str(),
352 FormatId(label_target_.id, label_target_.hex_width).c_str());
353 ImGui::SetNextItemWidth(260.0f);
354 if (ImGui::IsWindowAppearing()) {
355 ImGui::SetKeyboardFocusHere();
356 }
357 const bool submitted = ImGui::InputText("##LabelInput", label_buffer_.data(),
358 label_buffer_.size(),
359 ImGuiInputTextFlags_EnterReturnsTrue);
360 auto apply = [&](const std::string& label) {
361 const auto status =
365 label_target_.id, label);
366 if (status.ok()) {
367 label_error_.clear();
368 ImGui::CloseCurrentPopup();
369 } else {
370 label_error_ = std::string(status.message());
371 }
372 };
373 if (ImGui::Button(ICON_MD_CHECK " Apply") || submitted) {
374 apply(label_buffer_.data());
375 }
376 ImGui::SameLine();
377 if (ImGui::Button(ICON_MD_CLEAR " Clear")) {
378 apply("");
379 }
380 if (!label_error_.empty()) {
381 ImGui::TextWrapped("%s", label_error_.c_str());
382 }
383 ImGui::EndPopup();
384}
385
386void OverworldSidebar::DrawAreaSection(int property_map, int& game_state) {
387 const auto* map = overworld_->overworld_map(property_map);
388 if (!map || !BeginFieldTable("AreaFields")) {
389 return;
390 }
391
392 FieldLabel(tr("Game state"),
393 tr("Story state to preview. Sprite graphics and sprite "
394 "palettes below are stored per game state."));
395 ImGui::SetNextItemWidth(-FLT_MIN);
396 int selected_state = game_state;
397 if (ImGui::Combo("##GameState", &selected_state, kGameStateNames, 3) &&
399 on_story_changed(selected_state);
400 }
401
402 FieldLabel(tr("Area size"), tr("Screens this area spans. Wide and Tall need "
403 "ZSCustomOverworld v3."));
404 const auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
405 int area_size = static_cast<int>(map->area_size());
406 ImGui::SetNextItemWidth(-FLT_MIN);
408 if (ImGui::Combo("##AreaSize", &area_size, kAreaSizeNames, 4)) {
409 Apply(OverworldPropertyField::kAreaSize, 0, property_map, area_size);
410 }
411 } else {
412 const char* limited_names[] = {"Small (1x1)", "Large (2x2)"};
413 int limited = (area_size == 0 || area_size == 1) ? area_size : 0;
414 if (ImGui::Combo("##AreaSize", &limited, limited_names, 2)) {
415 const auto size = limited == 1 ? zelda3::AreaSizeEnum::LargeArea
418 static_cast<int>(size));
419 }
420 }
421
422 const LabelTarget message_label{"Message", "message", map->message_id(), 4};
423 FieldLabel(tr("Message"), tr("Area name message shown on entry (hex)"));
424 ImGui::PushID("Message");
425 uint16_t message_id = map->message_id();
426 if (gui::InputHexWord("##Value", &message_id,
427 ImGui::GetContentRegionAvail().x, /*no_step=*/true)) {
428 Apply(OverworldPropertyField::kMessageId, 0, property_map, message_id);
429 }
430 LabelContextMenu(message_label);
431 ImGui::PopID();
432 ImGui::EndTable();
433}
434
435void OverworldSidebar::DrawGraphicsSection(int property_map, int game_state) {
436 const auto* map = overworld_->overworld_map(property_map);
437 if (!map || !BeginFieldTable("GraphicsFields")) {
438 return;
439 }
440 const auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
441 const int state = std::clamp(game_state, 0, 2);
442
443 const LabelTarget area_gfx{"Area graphics", "graphics", map->area_graphics()};
444 HexByteField("AreaGfx", tr("Area graphics"),
445 tr("Tile graphics group for this area (hex)"),
447 map->area_graphics(), &area_gfx);
448
449 const std::string sprite_tip = absl::StrFormat(
450 "Sprite graphics group while in \"%s\" (hex)", kGameStateNames[state]);
451 const LabelTarget sprite_gfx{"Sprite graphics", "graphics",
452 map->sprite_graphics(state)};
453 HexByteField("SpriteGfx", tr("Sprite graphics"), sprite_tip.c_str(),
454 OverworldPropertyField::kSpriteGraphics, state, property_map,
455 map->sprite_graphics(state), &sprite_gfx);
456
458 const LabelTarget animated{"Animated graphics", "graphics",
459 map->animated_gfx()};
460 HexByteField("AnimatedGfx", tr("Animated graphics"),
461 tr("Animated tile sheet (water, flowers) (hex)"),
463 map->animated_gfx(), &animated);
464 }
465 ImGui::EndTable();
466
468 ImGui::TreeNode(tr("Custom tile sheets"))) {
469 if (BeginFieldTable("CustomTileSheets")) {
470 for (int i = 0; i < 8; ++i) {
471 const std::string id = absl::StrFormat("Sheet%d", i);
472 const std::string label = absl::StrFormat("Sheet %d", i);
473 const std::string tip =
474 absl::StrFormat("Custom graphics sheet slot %d (hex)", i);
475 HexByteField(id.c_str(), label.c_str(), tip.c_str(),
477 map->custom_tileset(i));
478 }
479 ImGui::EndTable();
480 }
481 ImGui::TreePop();
482 }
483}
484
485void OverworldSidebar::DrawPaletteSection(int property_map, int game_state,
486 bool& show_custom_bg_color_editor) {
487 const auto* map = overworld_->overworld_map(property_map);
488 if (!map || !BeginFieldTable("PaletteFields")) {
489 return;
490 }
491 const auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
492 const int state = std::clamp(game_state, 0, 2);
493
494 const LabelTarget area_palette{"Area palette", "overworld_area_palette",
495 map->area_palette()};
496 HexByteField("AreaPalette", tr("Area palette"), tr("Area palette set (hex)"),
498 map->area_palette(), &area_palette);
499
501 const LabelTarget main_palette{"Main palette", "overworld_main_palette",
502 map->main_palette()};
503 HexByteField("MainPalette", tr("Main palette"),
504 tr("Extended main palette (ZSCustomOverworld v2+) (hex)"),
506 map->main_palette(), &main_palette);
507 }
508
509 const std::string sprite_tip = absl::StrFormat(
510 "Sprite palette while in \"%s\" (hex)", kGameStateNames[state]);
511 const LabelTarget sprite_palette{"Sprite palette", "overworld_sprite_palette",
512 map->sprite_palette(state)};
513 HexByteField("SpritePalette", tr("Sprite palette"), sprite_tip.c_str(),
514 OverworldPropertyField::kSpritePalette, state, property_map,
515 map->sprite_palette(state), &sprite_palette);
516 ImGui::EndTable();
517
519 if (ImGui::Button(ICON_MD_FORMAT_COLOR_FILL " Background color...",
520 ImVec2(-FLT_MIN, 0))) {
521 show_custom_bg_color_editor = true;
522 }
523 }
524}
525
527 const auto* map = overworld_->overworld_map(property_map);
528 if (!map || !BeginFieldTable("MusicFields")) {
529 return;
530 }
531 for (int i = 0; i < 4; ++i) {
532 const std::string id = absl::StrFormat("Music%d", i);
533 const LabelTarget music{kMusicLabels[i], "overworld_music",
534 map->area_music(i)};
535 HexByteField(id.c_str(), tr(kMusicLabels[i]), tr(kMusicTooltips[i]),
536 OverworldPropertyField::kMusic, i, property_map,
537 map->area_music(i), &music);
538 }
539 ImGui::EndTable();
540}
541
543 bool& show_overlay_editor) {
544 auto* map = overworld_->mutable_overworld_map(property_map);
545 if (!map) {
546 return;
547 }
548 const auto rom_version = zelda3::OverworldVersionHelper::GetVersion(*rom_);
549 if (rom_version != zelda3::OverworldVersion::kVanilla) {
550 if (ImGui::Button(ICON_MD_LAYERS " Visual effects...",
551 ImVec2(-FLT_MIN, 0))) {
552 show_overlay_editor = true;
553 }
554 }
555
556 ImGui::TextUnformatted(tr("Mosaic transition"));
558 std::array<bool, 4> mosaic = map->mosaic_expanded();
559 const char* directions[] = {"North", "South", "East", "West"};
560 if (ImGui::BeginTable("MosaicTable", 2)) {
561 for (int i = 0; i < 4; ++i) {
562 ImGui::TableNextColumn();
563 if (ImGui::Checkbox(tr(directions[i]), &mosaic[i])) {
565 mosaic[i] ? 1 : 0);
566 }
567 }
568 ImGui::EndTable();
569 }
570 } else {
571 bool mosaic = *map->mutable_mosaic();
572 if (ImGui::Checkbox(tr("Mosaic effect"), &mosaic)) {
573 Apply(OverworldPropertyField::kMosaic, 0, property_map, mosaic ? 1 : 0);
574 }
575 }
576}
577
578} // namespace editor
579} // namespace yaze
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:49
absl::Status ApplyPropertyEdit(const OverworldPropertyEdit &edit)
void FieldLabel(const char *label, const char *tooltip)
void DrawQuickProperties(int current_map, bool current_map_lock, project::YazeProject *project=nullptr, bool compact=false)
void DrawAreaSection(int property_map, int &game_state)
void LabelContextMenu(const LabelTarget &target)
void DrawGraphicsSection(int property_map, int game_state)
MapPropertiesSystem * map_properties_system_
std::function< void(int)> on_story_changed
void DrawPaletteSection(int property_map, int game_state, bool &show_custom_bg_color_editor)
OverworldSidebar(zelda3::Overworld *overworld, Rom *rom, MapPropertiesSystem *map_properties_system)
bool HexByteField(const char *id, const char *label, const char *tooltip, OverworldPropertyField field, int index, int property_map, uint8_t value, const LabelTarget *label_target=nullptr)
void DrawMusicSection(int property_map)
std::array< char, 128 > label_buffer_
void Draw(int &current_world, int &current_map, bool &current_map_lock, int &game_state, bool &show_custom_bg_color_editor, bool &show_overlay_editor, project::YazeProject *project=nullptr)
void DrawEffectsSection(int property_map, bool &show_overlay_editor)
void Apply(OverworldPropertyField field, int index, int property_map, int value)
void DrawHeader(int current_world, int current_map, int property_map, bool &current_map_lock, int game_state)
project::YazeProject * project_
void RegisterWidget(const std::string &full_path, const std::string &type, ImGuiID imgui_id, const std::string &description="", const WidgetMetadata &metadata=WidgetMetadata())
static WidgetIdRegistry & Instance()
static bool SupportsCustomBGColors(OverworldVersion version)
Check if ROM supports custom background colors per area (v2+)
static OverworldVersion GetVersion(const Rom &rom)
Detect ROM version from ASM marker byte.
static bool SupportsAreaEnum(OverworldVersion version)
Check if ROM supports area enum system (v3+ only)
static bool SupportsAnimatedGFX(OverworldVersion version)
Check if ROM supports animated GFX selection (v3+)
static bool SupportsExpandedSpace(OverworldVersion version)
Check if ROM uses expanded ROM space for overworld data.
auto is_loaded() const
Definition overworld.h:803
auto overworld_map(int i) const
Definition overworld.h:737
auto mutable_overworld_map(int i)
Definition overworld.h:743
#define ICON_MD_INFO
Definition icons.h:993
#define ICON_MD_GPS_FIXED
Definition icons.h:883
#define ICON_MD_CHECK
Definition icons.h:397
#define ICON_MD_MAP
Definition icons.h:1173
#define ICON_MD_LABEL
Definition icons.h:1053
#define ICON_MD_FORMAT_COLOR_FILL
Definition icons.h:830
#define ICON_MD_EDIT
Definition icons.h:645
#define ICON_MD_LAYERS
Definition icons.h:1068
#define ICON_MD_CLEAR
Definition icons.h:416
#define ICON_MD_PUSH_PIN
Definition icons.h:1529
absl::Status RenameProjectResourceLabel(project::YazeProject *project, const std::string &type, int id, const std::string &label)
constexpr const char * kAreaSizeNames[]
OverworldMapMetadata BuildOverworldMapMetadata(const zelda3::Overworld &overworld, const Rom *rom, const project::YazeProject *project, int map_id, int game_state)
std::string GetProjectResourceLabel(const project::YazeProject *project, const std::string &type, int id)
constexpr const char * kGameStateNames[]
Definition ui_constants.h:8
bool InputHexWord(const char *label, uint16_t *data, float input_width, bool no_step)
Definition input.cc:489
ImVec4 GetErrorColor()
Definition ui_helpers.cc:59
bool ToolbarIconButton(const char *icon, const char *tooltip, bool is_active)
Convenience wrapper for toolbar-sized icon buttons.
bool InputHexByte(const char *label, uint8_t *data, float input_width, bool no_step)
Definition input.cc:510
constexpr int kNumOverworldMaps
Definition common.h:85
@ kVanilla
0xFF in ROM, no ZScream ASM applied
Modern project structure with comprehensive settings consolidation.
Definition project.h:287