Overworld map saving epic

This commit is contained in:
scawful
2024-01-31 13:17:14 -05:00
parent 1e5d02ab6f
commit 77d99724ef
12 changed files with 239 additions and 288 deletions

View File

@@ -43,23 +43,19 @@ uint32_t SnesToPc(uint32_t addr) {
} }
uint32_t PcToSnes(uint32_t addr) { uint32_t PcToSnes(uint32_t addr) {
// Impl1 std::bitset<24> addr_bits(addr);
// if (addr >= 0x400000) return -1; std::bitset<24> result_bits;
// addr = ((addr << 1) & 0x7F0000) | (addr & 0x7FFF) | 0x8000;
// Impl2 // Shift the address left by 1 bit
// return (addr & 0x7FFF) | 0x8000 | ((addr & 0x7F8000) << 1); addr_bits <<= 1;
uint8_t *b = reinterpret_cast<uint8_t *>(&addr); // Set the most significant bit of the second byte
b[2] = static_cast<uint8_t>(b[2] * 2); addr_bits.set(15, true);
if (b[1] >= 0x80) { // Convert the modified bitset back to an integer
b[2] += 1; uint32_t result = static_cast<uint32_t>(addr_bits.to_ulong());
} else {
b[1] += 0x80;
}
return addr; return result;
} }
uint32_t MapBankToWordAddress(uint8_t bank, uint16_t addr) { uint32_t MapBankToWordAddress(uint8_t bank, uint16_t addr) {

View File

@@ -130,9 +130,9 @@
using ushort = unsigned short; using ushort = unsigned short;
using uint = unsigned int; using uint = unsigned int;
using uchar = unsigned char; using uchar = unsigned char;
using Bytes = std::vector<uchar>; using Bytes = std::vector<uint8_t>;
using OWBlockset = std::vector<std::vector<ushort>>; using OWBlockset = std::vector<std::vector<uint16_t>>;
struct OWMapTiles { struct OWMapTiles {
OWBlockset light_world; // 64 maps OWBlockset light_world; // 64 maps
OWBlockset dark_world; // 64 maps OWBlockset dark_world; // 64 maps

View File

@@ -322,12 +322,12 @@ void OverworldEditor::RefreshOverworldMap() {
}; };
int source_map_id = current_map_; int source_map_id = current_map_;
bool is_large = overworld_.overworld_map(current_map_)->IsLargeMap(); bool is_large = overworld_.overworld_map(current_map_)->is_large_map();
if (is_large) { if (is_large) {
source_map_id = current_parent_; source_map_id = current_parent_;
// We need to update the map and its siblings if it's a large map // We need to update the map and its siblings if it's a large map
for (int i = 1; i < 4; i++) { for (int i = 1; i < 4; i++) {
int sibling_index = overworld_.overworld_map(source_map_id)->Parent() + i; int sibling_index = overworld_.overworld_map(source_map_id)->parent() + i;
if (i >= 2) sibling_index += 6; if (i >= 2) sibling_index += 6;
futures.push_back( futures.push_back(
std::async(std::launch::async, refresh_map_async, sibling_index)); std::async(std::launch::async, refresh_map_async, sibling_index));
@@ -358,10 +358,10 @@ void OverworldEditor::RefreshMapPalette() {
->mutable_current_palette()); ->mutable_current_palette());
}; };
if (overworld_.overworld_map(current_map_)->IsLargeMap()) { if (overworld_.overworld_map(current_map_)->is_large_map()) {
// We need to update the map and its siblings if it's a large map // We need to update the map and its siblings if it's a large map
for (int i = 1; i < 4; i++) { for (int i = 1; i < 4; i++) {
int sibling_index = overworld_.overworld_map(current_map_)->Parent() + i; int sibling_index = overworld_.overworld_map(current_map_)->parent() + i;
if (i >= 2) sibling_index += 6; if (i >= 2) sibling_index += 6;
futures.push_back( futures.push_back(
std::async(std::launch::async, refresh_palette_async, sibling_index)); std::async(std::launch::async, refresh_palette_async, sibling_index));
@@ -377,10 +377,10 @@ void OverworldEditor::RefreshMapPalette() {
void OverworldEditor::RefreshMapProperties() { void OverworldEditor::RefreshMapProperties() {
auto &current_ow_map = *overworld_.mutable_overworld_map(current_map_); auto &current_ow_map = *overworld_.mutable_overworld_map(current_map_);
if (current_ow_map.IsLargeMap()) { if (current_ow_map.is_large_map()) {
// We need to copy the properties from the parent map to the children // We need to copy the properties from the parent map to the children
for (int i = 1; i < 4; i++) { for (int i = 1; i < 4; i++) {
int sibling_index = current_ow_map.Parent() + i; int sibling_index = current_ow_map.parent() + i;
if (i >= 2) { if (i >= 2) {
sibling_index += 6; sibling_index += 6;
} }
@@ -405,7 +405,7 @@ void OverworldEditor::DrawOverworldMapSettings() {
TableNextColumn(); TableNextColumn();
ImGui::Text("Parent/Map ID:%#x, %#x", ImGui::Text("Parent/Map ID:%#x, %#x",
overworld_.overworld_map(current_map_)->Parent(), current_map_); overworld_.overworld_map(current_map_)->parent(), current_map_);
TableNextColumn(); TableNextColumn();
ImGui::SetNextItemWidth(120.f); ImGui::SetNextItemWidth(120.f);
@@ -663,15 +663,15 @@ void OverworldEditor::CheckForCurrentMap() {
current_map_ += 0x80; current_map_ += 0x80;
} }
current_parent_ = overworld_.overworld_map(current_map_)->Parent(); current_parent_ = overworld_.overworld_map(current_map_)->parent();
auto current_map_x = current_highlighted_map % 8; auto current_map_x = current_highlighted_map % 8;
auto current_map_y = current_highlighted_map / 8; auto current_map_y = current_highlighted_map / 8;
if (overworld_.overworld_map(current_map_)->IsLargeMap() || if (overworld_.overworld_map(current_map_)->is_large_map() ||
overworld_.overworld_map(current_map_)->large_index() != 0) { overworld_.overworld_map(current_map_)->large_index() != 0) {
auto highlight_parent = auto highlight_parent =
overworld_.overworld_map(current_highlighted_map)->Parent(); overworld_.overworld_map(current_highlighted_map)->parent();
auto parent_map_x = highlight_parent % 8; auto parent_map_x = highlight_parent % 8;
auto parent_map_y = highlight_parent / 8; auto parent_map_y = highlight_parent / 8;
ow_map_canvas_.DrawOutline(parent_map_x * small_map_size, ow_map_canvas_.DrawOutline(parent_map_x * small_map_size,
@@ -1576,7 +1576,7 @@ absl::Status OverworldEditor::LoadGraphics() {
for (int ty = 0; ty < 16; ty++) { for (int ty = 0; ty < 16; ty++) {
for (int tx = 0; tx < 16; tx++) { for (int tx = 0; tx < 16; tx++) {
int position = tx + (ty * 0x10); int position = tx + (ty * 0x10);
uchar value = uint8_t value =
tile16_data[(i % 8 * 16) + (i / 8 * 16 * 0x80) + (ty * 0x80) + tx]; tile16_data[(i % 8 * 16) + (i / 8 * 16 * 0x80) + (ty * 0x80) + tx];
tile_data[position] = value; tile_data[position] = value;
} }
@@ -1640,7 +1640,7 @@ void OverworldEditor::RefreshTile16Blockset() {
for (int ty = 0; ty < 16; ty++) { for (int ty = 0; ty < 16; ty++) {
for (int tx = 0; tx < 16; tx++) { for (int tx = 0; tx < 16; tx++) {
int position = tx + (ty * 0x10); int position = tx + (ty * 0x10);
uchar value = uint8_t value =
tile16_data[(index % 8 * 16) + (index / 8 * 16 * 0x80) + tile16_data[(index % 8 * 16) + (index / 8 * 16 * 0x80) +
(ty * 0x80) + tx]; (ty * 0x80) + tx];
tile_data[position] = value; tile_data[position] = value;

View File

@@ -109,10 +109,10 @@ struct SNESColor {
bool transparent = false; bool transparent = false;
}; };
gfx::SNESColor ReadColorFromROM(int offset, const uchar* rom); gfx::SNESColor ReadColorFromROM(int offset, const uint8_t* rom);
SNESColor GetCgxColor(uint16_t color); SNESColor GetCgxColor(uint16_t color);
std::vector<SNESColor> GetColFileData(uchar* data); std::vector<SNESColor> GetColFileData(uint8_t* data);
class SNESPalette { class SNESPalette {
public: public:
@@ -202,7 +202,7 @@ class SNESPalette {
std::vector<SNESColor> colors; /**< The colors in the palette. */ std::vector<SNESColor> colors; /**< The colors in the palette. */
}; };
SNESPalette ReadPaletteFromROM(int offset, int num_colors, const uchar* rom); SNESPalette ReadPaletteFromROM(int offset, int num_colors, const uint8_t* rom);
uint32_t GetPaletteAddress(const std::string& group_name, size_t palette_index, uint32_t GetPaletteAddress(const std::string& group_name, size_t palette_index,
size_t color_index); size_t color_index);
std::array<float, 4> ToFloatArray(const SNESColor& color); std::array<float, 4> ToFloatArray(const SNESColor& color);

View File

@@ -28,13 +28,13 @@ tile8 UnpackBppTile(const Bytes& data, const uint32_t offset,
bpp_pos[1] = offset + col * 2 + 1; bpp_pos[1] = offset + col * 2 + 1;
char mask = 1 << (7 - row); char mask = 1 << (7 - row);
tile.data[col * 8 + row] = (data[bpp_pos[0]] & mask) == mask; tile.data[col * 8 + row] = (data[bpp_pos[0]] & mask) == mask;
tile.data[col * 8 + row] |= (uchar)((data[bpp_pos[1]] & mask) == mask) tile.data[col * 8 + row] |= (uint8_t)((data[bpp_pos[1]] & mask) == mask)
<< 1; << 1;
if (bpp == 3) { if (bpp == 3) {
// When we have 3 bitplanes, the bytes for the third bitplane are after // When we have 3 bitplanes, the bytes for the third bitplane are after
// the 16 bytes of the 2 bitplanes. // the 16 bytes of the 2 bitplanes.
bpp_pos[2] = offset + 16 + col; bpp_pos[2] = offset + 16 + col;
tile.data[col * 8 + row] |= (uchar)((data[bpp_pos[2]] & mask) == mask) tile.data[col * 8 + row] |= (uint8_t)((data[bpp_pos[2]] & mask) == mask)
<< 2; << 2;
} }
if (bpp >= 4) { if (bpp >= 4) {
@@ -42,9 +42,9 @@ tile8 UnpackBppTile(const Bytes& data, const uint32_t offset,
// two. // two.
bpp_pos[2] = offset + 16 + col * 2; bpp_pos[2] = offset + 16 + col * 2;
bpp_pos[3] = offset + 16 + col * 2 + 1; bpp_pos[3] = offset + 16 + col * 2 + 1;
tile.data[col * 8 + row] |= (uchar)((data[bpp_pos[2]] & mask) == mask) tile.data[col * 8 + row] |= (uint8_t)((data[bpp_pos[2]] & mask) == mask)
<< 2; << 2;
tile.data[col * 8 + row] |= (uchar)((data[bpp_pos[3]] & mask) == mask) tile.data[col * 8 + row] |= (uint8_t)((data[bpp_pos[3]] & mask) == mask)
<< 3; << 3;
} }
if (bpp == 8) { if (bpp == 8) {
@@ -52,13 +52,13 @@ tile8 UnpackBppTile(const Bytes& data, const uint32_t offset,
bpp_pos[5] = offset + 32 + col * 2 + 1; bpp_pos[5] = offset + 32 + col * 2 + 1;
bpp_pos[6] = offset + 48 + col * 2; bpp_pos[6] = offset + 48 + col * 2;
bpp_pos[7] = offset + 48 + col * 2 + 1; bpp_pos[7] = offset + 48 + col * 2 + 1;
tile.data[col * 8 + row] |= (uchar)((data[bpp_pos[4]] & mask) == mask) tile.data[col * 8 + row] |= (uint8_t)((data[bpp_pos[4]] & mask) == mask)
<< 4; << 4;
tile.data[col * 8 + row] |= (uchar)((data[bpp_pos[5]] & mask) == mask) tile.data[col * 8 + row] |= (uint8_t)((data[bpp_pos[5]] & mask) == mask)
<< 5; << 5;
tile.data[col * 8 + row] |= (uchar)((data[bpp_pos[6]] & mask) == mask) tile.data[col * 8 + row] |= (uint8_t)((data[bpp_pos[6]] & mask) == mask)
<< 6; << 6;
tile.data[col * 8 + row] |= (uchar)((data[bpp_pos[7]] & mask) == mask) tile.data[col * 8 + row] |= (uint8_t)((data[bpp_pos[7]] & mask) == mask)
<< 7; << 7;
} }
} }
@@ -68,68 +68,68 @@ tile8 UnpackBppTile(const Bytes& data, const uint32_t offset,
Bytes PackBppTile(const tile8& tile, const uint32_t bpp) { Bytes PackBppTile(const tile8& tile, const uint32_t bpp) {
// Allocate memory for output data // Allocate memory for output data
std::vector<uchar> output(bpp * 8, 0); // initialized with 0 std::vector<uint8_t> output(bpp * 8, 0); // initialized with 0
unsigned maxcolor = 2 << bpp; unsigned maxcolor = 2 << bpp;
// Iterate over all columns and rows of the tile // Iterate over all columns and rows of the tile
for (unsigned int col = 0; col < 8; col++) { for (unsigned int col = 0; col < 8; col++) {
for (unsigned int row = 0; row < 8; row++) { for (unsigned int row = 0; row < 8; row++) {
uchar color = tile.data[col * 8 + row]; uint8_t color = tile.data[col * 8 + row];
if (color > maxcolor) { if (color > maxcolor) {
throw std::invalid_argument("Invalid color value."); throw std::invalid_argument("Invalid color value.");
} }
// 1bpp format // 1bpp format
if (bpp == 1) output[col] += (uchar)((color & 1) << (7 - row)); if (bpp == 1) output[col] += (uint8_t)((color & 1) << (7 - row));
// 2bpp format // 2bpp format
if (bpp >= 2) { if (bpp >= 2) {
output[col * 2] += (uchar)((color & 1) << (7 - row)); output[col * 2] += (uint8_t)((color & 1) << (7 - row));
output[col * 2 + 1] += (uchar)((uchar)((color & 2) == 2) << (7 - row)); output[col * 2 + 1] += (uint8_t)((uint8_t)((color & 2) == 2) << (7 - row));
} }
// 3bpp format // 3bpp format
if (bpp == 3) if (bpp == 3)
output[16 + col] += (uchar)(((color & 4) == 4) << (7 - row)); output[16 + col] += (uint8_t)(((color & 4) == 4) << (7 - row));
// 4bpp format // 4bpp format
if (bpp >= 4) { if (bpp >= 4) {
output[16 + col * 2] += (uchar)(((color & 4) == 4) << (7 - row)); output[16 + col * 2] += (uint8_t)(((color & 4) == 4) << (7 - row));
output[16 + col * 2 + 1] += (uchar)(((color & 8) == 8) << (7 - row)); output[16 + col * 2 + 1] += (uint8_t)(((color & 8) == 8) << (7 - row));
} }
// 8bpp format // 8bpp format
if (bpp == 8) { if (bpp == 8) {
output[32 + col * 2] += (uchar)(((color & 16) == 16) << (7 - row)); output[32 + col * 2] += (uint8_t)(((color & 16) == 16) << (7 - row));
output[32 + col * 2 + 1] += (uchar)(((color & 32) == 32) << (7 - row)); output[32 + col * 2 + 1] += (uint8_t)(((color & 32) == 32) << (7 - row));
output[48 + col * 2] += (uchar)(((color & 64) == 64) << (7 - row)); output[48 + col * 2] += (uint8_t)(((color & 64) == 64) << (7 - row));
output[48 + col * 2 + 1] += output[48 + col * 2 + 1] +=
(uchar)(((color & 128) == 128) << (7 - row)); (uint8_t)(((color & 128) == 128) << (7 - row));
} }
} }
} }
return output; return output;
} }
std::vector<uchar> ConvertBpp(const std::vector<uchar>& tiles, std::vector<uint8_t> ConvertBpp(const std::vector<uint8_t>& tiles,
uint32_t from_bpp, uint32_t to_bpp) { uint32_t from_bpp, uint32_t to_bpp) {
unsigned int nb_tile = tiles.size() / (from_bpp * 8); unsigned int nb_tile = tiles.size() / (from_bpp * 8);
std::vector<uchar> converted(nb_tile * to_bpp * 8); std::vector<uint8_t> converted(nb_tile * to_bpp * 8);
for (unsigned int i = 0; i < nb_tile; i++) { for (unsigned int i = 0; i < nb_tile; i++) {
tile8 tile = UnpackBppTile(tiles, i * from_bpp * 8, from_bpp); tile8 tile = UnpackBppTile(tiles, i * from_bpp * 8, from_bpp);
std::vector<uchar> packed_tile = PackBppTile(tile, to_bpp); std::vector<uint8_t> packed_tile = PackBppTile(tile, to_bpp);
std::memcpy(converted.data() + i * to_bpp * 8, packed_tile.data(), std::memcpy(converted.data() + i * to_bpp * 8, packed_tile.data(),
to_bpp * 8); to_bpp * 8);
} }
return converted; return converted;
} }
std::vector<uchar> Convert3bppTo4bpp(const std::vector<uchar>& tiles) { std::vector<uint8_t> Convert3bppTo4bpp(const std::vector<uint8_t>& tiles) {
return ConvertBpp(tiles, 3, 4); return ConvertBpp(tiles, 3, 4);
} }
std::vector<uchar> Convert4bppTo3bpp(const std::vector<uchar>& tiles) { std::vector<uint8_t> Convert4bppTo3bpp(const std::vector<uint8_t>& tiles) {
return ConvertBpp(tiles, 4, 3); return ConvertBpp(tiles, 4, 3);
} }
@@ -313,8 +313,8 @@ TileInfo WordToTileInfo(uint16_t word) {
return TileInfo(id, palette, vertical_mirror, horizontal_mirror, over); return TileInfo(id, palette, vertical_mirror, horizontal_mirror, over);
} }
ushort TileInfoToShort(TileInfo tile_info) { uint16_t TileInfoToShort(TileInfo tile_info) {
// ushort result = 0; // uint16_t result = 0;
// // Copy the id_ value // // Copy the id_ value
// result |= tile_info.id_ & 0x3FF; // ids are 10 bits // result |= tile_info.id_ & 0x3FF; // ids are 10 bits
@@ -327,7 +327,7 @@ ushort TileInfoToShort(TileInfo tile_info) {
// // Set the palette_ // // Set the palette_
// result |= (tile_info.palette_ & 0x07) << 13; // palettes are 3 bits // result |= (tile_info.palette_ & 0x07) << 13; // palettes are 3 bits
ushort value = 0; uint16_t value = 0;
// vhopppcc cccccccc // vhopppcc cccccccc
if (tile_info.over_) { if (tile_info.over_) {
value |= core::TilePriorityBit; value |= core::TilePriorityBit;
@@ -338,23 +338,20 @@ ushort TileInfoToShort(TileInfo tile_info) {
if (tile_info.vertical_mirror_) { if (tile_info.vertical_mirror_) {
value |= core::TileVFlipBit; value |= core::TileVFlipBit;
} }
value |= (ushort)((tile_info.palette_ << 10) & 0x1C00); value |= (uint16_t)((tile_info.palette_ << 10) & 0x1C00);
value |= (ushort)(tile_info.id_ & core::TileNameMask); value |= (uint16_t)(tile_info.id_ & core::TileNameMask);
return value; return value;
} }
TileInfo GetTilesInfo(ushort tile) { TileInfo GetTilesInfo(uint16_t tile) {
// vhopppcc cccccccc // vhopppcc cccccccc
bool o = false; auto tid = (uint16_t)(tile & core::TileNameMask);
bool v = false; auto p = (uint8_t)((tile >> 10) & 0x07);
bool h = false;
auto tid = (ushort)(tile & core::TileNameMask);
auto p = (uchar)((tile >> 10) & 0x07);
o = ((tile & core::TilePriorityBit) == core::TilePriorityBit); bool o = ((tile & core::TilePriorityBit) == core::TilePriorityBit);
h = ((tile & core::TileHFlipBit) == core::TileHFlipBit); bool h = ((tile & core::TileHFlipBit) == core::TileHFlipBit);
v = ((tile & core::TileVFlipBit) == core::TileVFlipBit); bool v = ((tile & core::TileVFlipBit) == core::TileVFlipBit);
return TileInfo(tid, p, v, h, o); return TileInfo(tid, p, v, h, o);
} }

View File

@@ -11,7 +11,7 @@ namespace yaze {
namespace app { namespace app {
namespace gfx { namespace gfx {
constexpr uchar kGraphicsBitmap[8] = {0x80, 0x40, 0x20, 0x10, constexpr uint8_t kGraphicsBitmap[8] = {0x80, 0x40, 0x20, 0x10,
0x08, 0x04, 0x02, 0x01}; 0x08, 0x04, 0x02, 0x01};
Bytes SnesTo8bppSheet(Bytes sheet, int bpp); Bytes SnesTo8bppSheet(Bytes sheet, int bpp);
@@ -29,24 +29,24 @@ tile8 UnpackBppTile(const Bytes& data, const uint32_t offset,
Bytes PackBppTile(const tile8& tile, const uint32_t bpp); Bytes PackBppTile(const tile8& tile, const uint32_t bpp);
std::vector<uchar> ConvertBpp(const std::vector<uchar>& tiles, std::vector<uint8_t> ConvertBpp(const std::vector<uint8_t>& tiles,
uint32_t from_bpp, uint32_t to_bpp); uint32_t from_bpp, uint32_t to_bpp);
std::vector<uchar> Convert3bppTo4bpp(const std::vector<uchar>& tiles); std::vector<uint8_t> Convert3bppTo4bpp(const std::vector<uint8_t>& tiles);
std::vector<uchar> Convert4bppTo3bpp(const std::vector<uchar>& tiles); std::vector<uint8_t> Convert4bppTo3bpp(const std::vector<uint8_t>& tiles);
// vhopppcc cccccccc // vhopppcc cccccccc
// [0, 1] // [0, 1]
// [2, 3] // [2, 3]
class TileInfo { class TileInfo {
public: public:
ushort id_; uint16_t id_;
uint8_t palette_;
bool over_; bool over_;
bool vertical_mirror_; bool vertical_mirror_;
bool horizontal_mirror_; bool horizontal_mirror_;
uchar palette_;
TileInfo() = default; TileInfo() = default;
TileInfo(ushort id, uchar palette, bool v, bool h, bool o) TileInfo(uint16_t id, uint8_t palette, bool v, bool h, bool o)
: id_(id), : id_(id),
over_(o), over_(o),
vertical_mirror_(v), vertical_mirror_(v),
@@ -63,9 +63,9 @@ class TileInfo {
uint16_t TileInfoToWord(TileInfo tile_info); uint16_t TileInfoToWord(TileInfo tile_info);
TileInfo WordToTileInfo(uint16_t word); TileInfo WordToTileInfo(uint16_t word);
ushort TileInfoToShort(TileInfo tile_info); uint16_t TileInfoToShort(TileInfo tile_info);
TileInfo GetTilesInfo(ushort tile); TileInfo GetTilesInfo(uint16_t tile);
class Tile32 { class Tile32 {
public: public:
@@ -90,10 +90,10 @@ class Tile32 {
// Constructor from packed value // Constructor from packed value
Tile32(uint64_t packedVal) { Tile32(uint64_t packedVal) {
tile0_ = (ushort)packedVal; tile0_ = (uint16_t)packedVal;
tile1_ = (ushort)(packedVal >> 16); tile1_ = (uint16_t)(packedVal >> 16);
tile2_ = (ushort)(packedVal >> 32); tile2_ = (uint16_t)(packedVal >> 32);
tile3_ = (ushort)(packedVal >> 48); tile3_ = (uint16_t)(packedVal >> 48);
} }
// Get packed uint64_t representation // Get packed uint64_t representation
@@ -145,15 +145,15 @@ class OAMTile {
int mx_; int mx_;
int my_; int my_;
int pal_; int pal_;
ushort tile_; uint16_t tile_;
OAMTile() = default; OAMTile() = default;
OAMTile(int x, int y, ushort tile, int pal, bool upper = false, int mx = 0, OAMTile(int x, int y, uint16_t tile, int pal, bool upper = false, int mx = 0,
int my = 0) int my = 0)
: x_(x), y_(y), mx_(mx), my_(my), pal_(pal) { : x_(x), y_(y), mx_(mx), my_(my), pal_(pal) {
if (upper) { if (upper) {
tile_ = (ushort)(tile + 512); tile_ = (uint16_t)(tile + 512);
} else { } else {
tile_ = (ushort)(tile + 256 + 512); tile_ = (uint16_t)(tile + 256 + 512);
} }
} }
}; };

View File

@@ -423,14 +423,6 @@ absl::Status ROM::SaveToFile(bool backup, bool save_new, std::string filename) {
SaveAllPalettes(); SaveAllPalettes();
} }
if (flags()->kSaveWithChangeQueue) {
while (!changes_.empty()) {
auto change = changes_.top();
change();
changes_.pop();
}
}
if (save_new) { if (save_new) {
// Create a file of the same name and append the date between the filename // Create a file of the same name and append the date between the filename
// and file extension // and file extension

View File

@@ -318,6 +318,10 @@ class ROM : public core::ExperimentFlags {
return result; return result;
} }
uint16_t toint16(int offset) {
return (uint16_t)(rom_data_[offset] | (rom_data_[offset + 1] << 8));
}
absl::StatusOr<uint32_t> ReadLong(int offset) { absl::StatusOr<uint32_t> ReadLong(int offset) {
if (offset + 2 >= rom_data_.size()) { if (offset + 2 >= rom_data_.size()) {
return absl::InvalidArgumentError("Offset out of range"); return absl::InvalidArgumentError("Offset out of range");
@@ -527,7 +531,7 @@ class ROM : public core::ExperimentFlags {
auto is_loaded() const { return is_loaded_; } auto is_loaded() const { return is_loaded_; }
auto version() const { return version_; } auto version() const { return version_; }
uchar& operator[](int i) { uint8_t& operator[](int i) {
if (i > size_) { if (i > size_) {
std::cout << "ROM: Index " << i << " out of bounds, size: " << size_ std::cout << "ROM: Index " << i << " out of bounds, size: " << size_
<< std::endl; << std::endl;
@@ -535,7 +539,7 @@ class ROM : public core::ExperimentFlags {
} }
return rom_data_[i]; return rom_data_[i];
} }
uchar& operator+(int i) { uint8_t& operator+(int i) {
if (i > size_) { if (i > size_) {
std::cout << "ROM: Index " << i << " out of bounds, size: " << size_ std::cout << "ROM: Index " << i << " out of bounds, size: " << size_
<< std::endl; << std::endl;
@@ -543,12 +547,7 @@ class ROM : public core::ExperimentFlags {
} }
return rom_data_[i]; return rom_data_[i];
} }
const uchar* operator&() { return rom_data_.data(); } const uint8_t* operator&() { return rom_data_.data(); }
ushort toint16(int offset) {
return (uint16_t)(rom_data_[offset] | (rom_data_[offset + 1] << 8));
// return (ushort)((rom_data_[offset + 1]) << 8) | rom_data_[offset];
}
void SetupRenderer(std::shared_ptr<SDL_Renderer> renderer) { void SetupRenderer(std::shared_ptr<SDL_Renderer> renderer) {
renderer_ = renderer; renderer_ = renderer;

View File

@@ -2,6 +2,7 @@
#include <SDL.h> #include <SDL.h>
#include <algorithm>
#include <fstream> #include <fstream>
#include <future> #include <future>
#include <memory> #include <memory>
@@ -101,63 +102,45 @@ absl::Status Overworld::Load(ROM &rom) {
void Overworld::FetchLargeMaps() { void Overworld::FetchLargeMaps() {
for (int i = 128; i < 145; i++) { for (int i = 128; i < 145; i++) {
map_parent_[i] = 0;
overworld_maps_[i].SetAsSmallMap(0); overworld_maps_[i].SetAsSmallMap(0);
} }
map_parent_[128] = 128;
map_parent_[129] = 129;
map_parent_[130] = 129;
map_parent_[137] = 129;
map_parent_[138] = 129;
overworld_maps_[129].SetAsLargeMap(129, 0); overworld_maps_[129].SetAsLargeMap(129, 0);
overworld_maps_[130].SetAsLargeMap(129, 1); overworld_maps_[130].SetAsLargeMap(129, 1);
overworld_maps_[137].SetAsLargeMap(129, 2); overworld_maps_[137].SetAsLargeMap(129, 2);
overworld_maps_[138].SetAsLargeMap(129, 3); overworld_maps_[138].SetAsLargeMap(129, 3);
map_parent_[136] = 136;
overworld_maps_[136].SetAsSmallMap(); overworld_maps_[136].SetAsSmallMap();
std::vector<bool> mapChecked; std::vector<bool> map_checked;
mapChecked.reserve(0x40); map_checked.reserve(0x40);
for (int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
mapChecked[i] = false; map_checked[i] = false;
} }
int xx = 0; int xx = 0;
int yy = 0; int yy = 0;
while (true) { while (true) {
if (int i = xx + (yy * 8); mapChecked[i] == false) { if (int i = xx + (yy * 8); map_checked[i] == false) {
if (overworld_maps_[i].IsLargeMap()) { if (overworld_maps_[i].is_large_map()) {
mapChecked[i] = true; map_checked[i] = true;
map_parent_[i] = (uchar)i;
map_parent_[i + 64] = (uchar)(i + 64);
overworld_maps_[i].SetAsLargeMap(i, 0); overworld_maps_[i].SetAsLargeMap(i, 0);
overworld_maps_[i + 64].SetAsLargeMap(i + 64, 0); overworld_maps_[i + 64].SetAsLargeMap(i + 64, 0);
mapChecked[i + 1] = true; map_checked[i + 1] = true;
map_parent_[i + 1] = (uchar)i;
map_parent_[i + 65] = (uchar)(i + 64);
overworld_maps_[i + 1].SetAsLargeMap(i, 1); overworld_maps_[i + 1].SetAsLargeMap(i, 1);
overworld_maps_[i + 65].SetAsLargeMap(i + 64, 1); overworld_maps_[i + 65].SetAsLargeMap(i + 64, 1);
mapChecked[i + 8] = true; map_checked[i + 8] = true;
map_parent_[i + 8] = (uchar)i;
map_parent_[i + 72] = (uchar)(i + 64);
overworld_maps_[i + 8].SetAsLargeMap(i, 2); overworld_maps_[i + 8].SetAsLargeMap(i, 2);
overworld_maps_[i + 72].SetAsLargeMap(i + 64, 2); overworld_maps_[i + 72].SetAsLargeMap(i + 64, 2);
mapChecked[i + 9] = true; map_checked[i + 9] = true;
map_parent_[i + 9] = (uchar)i;
map_parent_[i + 73] = (uchar)(i + 64);
overworld_maps_[i + 9].SetAsLargeMap(i, 3); overworld_maps_[i + 9].SetAsLargeMap(i, 3);
overworld_maps_[i + 73].SetAsLargeMap(i + 64, 3); overworld_maps_[i + 73].SetAsLargeMap(i + 64, 3);
xx++; xx++;
} else { } else {
map_parent_[i] = (uchar)i;
map_parent_[i + 64] = (uchar)(i + 64);
overworld_maps_[i].SetAsSmallMap(); overworld_maps_[i].SetAsSmallMap();
overworld_maps_[i + 64].SetAsSmallMap(); overworld_maps_[i + 64].SetAsSmallMap();
mapChecked[i] = true; map_checked[i] = true;
} }
} }
@@ -215,13 +198,13 @@ void Overworld::AssembleMap32Tiles() {
void Overworld::AssembleMap16Tiles() { void Overworld::AssembleMap16Tiles() {
int tpos = kMap16Tiles; int tpos = kMap16Tiles;
for (int i = 0; i < 4096; i += 1) { for (int i = 0; i < 4096; i += 1) {
auto t0 = gfx::GetTilesInfo(rom()->toint16(tpos)); gfx::TileInfo t0 = gfx::GetTilesInfo(rom()->toint16(tpos));
tpos += 2; tpos += 2;
auto t1 = gfx::GetTilesInfo(rom()->toint16(tpos)); gfx::TileInfo t1 = gfx::GetTilesInfo(rom()->toint16(tpos));
tpos += 2; tpos += 2;
auto t2 = gfx::GetTilesInfo(rom()->toint16(tpos)); gfx::TileInfo t2 = gfx::GetTilesInfo(rom()->toint16(tpos));
tpos += 2; tpos += 2;
auto t3 = gfx::GetTilesInfo(rom()->toint16(tpos)); gfx::TileInfo t3 = gfx::GetTilesInfo(rom()->toint16(tpos));
tpos += 2; tpos += 2;
tiles16_.emplace_back(t0, t1, t2, t3); tiles16_.emplace_back(t0, t1, t2, t3);
} }
@@ -243,7 +226,7 @@ void Overworld::OrganizeMapTiles(Bytes &bytes, Bytes &bytes2, int i, int sx,
int sy, int &ttpos) { int sy, int &ttpos) {
for (int y = 0; y < 16; y++) { for (int y = 0; y < 16; y++) {
for (int x = 0; x < 16; x++) { for (int x = 0; x < 16; x++) {
auto tidD = (ushort)((bytes2[ttpos] << 8) + bytes[ttpos]); auto tidD = (uint16_t)((bytes2[ttpos] << 8) + bytes[ttpos]);
if (int tpos = tidD; tpos < tiles32_unique_.size()) { if (int tpos = tidD; tpos < tiles32_unique_.size()) {
if (i < 64) { if (i < 64) {
AssignWorldTiles(x, y, sx, sy, tpos, map_tiles_.light_world); AssignWorldTiles(x, y, sx, sy, tpos, map_tiles_.light_world);
@@ -326,11 +309,11 @@ absl::Status Overworld::LoadOverworldMaps() {
} else if (i >= 0x80) { } else if (i >= 0x80) {
world_type = 2; world_type = 2;
} }
futures.emplace_back(std::async(std::launch::async, [this, i, size, futures.emplace_back(
world_type]() { std::async(std::launch::async, [this, i, size, world_type]() {
return overworld_maps_[i].BuildMap(size, game_state_, world_type, return overworld_maps_[i].BuildMap(size, game_state_, world_type,
map_parent_, GetMapTiles(world_type)); GetMapTiles(world_type));
})); }));
} }
// Wait for all tasks to complete and check their results // Wait for all tasks to complete and check their results
@@ -352,8 +335,8 @@ void Overworld::LoadTileTypes() {
void Overworld::LoadEntrances() { void Overworld::LoadEntrances() {
for (int i = 0; i < 129; i++) { for (int i = 0; i < 129; i++) {
short map_id = rom()->toint16(OWEntranceMap + (i * 2)); short map_id = rom()->toint16(OWEntranceMap + (i * 2));
ushort map_pos = rom()->toint16(OWEntrancePos + (i * 2)); uint16_t map_pos = rom()->toint16(OWEntrancePos + (i * 2));
uchar entrance_id = rom_[OWEntranceEntranceId + i]; uint8_t entrance_id = rom_[OWEntranceEntranceId + i];
int p = map_pos >> 1; int p = map_pos >> 1;
int x = (p % 64); int x = (p % 64);
int y = (p >> 6); int y = (p >> 6);
@@ -372,14 +355,14 @@ void Overworld::LoadEntrances() {
(rom_[OWHoleArea + (i * 2)])); (rom_[OWHoleArea + (i * 2)]));
auto map_pos = (short)((rom_[OWHolePos + (i * 2) + 1] << 8) + auto map_pos = (short)((rom_[OWHolePos + (i * 2) + 1] << 8) +
(rom_[OWHolePos + (i * 2)])); (rom_[OWHolePos + (i * 2)]));
uchar entrance_id = (rom_[OWHoleEntrance + i]); uint8_t entrance_id = (rom_[OWHoleEntrance + i]);
int p = (map_pos + 0x400) >> 1; int p = (map_pos + 0x400) >> 1;
int x = (p % 64); int x = (p % 64);
int y = (p >> 6); int y = (p >> 6);
all_holes_.emplace_back( all_holes_.emplace_back(
(x * 16) + (((map_id % 64) - (((map_id % 64) / 8) * 8)) * 512), (x * 16) + (((map_id % 64) - (((map_id % 64) / 8) * 8)) * 512),
(y * 16) + (((map_id % 64) / 8) * 512), entrance_id, map_id, (y * 16) + (((map_id % 64) / 8) * 512), entrance_id, map_id,
(ushort)(map_pos + 0x400), true); (uint16_t)(map_pos + 0x400), true);
} }
} }
@@ -413,10 +396,10 @@ absl::Status Overworld::LoadExits() {
OWExitDoorType1 + (i * 2), exit_door_type_2, OWExitDoorType1 + (i * 2), exit_door_type_2,
OWExitDoorType2 + (i * 2))); OWExitDoorType2 + (i * 2)));
ushort py = (ushort)((rom_data[OWExitYPlayer + (i * 2) + 1] << 8) + uint16_t py = (uint16_t)((rom_data[OWExitYPlayer + (i * 2) + 1] << 8) +
rom_data[OWExitYPlayer + (i * 2)]); rom_data[OWExitYPlayer + (i * 2)]);
ushort px = (ushort)((rom_data[OWExitXPlayer + (i * 2) + 1] << 8) + uint16_t px = (uint16_t)((rom_data[OWExitXPlayer + (i * 2) + 1] << 8) +
rom_data[OWExitXPlayer + (i * 2)]); rom_data[OWExitXPlayer + (i * 2)]);
if (rom()->flags()->kLogToConsole) { if (rom()->flags()->kLogToConsole) {
std::cout << "Exit: " << i << " RoomID: " << exit_room_id std::cout << "Exit: " << i << " RoomID: " << exit_room_id
@@ -450,8 +433,8 @@ absl::Status Overworld::LoadItems() {
uint32_t addr = (pointer & 0xFF0000) | word_address; // 1B F9 3C uint32_t addr = (pointer & 0xFF0000) | word_address; // 1B F9 3C
addr = core::SnesToPc(addr); addr = core::SnesToPc(addr);
if (overworld_maps_[i].IsLargeMap()) { if (overworld_maps_[i].is_large_map()) {
if (overworld_maps_[i].Parent() != (uint8_t)i) { if (overworld_maps_[i].parent() != (uint8_t)i) {
continue; continue;
} }
} }
@@ -478,7 +461,7 @@ absl::Status Overworld::LoadItems() {
int sy = fakeID / 8; int sy = fakeID / 8;
int sx = fakeID - (sy * 8); int sx = fakeID - (sy * 8);
all_items_.emplace_back(b3, (ushort)i, (x * 16) + (sx * 512), all_items_.emplace_back(b3, (uint16_t)i, (x * 16) + (sx * 512),
(y * 16) + (sy * 512), false); (y * 16) + (sy * 512), false);
auto size = all_items_.size(); auto size = all_items_.size();
@@ -527,9 +510,9 @@ absl::Status Overworld::LoadSpritesFromMap(int sprite_start, int sprite_count,
int realX = ((b2 & 0x3F) * 16) + mapX * 512; int realX = ((b2 & 0x3F) * 16) + mapX * 512;
int realY = ((b1 & 0x3F) * 16) + mapY * 512; int realY = ((b1 & 0x3F) * 16) + mapY * 512;
all_sprites_[sprite_index].emplace_back(overworld_maps_[i].AreaGraphics(), all_sprites_[sprite_index].emplace_back(
(uchar)i, b3, (uchar)(b2 & 0x3F), overworld_maps_[i].AreaGraphics(), (uint8_t)i, b3,
(uchar)(b1 & 0x3F), realX, realY); (uint8_t)(b2 & 0x3F), (uint8_t)(b1 & 0x3F), realX, realY);
// all_sprites_[sprite_index][i].Draw(); // all_sprites_[sprite_index][i].Draw();
sprite_address += 3; sprite_address += 3;
@@ -582,6 +565,9 @@ absl::Status Overworld::SaveOverworldMaps() {
// Compress single_map_1 and single_map_2 // Compress single_map_1 and single_map_2
auto a_char = gfx::lc_lz2::Compress(single_map_1.data(), 256, &size_a, 1); auto a_char = gfx::lc_lz2::Compress(single_map_1.data(), 256, &size_a, 1);
auto b_char = gfx::lc_lz2::Compress(single_map_2.data(), 256, &size_b, 1); auto b_char = gfx::lc_lz2::Compress(single_map_2.data(), 256, &size_b, 1);
if (a.empty() || b.empty()) {
return absl::AbortedError("Error compressing map gfx.");
}
// Copy the compressed data to a and b // Copy the compressed data to a and b
a.resize(size_a); a.resize(size_a);
b.resize(size_b); b.resize(size_b);
@@ -592,19 +578,16 @@ absl::Status Overworld::SaveOverworldMaps() {
for (int k = 0; k < size_b; k++) { for (int k = 0; k < size_b; k++) {
b[k] = b_char[k]; b[k] = b_char[k];
} }
if (a.empty() || b.empty()) {
return absl::AbortedError("Error compressing map gfx.");
}
// Save compressed data and pointers // Save compressed data and pointers
map_data_p1[i] = std::vector<uint8_t>(a.size()); map_data_p1[i] = std::vector<uint8_t>(size_a);
map_data_p2[i] = std::vector<uint8_t>(b.size()); map_data_p2[i] = std::vector<uint8_t>(size_b);
if ((pos + a.size()) >= 0x5FE70 && (pos + a.size()) <= 0x60000) { if ((pos + size_a) >= 0x5FE70 && (pos + size_a) <= 0x60000) {
pos = 0x60000; pos = 0x60000;
} }
if ((pos + a.size()) >= 0x6411F && (pos + a.size()) <= 0x70000) { if ((pos + size_a) >= 0x6411F && (pos + size_a) <= 0x70000) {
core::Logger::log("Pos set to overflow region for map " + core::Logger::log("Pos set to overflow region for map " +
std::to_string(i) + " at " + std::to_string(i) + " at " +
core::UppercaseHexLong(pos)); core::UppercaseHexLong(pos));
@@ -643,35 +626,24 @@ absl::Status Overworld::SaveOverworldMaps() {
std::copy(a.begin(), a.end(), map_data_p1[i].begin()); std::copy(a.begin(), a.end(), map_data_p1[i].begin());
int snes_pos = core::PcToSnes(pos); int snes_pos = core::PcToSnes(pos);
map_pointers1[i] = snes_pos; map_pointers1[i] = snes_pos;
uint8_t b1 = (uint8_t)(snes_pos & 0xFF); core::Logger::log("Saving map pointers1 and compressed data for map " +
uint8_t b2 = (uint8_t)((snes_pos >> 8) & 0xFF); core::UppercaseHexByte(i) + " at " +
uint8_t b3 = (uint8_t)((snes_pos >> 16) & 0xFF); core::UppercaseHexLong(snes_pos));
core::Logger::log("Saving map pointers1 for map " + std::to_string(i) +
" at " + core::UppercaseHexLong(snes_pos));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteByte(kCompressedAllMap32PointersLow + 0 + (3 * i), b1)); rom()->WriteLong(kCompressedAllMap32PointersLow + (3 * i), snes_pos));
RETURN_IF_ERROR( RETURN_IF_ERROR(rom()->WriteVector(pos, a));
rom()->WriteByte(kCompressedAllMap32PointersLow + 1 + (3 * i), b2)); pos += size_a;
RETURN_IF_ERROR(
rom()->WriteByte(kCompressedAllMap32PointersLow + 2 + (3 * i), b3));
for (const uint8_t byte : a) {
RETURN_IF_ERROR(rom()->WriteByte(pos, byte));
pos++;
}
} else { } else {
// Save pointer for map1 // Save pointer for map1
int snes_pos = map_pointers1[map_pointers1_id[i]]; int snes_pos = map_pointers1[map_pointers1_id[i]];
uint8_t b1 = (uint8_t)(snes_pos & 0xFF); uint8_t b1 = (uint8_t)(snes_pos & 0xFF);
uint8_t b2 = (uint8_t)((snes_pos >> 8) & 0xFF); uint8_t b2 = (uint8_t)((snes_pos >> 8) & 0xFF);
uint8_t b3 = (uint8_t)((snes_pos >> 16) & 0xFF); uint8_t b3 = (uint8_t)((snes_pos >> 16) & 0xFF);
core::Logger::log("Saving map pointers1 for map " + std::to_string(i) + core::Logger::log("Saving map pointers1 for map " +
" at " + core::UppercaseHexLong(snes_pos)); core::UppercaseHexByte(i) + " at " +
core::UppercaseHexLong(snes_pos));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteByte(kCompressedAllMap32PointersLow + 0 + (3 * i), b1)); rom()->WriteLong(kCompressedAllMap32PointersLow + (3 * i), snes_pos));
RETURN_IF_ERROR(
rom()->WriteByte(kCompressedAllMap32PointersLow + 1 + (3 * i), b2));
RETURN_IF_ERROR(
rom()->WriteByte(kCompressedAllMap32PointersLow + 2 + (3 * i), b3));
} }
if ((pos + b.size()) >= 0x5FE70 && (pos + b.size()) <= 0x60000) { if ((pos + b.size()) >= 0x5FE70 && (pos + b.size()) <= 0x60000) {
@@ -680,7 +652,7 @@ absl::Status Overworld::SaveOverworldMaps() {
if ((pos + b.size()) >= 0x6411F && (pos + b.size()) <= 0x70000) { if ((pos + b.size()) >= 0x6411F && (pos + b.size()) <= 0x70000) {
core::Logger::log("Pos set to overflow region for map " + core::Logger::log("Pos set to overflow region for map " +
std::to_string(i) + " at " + core::UppercaseHexByte(i) + " at " +
core::UppercaseHexLong(pos)); core::UppercaseHexLong(pos));
pos = OverworldMapDataOverflow; pos = OverworldMapDataOverflow;
} }
@@ -693,32 +665,21 @@ absl::Status Overworld::SaveOverworldMaps() {
uint8_t b1 = (uint8_t)(snes_pos & 0xFF); uint8_t b1 = (uint8_t)(snes_pos & 0xFF);
uint8_t b2 = (uint8_t)((snes_pos >> 8) & 0xFF); uint8_t b2 = (uint8_t)((snes_pos >> 8) & 0xFF);
uint8_t b3 = (uint8_t)((snes_pos >> 16) & 0xFF); uint8_t b3 = (uint8_t)((snes_pos >> 16) & 0xFF);
core::Logger::log("Saving map pointers2 for map " + std::to_string(i) + core::Logger::log("Saving map pointers2 and compressed data for map " +
" at " + core::UppercaseHexLong(snes_pos)); core::UppercaseHexByte(i) + " at " +
RETURN_IF_ERROR( core::UppercaseHexLong(snes_pos));
rom()->WriteByte(kCompressedAllMap32PointersHigh + 0 + (3 * i), b1)); RETURN_IF_ERROR(rom()->WriteLong(
RETURN_IF_ERROR( kCompressedAllMap32PointersHigh + (3 * i), snes_pos));
rom()->WriteByte(kCompressedAllMap32PointersHigh + 1 + (3 * i), b2)); RETURN_IF_ERROR(rom()->WriteVector(pos, b));
RETURN_IF_ERROR( pos += size_b;
rom()->WriteByte(kCompressedAllMap32PointersHigh + 2 + (3 * i), b3));
for (const uint8_t byte : b) {
RETURN_IF_ERROR(rom()->WriteByte(pos, byte));
pos++;
}
} else { } else {
// Save pointer for map2 // Save pointer for map2
int snes_pos = map_pointers2[map_pointers2_id[i]]; int snes_pos = map_pointers2[map_pointers2_id[i]];
uint8_t b1 = (uint8_t)(snes_pos & 0xFF); core::Logger::log("Saving map pointers2 for map " +
uint8_t b2 = (uint8_t)((snes_pos >> 8) & 0xFF); core::UppercaseHexByte(i) + " at " +
uint8_t b3 = (uint8_t)((snes_pos >> 16) & 0xFF); core::UppercaseHexLong(snes_pos));
core::Logger::log("Saving map pointers2 for map " + std::to_string(i) + RETURN_IF_ERROR(rom()->WriteLong(
" at " + core::UppercaseHexLong(snes_pos)); kCompressedAllMap32PointersHigh + (3 * i), snes_pos));
RETURN_IF_ERROR(
rom()->WriteByte(kCompressedAllMap32PointersHigh + 0 + (3 * i), b1));
RETURN_IF_ERROR(
rom()->WriteByte(kCompressedAllMap32PointersHigh + 1 + (3 * i), b2));
RETURN_IF_ERROR(
rom()->WriteByte(kCompressedAllMap32PointersHigh + 2 + (3 * i), b3));
} }
} }
@@ -737,24 +698,26 @@ absl::Status Overworld::SaveOverworldMaps() {
absl::Status Overworld::SaveLargeMaps() { absl::Status Overworld::SaveLargeMaps() {
core::Logger::log("Saving Large Maps"); core::Logger::log("Saving Large Maps");
for (int i = 0; i < 0x40; i++) { for (int i = 0; i < 0x40; i++) {
int yPos = i / 8; int y_pos = i / 8;
int xPos = i % 8; int x_pos = i % 8;
int parentyPos = overworld_maps_[i].Parent() / 8; int parent_y_pos = overworld_maps_[i].parent() / 8;
int parentxPos = overworld_maps_[i].Parent() % 8; int parent_x_pos = overworld_maps_[i].parent() % 8;
std::unordered_map<uint8_t, uint8_t> checked_map; // std::unordered_map<uint8_t, uint8_t> checked_map;
std::vector<uint8_t> checked_map;
// Always write the map parent since it should not matter // Always write the map parent since it should not matter
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->Write(overworldMapParentId + i, overworld_maps_[i].Parent())) rom()->Write(overworldMapParentId + i, overworld_maps_[i].parent()))
if (checked_map.count(overworld_maps_[i].Parent()) > 0) { if (std::find(checked_map.begin(), checked_map.end(), i) !=
checked_map.end()) {
continue; continue;
} }
// If it's large then save parent pos * // If it's large then save parent pos *
// 0x200 otherwise pos * 0x200 // 0x200 otherwise pos * 0x200
if (overworld_maps_[i].IsLargeMap()) { if (overworld_maps_[i].is_large_map()) {
const int large_map_offsets[] = {0, 1, 8, 9}; const int large_map_offsets[] = {0, 1, 8, 9};
for (const auto &offset : large_map_offsets) { for (const auto &offset : large_map_offsets) {
// Check 1 // Check 1
@@ -777,59 +740,63 @@ absl::Status Overworld::SaveLargeMaps() {
} }
// Check 5 and 6 // Check 5 and 6
RETURN_IF_ERROR(rom()->WriteShort(transition_target_north + (i * 2), RETURN_IF_ERROR(
(ushort)((parentyPos * 0x200) - 0xE0))); rom()->WriteShort(transition_target_north + (i * 2),
(uint16_t)((parent_y_pos * 0x200) - 0xE0)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(transition_target_west + (i * 2), rom()->WriteShort(transition_target_west + (i * 2),
(ushort)((parentxPos * 0x200) - 0x100))); (uint16_t)((parent_x_pos * 0x200) - 0x100)));
RETURN_IF_ERROR(rom()->WriteShort(transition_target_north + (i * 2) + 2, RETURN_IF_ERROR(
(ushort)((parentyPos * 0x200) - 0xE0))); rom()->WriteShort(transition_target_north + (i * 2) + 2,
(uint16_t)((parent_y_pos * 0x200) - 0xE0)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(transition_target_west + (i * 2) + 2, rom()->WriteShort(transition_target_west + (i * 2) + 2,
(ushort)((parentxPos * 0x200) - 0x100))); (uint16_t)((parent_x_pos * 0x200) - 0x100)));
RETURN_IF_ERROR(rom()->WriteShort(transition_target_north + (i * 2) + 16, RETURN_IF_ERROR(
(ushort)((parentyPos * 0x200) - 0xE0))); rom()->WriteShort(transition_target_north + (i * 2) + 16,
(uint16_t)((parent_y_pos * 0x200) - 0xE0)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(transition_target_west + (i * 2) + 16, rom()->WriteShort(transition_target_west + (i * 2) + 16,
(ushort)((parentxPos * 0x200) - 0x100))); (uint16_t)((parent_x_pos * 0x200) - 0x100)));
RETURN_IF_ERROR(rom()->WriteShort(transition_target_north + (i * 2) + 18, RETURN_IF_ERROR(
(ushort)((parentyPos * 0x200) - 0xE0))); rom()->WriteShort(transition_target_north + (i * 2) + 18,
(uint16_t)((parent_y_pos * 0x200) - 0xE0)));
RETURN_IF_ERROR( RETURN_IF_ERROR(
rom()->WriteShort(transition_target_west + (i * 2) + 18, rom()->WriteShort(transition_target_west + (i * 2) + 18,
(ushort)((parentxPos * 0x200) - 0x100))); (uint16_t)((parent_x_pos * 0x200) - 0x100)));
// Check 7 and 8 // Check 7 and 8
RETURN_IF_ERROR(rom()->WriteShort(overworldTransitionPositionX + (i * 2), RETURN_IF_ERROR(rom()->WriteShort(overworldTransitionPositionX + (i * 2),
(parentxPos * 0x200))); (parent_x_pos * 0x200)));
RETURN_IF_ERROR(rom()->WriteShort(overworldTransitionPositionY + (i * 2), RETURN_IF_ERROR(rom()->WriteShort(overworldTransitionPositionY + (i * 2),
(parentyPos * 0x200))); (parent_y_pos * 0x200)));
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
overworldTransitionPositionX + (i * 2) + 2, (parentxPos * 0x200))); overworldTransitionPositionX + (i * 2) + 02, (parent_x_pos * 0x200)));
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
overworldTransitionPositionY + (i * 2) + 2, (parentyPos * 0x200))); overworldTransitionPositionY + (i * 2) + 02, (parent_y_pos * 0x200)));
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
overworldTransitionPositionX + (i * 2) + 16, (parentxPos * 0x200))); overworldTransitionPositionX + (i * 2) + 16, (parent_x_pos * 0x200)));
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
overworldTransitionPositionY + (i * 2) + 16, (parentyPos * 0x200))); overworldTransitionPositionY + (i * 2) + 16, (parent_y_pos * 0x200)));
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
overworldTransitionPositionX + (i * 2) + 18, (parentxPos * 0x200))); overworldTransitionPositionX + (i * 2) + 18, (parent_x_pos * 0x200)));
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
overworldTransitionPositionY + (i * 2) + 18, (parentyPos * 0x200))); overworldTransitionPositionY + (i * 2) + 18, (parent_y_pos * 0x200)));
// Check 9 // Check 9
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
OverworldScreenTileMapChangeByScreen1 + (i * 2), 0x0060)); OverworldScreenTileMapChangeByScreen1 + (i * 2) + 00, 0x0060));
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
OverworldScreenTileMapChangeByScreen1 + (i * 2) + 2, 0x0060)); OverworldScreenTileMapChangeByScreen1 + (i * 2) + 02, 0x0060));
// If parentX == 0 then lower submaps == 0x0060 too // If parentX == 0 then lower submaps == 0x0060 too
if (parentxPos == 0) { if (parent_x_pos == 0) {
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
OverworldScreenTileMapChangeByScreen1 + (i * 2) + 16, 0x0060)); OverworldScreenTileMapChangeByScreen1 + (i * 2) + 16, 0x0060));
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
@@ -846,7 +813,7 @@ absl::Status Overworld::SaveLargeMaps() {
// don't try to read outside of the array. // don't try to read outside of the array.
if ((i - 1) >= 0) { if ((i - 1) >= 0) {
// If the area to the left is a large area. // If the area to the left is a large area.
if (overworld_maps_[i - 1].IsLargeMap()) { if (overworld_maps_[i - 1].is_large_map()) {
// If the area to the left is the bottom right of a large area. // If the area to the left is the bottom right of a large area.
if (overworld_maps_[i - 1].large_index() == 1) { if (overworld_maps_[i - 1].large_index() == 1) {
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
@@ -859,7 +826,7 @@ absl::Status Overworld::SaveLargeMaps() {
// Always 0x0080 // Always 0x0080
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
OverworldScreenTileMapChangeByScreen2 + (i * 2), 0x0080)); OverworldScreenTileMapChangeByScreen2 + (i * 2) + 00, 0x0080));
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
OverworldScreenTileMapChangeByScreen2 + (i * 2) + 2, 0x0080)); OverworldScreenTileMapChangeByScreen2 + (i * 2) + 2, 0x0080));
// Lower always 0x1080 // Lower always 0x1080
@@ -873,7 +840,7 @@ absl::Status Overworld::SaveLargeMaps() {
// to read outside of the array. // to read outside of the array.
if ((i + 2) < 64) { if ((i + 2) < 64) {
// If the area to the right is a large area. // If the area to the right is a large area.
if (overworld_maps_[i + 2].IsLargeMap()) { if (overworld_maps_[i + 2].is_large_map()) {
// If the area to the right is the top left of a large area. // If the area to the right is the top left of a large area.
if (overworld_maps_[i + 2].large_index() == 0) { if (overworld_maps_[i + 2].large_index() == 0) {
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
@@ -898,7 +865,7 @@ absl::Status Overworld::SaveLargeMaps() {
// Just to make sure where don't try to read outside of the array. // Just to make sure where don't try to read outside of the array.
if (i - 8 >= 0) { if (i - 8 >= 0) {
// If the area just above us is a large area. // If the area just above us is a large area.
if (overworld_maps_[i - 8].IsLargeMap()) { if (overworld_maps_[i - 8].is_large_map()) {
// If the area just above us is the bottom left of a large area. // If the area just above us is the bottom left of a large area.
if (overworld_maps_[i - 8].large_index() == 2) { if (overworld_maps_[i - 8].large_index() == 2) {
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
@@ -923,7 +890,7 @@ absl::Status Overworld::SaveLargeMaps() {
// Just to make sure where don't try to read outside of the array. // Just to make sure where don't try to read outside of the array.
if (i + 16 < 64) { if (i + 16 < 64) {
// If the area just below us is a large area. // If the area just below us is a large area.
if (overworld_maps_[i + 16].IsLargeMap()) { if (overworld_maps_[i + 16].is_large_map()) {
// If the area just below us is the top left of a large area. // If the area just below us is the top left of a large area.
if (overworld_maps_[i + 16].large_index() == 0) { if (overworld_maps_[i + 16].large_index() == 0) {
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
@@ -932,10 +899,10 @@ absl::Status Overworld::SaveLargeMaps() {
} }
} }
checked_map.emplace(i, 1); checked_map.emplace_back(i);
checked_map.emplace((i + 1), 1); checked_map.emplace_back((i + 1));
checked_map.emplace((i + 8), 1); checked_map.emplace_back((i + 8));
checked_map.emplace((i + 9), 1); checked_map.emplace_back((i + 9));
} else { } else {
RETURN_IF_ERROR(rom()->WriteByte(overworldMapSize + i, 0x00)); RETURN_IF_ERROR(rom()->WriteByte(overworldMapSize + i, 0x00));
@@ -957,8 +924,8 @@ absl::Status Overworld::SaveLargeMaps() {
// If the area to the left is a large map, we don't need to add an offset // If the area to the left is a large map, we don't need to add an offset
// to it. otherwise leave it the same. // to it. otherwise leave it the same.
// Just to make sure where don't try to read outside of the array. // Just to make sure where don't try to read outside of the array.
if (i - 1 >= 0 && parentxPos != 0) { if (i - 1 >= 0 && parent_x_pos != 0) {
if (overworld_maps_[i - 1].IsLargeMap()) { if (overworld_maps_[i - 1].is_large_map()) {
if (overworld_maps_[i - 1].large_index() == 3) { if (overworld_maps_[i - 1].large_index() == 3) {
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
OverworldScreenTileMapChangeByScreen1 + (i * 2), 0xF060)); OverworldScreenTileMapChangeByScreen1 + (i * 2), 0xF060));
@@ -968,9 +935,10 @@ absl::Status Overworld::SaveLargeMaps() {
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
OverworldScreenTileMapChangeByScreen2 + (i * 2), 0x0040)); OverworldScreenTileMapChangeByScreen2 + (i * 2), 0x0040));
if (i + 1 < 64 && parentxPos != 7) {
if (overworld_maps_[i + 1].IsLargeMap()) { if (i + 1 < 64 && parent_x_pos != 7) {
if (overworld_maps_[i + 1].large_index() == 1) { if (overworld_maps_[i + 1].is_large_map()) {
if (overworld_maps_[i + 1].large_index() == 2) {
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
OverworldScreenTileMapChangeByScreen2 + (i * 2), 0xF040)); OverworldScreenTileMapChangeByScreen2 + (i * 2), 0xF040));
} }
@@ -985,7 +953,7 @@ absl::Status Overworld::SaveLargeMaps() {
// Just to make sure where don't try to read outside of the array. // Just to make sure where don't try to read outside of the array.
if (i - 8 >= 0) { if (i - 8 >= 0) {
// If the area just above us is a large area. // If the area just above us is a large area.
if (overworld_maps_[i - 8].IsLargeMap()) { if (overworld_maps_[i - 8].is_large_map()) {
// If we are under the bottom right of the large area. // If we are under the bottom right of the large area.
if (overworld_maps_[i - 8].large_index() == 3) { if (overworld_maps_[i - 8].large_index() == 3) {
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
@@ -1002,7 +970,7 @@ absl::Status Overworld::SaveLargeMaps() {
// Just to make sure where don't try to read outside of the array. // Just to make sure where don't try to read outside of the array.
if (i + 8 < 64) { if (i + 8 < 64) {
// If the area just below us is a large area. // If the area just below us is a large area.
if (overworld_maps_[i + 8].IsLargeMap()) { if (overworld_maps_[i + 8].is_large_map()) {
// If we are on top of the top right of the large area. // If we are on top of the top right of the large area.
if (overworld_maps_[i + 8].large_index() == 1) { if (overworld_maps_[i + 8].large_index() == 1) {
RETURN_IF_ERROR(rom()->WriteShort( RETURN_IF_ERROR(rom()->WriteShort(
@@ -1012,16 +980,16 @@ absl::Status Overworld::SaveLargeMaps() {
} }
RETURN_IF_ERROR(rom()->WriteShort(transition_target_north + (i * 2), RETURN_IF_ERROR(rom()->WriteShort(transition_target_north + (i * 2),
(ushort)((yPos * 0x200) - 0xE0))); (uint16_t)((y_pos * 0x200) - 0xE0)));
RETURN_IF_ERROR(rom()->WriteShort(transition_target_west + (i * 2), RETURN_IF_ERROR(rom()->WriteShort(transition_target_west + (i * 2),
(ushort)((xPos * 0x200) - 0x100))); (uint16_t)((x_pos * 0x200) - 0x100)));
RETURN_IF_ERROR(rom()->WriteShort(overworldTransitionPositionX + (i * 2), RETURN_IF_ERROR(rom()->WriteShort(overworldTransitionPositionX + (i * 2),
(xPos * 0x200))); (x_pos * 0x200)));
RETURN_IF_ERROR(rom()->WriteShort(overworldTransitionPositionY + (i * 2), RETURN_IF_ERROR(rom()->WriteShort(overworldTransitionPositionY + (i * 2),
(yPos * 0x200))); (y_pos * 0x200)));
checked_map.emplace(i, 1); checked_map.emplace_back(i);
} }
} }
@@ -1100,10 +1068,10 @@ absl::Status Overworld::CreateTile32Tilemap() {
unique_tiles.assign(unique_tiles_set.begin(), unique_tiles_set.end()); unique_tiles.assign(unique_tiles_set.begin(), unique_tiles_set.end());
// Create the indexed tiles list // Create the indexed tiles list
std::unordered_map<uint64_t, ushort> all_tiles_indexed; std::unordered_map<uint64_t, uint16_t> all_tiles_indexed;
for (size_t tile32_id = 0; tile32_id < unique_tiles.size(); tile32_id++) { for (size_t tile32_id = 0; tile32_id < unique_tiles.size(); tile32_id++) {
all_tiles_indexed.insert( all_tiles_indexed.insert(
{unique_tiles[tile32_id], static_cast<ushort>(tile32_id)}); {unique_tiles[tile32_id], static_cast<uint16_t>(tile32_id)});
} }
// Add all tiles32 from all maps. // Add all tiles32 from all maps.
@@ -1114,7 +1082,7 @@ absl::Status Overworld::CreateTile32Tilemap() {
// Create the unique tiles list // Create the unique tiles list
for (int i = 0; i < unique_tiles.size(); ++i) { for (int i = 0; i < unique_tiles.size(); ++i) {
// static_cast<ushort>(tile) // static_cast<uint16_t>(tile)
tiles32_unique_.emplace_back(gfx::Tile32(unique_tiles[i])); tiles32_unique_.emplace_back(gfx::Tile32(unique_tiles[i]));
} }
@@ -1558,13 +1526,13 @@ absl::Status Overworld::LoadPrototype(ROM &rom,
for (int i = 0; i < kNumOverworldMaps; ++i) { for (int i = 0; i < kNumOverworldMaps; ++i) {
futures.emplace_back(std::async(std::launch::async, [this, i, size]() { futures.emplace_back(std::async(std::launch::async, [this, i, size]() {
if (i < 64) { if (i < 64) {
return overworld_maps_[i].BuildMap(size, game_state_, 0, map_parent_, return overworld_maps_[i].BuildMap(size, game_state_, 0,
map_tiles_.light_world); map_tiles_.light_world);
} else if (i < 0x80 && i >= 0x40) { } else if (i < 0x80 && i >= 0x40) {
return overworld_maps_[i].BuildMap(size, game_state_, 1, map_parent_, return overworld_maps_[i].BuildMap(size, game_state_, 1,
map_tiles_.dark_world); map_tiles_.dark_world);
} else { } else {
return overworld_maps_[i].BuildMap(size, game_state_, 2, map_parent_, return overworld_maps_[i].BuildMap(size, game_state_, 2,
map_tiles_.special_world); map_tiles_.special_world);
} }
})); }));

View File

@@ -143,18 +143,18 @@ constexpr int OWWhirlpoolPosition = 0x16CF8; // JP = ;016F94
class OverworldExit : public OverworldEntity { class OverworldExit : public OverworldEntity {
public: public:
ushort y_scroll_; uint16_t y_scroll_;
ushort x_scroll_; uint16_t x_scroll_;
uchar y_player_; uchar y_player_;
uchar x_player_; uchar x_player_;
uchar y_camera_; uchar y_camera_;
uchar x_camera_; uchar x_camera_;
uchar scroll_mod_y_; uchar scroll_mod_y_;
uchar scroll_mod_x_; uchar scroll_mod_x_;
ushort door_type_1_; uint16_t door_type_1_;
ushort door_type_2_; uint16_t door_type_2_;
ushort room_id_; uint16_t room_id_;
ushort map_pos_; // Position in the vram uint16_t map_pos_; // Position in the vram
uchar entrance_id_; uchar entrance_id_;
uchar area_x_; uchar area_x_;
uchar area_y_; uchar area_y_;
@@ -164,11 +164,11 @@ class OverworldExit : public OverworldEntity {
bool large_map_ = false; bool large_map_ = false;
OverworldExit() = default; OverworldExit() = default;
OverworldExit(ushort room_id, uchar map_id, ushort vram_location, OverworldExit(uint16_t room_id, uchar map_id, uint16_t vram_location,
ushort y_scroll, ushort x_scroll, ushort player_y, uint16_t y_scroll, uint16_t x_scroll, uint16_t player_y,
ushort player_x, ushort camera_y, ushort camera_x, uint16_t player_x, uint16_t camera_y, uint16_t camera_x,
uchar scroll_mod_y, uchar scroll_mod_x, ushort door_type_1, uchar scroll_mod_y, uchar scroll_mod_x, uint16_t door_type_1,
ushort door_type_2, bool deleted = false) uint16_t door_type_2, bool deleted = false)
: map_pos_(vram_location), : map_pos_(vram_location),
entrance_id_(0), entrance_id_(0),
area_x_(0), area_x_(0),
@@ -220,7 +220,7 @@ class OverworldExit : public OverworldEntity {
area_x_ = (uchar)((std::abs(x_ - (mapX * 512)) / 16)); area_x_ = (uchar)((std::abs(x_ - (mapX * 512)) / 16));
area_y_ = (uchar)((std::abs(y_ - (mapY * 512)) / 16)); area_y_ = (uchar)((std::abs(y_ - (mapY * 512)) / 16));
map_pos_ = (ushort)((((area_y_) << 6) | (area_x_ & 0x3F)) << 1); map_pos_ = (uint16_t)((((area_y_) << 6) | (area_x_ & 0x3F)) << 1);
} }
// Overworld overworld // Overworld overworld
@@ -293,8 +293,8 @@ class OverworldExit : public OverworldEntity {
short vram_x_scroll = (short)(x_ - mapx); short vram_x_scroll = (short)(x_ - mapx);
short vram_y_scroll = (short)(y_ - mapy); short vram_y_scroll = (short)(y_ - mapy);
map_pos_ = (ushort)(((vram_y_scroll & 0xFFF0) << 3) | map_pos_ = (uint16_t)(((vram_y_scroll & 0xFFF0) << 3) |
((vram_x_scroll & 0xFFF0) >> 3)); ((vram_x_scroll & 0xFFF0) >> 3));
std::cout << "Exit: " << room_id_ << " MapId: " << std::hex << mapid std::cout << "Exit: " << room_id_ << " MapId: " << std::hex << mapid
<< " X: " << static_cast<int>(area_x_) << " X: " << static_cast<int>(area_x_)
@@ -319,7 +319,7 @@ constexpr int OWHoleEntrance = 0xDB84C;
class OverworldEntrance : public OverworldEntity { class OverworldEntrance : public OverworldEntity {
public: public:
ushort map_pos_; uint16_t map_pos_;
uchar entrance_id_; uchar entrance_id_;
uchar area_x_; uchar area_x_;
uchar area_y_; uchar area_y_;
@@ -328,7 +328,7 @@ class OverworldEntrance : public OverworldEntity {
OverworldEntrance() = default; OverworldEntrance() = default;
OverworldEntrance(int x, int y, uchar entrance_id, short map_id, OverworldEntrance(int x, int y, uchar entrance_id, short map_id,
ushort map_pos, bool hole) uint16_t map_pos, bool hole)
: map_pos_(map_pos), entrance_id_(entrance_id), is_hole_(hole) { : map_pos_(map_pos), entrance_id_(entrance_id), is_hole_(hole) {
x_ = x; x_ = x;
y_ = y; y_ = y;
@@ -360,7 +360,7 @@ class OverworldEntrance : public OverworldEntity {
area_x_ = (uchar)((std::abs(x_ - (mapX * 512)) / 16)); area_x_ = (uchar)((std::abs(x_ - (mapX * 512)) / 16));
area_y_ = (uchar)((std::abs(y_ - (mapY * 512)) / 16)); area_y_ = (uchar)((std::abs(y_ - (mapY * 512)) / 16));
map_pos_ = (ushort)((((area_y_) << 6) | (area_x_ & 0x3F)) << 1); map_pos_ = (uint16_t)((((area_y_) << 6) | (area_x_ & 0x3F)) << 1);
} }
}; };
@@ -576,7 +576,7 @@ class Overworld : public SharedROM, public core::ExperimentFlags {
std::vector<gfx::Tile16> tiles16_; std::vector<gfx::Tile16> tiles16_;
std::vector<gfx::Tile32> tiles32_; std::vector<gfx::Tile32> tiles32_;
std::vector<ushort> tiles32_list_; std::vector<uint16_t> tiles32_list_;
std::vector<gfx::Tile32> tiles32_unique_; std::vector<gfx::Tile32> tiles32_unique_;
std::vector<OverworldMap> overworld_maps_; std::vector<OverworldMap> overworld_maps_;
std::vector<OverworldEntrance> all_entrances_; std::vector<OverworldEntrance> all_entrances_;

View File

@@ -26,11 +26,9 @@ OverworldMap::OverworldMap(int index, ROM& rom,
} }
absl::Status OverworldMap::BuildMap(int count, int game_state, int world, absl::Status OverworldMap::BuildMap(int count, int game_state, int world,
uchar* map_parent,
OWBlockset& world_blockset) { OWBlockset& world_blockset) {
game_state_ = game_state; game_state_ = game_state;
world_ = world; world_ = world;
parent_ = map_parent[index_];
if (large_map_) { if (large_map_) {
if (parent_ != index_ && !initialized_) { if (parent_ != index_ && !initialized_) {
if (index_ >= 0x80 && index_ <= 0x8A && index_ != 0x88) { if (index_ >= 0x80 && index_ <= 0x8A && index_ != 0x88) {
@@ -122,7 +120,8 @@ void OverworldMap::LoadAreaInfo() {
message_id_ = rom_[overworldMessages + parent_]; message_id_ = rom_[overworldMessages + parent_];
area_palette_ = rom_[overworldSpecialPALGroup + parent_ - 0x80]; area_palette_ = rom_[overworldSpecialPALGroup + parent_ - 0x80];
if ((index_ >= 0x80 && index_ <= 0x8A && index_ != 0x88) || index_ == 0x94) { if ((index_ >= 0x80 && index_ <= 0x8A && index_ != 0x88) ||
index_ == 0x94) {
area_graphics_ = rom_[overworldSpecialGFXGroup + (parent_ - 0x80)]; area_graphics_ = rom_[overworldSpecialGFXGroup + (parent_ - 0x80)];
area_palette_ = rom_[overworldSpecialPALGroup + 1]; area_palette_ = rom_[overworldSpecialPALGroup + 1];
} else if (index_ == 0x88) { } else if (index_ == 0x88) {

View File

@@ -30,7 +30,7 @@ class OverworldMap : public GfxContext {
OverworldMap() = default; OverworldMap() = default;
OverworldMap(int index, ROM& rom, std::vector<gfx::Tile16>& tiles16); OverworldMap(int index, ROM& rom, std::vector<gfx::Tile16>& tiles16);
absl::Status BuildMap(int count, int game_state, int world, uchar* map_parent, absl::Status BuildMap(int count, int game_state, int world,
OWBlockset& world_blockset); OWBlockset& world_blockset);
void LoadAreaGraphics(); void LoadAreaGraphics();
@@ -46,9 +46,9 @@ class OverworldMap : public GfxContext {
auto AreaPalette() const { return current_palette_; } auto AreaPalette() const { return current_palette_; }
auto BitmapData() const { return bitmap_data_; } auto BitmapData() const { return bitmap_data_; }
auto SetLargeMap(bool is_set) { large_map_ = is_set; } auto SetLargeMap(bool is_set) { large_map_ = is_set; }
auto IsLargeMap() const { return large_map_; } auto is_large_map() const { return large_map_; }
auto IsInitialized() const { return initialized_; } auto IsInitialized() const { return initialized_; }
auto Parent() const { return parent_; } auto parent() const { return parent_; }
auto mutable_current_palette() { return &current_palette_; } auto mutable_current_palette() { return &current_palette_; }