7#include <unordered_map>
10#include "absl/status/status.h"
11#include "absl/status/statusor.h"
25 : index_(index), parent_(index), rom_(rom), game_data_(game_data) {
72 std::vector<gfx::Tile16>& tiles16,
80 int count,
int game_state,
int world, std::vector<gfx::Tile16>& tiles16,
82 const std::vector<uint8_t>* cached_tileset) {
103 }
else if (
index_ == 0x88) {
121 if (cached_tileset && !cached_tileset->empty()) {
132 return absl::OkStatus();
307 }
else if (
index_ == 0x80) {
323 }
else if (
index_ == 0x94) {
328 }
else if (
index_ == 0x95) {
332 }
else if (
index_ == 0x96) {
336 }
else if (
index_ == 0x9C) {
402 int index_world = 0x20;
413 for (
int i = 0; i < 8; i++) {
415 (uint8_t)(*
rom_)[overworld_gfx_groups2 + (index_world * 8) + i];
421 uint8_t temp = (*rom_)[overworldgfxGroups + (
area_graphics_ * 4)];
480 }
else if (
index_ == 0x80) {
537 (mosaicByte & 0x08) != 0x00, (mosaicByte & 0x04) != 0x00,
538 (mosaicByte & 0x02) != 0x00, (mosaicByte & 0x01) != 0x00};
586 for (
int i = 0; i < 8; i++) {
592 int index_world = 0x20;
601 for (
int i = 0; i < 8; i++) {
604 (index_world * 8) + i];
612 uint8_t temp = (*rom_)[overworldgfxGroups + (
area_graphics_ * 4)];
666 }
else if (
index_ == 0x80) {
669 }
else if (
index_ == 0x88) {
695 int static_graphics_base = 0x73;
701 for (
int i = 0; i < 4; i++) {
705 static_graphics_base);
710 for (
int i = 0; i < 8; i++) {
734 for (
int i = 0; i < 4; i++) {
750 const bool is_light_dm =
752 const bool is_dark_dm =
768 for (
int i = 0; i < 8; i++) {
770 if (custom_sheet == 0x00 || custom_sheet == 0xFF) {
778namespace palette_internal {
790 std::array<gfx::SnesColor, 256> new_palette = {};
794 for (
int y = 2; y < 7; y++) {
795 for (
int x = 1; x < 8; x++) {
796 new_palette[x + (16 * y)] =
main[k];
802 for (
int x = 1; x < 8; x++) {
803 new_palette[(16 * 7) + (x)] = animated[(x - 1)];
810 for (
int y = 2; y < 5; y++) {
811 for (
int x = 9; x < 16; x++) {
812 new_palette[x + (16 * y)] = aux1[k];
819 for (
int y = 5; y < 8; y++) {
820 for (
int x = 9; x < 16; x++) {
821 new_palette[x + (16 * y)] = aux2[k];
827 for (
int i = 0; i < 32; i++) {
828 new_palette[i] = hud[i];
832 for (
int i = 0; i < 8; i++) {
833 new_palette[(i * 16)] = bgrcolor;
834 new_palette[(i * 16) + 8] = bgrcolor;
839 for (
int y = 8; y < 9; y++) {
840 for (
int x = 1; x < 8; x++) {
848 for (
int y = 8; y < 9; y++) {
849 for (
int x = 9; x < 16; x++) {
857 for (
int y = 9; y < 13; y++) {
858 for (
int x = 1; x < 16; x++) {
859 new_palette[x + (16 * y)] =
867 for (
int y = 13; y < 14; y++) {
868 for (
int x = 1; x < 8; x++) {
869 new_palette[x + (16 * y)] = spr[k];
876 for (
int y = 14; y < 15; y++) {
877 for (
int x = 1; x < 8; x++) {
878 new_palette[x + (16 * y)] = spr2[k];
885 for (
int y = 15; y < 16; y++) {
886 for (
int x = 1; x < 16; x++) {
892 for (
int i = 0; i < 256; i++) {
893 current[i] = new_palette[i];
894 current[(i / 16) * 16].set_transparent(
true);
898 return absl::OkStatus();
907 (previous_index * 4)];
909 if (index >= limit) {
912 return palette_group[index];
918 return absl::OkStatus();
924 int previous_pal_id = 0;
925 int previous_spr_pal_id = 0;
954 auto bgr = grass_pal_group[0][0];
959 (previous_pal_id * 4)];
964 (previous_pal_id * 4) + 1];
969 (previous_pal_id * 4) + 2];
974 GetPalette(ow_aux_pal_group, pal1, previous_pal_id, 20));
976 GetPalette(ow_aux_pal_group, pal2, previous_pal_id, 20));
979 bool use_area_specific_bg =
982 if (use_area_specific_bg) {
993 bgr = grass_pal_group[0][0];
996 bgr = grass_pal_group[0][1];
998 bgr = grass_pal_group[0][2];
1011 GetPalette(ow_main_pal_group, pal0, previous_pal_id, 255));
1014 GetPalette(ow_animated_pal_group, std::min((
int)pal3, 13),
1015 previous_pal_id, 14));
1040 previous_spr_pal_id, 24));
1043 previous_spr_pal_id, 24));
1047 hud, bgr, spr, spr2));
1054 return absl::OkStatus();
1068 return absl::OkStatus();
1079 address = ((address & 0x7F0000) >> 1) | (address & 0x7FFF);
1087 address = ((address & 0x7F0000) >> 1) | (address & 0x7FFF);
1095 return absl::OkStatus();
1100 uint8_t b = (*rom_)[address];
1103 while (b != 0x60 && address < rom_->size()) {
1175 if (address < rom_->size()) {
1176 b = (*rom_)[address];
1191 return absl::OkStatus();
1195 int size,
const uint8_t* all_gfx) {
1197 int max_offset = static_graphics_offset * size + size;
1200 for (
int i = 0; i < size; i++) {
1206 for (
int i = 0; i < size; i++) {
1207 auto byte = all_gfx[i + (static_graphics_offset * size)];
1226 return absl::OkStatus();
1230 for (
int i = 0; i < 8; i++) {
1238 for (
int i = 8; i < 16; i++) {
1251 return absl::OkStatus();
1259 const int offsets[] = {0x00, 0x08, 0x400, 0x408};
1263 for (
auto i = 0; i < count; i++) {
1264 for (
auto tile = 0; tile < 0x04; tile++) {
1266 int offset = offsets[tile];
1267 for (
auto y = 0; y < 0x08; ++y) {
1268 for (
auto x = 0; x < 0x08; ++x) {
1280 int xpos = ((info.
id_ % 0x10) * 0x08);
1281 int ypos = (((info.
id_ / 0x10)) * 0x400);
1282 int source = ypos + xpos + (x + (y * 0x80));
1284 auto destination = xx + yy + offset + (mx + (my * 0x80));
1298 return absl::OkStatus();
1306 for (
int i = 0; i < 0x40000; i++) {
1316 if (local_index < 0) {
1317 return absl::InvalidArgumentError(
"Invalid overworld map index");
1320 int superY = local_index / 0x08;
1321 int superX = local_index - (superY * 0x08);
1323 for (
int y = 0; y < 0x20; y++) {
1324 for (
int x = 0; x < 0x20; x++) {
1325 auto xt = x + (superX * 0x20);
1326 auto yt = y + (superY * 0x20);
1327 if (xt < 0 || yt < 0 || xt >=
static_cast<int>(world_blockset.size()) ||
1328 yt >=
static_cast<int>(world_blockset[xt].size())) {
1329 return absl::InvalidArgumentError(
1330 "Overworld blockset is too small for map bitmap build");
1336 return absl::OkStatus();
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
static std::unordered_map< uint8_t, gfx::Paletteset > palettesets_
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
void set_size(size_t size)
SNES 16-bit tile metadata container.
void ProcessGraphicsBuffer(int index, int static_graphics_offset, int size, const uint8_t *all_gfx)
zelda3_version_pointers version_constants() const
std::vector< uint8_t > current_gfx_
std::vector< uint8_t > current_blockset_
std::array< bool, 4 > mosaic_expanded_
absl::Status LoadVanillaOverlayData()
std::vector< uint8_t > bitmap_data_
absl::Status LoadOverlay()
absl::Status BuildMapWithCache(int count, int game_state, int world, std::vector< gfx::Tile16 > &tiles16, OverworldBlockset &world_blockset, const std::vector< uint8_t > *cached_tileset)
Build map with optional cached tileset for performance.
void SetupCustomTileset(uint8_t asm_version)
absl::StatusOr< gfx::SnesPalette > GetPalette(const gfx::PaletteGroup &group, int index, int previous_index, int limit)
absl::Status BuildTiles16Gfx(std::vector< gfx::Tile16 > &tiles16, int count)
absl::Status BuildMap(int count, int game_state, int world, std::vector< gfx::Tile16 > &tiles16, OverworldBlockset &world_blockset)
std::array< uint8_t, 3 > sprite_graphics_
void LoadAreaGraphicsBlocksets()
absl::Status BuildTileset()
void LoadDeathMountainGFX()
uint8_t ComputeWorldBasedMainPalette() const
absl::Status BuildBitmap(OverworldBlockset &world_blockset)
std::array< uint8_t, 3 > sprite_palette_
std::array< uint8_t, 4 > area_music_
std::array< uint8_t, 16 > static_graphics_
uint16_t subscreen_overlay_
std::array< uint8_t, 8 > custom_gfx_ids_
absl::Status LoadPalette()
void LoadMainBlocksetId()
std::vector< uint8_t > overlay_data_
void UseCachedTileset(const std::vector< uint8_t > &cached_gfx)
Use a pre-computed tileset from cache instead of rebuilding.
gfx::SnesPalette current_palette_
void LoadCustomOverworldData()
void LoadSpritesBlocksets()
uint16_t area_specific_bg_color_
static bool SupportsCustomBGColors(OverworldVersion version)
Check if ROM supports custom background colors per area (v2+)
static OverworldVersion GetVersion(const Rom &rom)
Detect ROM version from ASM marker byte.
static uint8_t GetAsmVersion(const Rom &rom)
Get raw ASM version byte from ROM.
static bool SupportsAreaEnum(OverworldVersion version)
Check if ROM supports area enum system (v3+ only)
static bool SupportsExpandedSpace(OverworldVersion version)
Check if ROM uses expanded ROM space for overworld data.
static bool SupportsCustomTileGFX(OverworldVersion version)
Check if ROM supports custom tile GFX groups (v3+)
int main(int argc, char **argv)
struct destination destination
Room transition destination.
#define ASSIGN_OR_RETURN(type_variable_name, expression)
void CopyTile8bpp16(int x, int y, int tile, std::vector< uint8_t > &bitmap, std::vector< uint8_t > &blockset)
absl::Status SetColorsPalette(Rom &rom, GameData *game_data, int index, gfx::SnesPalette ¤t, gfx::SnesPalette main, gfx::SnesPalette animated, gfx::SnesPalette aux1, gfx::SnesPalette aux2, gfx::SnesPalette hud, gfx::SnesColor bgrcolor, gfx::SnesPalette spr, gfx::SnesPalette spr2)
Zelda 3 specific classes and functions.
constexpr int kAreaGfxIdPtr
int GetOverworldMapParentIdExpanded()
constexpr int OverworldCustomTileGFXGroupEnabled
constexpr int OverworldCustomAreaSpecificBGEnabled
constexpr int kOverworldSpritePaletteGroup
constexpr int kNumMapsPerWorld
constexpr int kOverworldSpriteset
constexpr int kOverworldScreenSize
constexpr int kOverlayData1
constexpr int kSpecialWorldMapIdStart
constexpr int OverworldCustomMosaicArray
constexpr int OverworldCustomAnimatedGFXEnabled
constexpr int OverworldCustomMainPaletteEnabled
constexpr int kNumOverworldMaps
constexpr int OverworldCustomMainPaletteArray
constexpr int kOverworldSpecialSpritePaletteExpandedTemp
constexpr int kOverworldSpecialSpriteGfxGroupExpandedTemp
constexpr int kOverworldMusicBeginning
std::vector< std::vector< uint16_t > > OverworldBlockset
Represents tile32 data for the overworld.
AreaSizeEnum
Area size enumeration for v3+ ROMs.
constexpr int kOverworldMusicDarkWorld
constexpr int kOverlayPointersBank
constexpr int kOverworldSpecialPalGroup
constexpr int kOverworldSpritePaletteIds
constexpr int OverworldCustomASMHasBeenApplied
constexpr int kOverworldMusicAgahnim
constexpr int kOverworldMapParentId
@ kZSCustomV2
Parent system, BG colors, main palettes.
@ kVanilla
0xFF in ROM, no ZScream ASM applied
@ kZSCustomV3
Area enum, wide/tall areas, all features.
constexpr int kOverworldPalettesScreenToSetNew
constexpr int kOverworldMusicMasterSword
constexpr int kOverworldMusicZelda
constexpr int kOverworldMessageIds
constexpr int kOverlayData2
constexpr int kOverworldSpecialSpritePalette
constexpr int OverworldCustomAnimatedGFXArray
constexpr int kDarkWorldMapIdStart
constexpr int OverworldCustomMosaicEnabled
int WorldForOverworldMap(int map_index)
constexpr int kOverworldSpecialSpriteGFXGroup
constexpr int OverworldCustomTileGFXGroupArray
constexpr int OverworldCustomSubscreenOverlayEnabled
constexpr int OverworldCustomAreaSpecificBGPalette
int GetOverworldMessagesExpanded()
constexpr int kOverlayPointers
int LegacyScreenSizeTableIndexForMap(int map_index)
constexpr int kOverworldMapPaletteIds
constexpr int kOverworldSpecialGfxGroup
constexpr int OverworldCustomSubscreenOverlayArray
#define RETURN_IF_ERROR(expr)
Room transition destination.
PaletteGroup overworld_main
PaletteGroup overworld_aux
PaletteGroup sprites_aux1
PaletteGroup overworld_animated
PaletteGroup sprites_aux3
PaletteGroup global_sprites
Represents a group of palettes.
Represents a set of palettes used in a SNES graphics system.
gfx::PaletteGroupMap palette_groups
std::vector< uint8_t > graphics_buffer
uint32_t kOverworldMapPaletteGroup
uint32_t kOverworldGfxGroups1
uint32_t kSpriteBlocksetPointer
uint32_t kOverworldGfxGroups2