yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
YazeIOSBridge.mm
Go to the documentation of this file.
1#import "YazeIOSBridge.h"
2
3#include <string>
4
5#include "app/application.h"
6#include "app/controller.h"
8#include "app/editor/editor.h"
12#include "core/hack_manifest.h"
14#include "core/project.h"
15#include "rom/rom.h"
16
17@implementation YazeIOSBridge
18
19+ (void)loadRomAtPath:(NSString *)path {
20 if (!path || path.length == 0) {
21 return;
22 }
23 std::string cpp_path([path UTF8String]);
25}
26
27+ (void)openProjectAtPath:(NSString *)path {
28 if (!path || path.length == 0) {
29 return;
30 }
31 auto *controller = yaze::Application::Instance().GetController();
32 if (!controller || !controller->editor_manager()) {
33 return;
34 }
35
36 std::string cpp_path([path UTF8String]);
37 (void)controller->editor_manager()->OpenRomOrProject(cpp_path);
38}
39
40+ (NSString *)currentRomTitle {
41 auto *controller = yaze::Application::Instance().GetController();
42 if (!controller) {
43 return @"";
44 }
45 auto *rom = controller->GetCurrentRom();
46 if (!rom || !rom->is_loaded()) {
47 return @"";
48 }
49 return [NSString stringWithUTF8String:rom->title().c_str()];
50}
51
52+ (void)setOverlayTopInset:(double)inset {
53 yaze::platform::ios::SetOverlayTopInset(static_cast<float>(inset));
54}
55
56+ (void)setTouchScale:(double)scale {
57 yaze::platform::ios::SetTouchScale(static_cast<float>(scale));
58}
59
60+ (void)showProjectFileEditor {
61 auto *controller = yaze::Application::Instance().GetController();
62 if (!controller || !controller->editor_manager()) {
63 return;
64 }
66}
67
68+ (void)showProjectManagement {
69 auto *controller = yaze::Application::Instance().GetController();
70 if (!controller || !controller->editor_manager()) {
71 return;
72 }
74}
75
76+ (void)showPanelBrowser {
77 auto *controller = yaze::Application::Instance().GetController();
78 if (!controller || !controller->editor_manager()) {
79 return;
80 }
81 auto *ui_coordinator = controller->editor_manager()->ui_coordinator();
82 if (ui_coordinator) {
83 ui_coordinator->ShowWindowBrowser();
84 }
85}
86
87+ (void)showCommandPalette {
88 auto *controller = yaze::Application::Instance().GetController();
89 if (!controller || !controller->editor_manager()) {
90 return;
91 }
92 auto *ui_coordinator = controller->editor_manager()->ui_coordinator();
93 if (ui_coordinator) {
94 ui_coordinator->ShowCommandPalette();
95 }
96}
97
98// ─── Editor Actions ─────────────────────────────
99
100+ (void)saveRom {
101 auto *controller = yaze::Application::Instance().GetController();
102 if (!controller || !controller->editor_manager()) {
103 return;
104 }
105 auto status = controller->editor_manager()->SaveRom();
106 if (!status.ok()) {
107 auto *toast = controller->editor_manager()->toast_manager();
108 if (toast) {
109 toast->Show(std::string(status.message()),
111 }
112 }
113}
114
115+ (void)undo {
116 auto *controller = yaze::Application::Instance().GetController();
117 if (!controller || !controller->editor_manager()) {
118 return;
119 }
120 auto *editor = controller->editor_manager()->GetCurrentEditor();
121 if (editor) {
122 (void)editor->Undo();
123 }
124}
125
126+ (void)redo {
127 auto *controller = yaze::Application::Instance().GetController();
128 if (!controller || !controller->editor_manager()) {
129 return;
130 }
131 auto *editor = controller->editor_manager()->GetCurrentEditor();
132 if (editor) {
133 (void)editor->Redo();
134 }
135}
136
137+ (void)switchToEditor:(NSString *)editorName {
138 if (!editorName || editorName.length == 0) {
139 return;
140 }
141 auto *controller = yaze::Application::Instance().GetController();
142 if (!controller || !controller->editor_manager()) {
143 return;
144 }
145 std::string name([editorName UTF8String]);
146 for (size_t i = 0; i < yaze::editor::kEditorNames.size(); ++i) {
147 if (name == yaze::editor::kEditorNames[i]) {
148 controller->editor_manager()->SwitchToEditor(
149 static_cast<yaze::editor::EditorType>(i), /*force_visible=*/true);
150 return;
151 }
152 }
153}
154
155+ (NSArray<NSString *> *)availableEditorTypes {
156 // Return user-facing editor types (skip Unknown, Hex, Agent, Settings).
157 NSMutableArray<NSString *> *result = [NSMutableArray array];
158 for (size_t i = 0; i < yaze::editor::kEditorNames.size(); ++i) {
159 auto type = static_cast<yaze::editor::EditorType>(i);
160 switch (type) {
165 continue;
166 default:
167 [result
168 addObject:[NSString
169 stringWithUTF8String:yaze::editor::kEditorNames[i]]];
170 break;
171 }
172 }
173 return result;
174}
175
176// ─── Editor Status ──────────────────────────────
177
178+ (nullable NSString *)currentEditorType {
179 auto *controller = yaze::Application::Instance().GetController();
180 if (!controller || !controller->editor_manager()) {
181 return nil;
182 }
183 auto *editor = controller->editor_manager()->GetCurrentEditor();
184 if (!editor) {
185 return nil;
186 }
187 auto index = yaze::editor::EditorTypeIndex(editor->type());
188 if (index < yaze::editor::kEditorNames.size()) {
189 return [NSString stringWithUTF8String:yaze::editor::kEditorNames[index]];
190 }
191 return @"Unknown";
192}
193
194+ (nullable NSString *)currentRoomStatus {
195 auto *controller = yaze::Application::Instance().GetController();
196 if (!controller || !controller->editor_manager()) {
197 return nil;
198 }
199 auto *editor = controller->editor_manager()->GetCurrentEditor();
200 if (!editor || editor->type() != yaze::editor::EditorType::kDungeon) {
201 return nil;
202 }
203 auto *dungeon_editor =
204 static_cast<yaze::editor::DungeonEditorV2 *>(editor);
205 int room_id = dungeon_editor->current_room_id();
206 return [NSString stringWithFormat:@"Room 0x%03X", room_id];
207}
208
209+ (NSArray<NSDictionary *> *)getActiveDungeonRooms {
210 auto *controller = yaze::Application::Instance().GetController();
211 if (!controller || !controller->editor_manager()) {
212 return @[];
213 }
214 auto *editor = controller->editor_manager()->GetCurrentEditor();
215 if (!editor || editor->type() != yaze::editor::EditorType::kDungeon) {
216 return @[];
217 }
218
219 auto *dungeon_editor = static_cast<yaze::editor::DungeonEditorV2 *>(editor);
220 const int current_room = dungeon_editor->current_room_id();
221 NSMutableArray<NSDictionary *> *rooms = [NSMutableArray array];
222
223 const auto &active_rooms = dungeon_editor->active_rooms();
224 if (active_rooms.Size > 0) {
225 for (int i = 0; i < active_rooms.Size; ++i) {
226 const int room_id = active_rooms[i];
227 if (room_id < 0 || room_id >= yaze::zelda3::kNumberOfRooms) {
228 continue;
229 }
230 const std::string label = yaze::zelda3::GetRoomLabel(room_id);
231 [rooms addObject:@{
232 @"room_id" : @(room_id),
233 @"name" : [NSString stringWithUTF8String:label.c_str()],
234 @"is_current" : @(room_id == current_room),
235 }];
236 }
237 return rooms;
238 }
239
240 for (int room_id = 0; room_id < yaze::zelda3::kNumberOfRooms; ++room_id) {
241 const std::string label = yaze::zelda3::GetRoomLabel(room_id);
242 [rooms addObject:@{
243 @"room_id" : @(room_id),
244 @"name" : [NSString stringWithUTF8String:label.c_str()],
245 @"is_current" : @(room_id == current_room),
246 }];
247 }
248 return rooms;
249}
250
251+ (void)focusDungeonRoom:(NSInteger)roomID {
252 if (roomID < 0 || roomID >= yaze::zelda3::kNumberOfRooms) {
253 return;
254 }
255
256 auto *controller = yaze::Application::Instance().GetController();
257 if (!controller || !controller->editor_manager()) {
258 return;
259 }
260
261 auto *editor = controller->editor_manager()->GetCurrentEditor();
262 if (!editor || editor->type() != yaze::editor::EditorType::kDungeon) {
263 controller->editor_manager()->SwitchToEditor(yaze::editor::EditorType::kDungeon,
264 /*force_visible=*/true);
265 editor = controller->editor_manager()->GetCurrentEditor();
266 }
267 if (!editor || editor->type() != yaze::editor::EditorType::kDungeon) {
268 return;
269 }
270
271 auto *dungeon_editor = static_cast<yaze::editor::DungeonEditorV2 *>(editor);
272 dungeon_editor->add_room(static_cast<int>(roomID));
273}
274
275// ─── Oracle Integration ──────────────────────────
276
277+ (OracleProgressionData)getProgressionState {
278 OracleProgressionData data = {};
279 auto *controller = yaze::Application::Instance().GetController();
280 if (!controller || !controller->editor_manager()) {
281 return data;
282 }
283
284 const auto &project = *controller->editor_manager()->GetCurrentProject();
285 if (!project.hack_manifest.loaded()) {
286 return data;
287 }
288
289 // Note: In a real scenario, this would read from a loaded .srm file
290 // or live emulator state. For now, return the default zero state.
293 data.game_state = state.game_state;
294 data.oosprog = state.oosprog;
295 data.oosprog2 = state.oosprog2;
296 data.side_quest = state.side_quest;
297 data.pendants = state.pendants;
298 data.crystal_count = state.GetCrystalCount();
299 return data;
300}
301
302+ (nullable NSString *)getStoryEventsJSON {
303 auto *controller = yaze::Application::Instance().GetController();
304 if (!controller || !controller->editor_manager()) {
305 return nil;
306 }
307
308 const auto &project = *controller->editor_manager()->GetCurrentProject();
309 if (!project.hack_manifest.loaded() ||
310 !project.hack_manifest.HasProjectRegistry()) {
311 return nil;
312 }
313
314 const auto &graph = project.hack_manifest.project_registry().story_events;
315 if (!graph.loaded()) {
316 return nil;
317 }
318
319 // Build a JSON array of events
320 NSMutableArray *events = [NSMutableArray array];
321 for (const auto &node : graph.nodes()) {
322 NSMutableDictionary *event = [NSMutableDictionary dictionary];
323 event[@"id"] = [NSString stringWithUTF8String:node.id.c_str()];
324 event[@"name"] = [NSString stringWithUTF8String:node.name.c_str()];
325 event[@"notes"] = [NSString stringWithUTF8String:node.notes.c_str()];
326
327 NSMutableArray *flags = [NSMutableArray array];
328 for (const auto &f : node.flags) {
329 [flags addObject:[NSString stringWithUTF8String:f.name.c_str()]];
330 }
331 event[@"flags"] = flags;
332
333 NSMutableArray *locations = [NSMutableArray array];
334 for (const auto &loc : node.locations) {
335 [locations addObject:[NSString stringWithUTF8String:loc.name.c_str()]];
336 }
337 event[@"locations"] = locations;
338
339 NSMutableArray *text_ids = [NSMutableArray array];
340 for (const auto &tid : node.text_ids) {
341 [text_ids addObject:[NSString stringWithUTF8String:tid.c_str()]];
342 }
343 event[@"text_ids"] = text_ids;
344
345 NSMutableArray *scripts = [NSMutableArray array];
346 for (const auto &s : node.scripts) {
347 [scripts addObject:[NSString stringWithUTF8String:s.c_str()]];
348 }
349 event[@"scripts"] = scripts;
350
351 NSMutableArray *deps = [NSMutableArray array];
352 for (const auto &d : node.dependencies) {
353 [deps addObject:[NSString stringWithUTF8String:d.c_str()]];
354 }
355 event[@"dependencies"] = deps;
356
357 NSMutableArray *unlocks = [NSMutableArray array];
358 for (const auto &u : node.unlocks) {
359 [unlocks addObject:[NSString stringWithUTF8String:u.c_str()]];
360 }
361 event[@"unlocks"] = unlocks;
362
363 [events addObject:event];
364 }
365
366 NSError *error = nil;
367 NSData *jsonData = [NSJSONSerialization dataWithJSONObject:events
368 options:0
369 error:&error];
370 if (error || !jsonData) {
371 return nil;
372 }
373 return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
374}
375
376+ (NSArray<NSDictionary *> *)getDungeonRooms:(NSString *)dungeonId {
377 if (!dungeonId) {
378 return @[];
379 }
380
381 auto *controller = yaze::Application::Instance().GetController();
382 if (!controller || !controller->editor_manager()) {
383 return @[];
384 }
385
386 const auto &project = *controller->editor_manager()->GetCurrentProject();
387 if (!project.hack_manifest.loaded() ||
388 !project.hack_manifest.HasProjectRegistry()) {
389 return @[];
390 }
391
392 std::string target_id([dungeonId UTF8String]);
393 const auto &registry = project.hack_manifest.project_registry();
394
395 for (const auto &dungeon : registry.dungeons) {
396 if (dungeon.id == target_id) {
397 NSMutableArray *rooms = [NSMutableArray array];
398 for (const auto &room : dungeon.rooms) {
399 [rooms addObject:@{
400 @"room_id" : @(room.id),
401 @"name" : [NSString stringWithUTF8String:room.name.c_str()],
402 @"type" : [NSString stringWithUTF8String:room.type.c_str()],
403 }];
404 }
405 return rooms;
406 }
407 }
408 return @[];
409}
410
411@end
Controller * GetController()
Definition application.h:81
static Application & Instance()
void LoadRom(const std::string &path)
editor::EditorManager * editor_manager()
Definition controller.h:80
bool is_loaded() const
Definition rom.h:155
const ProjectRegistry & project_registry() const
DungeonEditorV2 - Simplified dungeon editor using component delegation.
UICoordinator * ui_coordinator()
void ShowProjectManagement()
Injects dependencies into all editors within an EditorSet.
auto GetCurrentEditor() const -> Editor *override
project::YazeProject * GetCurrentProject()
void ShowCommandPalette(const char *initial_query=nullptr)
Rom * rom()
Get the current ROM instance.
constexpr std::array< const char *, 14 > kEditorNames
Definition editor.h:226
size_t EditorTypeIndex(EditorType type)
Definition editor.h:235
void SetOverlayTopInset(float top)
void SetTouchScale(float scale)
std::string GetRoomLabel(int id)
Convenience function to get a room label.
constexpr int kNumberOfRooms
Interop structs for passing data from C++ to Swift.
Oracle of Secrets game progression state parsed from SRAM.
int GetCrystalCount() const
Count completed dungeons using popcount on crystal bitfield.
core::HackManifest hack_manifest
Definition project.h:212
std::string switchToEditor(std::string editor_name)