yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
yaze.cc
Go to the documentation of this file.
1// C API implementation - no heavy GUI/editor dependencies
2#include <cstring>
3#include <memory>
4#include <string>
5#include <vector>
6
8#include "rom/rom.h"
9#include "yaze.h"
10#include "yaze_config.h"
11#include "zelda3/game_data.h"
13
14extern "C" {
15
16// Static variables for library state
17static bool g_library_initialized = false;
18
19// Version and initialization functions
21 if (g_library_initialized) {
22 return YAZE_OK;
23 }
24
25 // Initialize SDL and other subsystems if needed
26 g_library_initialized = true;
27 return YAZE_OK;
28}
29
31 if (!g_library_initialized) {
32 return;
33 }
34
35 // Cleanup subsystems
36 g_library_initialized = false;
37
38 return;
39}
40
42 switch (status) {
43 case YAZE_OK:
44 return "Success";
46 return "Unknown error";
48 return "Invalid argument";
50 return "File not found";
52 return "Memory allocation failed";
53 case YAZE_ERROR_IO:
54 return "I/O operation failed";
56 return "Data corruption detected";
58 return "Component not initialized";
59 default:
60 return "Unknown status code";
61 }
62}
63
65
67
68bool yaze_check_version_compatibility(const char* expected_version) {
69 if (expected_version == nullptr) {
70 return false;
71 }
72 return strcmp(expected_version, YAZE_VERSION_STRING) == 0;
73}
74
75yaze_status yaze_init(yaze_editor_context* context, const char* rom_filename) {
76 if (context == nullptr) {
78 }
79
80 if (!g_library_initialized) {
81 yaze_status init_status = yaze_library_init();
82 if (init_status != YAZE_OK) {
83 return init_status;
84 }
85 }
86
87 context->rom = nullptr;
88 context->error_message = nullptr;
89
90 if (rom_filename != nullptr && strlen(rom_filename) > 0) {
91 context->rom = yaze_load_rom(rom_filename);
92 if (context->rom == nullptr) {
93 context->error_message = "Failed to load ROM file";
95 }
96 }
97
98 return YAZE_OK;
99}
100
102 if (context == nullptr) {
104 }
105
106 if (context->rom != nullptr) {
107 yaze_unload_rom(context->rom);
108 context->rom = nullptr;
109 }
110
111 context->error_message = nullptr;
112 return YAZE_OK;
113}
114
115zelda3_rom* yaze_load_rom(const char* filename) {
116 if (filename == nullptr || strlen(filename) == 0) {
117 return nullptr;
118 }
119
120 auto internal_rom = std::make_unique<yaze::Rom>();
121 if (!internal_rom->LoadFromFile(filename).ok()) {
122 return nullptr;
123 }
124
125 // Create and load GameData
126 auto internal_game_data = std::make_unique<yaze::zelda3::GameData>();
127 auto load_status = yaze::zelda3::LoadGameData(*internal_rom, *internal_game_data);
128 if (!load_status.ok()) {
129 return nullptr;
130 }
131
132 auto* rom = new zelda3_rom();
133 rom->filename = filename;
134 rom->impl = internal_rom.release(); // Transfer ownership
135 rom->game_data = internal_game_data.release(); // Transfer ownership
136 rom->data = const_cast<uint8_t*>(static_cast<yaze::Rom*>(rom->impl)->data());
137 rom->size = static_cast<yaze::Rom*>(rom->impl)->size();
138 rom->version = ZELDA3_VERSION_US; // Default, should be detected
139 rom->is_modified = false;
140 return rom;
141}
142
144 if (rom == nullptr) {
145 return;
146 }
147
148 if (rom->impl != nullptr) {
149 delete static_cast<yaze::Rom*>(rom->impl);
150 rom->impl = nullptr;
151 }
152
153 if (rom->game_data != nullptr) {
154 delete static_cast<yaze::zelda3::GameData*>(rom->game_data);
155 rom->game_data = nullptr;
156 }
157
158 delete rom;
159}
160
161int yaze_save_rom(zelda3_rom* rom, const char* filename) {
162 if (rom == nullptr || filename == nullptr) {
164 }
165
166 if (rom->impl == nullptr) {
168 }
169
170 auto* internal_rom = static_cast<yaze::Rom*>(rom->impl);
171 auto status = internal_rom->SaveToFile(yaze::Rom::SaveSettings{
172 .backup = true, .save_new = false, .filename = filename});
173
174 if (!status.ok()) {
175 return YAZE_ERROR_IO;
176 }
177
178 rom->is_modified = false;
179 return YAZE_OK;
180}
181
182yaze_bitmap yaze_load_bitmap(const char* filename) {
183 yaze_bitmap bitmap;
184 bitmap.width = 0;
185 bitmap.height = 0;
186 bitmap.bpp = 0;
187 bitmap.data = nullptr;
188 return bitmap;
189}
190
192 int palette_set, int palette,
193 int color) {
194 snes_color color_struct;
195 color_struct.red = 0;
196 color_struct.green = 0;
197 color_struct.blue = 0;
198
199 if (rom->game_data) {
200 auto* game_data = static_cast<yaze::zelda3::GameData*>(rom->game_data);
201 auto get_color =
202 game_data->palette_groups
204 ->palette(palette)[color];
205 color_struct = get_color.rom_color();
206
207 return color_struct;
208 }
209
210 return color_struct;
211}
212
214 if (rom->impl == nullptr) {
215 return nullptr;
216 }
217
218 yaze::Rom* internal_rom = static_cast<yaze::Rom*>(rom->impl);
219 auto* game_data = static_cast<yaze::zelda3::GameData*>(rom->game_data);
220 auto internal_overworld = new yaze::zelda3::Overworld(internal_rom, game_data);
221 if (!internal_overworld->Load(internal_rom).ok()) {
222 return nullptr;
223 }
224
225 zelda3_overworld* overworld = new zelda3_overworld();
226 overworld->impl = internal_overworld;
227 int map_id = 0;
228 for (const auto& ow_map : internal_overworld->overworld_maps()) {
229 overworld->maps[map_id] = new zelda3_overworld_map();
230 overworld->maps[map_id]->id = map_id;
231 map_id++;
232 }
233 return overworld;
234}
235
237 int* room_count) {
238 if (room_count != nullptr) {
239 *room_count = 0;
240 }
241 if (rom == nullptr || rom->impl == nullptr) {
242 return nullptr;
243 }
244
245 constexpr int kRoomCount = 256;
246 auto* rooms = new zelda3_dungeon_room[kRoomCount]();
247 for (int i = 0; i < kRoomCount; ++i) {
248 rooms[i].id = static_cast<uint16_t>(i);
249 }
250 if (room_count != nullptr) {
251 *room_count = kRoomCount;
252 }
253 return rooms;
254}
255
257 int* message_count) {
258 if (rom == nullptr || messages == nullptr || message_count == nullptr) {
260 }
261
262 if (rom->impl == nullptr) {
264 }
265
266 try {
267 // Use LoadAllTextData from message_data.h
268 std::vector<yaze::editor::MessageData> message_data =
270
271 *message_count = static_cast<int>(message_data.size());
272 *messages = new zelda3_message[*message_count];
273
274 for (size_t i = 0; i < message_data.size(); ++i) {
275 const auto& msg = message_data[i];
276 (*messages)[i].id = msg.ID;
277 (*messages)[i].rom_address = msg.Address;
278 (*messages)[i].length = static_cast<uint16_t>(msg.RawString.length());
279
280 // Allocate and copy string data
281 (*messages)[i].raw_data = new uint8_t[msg.Data.size()];
282 std::memcpy((*messages)[i].raw_data, msg.Data.data(), msg.Data.size());
283
284 (*messages)[i].parsed_text = new char[msg.ContentsParsed.length() + 1];
285 // Safe string copy with bounds checking
286 std::memcpy((*messages)[i].parsed_text, msg.ContentsParsed.c_str(),
287 msg.ContentsParsed.length());
288 (*messages)[i].parsed_text[msg.ContentsParsed.length()] = '\0';
289
290 (*messages)[i].is_compressed = msg.Data.size() != msg.DataParsed.size();
291 (*messages)[i].encoding_type = 1; // ALttP standard encoding
292 }
293 } catch (const std::exception& e) {
294 return YAZE_ERROR_MEMORY;
295 }
296
297 return YAZE_OK;
298}
299
300// Additional API functions implementation
301
302// Graphics functions
304 if (bitmap != nullptr && bitmap->data != nullptr) {
305 delete[] bitmap->data;
306 bitmap->data = nullptr;
307 bitmap->width = 0;
308 bitmap->height = 0;
309 bitmap->bpp = 0;
310 }
311}
312
313yaze_bitmap yaze_create_bitmap(int width, int height, uint8_t bpp) {
314 yaze_bitmap bitmap = {};
315
316 if (width <= 0 || height <= 0 ||
317 (bpp != 1 && bpp != 2 && bpp != 4 && bpp != 8)) {
318 return bitmap; // Return empty bitmap on invalid args
319 }
320
321 bitmap.width = width;
322 bitmap.height = height;
323 bitmap.bpp = bpp;
324 bitmap.data = new uint8_t[width * height]();
325
326 return bitmap;
327}
328
329snes_color yaze_rgb_to_snes_color(uint8_t r, uint8_t g, uint8_t b) {
330 snes_color color = {};
331 color.red = r; // Store full 8-bit values (existing code expects this)
332 color.green = g;
333 color.blue = b;
334 return color;
335}
336
337void yaze_snes_color_to_rgb(snes_color color, uint8_t* r, uint8_t* g,
338 uint8_t* b) {
339 if (r != nullptr) *r = static_cast<uint8_t>(color.red);
340 if (g != nullptr) *g = static_cast<uint8_t>(color.green);
341 if (b != nullptr) *b = static_cast<uint8_t>(color.blue);
342}
343
344// Version detection functions
345zelda3_version zelda3_detect_version(const uint8_t* rom_data, size_t size) {
346 if (rom_data == nullptr || size < 0x8000) {
348 }
349
350 // SNES LoROM header titles at 0x7FC0 (PC offset)
351 // Titles are 21 bytes long
352 std::string title;
353 for (int i = 0; i < 21; ++i) {
354 char c = static_cast<char>(rom_data[0x7FC0 + i]);
355 if (c >= 0x20 && c < 0x7F) {
356 title += c;
357 }
358 }
359
360 if (absl::StrContains(title, "THE LEGEND OF ZELDA")) {
361 // US or EU version often share this title
362 // Check destination code at 0x7FD9: 0x01 = USA, 0x02+ = PAL regions
363 uint8_t region = rom_data[0x7FD9];
364 if (region == 0x00) return ZELDA3_VERSION_JP;
365 if (region == 0x01) return ZELDA3_VERSION_US;
366 return ZELDA3_VERSION_EU;
367 }
368
369 if (absl::StrContains(title, "ZELDA NO DENSETSU")) {
370 return ZELDA3_VERSION_JP;
371 }
372
373 // Fallback: Check for common randomizer indicators
374 if (absl::StrContains(title, "VT RANDO") ||
375 absl::StrContains(title, "Z3 RANDOMIZER")) {
377 }
378
379 return ZELDA3_VERSION_US; // Default assumption for ALttP clones/hacks
380}
381
383 switch (version) {
385 return "US/North American";
387 return "Japanese";
389 return "European";
391 return "Prototype";
393 return "Randomizer";
394 default:
395 return "Unknown";
396 }
397}
398
400 zelda3_version version) {
401 switch (version) {
403 return &zelda3_us_pointers;
405 return &zelda3_jp_pointers;
406 default:
407 return &zelda3_us_pointers; // Default fallback
408 }
409}
410} // extern "C"
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
absl::Status SaveToFile(const SaveSettings &settings)
Definition rom.cc:165
Represents the full Overworld data, light and dark world.
Definition overworld.h:217
yaze_status yaze_library_init()
Initialize the YAZE library.
Definition yaze.cc:20
int yaze_get_version_number()
Get the current YAZE version number.
Definition yaze.cc:66
const char * yaze_get_version_string()
Get the current YAZE version string.
Definition yaze.cc:64
yaze_status
Status codes returned by YAZE functions.
Definition yaze.h:65
bool yaze_check_version_compatibility(const char *expected_version)
Check if the current YAZE version is compatible with the expected version.
Definition yaze.cc:68
yaze_status yaze_shutdown(yaze_editor_context *context)
Shutdown and clean up a YAZE editor context.
Definition yaze.cc:101
yaze_status yaze_init(yaze_editor_context *context, const char *rom_filename)
Initialize a YAZE editor context.
Definition yaze.cc:75
const char * yaze_status_to_string(yaze_status status)
Convert a status code to a human-readable string.
Definition yaze.cc:41
void yaze_library_shutdown()
Shutdown the YAZE library.
Definition yaze.cc:30
@ YAZE_OK
Definition yaze.h:66
@ YAZE_ERROR_CORRUPTION
Definition yaze.h:72
@ YAZE_ERROR_IO
Definition yaze.h:71
@ YAZE_ERROR_FILE_NOT_FOUND
Definition yaze.h:69
@ YAZE_ERROR_INVALID_ARG
Definition yaze.h:68
@ YAZE_ERROR_MEMORY
Definition yaze.h:70
@ YAZE_ERROR_NOT_INITIALIZED
Definition yaze.h:73
@ YAZE_ERROR_UNKNOWN
Definition yaze.h:67
zelda3_dungeon_room * yaze_load_all_rooms(const zelda3_rom *rom, int *room_count)
Load all dungeon rooms from ROM.
Definition yaze.cc:236
snes_color yaze_rgb_to_snes_color(uint8_t r, uint8_t g, uint8_t b)
Convert RGB888 color to SNES color.
Definition yaze.cc:329
yaze_bitmap yaze_load_bitmap(const char *filename)
Load a bitmap from file.
Definition yaze.cc:182
yaze_bitmap yaze_create_bitmap(int width, int height, uint8_t bpp)
Create an empty bitmap.
Definition yaze.cc:313
void yaze_free_bitmap(yaze_bitmap *bitmap)
Free bitmap data.
Definition yaze.cc:303
void yaze_snes_color_to_rgb(snes_color color, uint8_t *r, uint8_t *g, uint8_t *b)
Convert SNES color to RGB888.
Definition yaze.cc:337
yaze_status yaze_load_messages(const zelda3_rom *rom, zelda3_message **messages, int *message_count)
Load all text messages from ROM.
Definition yaze.cc:256
zelda3_overworld * yaze_load_overworld(const zelda3_rom *rom)
Load the overworld from ROM.
Definition yaze.cc:213
struct zelda3_overworld_map zelda3_overworld_map
Overworld map data.
struct zelda3_overworld zelda3_overworld
Complete overworld data.
void yaze_unload_rom(zelda3_rom *rom)
Unload and free ROM data.
Definition yaze.cc:143
zelda3_rom * yaze_load_rom(const char *filename)
Load a ROM file.
Definition yaze.cc:115
int yaze_save_rom(zelda3_rom *rom, const char *filename)
Save ROM to file.
Definition yaze.cc:161
const char * zelda3_version_to_string(zelda3_version version)
Get version name as string.
Definition yaze.cc:382
struct zelda3_rom zelda3_rom
ROM data structure.
zelda3_version
Different versions of the game supported by YAZE.
Definition zelda.h:33
const zelda3_version_pointers * zelda3_get_version_pointers(zelda3_version version)
Get version-specific pointers.
Definition yaze.cc:399
zelda3_version zelda3_detect_version(const uint8_t *rom_data, size_t size)
Detect ROM version from header data.
Definition yaze.cc:345
@ ZELDA3_VERSION_JP
Definition zelda.h:36
@ ZELDA3_VERSION_PROTO
Definition zelda.h:38
@ ZELDA3_VERSION_EU
Definition zelda.h:37
@ ZELDA3_VERSION_US
Definition zelda.h:35
@ ZELDA3_VERSION_RANDOMIZER
Definition zelda.h:39
@ ZELDA3_VERSION_UNKNOWN
Definition zelda.h:34
snes_color yaze_get_color_from_paletteset(const zelda3_rom *rom, int palette_set, int palette, int color)
Get a color from a palette set.
Definition yaze.cc:191
#define YAZE_VERSION_NUMBER
Definition yaze.h:44
#define YAZE_VERSION_STRING
Definition yaze.h:43
std::vector< MessageData > ReadAllTextData(uint8_t *rom, int pos)
constexpr const char * kPaletteGroupAddressesKeys[]
absl::Status LoadGameData(Rom &rom, GameData &data, const LoadOptions &options)
Loads all Zelda3-specific game data from a generic ROM.
Definition game_data.cc:122
SNES color in 15-bit RGB format (BGR555)
Definition yaze.h:218
uint16_t green
Definition yaze.h:220
uint16_t red
Definition yaze.h:219
uint16_t blue
Definition yaze.h:221
PaletteGroup * get_group(const std::string &group_name)
auto palette(int i) const
gfx::PaletteGroupMap palette_groups
Definition game_data.h:89
Bitmap data structure.
Definition yaze.h:171
uint8_t * data
Definition yaze.h:175
int height
Definition yaze.h:173
uint8_t bpp
Definition yaze.h:174
int width
Definition yaze.h:172
zelda3_rom * rom
Definition yaze.h:50
const char * error_message
Definition yaze.h:51
Complete dungeon room data.
Definition zelda.h:461
In-game text message data.
Definition zelda.h:272
uint16_t id
Definition zelda.h:273
Complete overworld data.
Definition zelda.h:333
void * impl
Definition zelda.h:334
zelda3_overworld_map ** maps
Definition zelda.h:335
ROM data structure.
Definition zelda.h:210
uint8_t * data
Definition zelda.h:212
bool is_modified
Definition zelda.h:215
void * game_data
Definition zelda.h:217
void * impl
Definition zelda.h:216
ROM data pointers for different game versions.
Definition zelda.h:71
Yet Another Zelda3 Editor (YAZE) - Public C API.