yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
game_data.cc
Go to the documentation of this file.
1#include "zelda3/game_data.h"
2
3#include "absl/strings/str_format.h"
5#include "core/rom_settings.h"
6#include "util/log.h"
7#include "util/macro.h"
9
10#include <algorithm>
11
12#ifdef __EMSCRIPTEN__
14#endif
15
16namespace yaze {
17namespace zelda3 {
18
19namespace {
20
21constexpr uint32_t kUncompressedSheetSize = 0x0800;
22// constexpr uint32_t kTile16Ptr = 0x78000;
23
24// Helper to get address from bytes
25uint32_t AddressFromBytes(uint8_t bank, uint8_t high, uint8_t low) {
26 return (bank << 16) | (high << 8) | low;
27}
28
29// Helper to convert SNES to PC address
30uint32_t SnesToPc(uint32_t snes_addr) {
31 return (snes_addr & 0x7FFF) | ((snes_addr & 0x7F0000) >> 1);
32}
33
35 size_t offset = 0;
36 int length = 0;
37 bool valid = false;
38};
39
41 const int palette_size = static_cast<int>(palette.size());
42 if (palette_size <= 0) {
43 return {};
44 }
45
46 const bool has_explicit_transparent =
47 palette_size >= 16 && (palette_size % 16 == 0);
48 PaletteSlice slice;
49 slice.offset = has_explicit_transparent ? 1 : 0;
50 slice.length = has_explicit_transparent ? 15 : std::min(palette_size, 15);
51 slice.valid =
52 slice.length > 0 &&
53 (slice.offset + static_cast<size_t>(slice.length) <= palette.size());
54
55 if (!slice.valid) {
56 slice.offset = 0;
57 slice.length = std::min(palette_size, 15);
58 slice.valid =
59 slice.length > 0 &&
60 (slice.offset + static_cast<size_t>(slice.length) <= palette.size());
61 }
62
63 return slice;
64}
65
66void ApplyDefaultPalette(gfx::Bitmap& bitmap, const gfx::SnesPalette& palette) {
67 auto slice = GetDefaultPaletteSlice(palette);
68 if (!slice.valid) {
69 return;
70 }
71 bitmap.SetPaletteWithTransparent(palette, slice.offset, slice.length);
72}
73
74// Helper to convert PC to SNES address
75// uint32_t PcToSnes(uint32_t pc_addr) {
76// return ((pc_addr & 0x7FFF) | 0x8000) | ((pc_addr & 0x3F8000) << 1);
77// }
78
79// ============================================================================
80// Graphics Address Resolution
81// ============================================================================
82
108} // namespace
109
112uint32_t GetGraphicsAddress(const uint8_t* data, uint8_t addr, uint32_t ptr1,
113 uint32_t ptr2, uint32_t ptr3, size_t rom_size) {
114 if (ptr1 > UINT32_MAX - addr || ptr1 + addr >= rom_size ||
115 ptr2 > UINT32_MAX - addr || ptr2 + addr >= rom_size ||
116 ptr3 > UINT32_MAX - addr || ptr3 + addr >= rom_size) {
117 return static_cast<uint32_t>(rom_size);
118 }
119 return SnesToPc(AddressFromBytes(data[ptr1 + addr], data[ptr2 + addr],
120 data[ptr3 + addr]));
121}
122
123absl::Status LoadGameData(Rom& rom, GameData& data,
124 const LoadOptions& options) {
125 data.Clear();
126 data.set_rom(&rom);
127
128 if (options.populate_metadata) {
129 RETURN_IF_ERROR(LoadMetadata(rom, data));
130 }
131
132 if (options.load_palettes) {
133 RETURN_IF_ERROR(LoadPalettes(rom, data));
134 }
135
136 if (options.load_gfx_groups) {
137 RETURN_IF_ERROR(LoadGfxGroups(rom, data));
138 }
139
140 if (options.load_graphics) {
141 RETURN_IF_ERROR(LoadGraphics(rom, data));
142 }
143
144 if (options.expand_rom) {
145 if (rom.size() < 1048576 * 2) {
146 rom.Expand(1048576 * 2);
147 }
148 }
149
150 return absl::OkStatus();
151}
152
153absl::Status SaveGameData(Rom& rom, GameData& data) {
154 if (core::FeatureFlags::get().kSaveAllPalettes) {
155 // TODO: Implement SaveAllPalettes logic using Rom::WriteColor
156 // This was previously in Rom::SaveAllPalettes
157 return data.palette_groups.for_each(
158 [&](gfx::PaletteGroup& group) -> absl::Status {
159 for (size_t i = 0; i < group.size(); ++i) {
160 auto* palette = group.mutable_palette(i);
161 for (size_t j = 0; j < palette->size(); ++j) {
162 gfx::SnesColor color = (*palette)[j];
163 if (color.is_modified()) {
164 RETURN_IF_ERROR(rom.WriteColor(
165 gfx::GetPaletteAddress(group.name(), i, j), color));
166 color.set_modified(false);
167 }
168 }
169 }
170 return absl::OkStatus();
171 });
172 }
173
175 RETURN_IF_ERROR(SaveGfxGroups(rom, data));
176 }
177
178 // TODO: Implement SaveAllGraphicsData logic
179 return absl::OkStatus();
180}
181
182absl::Status LoadMetadata(const Rom& rom, GameData& data) {
183 constexpr uint32_t kTitleStringOffset = 0x7FC0;
184 constexpr uint32_t kTitleStringLength = 20;
185
186 if (rom.size() < kTitleStringOffset + kTitleStringLength) {
187 return absl::OutOfRangeError("ROM too small for metadata");
188 }
189
190 // Check version byte at offset + 0x19 (0x7FD9)
191 if (kTitleStringOffset + 0x19 < rom.size()) {
192 // Access directly via data() since ReadByte is non-const
193 uint8_t version_byte = rom.data()[kTitleStringOffset + 0x19];
194 data.version =
195 (version_byte == 0) ? zelda3_version::JP : zelda3_version::US;
196 }
197
198 auto title_bytes = rom.ReadByteVector(kTitleStringOffset, kTitleStringLength);
199 if (title_bytes.ok()) {
200 data.title.assign(title_bytes->begin(), title_bytes->end());
201 }
202
203 return absl::OkStatus();
204}
205
206absl::Status LoadPalettes(const Rom& rom, GameData& data) {
207 // Create a vector from rom data for palette loading
208 const std::vector<uint8_t>& rom_vec = rom.vector();
209 return gfx::LoadAllPalettes(rom_vec, data.palette_groups);
210}
211
212absl::Status LoadGfxGroups(Rom& rom, GameData& data) {
213 if (kVersionConstantsMap.find(data.version) == kVersionConstantsMap.end()) {
214 return absl::FailedPreconditionError("Unsupported ROM version");
215 }
216
217 auto version_constants = kVersionConstantsMap.at(data.version);
218
219 // Load Main Blocksets
220 auto main_ptr_res = rom.ReadWord(kGfxGroupsPointer);
221 if (main_ptr_res.ok()) {
222 uint32_t main_ptr = SnesToPc(*main_ptr_res);
223 for (uint32_t i = 0; i < kNumMainBlocksets; i++) {
224 for (int j = 0; j < 8; j++) {
225 auto val = rom.ReadByte(main_ptr + (i * 8) + j);
226 if (val.ok())
227 data.main_blockset_ids[i][j] = *val;
228 }
229 }
230 }
231
232 // Load Room Blocksets
233 for (uint32_t i = 0; i < kNumRoomBlocksets; i++) {
234 for (int j = 0; j < 4; j++) {
235 auto val = rom.ReadByte(kEntranceGfxGroup + (i * 4) + j);
236 if (val.ok())
237 data.room_blockset_ids[i][j] = *val;
238 }
239 }
240
241 // Load Sprite Blocksets
242 for (uint32_t i = 0; i < kNumSpritesets; i++) {
243 for (int j = 0; j < 4; j++) {
244 auto val =
245 rom.ReadByte(version_constants.kSpriteBlocksetPointer + (i * 4) + j);
246 if (val.ok())
247 data.spriteset_ids[i][j] = *val;
248 }
249 }
250
251 // Load Palette Sets
252 for (uint32_t i = 0; i < kNumPalettesets; i++) {
253 for (int j = 0; j < 4; j++) {
254 auto val =
255 rom.ReadByte(version_constants.kDungeonPalettesGroups + (i * 4) + j);
256 if (val.ok())
257 data.paletteset_ids[i][j] = *val;
258 }
259 }
260
261 return absl::OkStatus();
262}
263
264absl::Status SaveGfxGroups(Rom& rom, const GameData& data) {
265 auto version_constants = kVersionConstantsMap.at(data.version);
266
267 ASSIGN_OR_RETURN(auto main_ptr, rom.ReadWord(kGfxGroupsPointer));
268 main_ptr = SnesToPc(main_ptr);
269
270 // Save Main Blocksets
271 for (uint32_t i = 0; i < kNumMainBlocksets; i++) {
272 for (int j = 0; j < 8; j++) {
274 rom.WriteByte(main_ptr + (i * 8) + j, data.main_blockset_ids[i][j]));
275 }
276 }
277
278 // Save Room Blocksets
279 for (uint32_t i = 0; i < kNumRoomBlocksets; i++) {
280 for (int j = 0; j < 4; j++) {
282 data.room_blockset_ids[i][j]));
283 }
284 }
285
286 // Save Sprite Blocksets
287 for (uint32_t i = 0; i < kNumSpritesets; i++) {
288 for (int j = 0; j < 4; j++) {
290 rom.WriteByte(version_constants.kSpriteBlocksetPointer + (i * 4) + j,
291 data.spriteset_ids[i][j]));
292 }
293 }
294
295 // Save Palette Sets
296 for (uint32_t i = 0; i < kNumPalettesets; i++) {
297 for (int j = 0; j < 4; j++) {
299 rom.WriteByte(version_constants.kDungeonPalettesGroups + (i * 4) + j,
300 data.paletteset_ids[i][j]));
301 }
302 }
303
304 return absl::OkStatus();
305}
306
307// ============================================================================
308// Main Graphics Loading
309// ============================================================================
310
341 std::vector<uint8_t> data;
342 bool is_compressed = false;
344 bool is_bpp3 = false; // true if 3BPP, false if skipped/2BPP
345 uint32_t pc_offset = 0;
346};
347
348SheetLoadResult LoadSheetRaw(const Rom& rom, uint32_t i, uint32_t ptr1,
349 uint32_t ptr2, uint32_t ptr3) {
350 SheetLoadResult result;
351 result.data.assign(zelda3::kUncompressedSheetSize, 0); // Default empty
352
353 // Uncompressed 3BPP (115-126)
354 if (i >= 115 && i <= 126) {
355 result.is_compressed = false;
356 result.pc_offset =
357 GetGraphicsAddress(rom.data(), i, ptr1, ptr2, ptr3, rom.size());
358
359 auto read_res =
361 if (read_res.ok()) {
362 result.data = *read_res;
363 result.decompression_succeeded = true;
364 result.is_bpp3 = true;
365 } else {
366 result.decompression_succeeded = false;
367 }
368 }
369 // 2BPP (113-114, 218+) - Skipped in main loop
370 else if (i == 113 || i == 114 || i >= 218) {
371 result.is_compressed = true;
372 result.is_bpp3 = false;
373 }
374 // Compressed 3BPP (Standard)
375 else {
376 result.is_compressed = true;
377 result.pc_offset =
378 GetGraphicsAddress(rom.data(), i, ptr1, ptr2, ptr3, rom.size());
379
380 if (result.pc_offset < rom.size()) {
381 auto decomp_res =
382 gfx::lc_lz2::DecompressV2(rom.data(), result.pc_offset, 0x800, 1, rom.size());
383 if (decomp_res.ok()) {
384 result.data = *decomp_res;
385 result.decompression_succeeded = true;
386 result.is_bpp3 = true;
387 } else {
388 result.decompression_succeeded = false;
389 }
390 }
391 }
392 return result;
393}
394
395void ProcessSheetBitmap(GameData& data, uint32_t i, const SheetLoadResult& result) {
396 if (result.is_bpp3) {
397 auto converted_sheet = gfx::SnesTo8bppSheet(result.data, 3);
398 if (converted_sheet.size() != 4096)
399 converted_sheet.resize(4096, 0);
400
401 data.raw_gfx_sheets[i] = converted_sheet;
403 gfx::kTilesheetDepth, converted_sheet);
404
405 // Apply default palettes
406 if (!data.palette_groups.empty()) {
407 gfx::SnesPalette default_palette;
408 if (i < 113 && data.palette_groups.dungeon_main.size() > 0) {
409 default_palette = data.palette_groups.dungeon_main[0];
410 } else if (i < 128 && data.palette_groups.sprites_aux1.size() > 0) {
411 default_palette = data.palette_groups.sprites_aux1[0];
412 } else if (data.palette_groups.hud.size() > 0) {
413 default_palette = data.palette_groups.hud.palette(0);
414 }
415
416 if (!default_palette.empty()) {
417 ApplyDefaultPalette(data.gfx_bitmaps[i], default_palette);
418 } else {
419 // Fallback to grayscale if no palette found
420 std::vector<gfx::SnesColor> grayscale;
421 for (int color_idx = 0; color_idx < 16; ++color_idx) {
422 float val = color_idx / 15.0f;
423 grayscale.emplace_back(ImVec4(val, val, val, 1.0f));
424 }
425 if (!grayscale.empty()) {
426 grayscale[0].set_transparent(true);
427 }
428 data.gfx_bitmaps[i].SetPalette(gfx::SnesPalette(grayscale));
429 }
430 } else {
431 // Fallback to grayscale if no palette groups loaded
432 std::vector<gfx::SnesColor> grayscale;
433 for (int color_idx = 0; color_idx < 16; ++color_idx) {
434 float val = color_idx / 15.0f;
435 grayscale.emplace_back(ImVec4(val, val, val, 1.0f));
436 }
437 if (!grayscale.empty()) {
438 grayscale[0].set_transparent(true);
439 }
440 data.gfx_bitmaps[i].SetPalette(gfx::SnesPalette(grayscale));
441 }
442
443 data.graphics_buffer.insert(
444 data.graphics_buffer.end(), data.gfx_bitmaps[i].data(),
445 data.gfx_bitmaps[i].data() + data.gfx_bitmaps[i].size());
446 } else {
447 // Placeholder - Fill with 0 (transparent) instead of 0xFF (white)
448 std::vector<uint8_t> placeholder(4096, 0);
449 data.raw_gfx_sheets[i] = placeholder;
451 gfx::kTilesheetDepth, placeholder);
452 data.graphics_buffer.resize(data.graphics_buffer.size() + 4096, 0);
453 }
454}
455
456absl::Status LoadGraphics(Rom& rom, GameData& data) {
457 if (kVersionConstantsMap.find(data.version) == kVersionConstantsMap.end()) {
458 return absl::FailedPreconditionError(
459 "Unsupported ROM version for graphics");
460 }
461 auto version_constants = kVersionConstantsMap.at(data.version);
462 const uint32_t gfx_ptr1 = core::RomSettings::Get().GetAddressOr(
464 version_constants.kOverworldGfxPtr1);
465 const uint32_t gfx_ptr2 = core::RomSettings::Get().GetAddressOr(
467 version_constants.kOverworldGfxPtr2);
468 const uint32_t gfx_ptr3 = core::RomSettings::Get().GetAddressOr(
470 version_constants.kOverworldGfxPtr3);
471
472 data.graphics_buffer.clear();
473
474#ifdef __EMSCRIPTEN__
475 auto loading_handle =
476 app::platform::WasmLoadingManager::BeginLoading("Loading Graphics");
477#endif
478
479 // Initialize Diagnostics
480 auto& diag = data.diagnostics;
481 diag.rom_size = rom.size();
482 diag.ptr1_loc = gfx_ptr1;
483 diag.ptr2_loc = gfx_ptr2;
484 diag.ptr3_loc = gfx_ptr3;
485
486 LOG_INFO("Graphics", "Loading %d graphics sheets...", kNumGfxSheets);
487
488 for (uint32_t i = 0; i < kNumGfxSheets; i++) {
489#ifdef __EMSCRIPTEN__
490 app::platform::WasmLoadingManager::UpdateProgress(
491 loading_handle, static_cast<float>(i) / kNumGfxSheets);
492#endif
493
494 // Inside LoadGraphics loop:
495 auto result = LoadSheetRaw(rom, i, gfx_ptr1, gfx_ptr2, gfx_ptr3);
496
497 // Update Diagnostics
498 auto& sd = diag.sheets[i];
499 sd.index = i;
500 sd.is_compressed = result.is_compressed;
501 sd.pc_offset = result.pc_offset;
502 sd.decompression_succeeded = result.decompression_succeeded;
503 sd.actual_decomp_size = result.data.size();
504 if (!result.data.empty()) {
505 size_t count = std::min<size_t>(result.data.size(), 8);
506 sd.first_bytes.assign(result.data.begin(), result.data.begin() + count);
507 }
508 if (result.is_compressed && !result.is_bpp3) {
509 sd.decomp_size_param = 0x800; // Expected for LC-LZ2
510 }
511
512 ProcessSheetBitmap(data, i, result);
513
514 if (i % 50 == 0 || i == kNumGfxSheets - 1) {
515 LOG_DEBUG("Graphics", "Sheet %d: offset=0x%06X, size=%zu, %s",
516 i, result.pc_offset, result.data.size(),
517 result.decompression_succeeded ? "OK" : "FAILED");
518 }
519 }
520
521 diag.Analyze();
522 LOG_INFO("Graphics", "Graphics loading complete. Sheets processed: %d", kNumGfxSheets);
523
524#ifdef __EMSCRIPTEN__
525 app::platform::WasmLoadingManager::EndLoading(loading_handle);
526#endif
527
528 return absl::OkStatus();
529}
530
531// ============================================================================
532// Link Graphics Loading
533// ============================================================================
534
535absl::StatusOr<std::array<gfx::Bitmap, kNumLinkSheets>> LoadLinkGraphics(
536 const Rom& rom) {
537 std::array<gfx::Bitmap, kNumLinkSheets> link_graphics;
538 for (uint32_t i = 0; i < kNumLinkSheets; i++) {
539 auto link_sheet_data_result =
540 rom.ReadByteVector(/*offset=*/kLinkGfxOffset + (i * kLinkGfxLength),
541 /*length=*/kLinkGfxLength);
542 if (!link_sheet_data_result.ok()) {
543 return link_sheet_data_result.status();
544 }
545 auto link_sheet_8bpp =
546 gfx::SnesTo8bppSheet(*link_sheet_data_result, /*bpp=*/4);
547 if (link_sheet_8bpp.size() != 4096)
548 link_sheet_8bpp.resize(4096, 0);
549
550 link_graphics[i].Create(gfx::kTilesheetWidth, gfx::kTilesheetHeight,
551 gfx::kTilesheetDepth, link_sheet_8bpp);
552 // Palette is applied by the caller since GameData may not be available here
553 }
554 return link_graphics;
555}
556
557// ============================================================================
558// 2BPP Graphics Loading
559// ============================================================================
560
561absl::StatusOr<std::vector<uint8_t>> Load2BppGraphics(const Rom& rom) {
562 std::vector<uint8_t> sheet;
563 const uint8_t sheets[] = {0x71, 0x72, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE};
564
565 // Get version constants - default to US if we don't know
566 auto version_constants = kVersionConstantsMap.at(zelda3_version::US);
567 const uint32_t gfx_ptr1 = core::RomSettings::Get().GetAddressOr(
569 version_constants.kOverworldGfxPtr1);
570 const uint32_t gfx_ptr2 = core::RomSettings::Get().GetAddressOr(
572 version_constants.kOverworldGfxPtr2);
573 const uint32_t gfx_ptr3 = core::RomSettings::Get().GetAddressOr(
575 version_constants.kOverworldGfxPtr3);
576
577 for (const auto& sheet_id : sheets) {
578 auto offset = GetGraphicsAddress(rom.data(), sheet_id, gfx_ptr1, gfx_ptr2,
579 gfx_ptr3, rom.size());
580
581 if (offset >= rom.size()) {
582 return absl::OutOfRangeError(absl::StrFormat(
583 "2BPP graphics sheet %u offset %u exceeds ROM size %zu", sheet_id,
584 offset, rom.size()));
585 }
586
587 // Decompress using LC-LZ2 algorithm with 0x800 byte output buffer.
588 auto decomp_result =
589 gfx::lc_lz2::DecompressV2(rom.data(), offset, 0x800, 1, rom.size());
590 if (!decomp_result.ok()) {
591 return decomp_result.status();
592 }
593 auto converted_sheet = gfx::SnesTo8bppSheet(*decomp_result, 2);
594 for (const auto& each_pixel : converted_sheet) {
595 sheet.push_back(each_pixel);
596 }
597 }
598 return sheet;
599}
600
601// ============================================================================
602// Font Graphics Loading
603// ============================================================================
604
605absl::StatusOr<gfx::Bitmap> LoadFontGraphics(const Rom& rom) {
606 // Font sprites are located at 0x70000, 2BPP format
607 constexpr uint32_t kFontDataSize = 0x4000; // 16KB of font data
608
609 auto font_data_result =
610 rom.ReadByteVector(kFontSpriteLocation, kFontDataSize);
611 if (!font_data_result.ok()) {
612 return font_data_result.status();
613 }
614
615 // Convert from 2BPP SNES format to 8BPP
616 auto font_8bpp = gfx::SnesTo8bppSheet(*font_data_result, /*bpp=*/2);
617
618 gfx::Bitmap font_bitmap;
620 gfx::kTilesheetDepth, font_8bpp);
621
622 return font_bitmap;
623}
624
625// ============================================================================
626// Graphics Saving
627// ============================================================================
628
630 [[maybe_unused]] Rom& rom,
631 [[maybe_unused]] const std::array<gfx::Bitmap, kNumGfxSheets>& sheets) {
632 // For now, return OK status - full implementation would write sheets back
633 // to ROM at their respective addresses with proper compression
634 LOG_INFO("SaveAllGraphicsData", "Graphics save not yet fully implemented");
635 return absl::OkStatus();
636}
637
638} // namespace zelda3
639} // 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:28
absl::StatusOr< std::vector< uint8_t > > ReadByteVector(uint32_t offset, uint32_t length) const
Definition rom.cc:431
absl::Status WriteByte(int addr, uint8_t value)
Definition rom.cc:476
absl::StatusOr< uint8_t > ReadByte(int offset) const
Definition rom.cc:408
const auto & vector() const
Definition rom.h:143
void Expand(int size)
Definition rom.h:53
absl::StatusOr< uint16_t > ReadWord(int offset) const
Definition rom.cc:416
auto data() const
Definition rom.h:139
auto size() const
Definition rom.h:138
static Flags & get()
Definition features.h:118
static RomSettings & Get()
uint32_t GetAddressOr(const std::string &key, uint32_t default_value) const
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:67
void Create(int width, int height, int depth, std::span< uint8_t > data)
Create a bitmap with the given dimensions and data.
Definition bitmap.cc:201
void SetPaletteWithTransparent(const SnesPalette &palette, size_t index, int length=7)
Set the palette with a transparent color.
Definition bitmap.cc:456
SNES Color container.
Definition snes_color.h:110
constexpr bool is_modified() const
Definition snes_color.h:195
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
#define LOG_DEBUG(category, format,...)
Definition log.h:103
#define LOG_INFO(category, format,...)
Definition log.h:105
#define ASSIGN_OR_RETURN(type_variable_name, expression)
Definition macro.h:62
constexpr char kOverworldGfxPtr3[]
constexpr char kOverworldGfxPtr1[]
constexpr char kOverworldGfxPtr2[]
absl::StatusOr< std::vector< uint8_t > > DecompressV2(const uint8_t *data, int offset, int size, int mode, size_t rom_size)
Decompresses a buffer of data using the LC_LZ2 algorithm.
constexpr int kTilesheetHeight
Definition snes_tile.h:17
constexpr int kTilesheetWidth
Definition snes_tile.h:16
constexpr int kTilesheetDepth
Definition snes_tile.h:18
std::vector< uint8_t > SnesTo8bppSheet(std::span< const uint8_t > sheet, int bpp, int num_sheets)
Definition snes_tile.cc:132
absl::Status LoadAllPalettes(const std::vector< uint8_t > &rom_data, PaletteGroupMap &groups)
Loads all the palettes for the game.
void ApplyDefaultPalette(gfx::Bitmap &bitmap, const gfx::SnesPalette &palette)
Definition game_data.cc:66
PaletteSlice GetDefaultPaletteSlice(const gfx::SnesPalette &palette)
Definition game_data.cc:40
absl::Status SaveGfxGroups(Rom &rom, const GameData &data)
Definition game_data.cc:264
absl::StatusOr< std::vector< uint8_t > > Load2BppGraphics(const Rom &rom)
Loads 2BPP graphics sheets from ROM.
Definition game_data.cc:561
constexpr uint16_t kLinkGfxLength
Definition game_data.h:48
constexpr uint32_t kFontSpriteLocation
Definition game_data.h:51
absl::StatusOr< std::array< gfx::Bitmap, kNumLinkSheets > > LoadLinkGraphics(const Rom &rom)
Loads Link's graphics sheets from ROM.
Definition game_data.cc:535
absl::StatusOr< gfx::Bitmap > LoadFontGraphics(const Rom &rom)
Loads font graphics from ROM.
Definition game_data.cc:605
constexpr uint32_t kNumRoomBlocksets
Definition game_data.h:30
constexpr uint32_t kUncompressedSheetSize
Definition game_data.h:54
absl::Status LoadGameData(Rom &rom, GameData &data, const LoadOptions &options)
Loads all Zelda3-specific game data from a generic ROM.
Definition game_data.cc:123
absl::Status LoadMetadata(const Rom &rom, GameData &data)
Definition game_data.cc:182
constexpr uint32_t kNumPalettesets
Definition game_data.h:32
absl::Status SaveAllGraphicsData(Rom &rom, const std::array< gfx::Bitmap, kNumGfxSheets > &sheets)
Saves all graphics sheets back to ROM.
Definition game_data.cc:629
constexpr uint32_t kLinkGfxOffset
Definition game_data.h:47
constexpr uint32_t kNumMainBlocksets
Definition game_data.h:29
constexpr uint32_t kNumGfxSheets
Definition game_data.h:25
constexpr uint32_t kEntranceGfxGroup
Definition game_data.h:35
void ProcessSheetBitmap(GameData &data, uint32_t i, const SheetLoadResult &result)
Definition game_data.cc:395
constexpr uint32_t kNumSpritesets
Definition game_data.h:31
constexpr uint32_t kNumLinkSheets
Definition game_data.h:26
absl::Status LoadPalettes(const Rom &rom, GameData &data)
Definition game_data.cc:206
absl::Status SaveGameData(Rom &rom, GameData &data)
Saves modified game data back to the ROM.
Definition game_data.cc:153
absl::Status LoadGraphics(Rom &rom, GameData &data)
Definition game_data.cc:456
uint32_t GetGraphicsAddress(const uint8_t *data, uint8_t addr, uint32_t ptr1, uint32_t ptr2, uint32_t ptr3, size_t rom_size)
Gets the graphics address for a sheet index.
Definition game_data.cc:112
absl::Status LoadGfxGroups(Rom &rom, GameData &data)
Definition game_data.cc:212
constexpr int kGfxGroupsPointer
SheetLoadResult LoadSheetRaw(const Rom &rom, uint32_t i, uint32_t ptr1, uint32_t ptr2, uint32_t ptr3)
Definition game_data.cc:348
int AddressFromBytes(uint8_t bank, uint8_t high, uint8_t low) noexcept
Definition snes.h:39
uint32_t SnesToPc(uint32_t addr) noexcept
Definition snes.h:8
#define RETURN_IF_ERROR(expr)
Definition snes.cc:22
absl::Status for_each(Func &&func)
Represents a group of palettes.
auto palette(int i) const
std::array< std::array< uint8_t, 4 >, kNumSpritesets > spriteset_ids
Definition game_data.h:93
void set_rom(Rom *rom)
Definition game_data.h:75
std::array< std::array< uint8_t, 4 >, kNumRoomBlocksets > room_blockset_ids
Definition game_data.h:92
std::array< std::array< uint8_t, 4 >, kNumPalettesets > paletteset_ids
Definition game_data.h:99
gfx::PaletteGroupMap palette_groups
Definition game_data.h:89
GraphicsLoadDiagnostics diagnostics
Definition game_data.h:102
zelda3_version version
Definition game_data.h:78
std::array< gfx::Bitmap, kNumGfxSheets > gfx_bitmaps
Definition game_data.h:84
std::array< std::array< uint8_t, 8 >, kNumMainBlocksets > main_blockset_ids
Definition game_data.h:91
std::array< std::vector< uint8_t >, kNumGfxSheets > raw_gfx_sheets
Definition game_data.h:83
std::vector< uint8_t > graphics_buffer
Definition game_data.h:82
std::vector< uint8_t > data
Definition game_data.cc:341