Files
yaze/src/app/zelda3/overworld.cc
Justin Scofield d2da16b47d housekeeping
2022-07-20 21:40:18 -04:00

219 lines
6.0 KiB
C++

#include "overworld.h"
#include "app/gfx/snes_tile.h"
#include "app/rom.h"
namespace yaze {
namespace app {
namespace zelda3 {
void Overworld::Load(ROM &rom, uchar *ow_blockset, uchar *current_gfx) {
rom_ = rom;
AssembleMap32Tiles();
AssembleMap16Tiles();
DecompressAllMapTiles();
for (int i = 0; i < core::NumberOfOWMaps; i++) {
overworld_maps_.emplace_back(i, rom_, tiles16);
}
FetchLargeMaps();
for (int i = 0; i < core::NumberOfOWMaps; i++) {
overworld_maps_[i].BuildMap(tiles16.size(), game_state_, map_parent_,
ow_blockset, current_gfx, map_tiles_);
}
is_loaded_ = true;
}
ushort Overworld::GenerateTile32(int i, int k, int dimension) {
return (ushort)(rom_.data()[map32address[dimension] + k + (i)] +
(((rom_.data()[map32address[dimension] + (i) +
(k <= 1 ? 4 : 5)] >>
(k % 2 == 0 ? 4 : 0)) &
0x0F) *
256));
}
void Overworld::AssembleMap32Tiles() {
for (int i = 0; i < 0x33F0; i += 6) {
ushort tl, tr, bl, br;
for (int k = 0; k < 4; k++) {
tl = GenerateTile32(i, k, (int)Dimension::map32TilesTL);
tr = GenerateTile32(i, k, (int)Dimension::map32TilesTR);
bl = GenerateTile32(i, k, (int)Dimension::map32TilesBL);
br = GenerateTile32(i, k, (int)Dimension::map32TilesBR);
tiles32.push_back(gfx::Tile32(tl, tr, bl, br));
}
}
map_tiles_.light_world.resize(tiles32.size());
map_tiles_.dark_world.resize(tiles32.size());
map_tiles_.special_world.resize(tiles32.size());
for (int i = 0; i < tiles32.size(); i++) {
map_tiles_.light_world[i].resize(tiles32.size());
map_tiles_.dark_world[i].resize(tiles32.size());
map_tiles_.special_world[i].resize(tiles32.size());
}
}
void Overworld::AssembleMap16Tiles() {
int tpos = core::map16Tiles;
auto rom_data = rom_.data();
for (int i = 0; i < 4096; i += 1) // 3760
{
gfx::TileInfo t0 = gfx::GetTilesInfo((uintptr_t)(rom_data + tpos));
tpos += 2;
gfx::TileInfo t1 = gfx::GetTilesInfo((uintptr_t)(rom_data + tpos));
tpos += 2;
gfx::TileInfo t2 = gfx::GetTilesInfo((uintptr_t)(rom_data + tpos));
tpos += 2;
gfx::TileInfo t3 = gfx::GetTilesInfo((uintptr_t)(rom_data + tpos));
tpos += 2;
tiles16.emplace_back(t0, t1, t2, t3);
}
}
void Overworld::AssignWorldTiles(std::vector<std::vector<ushort>> &world, int x,
int y, int sx, int sy, int tpos) {
world[(x * 2) + (sx * 32)][(y * 2) + (sy * 32)] = tiles32[tpos].tile0_;
world[(x * 2) + 1 + (sx * 32)][(y * 2) + (sy * 32)] = tiles32[tpos].tile1_;
world[(x * 2) + (sx * 32)][(y * 2) + 1 + (sy * 32)] = tiles32[tpos].tile2_;
world[(x * 2) + 1 + (sx * 32)][(y * 2) + 1 + (sy * 32)] =
tiles32[tpos].tile3_;
}
void Overworld::DecompressAllMapTiles() {
int lowest = 0x0FFFFF;
int highest = 0x0F8000;
int sx = 0;
int sy = 0;
int c = 0;
for (int i = 0; i < 160; i++) {
int map_high_ptr = core::compressedAllMap32PointersHigh;
int p1 = (rom_.data()[(map_high_ptr) + 2 + (3 * i)] << 16) +
(rom_.data()[(map_high_ptr) + 1 + (3 * i)] << 8) +
(rom_.data()[(map_high_ptr + (3 * i))]);
p1 = core::SnesToPc(p1);
int map_low_ptr = core::compressedAllMap32PointersLow;
int p2 = (rom_.data()[(map_low_ptr) + 2 + (3 * i)] << 16) +
(rom_.data()[(map_low_ptr) + 1 + (3 * i)] << 8) +
(rom_.data()[(map_low_ptr + (3 * i))]);
p2 = core::SnesToPc(p2);
int ttpos = 0;
if (p1 >= highest) {
highest = p1;
}
if (p2 >= highest) {
highest = p2;
}
if (p1 <= lowest && p1 > 0x0F8000) {
lowest = p1;
}
if (p2 <= lowest && p2 > 0x0F8000) {
lowest = p2;
}
auto bytes = rom_.DecompressOverworld(p2, 1000);
auto bytes2 = rom_.DecompressOverworld(p1, 1000);
for (int y = 0; y < 16; y++) {
for (int x = 0; x < 16; x++) {
auto tidD = (ushort)((bytes2[ttpos] << 8) + bytes[ttpos]);
int tpos = tidD;
if (tpos < tiles32.size()) {
if (i < 64) {
AssignWorldTiles(map_tiles_.light_world, x, y, sx, sy, tpos);
} else if (i < 128 && i >= 64) {
AssignWorldTiles(map_tiles_.dark_world, x, y, sx, sy, tpos);
} else {
AssignWorldTiles(map_tiles_.special_world, x, y, sx, sy, tpos);
}
}
ttpos += 1;
}
}
sx++;
if (sx >= 8) {
sy++;
sx = 0;
}
c++;
if (c >= 64) {
sx = 0;
sy = 0;
c = 0;
}
}
std::cout << "MapPointers(lowest) : " << lowest << std::endl;
std::cout << "MapPointers(highest) : " << highest << std::endl;
}
void Overworld::FetchLargeMaps() {
for (int i = 128; i < 145; i++) {
map_parent_[i] = 0;
}
map_parent_[128] = 128;
map_parent_[129] = 129;
map_parent_[130] = 129;
map_parent_[137] = 129;
map_parent_[138] = 129;
map_parent_[136] = 136;
overworld_maps_[136].SetLargeMap(false);
bool mapChecked[64];
for (auto &each : mapChecked) {
each = false;
}
int xx = 0;
int yy = 0;
while (true) {
int i = xx + (yy * 8);
if (mapChecked[i] == false) {
if (overworld_maps_[i].IsLargeMap() == true) {
mapChecked[i] = true;
map_parent_[i] = (uchar)i;
map_parent_[i + 64] = (uchar)(i + 64);
mapChecked[i + 1] = true;
map_parent_[i + 1] = (uchar)i;
map_parent_[i + 65] = (uchar)(i + 64);
mapChecked[i + 8] = true;
map_parent_[i + 8] = (uchar)i;
map_parent_[i + 72] = (uchar)(i + 64);
mapChecked[i + 9] = true;
map_parent_[i + 9] = (uchar)i;
map_parent_[i + 73] = (uchar)(i + 64);
xx++;
} else {
map_parent_[i] = (uchar)i;
map_parent_[i + 64] = (uchar)(i + 64);
mapChecked[i] = true;
}
}
xx++;
if (xx >= 8) {
xx = 0;
yy += 1;
if (yy >= 8) {
break;
}
}
}
}
} // namespace zelda3
} // namespace app
} // namespace yaze