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
151
152 return absl::OkStatus();
153}
154
155absl::Status SaveGameData(Rom& rom, GameData& data) {
156 if (core::FeatureFlags::get().kSaveAllPalettes) {
157 // TODO: Implement SaveAllPalettes logic using Rom::WriteColor
158 // This was previously in Rom::SaveAllPalettes
159 return data.palette_groups.for_each(
160 [&](gfx::PaletteGroup& group) -> absl::Status {
161 for (size_t i = 0; i < group.size(); ++i) {
162 auto* palette = group.mutable_palette(i);
163 for (size_t j = 0; j < palette->size(); ++j) {
164 gfx::SnesColor color = (*palette)[j];
165 if (color.is_modified()) {
166 RETURN_IF_ERROR(rom.WriteColor(
167 gfx::GetPaletteAddress(group.name(), i, j), color));
168 color.set_modified(false);
169 }
170 }
171 }
172 return absl::OkStatus();
173 });
174 }
175
177 RETURN_IF_ERROR(SaveGfxGroups(rom, data));
178 }
179
180 // TODO: Implement SaveAllGraphicsData logic
181 return absl::OkStatus();
182}
183
184absl::Status LoadMetadata(const Rom& rom, GameData& data) {
185 constexpr uint32_t kTitleStringOffset = 0x7FC0;
186 constexpr uint32_t kTitleStringLength = 20;
187
188 if (rom.size() < kTitleStringOffset + kTitleStringLength) {
189 return absl::OutOfRangeError("ROM too small for metadata");
190 }
191
192 // Check version byte at offset + 0x19 (0x7FD9)
193 if (kTitleStringOffset + 0x19 < rom.size()) {
194 // Access directly via data() since ReadByte is non-const
195 uint8_t version_byte = rom.data()[kTitleStringOffset + 0x19];
196 data.version =
197 (version_byte == 0) ? zelda3_version::JP : zelda3_version::US;
198 }
199
200 auto title_bytes = rom.ReadByteVector(kTitleStringOffset, kTitleStringLength);
201 if (title_bytes.ok()) {
202 data.title.assign(title_bytes->begin(), title_bytes->end());
203 }
204
205 return absl::OkStatus();
206}
207
208absl::Status LoadPalettes(const Rom& rom, GameData& data) {
209 // Create a vector from rom data for palette loading
210 const std::vector<uint8_t>& rom_vec = rom.vector();
211 return gfx::LoadAllPalettes(rom_vec, data.palette_groups);
212}
213
214absl::Status LoadGfxGroups(Rom& rom, GameData& data) {
215 if (kVersionConstantsMap.find(data.version) == kVersionConstantsMap.end()) {
216 return absl::FailedPreconditionError("Unsupported ROM version");
217 }
218
219 auto version_constants = kVersionConstantsMap.at(data.version);
220
221 // Load Main Blocksets
222 auto main_ptr_res = rom.ReadWord(kGfxGroupsPointer);
223 if (main_ptr_res.ok()) {
224 uint32_t main_ptr = SnesToPc(*main_ptr_res);
225 for (uint32_t i = 0; i < kNumMainBlocksets; i++) {
226 for (int j = 0; j < 8; j++) {
227 auto val = rom.ReadByte(main_ptr + (i * 8) + j);
228 if (val.ok())
229 data.main_blockset_ids[i][j] = *val;
230 }
231 }
232 }
233
234 // Load Room Blocksets
235 for (uint32_t i = 0; i < kNumRoomBlocksets; i++) {
236 for (int j = 0; j < 4; j++) {
237 auto val = rom.ReadByte(kEntranceGfxGroup + (i * 4) + j);
238 if (val.ok())
239 data.room_blockset_ids[i][j] = *val;
240 }
241 }
242
243 // Load Sprite Blocksets
244 for (uint32_t i = 0; i < kNumSpritesets; i++) {
245 for (int j = 0; j < 4; j++) {
246 auto val =
247 rom.ReadByte(version_constants.kSpriteBlocksetPointer + (i * 4) + j);
248 if (val.ok())
249 data.spriteset_ids[i][j] = *val;
250 }
251 }
252
253 // Load Palette Sets
254 for (uint32_t i = 0; i < kNumPalettesets; i++) {
255 for (int j = 0; j < 4; j++) {
256 auto val =
257 rom.ReadByte(version_constants.kDungeonPalettesGroups + (i * 4) + j);
258 if (val.ok())
259 data.paletteset_ids[i][j] = *val;
260 }
261 }
262
263 return absl::OkStatus();
264}
265
266absl::Status SaveGfxGroups(Rom& rom, const GameData& data) {
267 auto version_constants = kVersionConstantsMap.at(data.version);
268
269 ASSIGN_OR_RETURN(auto main_ptr, rom.ReadWord(kGfxGroupsPointer));
270 main_ptr = SnesToPc(main_ptr);
271
272 // Save Main Blocksets
273 for (uint32_t i = 0; i < kNumMainBlocksets; i++) {
274 for (int j = 0; j < 8; j++) {
276 rom.WriteByte(main_ptr + (i * 8) + j, data.main_blockset_ids[i][j]));
277 }
278 }
279
280 // Save Room Blocksets
281 for (uint32_t i = 0; i < kNumRoomBlocksets; i++) {
282 for (int j = 0; j < 4; j++) {
284 data.room_blockset_ids[i][j]));
285 }
286 }
287
288 // Save Sprite Blocksets
289 for (uint32_t i = 0; i < kNumSpritesets; i++) {
290 for (int j = 0; j < 4; j++) {
292 rom.WriteByte(version_constants.kSpriteBlocksetPointer + (i * 4) + j,
293 data.spriteset_ids[i][j]));
294 }
295 }
296
297 // Save Palette Sets
298 for (uint32_t i = 0; i < kNumPalettesets; i++) {
299 for (int j = 0; j < 4; j++) {
301 rom.WriteByte(version_constants.kDungeonPalettesGroups + (i * 4) + j,
302 data.paletteset_ids[i][j]));
303 }
304 }
305
306 return absl::OkStatus();
307}
308
309// ============================================================================
310// Main Graphics Loading
311// ============================================================================
312
343 std::vector<uint8_t> data;
344 bool is_compressed = false;
346 bool is_bpp3 = false; // true if 3BPP, false if skipped/2BPP
347 uint32_t pc_offset = 0;
348};
349
350SheetLoadResult LoadSheetRaw(const Rom& rom, uint32_t i, uint32_t ptr1,
351 uint32_t ptr2, uint32_t ptr3) {
352 SheetLoadResult result;
353 result.data.assign(zelda3::kUncompressedSheetSize, 0); // Default empty
354
355 // Uncompressed 3BPP (115-126)
356 if (i >= 115 && i <= 126) {
357 result.is_compressed = false;
358 result.pc_offset =
359 GetGraphicsAddress(rom.data(), i, ptr1, ptr2, ptr3, rom.size());
360
361 auto read_res =
363 if (read_res.ok()) {
364 result.data = *read_res;
365 result.decompression_succeeded = true;
366 result.is_bpp3 = true;
367 } else {
368 result.decompression_succeeded = false;
369 }
370 }
371 // 2BPP (113-114, 218+) - Skipped in main loop
372 else if (i == 113 || i == 114 || i >= 218) {
373 result.is_compressed = true;
374 result.is_bpp3 = false;
375 }
376 // Compressed 3BPP (Standard)
377 else {
378 result.is_compressed = true;
379 result.pc_offset =
380 GetGraphicsAddress(rom.data(), i, ptr1, ptr2, ptr3, rom.size());
381
382 if (result.pc_offset < rom.size()) {
383 auto decomp_res = gfx::lc_lz2::DecompressV2(rom.data(), result.pc_offset,
384 0x800, 1, rom.size());
385 if (decomp_res.ok()) {
386 result.data = *decomp_res;
387 result.decompression_succeeded = true;
388 result.is_bpp3 = true;
389 } else {
390 result.decompression_succeeded = false;
391 }
392 }
393 }
394 return result;
395}
396
397void ProcessSheetBitmap(GameData& data, uint32_t i,
398 const SheetLoadResult& result) {
399 if (result.is_bpp3) {
400 auto converted_sheet = gfx::SnesTo8bppSheet(result.data, 3);
401 if (converted_sheet.size() != 4096)
402 converted_sheet.resize(4096, 0);
403
404 data.raw_gfx_sheets[i] = converted_sheet;
406 gfx::kTilesheetDepth, converted_sheet);
407
408 // Apply default palettes
409 if (!data.palette_groups.empty()) {
410 gfx::SnesPalette default_palette;
411 if (i < 113 && data.palette_groups.dungeon_main.size() > 0) {
412 default_palette = data.palette_groups.dungeon_main[0];
413 } else if (i < 128 && data.palette_groups.sprites_aux1.size() > 0) {
414 default_palette = data.palette_groups.sprites_aux1[0];
415 } else if (data.palette_groups.hud.size() > 0) {
416 default_palette = data.palette_groups.hud.palette(0);
417 }
418
419 if (!default_palette.empty()) {
420 ApplyDefaultPalette(data.gfx_bitmaps[i], default_palette);
421 } else {
422 // Fallback to grayscale if no palette found
423 std::vector<gfx::SnesColor> grayscale;
424 for (int color_idx = 0; color_idx < 16; ++color_idx) {
425 float val = color_idx / 15.0f;
426 grayscale.emplace_back(ImVec4(val, val, val, 1.0f));
427 }
428 if (!grayscale.empty()) {
429 grayscale[0].set_transparent(true);
430 }
431 data.gfx_bitmaps[i].SetPalette(gfx::SnesPalette(grayscale));
432 }
433 } else {
434 // Fallback to grayscale if no palette groups loaded
435 std::vector<gfx::SnesColor> grayscale;
436 for (int color_idx = 0; color_idx < 16; ++color_idx) {
437 float val = color_idx / 15.0f;
438 grayscale.emplace_back(ImVec4(val, val, val, 1.0f));
439 }
440 if (!grayscale.empty()) {
441 grayscale[0].set_transparent(true);
442 }
443 data.gfx_bitmaps[i].SetPalette(gfx::SnesPalette(grayscale));
444 }
445
446 data.graphics_buffer.insert(
447 data.graphics_buffer.end(), data.gfx_bitmaps[i].data(),
448 data.gfx_bitmaps[i].data() + data.gfx_bitmaps[i].size());
449 } else {
450 // Placeholder - Fill with 0 (transparent) instead of 0xFF (white)
451 std::vector<uint8_t> placeholder(4096, 0);
452 data.raw_gfx_sheets[i] = placeholder;
454 gfx::kTilesheetDepth, placeholder);
455 data.graphics_buffer.resize(data.graphics_buffer.size() + 4096, 0);
456 }
457}
458
459absl::Status LoadGraphics(Rom& rom, GameData& data) {
460 if (kVersionConstantsMap.find(data.version) == kVersionConstantsMap.end()) {
461 return absl::FailedPreconditionError(
462 "Unsupported ROM version for graphics");
463 }
464 auto version_constants = kVersionConstantsMap.at(data.version);
465 const uint32_t gfx_ptr1 = core::RomSettings::Get().GetAddressOr(
467 version_constants.kOverworldGfxPtr1);
468 const uint32_t gfx_ptr2 = core::RomSettings::Get().GetAddressOr(
470 version_constants.kOverworldGfxPtr2);
471 const uint32_t gfx_ptr3 = core::RomSettings::Get().GetAddressOr(
473 version_constants.kOverworldGfxPtr3);
474
475 data.graphics_buffer.clear();
476
477#ifdef __EMSCRIPTEN__
478 auto loading_handle =
479 app::platform::WasmLoadingManager::BeginLoading("Loading Graphics");
480#endif
481
482 // Initialize Diagnostics
483 auto& diag = data.diagnostics;
484 diag.rom_size = rom.size();
485 diag.ptr1_loc = gfx_ptr1;
486 diag.ptr2_loc = gfx_ptr2;
487 diag.ptr3_loc = gfx_ptr3;
488
489 LOG_INFO("Graphics", "Loading %d graphics sheets...", kNumGfxSheets);
490
491 for (uint32_t i = 0; i < kNumGfxSheets; i++) {
492#ifdef __EMSCRIPTEN__
493 app::platform::WasmLoadingManager::UpdateProgress(
494 loading_handle, static_cast<float>(i) / kNumGfxSheets);
495#endif
496
497 // Inside LoadGraphics loop:
498 auto result = LoadSheetRaw(rom, i, gfx_ptr1, gfx_ptr2, gfx_ptr3);
499
500 // Update Diagnostics
501 auto& sd = diag.sheets[i];
502 sd.index = i;
503 sd.is_compressed = result.is_compressed;
504 sd.pc_offset = result.pc_offset;
505 sd.decompression_succeeded = result.decompression_succeeded;
506 sd.actual_decomp_size = result.data.size();
507 if (!result.data.empty()) {
508 size_t count = std::min<size_t>(result.data.size(), 8);
509 sd.first_bytes.assign(result.data.begin(), result.data.begin() + count);
510 }
511 if (result.is_compressed && !result.is_bpp3) {
512 sd.decomp_size_param = 0x800; // Expected for LC-LZ2
513 }
514
515 ProcessSheetBitmap(data, i, result);
516
517 if (i % 50 == 0 || i == kNumGfxSheets - 1) {
518 LOG_DEBUG("Graphics", "Sheet %d: offset=0x%06X, size=%zu, %s", i,
519 result.pc_offset, result.data.size(),
520 result.decompression_succeeded ? "OK" : "FAILED");
521 }
522 }
523
524 diag.Analyze();
525 LOG_INFO("Graphics", "Graphics loading complete. Sheets processed: %d",
527
528#ifdef __EMSCRIPTEN__
529 app::platform::WasmLoadingManager::EndLoading(loading_handle);
530#endif
531
532 return absl::OkStatus();
533}
534
535// ============================================================================
536// Link Graphics Loading
537// ============================================================================
538
539absl::StatusOr<std::array<gfx::Bitmap, kNumLinkSheets>> LoadLinkGraphics(
540 const Rom& rom) {
541 std::array<gfx::Bitmap, kNumLinkSheets> link_graphics;
542 for (uint32_t i = 0; i < kNumLinkSheets; i++) {
543 auto link_sheet_data_result =
544 rom.ReadByteVector(/*offset=*/kLinkGfxOffset + (i * kLinkGfxLength),
545 /*length=*/kLinkGfxLength);
546 if (!link_sheet_data_result.ok()) {
547 return link_sheet_data_result.status();
548 }
549 auto link_sheet_8bpp =
550 gfx::SnesTo8bppSheet(*link_sheet_data_result, /*bpp=*/4);
551 if (link_sheet_8bpp.size() != 4096)
552 link_sheet_8bpp.resize(4096, 0);
553
554 link_graphics[i].Create(gfx::kTilesheetWidth, gfx::kTilesheetHeight,
555 gfx::kTilesheetDepth, link_sheet_8bpp);
556 // Palette is applied by the caller since GameData may not be available here
557 }
558 return link_graphics;
559}
560
561// ============================================================================
562// 2BPP Graphics Loading
563// ============================================================================
564
565absl::StatusOr<std::vector<uint8_t>> Load2BppGraphics(const Rom& rom) {
566 std::vector<uint8_t> sheet;
567 const uint8_t sheets[] = {0x71, 0x72, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE};
568
569 // Get version constants - default to US if we don't know
570 auto version_constants = kVersionConstantsMap.at(zelda3_version::US);
571 const uint32_t gfx_ptr1 = core::RomSettings::Get().GetAddressOr(
573 version_constants.kOverworldGfxPtr1);
574 const uint32_t gfx_ptr2 = core::RomSettings::Get().GetAddressOr(
576 version_constants.kOverworldGfxPtr2);
577 const uint32_t gfx_ptr3 = core::RomSettings::Get().GetAddressOr(
579 version_constants.kOverworldGfxPtr3);
580
581 for (const auto& sheet_id : sheets) {
582 auto offset = GetGraphicsAddress(rom.data(), sheet_id, gfx_ptr1, gfx_ptr2,
583 gfx_ptr3, rom.size());
584
585 if (offset >= rom.size()) {
586 return absl::OutOfRangeError(absl::StrFormat(
587 "2BPP graphics sheet %u offset %u exceeds ROM size %zu", sheet_id,
588 offset, rom.size()));
589 }
590
591 // Decompress using LC-LZ2 algorithm with 0x800 byte output buffer.
592 auto decomp_result =
593 gfx::lc_lz2::DecompressV2(rom.data(), offset, 0x800, 1, rom.size());
594 if (!decomp_result.ok()) {
595 return decomp_result.status();
596 }
597 auto converted_sheet = gfx::SnesTo8bppSheet(*decomp_result, 2);
598 for (const auto& each_pixel : converted_sheet) {
599 sheet.push_back(each_pixel);
600 }
601 }
602 return sheet;
603}
604
605// ============================================================================
606// Font Graphics Loading
607// ============================================================================
608
609absl::StatusOr<gfx::Bitmap> LoadFontGraphics(const Rom& rom) {
610 // Font sprites are located at 0x70000, 2BPP format
611 constexpr uint32_t kFontDataSize = 0x4000; // 16KB of font data
612
613 auto font_data_result =
614 rom.ReadByteVector(kFontSpriteLocation, kFontDataSize);
615 if (!font_data_result.ok()) {
616 return font_data_result.status();
617 }
618
619 // Convert from 2BPP SNES format to 8BPP
620 auto font_8bpp = gfx::SnesTo8bppSheet(*font_data_result, /*bpp=*/2);
621
622 gfx::Bitmap font_bitmap;
624 gfx::kTilesheetDepth, font_8bpp);
625
626 return font_bitmap;
627}
628
629// ============================================================================
630// Graphics Saving
631// ============================================================================
632
634 [[maybe_unused]] Rom& rom,
635 [[maybe_unused]] const std::array<gfx::Bitmap, kNumGfxSheets>& sheets) {
636 // For now, return OK status - full implementation would write sheets back
637 // to ROM at their respective addresses with proper compression
638 LOG_INFO("SaveAllGraphicsData", "Graphics save not yet fully implemented");
639 return absl::OkStatus();
640}
641
642} // namespace zelda3
643} // 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:541
absl::Status WriteByte(int addr, uint8_t value)
Definition rom.cc:586
absl::StatusOr< uint8_t > ReadByte(int offset) const
Definition rom.cc:518
const auto & vector() const
Definition rom.h:155
void Expand(int size)
Definition rom.h:60
absl::StatusOr< uint16_t > ReadWord(int offset) const
Definition rom.cc:526
auto data() const
Definition rom.h:151
auto size() const
Definition rom.h:150
static Flags & get()
Definition features.h:119
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).
static absl::Status LoadFromRom(Rom *rom, PitDamageTable *out)
#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:266
absl::StatusOr< std::vector< uint8_t > > Load2BppGraphics(const Rom &rom)
Loads 2BPP graphics sheets from ROM.
Definition game_data.cc:565
constexpr uint16_t kLinkGfxLength
Definition game_data.h:50
constexpr uint32_t kFontSpriteLocation
Definition game_data.h:53
absl::StatusOr< std::array< gfx::Bitmap, kNumLinkSheets > > LoadLinkGraphics(const Rom &rom)
Loads Link's graphics sheets from ROM.
Definition game_data.cc:539
absl::StatusOr< gfx::Bitmap > LoadFontGraphics(const Rom &rom)
Loads font graphics from ROM.
Definition game_data.cc:609
constexpr uint32_t kNumRoomBlocksets
Definition game_data.h:31
constexpr uint32_t kUncompressedSheetSize
Definition game_data.h:56
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:184
constexpr uint32_t kNumPalettesets
Definition game_data.h:33
absl::Status SaveAllGraphicsData(Rom &rom, const std::array< gfx::Bitmap, kNumGfxSheets > &sheets)
Saves all graphics sheets back to ROM.
Definition game_data.cc:633
constexpr uint32_t kLinkGfxOffset
Definition game_data.h:49
constexpr uint32_t kNumMainBlocksets
Definition game_data.h:30
constexpr uint32_t kNumGfxSheets
Definition game_data.h:26
constexpr uint32_t kEntranceGfxGroup
Definition game_data.h:36
void ProcessSheetBitmap(GameData &data, uint32_t i, const SheetLoadResult &result)
Definition game_data.cc:397
constexpr uint32_t kNumSpritesets
Definition game_data.h:32
constexpr uint32_t kNumLinkSheets
Definition game_data.h:27
absl::Status LoadPalettes(const Rom &rom, GameData &data)
Definition game_data.cc:208
absl::Status SaveGameData(Rom &rom, GameData &data)
Saves modified game data back to the ROM.
Definition game_data.cc:155
absl::Status LoadGraphics(Rom &rom, GameData &data)
Definition game_data.cc:459
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:214
constexpr int kGfxGroupsPointer
SheetLoadResult LoadSheetRaw(const Rom &rom, uint32_t i, uint32_t ptr1, uint32_t ptr2, uint32_t ptr3)
Definition game_data.cc:350
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:96
void set_rom(Rom *rom)
Definition game_data.h:77
std::array< std::array< uint8_t, 4 >, kNumRoomBlocksets > room_blockset_ids
Definition game_data.h:95
std::array< std::array< uint8_t, 4 >, kNumPalettesets > paletteset_ids
Definition game_data.h:102
gfx::PaletteGroupMap palette_groups
Definition game_data.h:92
GraphicsLoadDiagnostics diagnostics
Definition game_data.h:105
zelda3_version version
Definition game_data.h:80
PitDamageTable pit_damage_table
Definition game_data.h:108
std::array< gfx::Bitmap, kNumGfxSheets > gfx_bitmaps
Definition game_data.h:87
std::array< std::array< uint8_t, 8 >, kNumMainBlocksets > main_blockset_ids
Definition game_data.h:94
std::array< std::vector< uint8_t >, kNumGfxSheets > raw_gfx_sheets
Definition game_data.h:86
std::vector< uint8_t > graphics_buffer
Definition game_data.h:84
std::vector< uint8_t > data
Definition game_data.cc:343