yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
overworld_sidebar.cc
Go to the documentation of this file.
2
7#include "imgui/imgui.h"
10
11namespace yaze {
12namespace editor {
13
14using ImGui::Separator;
15using ImGui::Text;
16
18 MapPropertiesSystem* map_properties_system)
19 : overworld_(overworld),
20 rom_(rom),
21 map_properties_system_(map_properties_system) {}
22
23void OverworldSidebar::Draw(int& current_world, int& current_map,
24 bool& current_map_lock, int& game_state,
25 bool& show_custom_bg_color_editor,
26 bool& show_overlay_editor) {
27 if (!overworld_->is_loaded()) {
28 return;
29 }
30
31 // Use a child window for the sidebar to allow scrolling
32 if (ImGui::BeginChild("OverworldSidebar", ImVec2(0, 0), false,
33 ImGuiWindowFlags_None)) {
34 DrawMapSelection(current_world, current_map, current_map_lock);
35
36 ImGui::Spacing();
37 Separator();
38 ImGui::Spacing();
39
40 // Use CollapsingHeader layout for better visibility and configurability
41 if (ImGui::CollapsingHeader("General Settings",
42 ImGuiTreeNodeFlags_DefaultOpen)) {
43 DrawBasicPropertiesTab(current_map, game_state,
44 show_custom_bg_color_editor,
45 show_overlay_editor);
46 }
47
48 if (ImGui::CollapsingHeader("Graphics", ImGuiTreeNodeFlags_DefaultOpen)) {
49 DrawGraphicsTab(current_map, game_state);
50 }
51
52 if (ImGui::CollapsingHeader("Sprites")) {
53 DrawSpritePropertiesTab(current_map, game_state);
54 }
55
56 if (ImGui::CollapsingHeader("Music")) {
57 DrawMusicTab(current_map);
58 }
59 }
60 ImGui::EndChild();
61}
62
63void OverworldSidebar::DrawBasicPropertiesTab(int current_map, int& game_state,
64 bool& show_custom_bg_color_editor,
65 bool& show_overlay_editor) {
66 ImGui::Spacing();
67 DrawConfiguration(current_map, game_state, show_overlay_editor);
68 ImGui::Spacing();
69 Separator();
70 ImGui::Spacing();
71 DrawPaletteSettings(current_map, game_state, show_custom_bg_color_editor);
72}
73
74void OverworldSidebar::DrawGraphicsTab(int current_map, int game_state) {
75 ImGui::Spacing();
76 DrawGraphicsSettings(current_map, game_state);
77}
78
80 int game_state) {
81 ImGui::Spacing();
82 // Reuse existing logic from MapPropertiesSystem if possible, or reimplement
83 // Here we'll reimplement a simplified version based on what was in MapPropertiesSystem
84
85 ImGui::Text(ICON_MD_PEST_CONTROL_RODENT " Sprite Settings");
86 ImGui::Separator();
87
88 // Sprite Graphics (already in Graphics tab, but useful here too)
89 if (gui::InputHexByte("Sprite GFX",
91 ->mutable_sprite_graphics(game_state),
96 }
97
98 // Sprite Palette (already in General->Palettes, but useful here too)
99 if (gui::InputHexByte("Sprite Palette",
101 ->mutable_sprite_palette(game_state),
105 }
106}
107
108void OverworldSidebar::DrawMusicTab(int current_map) {
109 ImGui::Spacing();
110 ImGui::Text(ICON_MD_MUSIC_NOTE " Music Settings");
111 ImGui::Separator();
112
113 // Music byte 1
114 uint8_t* music_byte =
115 overworld_->mutable_overworld_map(current_map)->mutable_area_music(0);
116 if (gui::InputHexByte("Music Byte 1", music_byte, kHexByteInputWidth)) {
117 // No refresh needed usually
118 }
119
120 // Music byte 2
121 music_byte =
122 overworld_->mutable_overworld_map(current_map)->mutable_area_music(1);
123 if (gui::InputHexByte("Music Byte 2", music_byte, kHexByteInputWidth)) {
124 // No refresh needed usually
125 }
126
127 // Music byte 3
128 music_byte =
129 overworld_->mutable_overworld_map(current_map)->mutable_area_music(2);
130 if (gui::InputHexByte("Music Byte 3", music_byte, kHexByteInputWidth)) {
131 // No refresh needed usually
132 }
133
134 // Music byte 4
135 music_byte =
136 overworld_->mutable_overworld_map(current_map)->mutable_area_music(3);
137 if (gui::InputHexByte("Music Byte 4", music_byte, kHexByteInputWidth)) {
138 // No refresh needed usually
139 }
140}
141
142void OverworldSidebar::DrawMapSelection(int& current_world, int& current_map,
143 bool& current_map_lock) {
144 ImGui::Text(ICON_MD_MAP " Map Selection");
145
146 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
147 ImGui::Combo("##world", &current_world, kWorldNames, 3);
148
149 ImGui::BeginGroup();
150 ImGui::Text("ID: %02X", current_map);
151 ImGui::SameLine();
152 if (ImGui::Button(current_map_lock ? ICON_MD_LOCK : ICON_MD_LOCK_OPEN)) {
153 current_map_lock = !current_map_lock;
154 }
155 if (ImGui::IsItemHovered()) {
156 ImGui::SetTooltip(current_map_lock ? "Unlock Map" : "Lock Map");
157 }
158 ImGui::EndGroup();
159
160}
161
162void OverworldSidebar::DrawGraphicsSettings(int current_map, int game_state) {
163 ImGui::Text(ICON_MD_IMAGE " Graphics");
164
165 // Area Graphics
166 if (gui::InputHexByte("Area GFX",
168 ->mutable_area_graphics(),
171 overworld_->mutable_overworld_map(current_map)->LoadAreaGraphics();
175 }
176
177 // Sprite Graphics
178 if (gui::InputHexByte("Spr GFX",
180 ->mutable_sprite_graphics(game_state),
185 }
186
187 // Animated Graphics (v3+)
190 if (gui::InputHexByte("Ani GFX",
192 ->mutable_animated_gfx(),
198 }
199 }
200
201 // Custom Tile Graphics (v1+)
203 if (ImGui::TreeNode("Custom Tile Graphics")) {
204 if (ImGui::BeginTable("CustomTileGraphics", 2, ImGuiTableFlags_SizingFixedFit)) {
205 for (int i = 0; i < 8; i++) {
206 ImGui::TableNextColumn();
207 std::string label = absl::StrFormat("Sheet %d", i);
208 if (gui::InputHexByte(label.c_str(),
210 ->mutable_custom_tileset(i),
216 }
217 if (ImGui::IsItemHovered()) {
218 ImGui::SetTooltip("Custom graphics sheet %d (0x00-0xFF)", i);
219 }
220 }
221 ImGui::EndTable();
222 }
223 ImGui::TreePop();
224 }
225 }
226}
227
228void OverworldSidebar::DrawPaletteSettings(int current_map, int game_state,
229 bool& show_custom_bg_color_editor) {
230 ImGui::Text(ICON_MD_PALETTE " Palettes");
231
232 // Area Palette
233 if (gui::InputHexByte("Area Pal",
235 ->mutable_area_palette(),
240 }
241
242 // Main Palette (v2+)
245 if (gui::InputHexByte("Main Pal",
247 ->mutable_main_palette(),
252 }
253 }
254
255 // Sprite Palette
256 if (gui::InputHexByte("Spr Pal",
258 ->mutable_sprite_palette(game_state),
262 }
263
264 // Custom Background Color Button
266 if (ImGui::Button(ICON_MD_FORMAT_COLOR_FILL " Custom BG Color")) {
267 show_custom_bg_color_editor = !show_custom_bg_color_editor;
268 }
269 }
270}
271
272void OverworldSidebar::DrawConfiguration(int current_map, int& game_state,
273 bool& show_overlay_editor) {
274 if (ImGui::BeginTable("ConfigTable", 2, ImGuiTableFlags_SizingFixedFit)) {
275 ImGui::TableSetupColumn("Label", ImGuiTableColumnFlags_WidthFixed, 100.0f);
276 ImGui::TableSetupColumn("Control", ImGuiTableColumnFlags_WidthStretch);
277
278 // Game State
279 ImGui::TableNextColumn();
280 ImGui::Text(ICON_MD_GAMEPAD " Game State");
281 ImGui::TableNextColumn();
282 ImGui::SetNextItemWidth(-1);
283 if (ImGui::Combo("##GameState", &game_state, kGameStateNames, 3)) {
286 }
287
288 // Area Size
289 ImGui::TableNextColumn();
290 ImGui::Text(ICON_MD_PHOTO_SIZE_SELECT_LARGE " Area Size");
291 ImGui::TableNextColumn();
292
294 int current_area_size =
295 static_cast<int>(overworld_->overworld_map(current_map)->area_size());
296
297 ImGui::SetNextItemWidth(-1);
299 if (ImGui::Combo("##AreaSize", &current_area_size, kAreaSizeNames, 4)) {
300 auto status = overworld_->ConfigureMultiAreaMap(
301 current_map, static_cast<zelda3::AreaSizeEnum>(current_area_size));
302 if (status.ok()) {
305 }
306 }
307 } else {
308 const char* limited_names[] = {"Small (1x1)", "Large (2x2)"};
309 int limited_size = (current_area_size == 0 || current_area_size == 1)
310 ? current_area_size
311 : 0;
312 if (ImGui::Combo("##AreaSize", &limited_size, limited_names, 2)) {
313 auto size = (limited_size == 1) ? zelda3::AreaSizeEnum::LargeArea
315 auto status = overworld_->ConfigureMultiAreaMap(current_map, size);
316 if (status.ok()) {
319 }
320 }
321 }
322
323 // Message ID
324 ImGui::TableNextColumn();
325 ImGui::Text(ICON_MD_MESSAGE " Message ID");
326 ImGui::TableNextColumn();
327 ImGui::SetNextItemWidth(-1);
328 if (gui::InputHexWordCustom("##MsgID",
330 ->mutable_message_id(),
334 }
335
336 ImGui::EndTable();
337 }
338
339 // Visual Effects (Overlay)
341 if (rom_version != zelda3::OverworldVersion::kVanilla) {
342 if (ImGui::Button(ICON_MD_LAYERS " Visual Effects", ImVec2(-1, 0))) {
343 show_overlay_editor = !show_overlay_editor;
344 }
345 }
346
347 // Mosaic Settings
348 ImGui::Separator();
349 ImGui::Text(ICON_MD_GRID_ON " Mosaic");
350
352 auto* current_map_ptr = overworld_->mutable_overworld_map(current_map);
353 std::array<bool, 4> mosaic_expanded = current_map_ptr->mosaic_expanded();
354 const char* direction_names[] = {"North", "South", "East", "West"};
355
356 if (ImGui::BeginTable("MosaicTable", 2)) {
357 for (int i = 0; i < 4; i++) {
358 ImGui::TableNextColumn();
359 if (ImGui::Checkbox(direction_names[i], &mosaic_expanded[i])) {
360 current_map_ptr->set_mosaic_expanded(i, mosaic_expanded[i]);
363 }
364 }
365 ImGui::EndTable();
366 }
367 } else {
368 if (ImGui::Checkbox(
369 "Mosaic Effect",
370 overworld_->mutable_overworld_map(current_map)->mutable_mosaic())) {
373 }
374 }
375}
376
377} // namespace editor
378} // 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:24
void RefreshSiblingMapGraphics(int map_index, bool include_self=false)
void DrawSpritePropertiesTab(int current_map, int game_state)
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)
void DrawGraphicsTab(int current_map, int game_state)
void DrawConfiguration(int current_map, int &game_state, bool &show_overlay_editor)
MapPropertiesSystem * map_properties_system_
void DrawBasicPropertiesTab(int current_map, int &game_state, bool &show_custom_bg_color_editor, bool &show_overlay_editor)
void DrawPaletteSettings(int current_map, int game_state, bool &show_custom_bg_color_editor)
OverworldSidebar(zelda3::Overworld *overworld, Rom *rom, MapPropertiesSystem *map_properties_system)
void DrawMapSelection(int &current_world, int &current_map, bool &current_map_lock)
void DrawGraphicsSettings(int current_map, int game_state)
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.
Represents the full Overworld data, light and dark world.
Definition overworld.h:217
auto is_loaded() const
Definition overworld.h:528
auto overworld_map(int i) const
Definition overworld.h:473
auto mutable_overworld_map(int i)
Definition overworld.h:479
absl::Status ConfigureMultiAreaMap(int parent_index, AreaSizeEnum size)
Configure a multi-area map structure (Large/Wide/Tall)
Definition overworld.cc:306
#define ICON_MD_LOCK_OPEN
Definition icons.h:1142
#define ICON_MD_LOCK
Definition icons.h:1140
#define ICON_MD_PHOTO_SIZE_SELECT_LARGE
Definition icons.h:1459
#define ICON_MD_MAP
Definition icons.h:1173
#define ICON_MD_MESSAGE
Definition icons.h:1201
#define ICON_MD_FORMAT_COLOR_FILL
Definition icons.h:830
#define ICON_MD_MUSIC_NOTE
Definition icons.h:1264
#define ICON_MD_GRID_ON
Definition icons.h:896
#define ICON_MD_LAYERS
Definition icons.h:1068
#define ICON_MD_IMAGE
Definition icons.h:982
#define ICON_MD_PALETTE
Definition icons.h:1370
#define ICON_MD_PEST_CONTROL_RODENT
Definition icons.h:1430
#define ICON_MD_GAMEPAD
Definition icons.h:866
constexpr const char * kAreaSizeNames[]
constexpr const char * kWorldNames[]
constexpr float kHexByteInputWidth
constexpr const char * kGameStateNames[]
Definition ui_constants.h:8
constexpr float kHexWordInputWidth
bool InputHexWordCustom(const char *label, uint16_t *data, float input_width)
Definition input.cc:726
bool InputHexByte(const char *label, uint8_t *data, float input_width, bool no_step)
Definition input.cc:370
AreaSizeEnum
Area size enumeration for v3+ ROMs.
@ kVanilla
0xFF in ROM, no ZScream ASM applied