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 }
82}
83
84+ (void)showCommandPalette {
85 auto *controller = yaze::Application::Instance().GetController();
86 if (!controller || !controller->editor_manager()) {
87 return;
88 }
90}
91
92// ─── Editor Actions ─────────────────────────────
93
94+ (void)saveRom {
95 auto *controller = yaze::Application::Instance().GetController();
96 if (!controller || !controller->editor_manager()) {
97 return;
98 }
99 auto status = controller->editor_manager()->SaveRom();
100 if (!status.ok()) {
101 auto *toast = controller->editor_manager()->toast_manager();
102 if (toast) {
103 toast->Show(std::string(status.message()),
105 }
106 }
107}
108
109+ (void)undo {
110 auto *controller = yaze::Application::Instance().GetController();
111 if (!controller || !controller->editor_manager()) {
112 return;
113 }
114 auto *editor = controller->editor_manager()->GetCurrentEditor();
115 if (editor) {
116 (void)editor->Undo();
117 }
118}
119
120+ (void)redo {
121 auto *controller = yaze::Application::Instance().GetController();
122 if (!controller || !controller->editor_manager()) {
123 return;
124 }
125 auto *editor = controller->editor_manager()->GetCurrentEditor();
126 if (editor) {
127 (void)editor->Redo();
128 }
129}
130
131+ (void)switchToEditor:(NSString *)editorName {
132 if (!editorName || editorName.length == 0) {
133 return;
134 }
135 auto *controller = yaze::Application::Instance().GetController();
136 if (!controller || !controller->editor_manager()) {
137 return;
138 }
139 std::string name([editorName UTF8String]);
140 for (size_t i = 0; i < yaze::editor::kEditorNames.size(); ++i) {
141 if (name == yaze::editor::kEditorNames[i]) {
142 controller->editor_manager()->SwitchToEditor(
143 static_cast<yaze::editor::EditorType>(i), /*force_visible=*/true);
144 return;
145 }
146 }
147}
148
149+ (NSArray<NSString *> *)availableEditorTypes {
150 // Return user-facing editor types (skip Unknown, Hex, Agent, Settings).
151 NSMutableArray<NSString *> *result = [NSMutableArray array];
152 for (size_t i = 0; i < yaze::editor::kEditorNames.size(); ++i) {
153 auto type = static_cast<yaze::editor::EditorType>(i);
154 switch (type) {
159 continue;
160 default:
161 [result
162 addObject:[NSString
163 stringWithUTF8String:yaze::editor::kEditorNames[i]]];
164 break;
165 }
166 }
167 return result;
168}
169
170// ─── Editor Status ──────────────────────────────
171
172+ (nullable NSString *)currentEditorType {
173 auto *controller = yaze::Application::Instance().GetController();
174 if (!controller || !controller->editor_manager()) {
175 return nil;
176 }
177 auto *editor = controller->editor_manager()->GetCurrentEditor();
178 if (!editor) {
179 return nil;
180 }
181 auto index = yaze::editor::EditorTypeIndex(editor->type());
182 if (index < yaze::editor::kEditorNames.size()) {
183 return [NSString stringWithUTF8String:yaze::editor::kEditorNames[index]];
184 }
185 return @"Unknown";
186}
187
188+ (nullable NSString *)currentRoomStatus {
189 auto *controller = yaze::Application::Instance().GetController();
190 if (!controller || !controller->editor_manager()) {
191 return nil;
192 }
193 auto *editor = controller->editor_manager()->GetCurrentEditor();
194 if (!editor || editor->type() != yaze::editor::EditorType::kDungeon) {
195 return nil;
196 }
197 auto *dungeon_editor =
198 static_cast<yaze::editor::DungeonEditorV2 *>(editor);
199 int room_id = dungeon_editor->current_room_id();
200 return [NSString stringWithFormat:@"Room 0x%03X", room_id];
201}
202
203+ (NSArray<NSDictionary *> *)getActiveDungeonRooms {
204 auto *controller = yaze::Application::Instance().GetController();
205 if (!controller || !controller->editor_manager()) {
206 return @[];
207 }
208 auto *editor = controller->editor_manager()->GetCurrentEditor();
209 if (!editor || editor->type() != yaze::editor::EditorType::kDungeon) {
210 return @[];
211 }
212
213 auto *dungeon_editor = static_cast<yaze::editor::DungeonEditorV2 *>(editor);
214 const int current_room = dungeon_editor->current_room_id();
215 NSMutableArray<NSDictionary *> *rooms = [NSMutableArray array];
216
217 const auto &active_rooms = dungeon_editor->active_rooms();
218 if (active_rooms.Size > 0) {
219 for (int i = 0; i < active_rooms.Size; ++i) {
220 const int room_id = active_rooms[i];
221 if (room_id < 0 || room_id >= yaze::zelda3::kNumberOfRooms) {
222 continue;
223 }
224 const std::string label = yaze::zelda3::GetRoomLabel(room_id);
225 [rooms addObject:@{
226 @"room_id" : @(room_id),
227 @"name" : [NSString stringWithUTF8String:label.c_str()],
228 @"is_current" : @(room_id == current_room),
229 }];
230 }
231 return rooms;
232 }
233
234 for (int room_id = 0; room_id < yaze::zelda3::kNumberOfRooms; ++room_id) {
235 const std::string label = yaze::zelda3::GetRoomLabel(room_id);
236 [rooms addObject:@{
237 @"room_id" : @(room_id),
238 @"name" : [NSString stringWithUTF8String:label.c_str()],
239 @"is_current" : @(room_id == current_room),
240 }];
241 }
242 return rooms;
243}
244
245+ (void)focusDungeonRoom:(NSInteger)roomID {
246 if (roomID < 0 || roomID >= yaze::zelda3::kNumberOfRooms) {
247 return;
248 }
249
250 auto *controller = yaze::Application::Instance().GetController();
251 if (!controller || !controller->editor_manager()) {
252 return;
253 }
254
255 auto *editor = controller->editor_manager()->GetCurrentEditor();
256 if (!editor || editor->type() != yaze::editor::EditorType::kDungeon) {
257 controller->editor_manager()->SwitchToEditor(yaze::editor::EditorType::kDungeon,
258 /*force_visible=*/true);
259 editor = controller->editor_manager()->GetCurrentEditor();
260 }
261 if (!editor || editor->type() != yaze::editor::EditorType::kDungeon) {
262 return;
263 }
264
265 auto *dungeon_editor = static_cast<yaze::editor::DungeonEditorV2 *>(editor);
266 dungeon_editor->add_room(static_cast<int>(roomID));
267}
268
269// ─── Oracle Integration ──────────────────────────
270
271+ (OracleProgressionData)getProgressionState {
272 OracleProgressionData data = {};
273 auto *controller = yaze::Application::Instance().GetController();
274 if (!controller || !controller->editor_manager()) {
275 return data;
276 }
277
278 const auto &project = *controller->editor_manager()->GetCurrentProject();
279 if (!project.hack_manifest.loaded()) {
280 return data;
281 }
282
283 // Note: In a real scenario, this would read from a loaded .srm file
284 // or live emulator state. For now, return the default zero state.
287 data.game_state = state.game_state;
288 data.oosprog = state.oosprog;
289 data.oosprog2 = state.oosprog2;
290 data.side_quest = state.side_quest;
291 data.pendants = state.pendants;
292 data.crystal_count = state.GetCrystalCount();
293 return data;
294}
295
296+ (nullable NSString *)getStoryEventsJSON {
297 auto *controller = yaze::Application::Instance().GetController();
298 if (!controller || !controller->editor_manager()) {
299 return nil;
300 }
301
302 const auto &project = *controller->editor_manager()->GetCurrentProject();
303 if (!project.hack_manifest.loaded() ||
304 !project.hack_manifest.HasProjectRegistry()) {
305 return nil;
306 }
307
308 const auto &graph = project.hack_manifest.project_registry().story_events;
309 if (!graph.loaded()) {
310 return nil;
311 }
312
313 // Build a JSON array of events
314 NSMutableArray *events = [NSMutableArray array];
315 for (const auto &node : graph.nodes()) {
316 NSMutableDictionary *event = [NSMutableDictionary dictionary];
317 event[@"id"] = [NSString stringWithUTF8String:node.id.c_str()];
318 event[@"name"] = [NSString stringWithUTF8String:node.name.c_str()];
319 event[@"notes"] = [NSString stringWithUTF8String:node.notes.c_str()];
320
321 NSMutableArray *flags = [NSMutableArray array];
322 for (const auto &f : node.flags) {
323 [flags addObject:[NSString stringWithUTF8String:f.name.c_str()]];
324 }
325 event[@"flags"] = flags;
326
327 NSMutableArray *locations = [NSMutableArray array];
328 for (const auto &loc : node.locations) {
329 [locations addObject:[NSString stringWithUTF8String:loc.name.c_str()]];
330 }
331 event[@"locations"] = locations;
332
333 NSMutableArray *text_ids = [NSMutableArray array];
334 for (const auto &tid : node.text_ids) {
335 [text_ids addObject:[NSString stringWithUTF8String:tid.c_str()]];
336 }
337 event[@"text_ids"] = text_ids;
338
339 NSMutableArray *scripts = [NSMutableArray array];
340 for (const auto &s : node.scripts) {
341 [scripts addObject:[NSString stringWithUTF8String:s.c_str()]];
342 }
343 event[@"scripts"] = scripts;
344
345 NSMutableArray *deps = [NSMutableArray array];
346 for (const auto &d : node.dependencies) {
347 [deps addObject:[NSString stringWithUTF8String:d.c_str()]];
348 }
349 event[@"dependencies"] = deps;
350
351 NSMutableArray *unlocks = [NSMutableArray array];
352 for (const auto &u : node.unlocks) {
353 [unlocks addObject:[NSString stringWithUTF8String:u.c_str()]];
354 }
355 event[@"unlocks"] = unlocks;
356
357 [events addObject:event];
358 }
359
360 NSError *error = nil;
361 NSData *jsonData = [NSJSONSerialization dataWithJSONObject:events
362 options:0
363 error:&error];
364 if (error || !jsonData) {
365 return nil;
366 }
367 return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
368}
369
370+ (NSArray<NSDictionary *> *)getDungeonRooms:(NSString *)dungeonId {
371 if (!dungeonId) {
372 return @[];
373 }
374
375 auto *controller = yaze::Application::Instance().GetController();
376 if (!controller || !controller->editor_manager()) {
377 return @[];
378 }
379
380 const auto &project = *controller->editor_manager()->GetCurrentProject();
381 if (!project.hack_manifest.loaded() ||
382 !project.hack_manifest.HasProjectRegistry()) {
383 return @[];
384 }
385
386 std::string target_id([dungeonId UTF8String]);
387 const auto &registry = project.hack_manifest.project_registry();
388
389 for (const auto &dungeon : registry.dungeons) {
390 if (dungeon.id == target_id) {
391 NSMutableArray *rooms = [NSMutableArray array];
392 for (const auto &room : dungeon.rooms) {
393 [rooms addObject:@{
394 @"room_id" : @(room.id),
395 @"name" : [NSString stringWithUTF8String:room.name.c_str()],
396 @"type" : [NSString stringWithUTF8String:room.type.c_str()],
397 }];
398 }
399 return rooms;
400 }
401 }
402 return @[];
403}
404
405@end
Controller * GetController()
Definition application.h:81
static Application & Instance()
void LoadRom(const std::string &path)
editor::EditorManager * editor_manager()
Definition controller.h:69
bool is_loaded() const
Definition rom.h:132
const ProjectRegistry & project_registry() const
DungeonEditorV2 - Simplified dungeon editor using component delegation.
void ShowProjectManagement()
Injects dependencies into all editors within an EditorSet.
auto GetCurrentEditor() const -> Editor *
project::YazeProject * GetCurrentProject()
Rom * rom()
Get the current ROM instance.
constexpr std::array< const char *, 14 > kEditorNames
Definition editor.h:217
size_t EditorTypeIndex(EditorType type)
Definition editor.h:226
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:160
std::string switchToEditor(std::string editor_name)