Overworld map saving epic
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 ¤t_ow_map = *overworld_.mutable_overworld_map(current_map_);
|
auto ¤t_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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,10 +309,10 @@ 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));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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,9 +396,9 @@ 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) {
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -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,7 +293,7 @@ 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
|
||||||
@@ -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_;
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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 ¤t_palette_; }
|
auto mutable_current_palette() { return ¤t_palette_; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user