yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_entrances_panel.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_DUNGEON_PANELS_DUNGEON_ENTRANCES_PANEL_H_
2#define YAZE_APP_EDITOR_DUNGEON_PANELS_DUNGEON_ENTRANCES_PANEL_H_
3
4#include <array>
5#include <cstdio>
6#include <functional>
7#include <string>
8#include <utility>
9
12#include "app/gui/core/icons.h"
13#include "app/gui/core/input.h"
14#include "imgui/imgui.h"
15#include "util/i18n/tr.h"
16#include "zelda3/common.h"
19
20namespace yaze {
21namespace editor {
22
33 public:
35 std::array<zelda3::RoomEntrance, zelda3::kNumDungeonEntranceSlots>*
36 entrances,
37 std::array<zelda3::DungeonSpawnPoint, zelda3::kNumDungeonSpawnPoints>*
38 spawn_points,
39 int* current_entrance_id, std::function<void(int)> on_entrance_selected)
40 : entrances_(entrances),
41 spawn_points_(spawn_points),
42 current_entrance_id_(current_entrance_id),
43 on_entrance_selected_(std::move(on_entrance_selected)) {}
44
45 // ==========================================================================
46 // WindowContent Identity
47 // ==========================================================================
48
49 std::string GetId() const override { return "dungeon.entrance_properties"; }
50 std::string GetDisplayName() const override { return "Entrance Properties"; }
51 std::string GetIcon() const override { return ICON_MD_TUNE; }
52 std::string GetEditorCategory() const override { return "Dungeon"; }
53 int GetPriority() const override { return 26; }
54
55 // ==========================================================================
56 // WindowContent Drawing
57 // ==========================================================================
58
59 void Draw(bool* p_open) override {
61 return;
62 if (*current_entrance_id_ < 0 ||
63 *current_entrance_id_ >= static_cast<int>(entrances_->size())) {
65 }
66
69 } else {
71 }
72
73 ImGui::Separator();
74
75 // Entrance list
76 // Array layout (from LoadRoomEntrances):
77 // indices 0-6 (0x00-0x06): Spawn points (7 entries)
78 // indices 7-139 (0x07-0x8B): Regular entrances (133 entries)
79 constexpr int kNumSpawnPoints = zelda3::kNumDungeonSpawnPoints;
80 constexpr int kNumEntrances = zelda3::kNumRegularDungeonEntrances;
81 constexpr int kTotalEntries = zelda3::kNumDungeonEntranceSlots;
82
83 if (ImGui::BeginChild("##EntrancesList", ImVec2(0, 0), true,
84 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
85 for (int i = 0; i < kTotalEntries; i++) {
86 std::string entrance_name;
87 if (i < kNumSpawnPoints) {
88 // Spawn points at indices 0-6
89 char buf[32];
90 snprintf(buf, sizeof(buf), "Spawn Point %d", i);
91 entrance_name = buf;
92 } else {
93 // Regular entrances at indices 7-139, mapped to kEntranceNames[0-132]
94 int entrance_id = i - kNumSpawnPoints;
95 if (entrance_id < kNumEntrances) {
96 // Use unified ResourceLabelProvider for entrance names
97 entrance_name = zelda3::GetEntranceLabel(entrance_id);
98 } else {
99 char buf[32];
100 snprintf(buf, sizeof(buf), "Unknown %d", i);
101 entrance_name = buf;
102 }
103 }
104
105 const int room_id = i < kNumSpawnPoints ? (*spawn_points_)[i].room_id
106 : (*entrances_)[i].room_;
107 // Use unified ResourceLabelProvider for room names
108 std::string room_name = zelda3::GetRoomLabel(room_id);
109
110 char label[256];
111 snprintf(label, sizeof(label), "[%02X] %s -> %s (%03X)", i,
112 entrance_name.c_str(), room_name.c_str(), room_id);
113
114 bool is_selected = (*current_entrance_id_ == i);
115 if (ImGui::Selectable(label, is_selected)) {
119 }
120 }
121 }
122 }
123 ImGui::EndChild();
124 }
125
126 private:
127 void DrawSpawnPointProperties(int slot_index) {
128 auto& spawn = (*spawn_points_)[slot_index];
129 const bool properties_editable =
130 CanEditDungeonSpawnPoint(slot_index, spawn);
131 bool changed = false;
132
133 ImGui::Text(tr("Spawn Point %d"), slot_index);
134 if (!properties_editable) {
135 ImGui::TextWrapped(tr(
136 "Spawn point data is unavailable; reload the ROM before editing."));
137 }
138 ImGui::BeginDisabled(!properties_editable);
139
140 changed |= gui::InputHexWord("Entrance ID", &spawn.entrance_id);
141 changed |= gui::InputHexWord("Room ID", &spawn.room_id);
142 ImGui::SameLine();
143 changed |= gui::InputHexByte("Dungeon ID", &spawn.dungeon_id, 50.f, true);
144
145 changed |= gui::InputHexByte("Main GFX", &spawn.main_gfx, 50.f, true);
146 ImGui::SameLine();
147 changed |= gui::InputHexByte("Song", &spawn.song, 50.f, true);
148 ImGui::SameLine();
149 changed |= gui::InputHexByte("Floor", &spawn.floor);
150
151 ImGui::Separator();
152
153 changed |= gui::InputHexWord("Player X", &spawn.x_coordinate);
154 ImGui::SameLine();
155 changed |= gui::InputHexWord("Player Y", &spawn.y_coordinate);
156
157 changed |= gui::InputHexWord("Camera Trigger X", &spawn.camera_trigger_x);
158 ImGui::SameLine();
159 changed |= gui::InputHexWord("Camera Trigger Y", &spawn.camera_trigger_y);
160
161 changed |= gui::InputHexWord("Horizontal Scroll", &spawn.horizontal_scroll);
162 ImGui::SameLine();
163 changed |= gui::InputHexWord("Vertical Scroll", &spawn.vertical_scroll);
164
165 changed |= gui::InputHexWord("Overworld Door Tilemap",
166 &spawn.overworld_door_tilemap, 70.f, true);
167
168 ImGui::Separator();
169 changed |= gui::InputHexByte("Layer", &spawn.layer, 50.f, true);
170 ImGui::SameLine();
171 changed |= gui::InputHexByte("Spawn Quadrant", &spawn.quadrant, 50.f, true);
172 ImGui::SameLine();
173 changed |= gui::InputHexByte("Scroll Controller",
174 &spawn.camera_scroll_controller, 50.f, true);
175
176 ImGui::Separator();
177 ImGui::Text(tr("Camera Boundaries"));
178 ImGui::Separator();
179 ImGui::Text(tr("\t\t\t\t\tNorth East South West"));
180
181 changed |=
182 gui::InputHexByte("Quadrant##SpawnBoundaryQN",
183 &spawn.camera_scroll_boundaries[0], 50.f, true);
184 ImGui::SameLine();
185 changed |= gui::InputHexByte(
186 "##SpawnQE", &spawn.camera_scroll_boundaries[6], 50.f, true);
187 ImGui::SameLine();
188 changed |= gui::InputHexByte(
189 "##SpawnQS", &spawn.camera_scroll_boundaries[2], 50.f, true);
190 ImGui::SameLine();
191 changed |= gui::InputHexByte(
192 "##SpawnQW", &spawn.camera_scroll_boundaries[4], 50.f, true);
193
194 changed |= gui::InputHexByte(
195 "Full room", &spawn.camera_scroll_boundaries[1], 50.f, true);
196 ImGui::SameLine();
197 changed |= gui::InputHexByte(
198 "##SpawnFE", &spawn.camera_scroll_boundaries[7], 50.f, true);
199 ImGui::SameLine();
200 changed |= gui::InputHexByte(
201 "##SpawnFS", &spawn.camera_scroll_boundaries[3], 50.f, true);
202 ImGui::SameLine();
203 changed |= gui::InputHexByte(
204 "##SpawnFW", &spawn.camera_scroll_boundaries[5], 50.f, true);
205 ImGui::EndDisabled();
206
207 MarkDungeonSpawnPointDirtyIfEditable(slot_index, spawn, changed);
208 }
209
210 void DrawRegularEntranceProperties(int slot_index) {
211 auto& entrance = (*entrances_)[slot_index];
212 const bool properties_editable =
213 CanEditDungeonEntrance(slot_index, entrance);
214 bool changed = false;
215
216 ImGui::Text(tr("Entrance ID: %04X"), entrance.entrance_id_);
217 ImGui::BeginDisabled(!properties_editable);
218 changed |= gui::InputHexWord("Room ID", &entrance.room_);
219 ImGui::SameLine();
220 changed |=
221 gui::InputHexByte("Dungeon ID", &entrance.dungeon_id_, 50.f, true);
222
223 changed |= gui::InputHexByte("Blockset", &entrance.blockset_, 50.f, true);
224 ImGui::SameLine();
225 changed |= gui::InputHexByte("Music", &entrance.music_, 50.f, true);
226 ImGui::SameLine();
227 changed |= gui::InputHexByte("Floor", &entrance.floor_);
228
229 ImGui::Separator();
230
231 changed |= gui::InputHexWord("Player X ", &entrance.x_position_);
232 ImGui::SameLine();
233 changed |= gui::InputHexWord("Player Y ", &entrance.y_position_);
234
235 changed |= gui::InputHexWord("Camera X", &entrance.camera_trigger_x_);
236 ImGui::SameLine();
237 changed |= gui::InputHexWord("Camera Y", &entrance.camera_trigger_y_);
238
239 changed |= gui::InputHexWord("Scroll X ", &entrance.camera_x_);
240 ImGui::SameLine();
241 changed |= gui::InputHexWord("Scroll Y ", &entrance.camera_y_);
242
243 changed |= gui::InputHexWord("Exit", &entrance.exit_, 50.f, true);
244
245 ImGui::Separator();
246 ImGui::Text(tr("Camera Boundaries"));
247 ImGui::Separator();
248 ImGui::Text(tr("\t\t\t\t\tNorth East South West"));
249
250 changed |= gui::InputHexByte("Quadrant", &entrance.camera_boundary_qn_,
251 50.f, true);
252 ImGui::SameLine();
253 changed |=
254 gui::InputHexByte("##QE", &entrance.camera_boundary_qe_, 50.f, true);
255 ImGui::SameLine();
256 changed |=
257 gui::InputHexByte("##QS", &entrance.camera_boundary_qs_, 50.f, true);
258 ImGui::SameLine();
259 changed |=
260 gui::InputHexByte("##QW", &entrance.camera_boundary_qw_, 50.f, true);
261
262 changed |= gui::InputHexByte("Full room", &entrance.camera_boundary_fn_,
263 50.f, true);
264 ImGui::SameLine();
265 changed |=
266 gui::InputHexByte("##FE", &entrance.camera_boundary_fe_, 50.f, true);
267 ImGui::SameLine();
268 changed |=
269 gui::InputHexByte("##FS", &entrance.camera_boundary_fs_, 50.f, true);
270 ImGui::SameLine();
271 changed |=
272 gui::InputHexByte("##FW", &entrance.camera_boundary_fw_, 50.f, true);
273 ImGui::EndDisabled();
274
275 MarkDungeonEntranceDirtyIfEditable(slot_index, entrance, changed);
276 }
277
278 std::array<zelda3::RoomEntrance, zelda3::kNumDungeonEntranceSlots>*
279 entrances_ = nullptr;
280 std::array<zelda3::DungeonSpawnPoint, zelda3::kNumDungeonSpawnPoints>*
281 spawn_points_ = nullptr;
282 int* current_entrance_id_ = nullptr;
283 std::function<void(int)> on_entrance_selected_;
284};
285
286} // namespace editor
287} // namespace yaze
288
289#endif // YAZE_APP_EDITOR_DUNGEON_PANELS_DUNGEON_ENTRANCES_PANEL_H_
WindowContent for displaying and editing dungeon entrances.
DungeonEntrancesPanel(std::array< zelda3::RoomEntrance, zelda3::kNumDungeonEntranceSlots > *entrances, std::array< zelda3::DungeonSpawnPoint, zelda3::kNumDungeonSpawnPoints > *spawn_points, int *current_entrance_id, std::function< void(int)> on_entrance_selected)
void Draw(bool *p_open) override
Draw the panel content.
std::function< void(int)> on_entrance_selected_
int GetPriority() const override
Get display priority for menu ordering.
std::array< zelda3::DungeonSpawnPoint, zelda3::kNumDungeonSpawnPoints > * spawn_points_
std::string GetDisplayName() const override
Human-readable name shown in menus and title bars.
std::array< zelda3::RoomEntrance, zelda3::kNumDungeonEntranceSlots > * entrances_
std::string GetEditorCategory() const override
Editor category this panel belongs to.
std::string GetId() const override
Unique identifier for this panel.
std::string GetIcon() const override
Material Design icon for this panel.
Base interface for all logical window content components.
#define ICON_MD_TUNE
Definition icons.h:2022
bool CanEditDungeonEntrance(int slot_index, const zelda3::RoomEntrance &entrance)
bool CanEditDungeonSpawnPoint(int slot_index, const zelda3::DungeonSpawnPoint &spawn)
bool MarkDungeonEntranceDirtyIfEditable(int slot_index, zelda3::RoomEntrance &entrance, bool properties_changed)
bool MarkDungeonSpawnPointDirtyIfEditable(int slot_index, zelda3::DungeonSpawnPoint &spawn, bool properties_changed)
bool InputHexWord(const char *label, uint16_t *data, float input_width, bool no_step)
Definition input.cc:485
bool InputHexByte(const char *label, uint8_t *data, float input_width, bool no_step)
Definition input.cc:506
std::string GetEntranceLabel(int id)
Convenience function to get an entrance label.
std::string GetRoomLabel(int id)
Convenience function to get a room label.
constexpr int kNumRegularDungeonEntrances
constexpr int kNumDungeonSpawnPoints
constexpr int kNumDungeonEntranceSlots