From c49e9772a1ded867e6263e8024c7eb0ec3b858ab Mon Sep 17 00:00:00 2001 From: Justin Scofield Date: Thu, 9 Jun 2022 22:15:10 -0400 Subject: [PATCH] Overworld porting --- src/Application/Data/Overworld.cc | 263 ++++++++++++++++++++++++++---- src/Application/Data/Overworld.h | 128 ++++----------- src/Application/Data/Tile.cc | 26 +++ src/Application/Data/Tile.h | 91 +++++++++++ src/Application/Utils/Bitmap.cc | 1 + src/Application/Utils/Bitmap.h | 19 +++ 6 files changed, 400 insertions(+), 128 deletions(-) create mode 100644 src/Application/Data/Tile.cc create mode 100644 src/Application/Data/Tile.h create mode 100644 src/Application/Utils/Bitmap.cc create mode 100644 src/Application/Utils/Bitmap.h diff --git a/src/Application/Data/Overworld.cc b/src/Application/Data/Overworld.cc index 81f89298..c8b55183 100644 --- a/src/Application/Data/Overworld.cc +++ b/src/Application/Data/Overworld.cc @@ -1,54 +1,245 @@ #include "Overworld.h" +#include "Tile.h" + namespace yaze { namespace Application { namespace Data { -Overworld::Overworld() { +using namespace Core; - for(int i = 0; i < 0x2B ;i++) - { - // tileLeftEntrance[i] = (ushort)ROM.ReadShort(Core::Constants::overworldEntranceAllowedTilesLeft + (i * 2)); - // tileRightEntrance[i] = (ushort)ROM.ReadShort(Core::Constants::overworldEntranceAllowedTilesRight + (i * 2)); +static TileInfo GetTilesInfo(ushort tile) { + // vhopppcc cccccccc + ushort o = 0; + ushort v = 0; + ushort h = 0; + ushort tid = (ushort)(tile & 0x3FF); + byte p = (byte)((tile >> 10) & 0x07); - //Console.WriteLine(tileLeftEntrance[i].ToString("D4") + " , " + tileRightEntrance[i].ToString("D4")); + o = (ushort)((tile & 0x2000) >> 13); + h = (ushort)((tile & 0x4000) >> 14); + v = (ushort)((tile & 0x8000) >> 15); + + return TileInfo(tid, p, v, h, o); +} + +Overworld::Overworld(Utils::ROM rom) : rom_(rom) { + for (int i = 0; i < 0x2B; i++) { + tileLeftEntrance[i] = (ushort)rom_.ReadShort( + Constants::overworldEntranceAllowedTilesLeft + (i * 2)); + tileRightEntrance[i] = (ushort)rom_.ReadShort( + Constants::overworldEntranceAllowedTilesRight + (i * 2)); + } + + AssembleMap32Tiles(); + AssembleMap16Tiles(); +} + +ushort Overworld::GenerateTile32(int i, int k, int dimension) { + return (ushort)(rom_.GetRawData()[map32address[dimension] + k + (i)] + + (((rom_.GetRawData()[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(Tile32(tl, tr, bl, br)); + } } } -void Overworld::AssembleMap32Tiles() -{ - for (int i = 0; i < 0x33F0; i += 6) - { - // ushort[,] b = new ushort[4, 4]; - // ushort tl, tr, bl, br; - // for (int k = 0; k < 4; k++) - // { - // tl = generate(i, k, (int)Dimension.map32TilesTL); - // tr = generate(i, k, (int)Dimension.map32TilesTR); - // bl = generate(i, k, (int)Dimension.map32TilesBL); - // br = generate(i, k, (int)Dimension.map32TilesBR); - // tiles32.Add(new Tile32(tl, tr, bl, br)); - // } - } -} - -void Overworld::AssembleMap16Tiles() -{ +void Overworld::AssembleMap16Tiles() { int tpos = Core::Constants::map16Tiles; - for (int i = 0; i < 4096; i += 1)//3760 + for (int i = 0; i < 4096; i += 1) // 3760 { - // TileInfo t0 = GFX.gettilesinfo((ushort)BitConverter.ToInt16(ROM.DATA, (tpos))); - // tpos += 2; - // TileInfo t1 = GFX.gettilesinfo((ushort)BitConverter.ToInt16(ROM.DATA, (tpos))); - // tpos += 2; - // TileInfo t2 = GFX.gettilesinfo((ushort)BitConverter.ToInt16(ROM.DATA, (tpos))); - // tpos += 2; - // TileInfo t3 = GFX.gettilesinfo((ushort)BitConverter.ToInt16(ROM.DATA, (tpos))); - // tpos += 2; - // tiles16.push_back(new Tile16(t0, t1, t2, t3)); + TileInfo t0 = GetTilesInfo((uintptr_t)rom_.GetRawData() + tpos); + tpos += 2; + TileInfo t1 = GetTilesInfo((uintptr_t)rom_.GetRawData() + tpos); + tpos += 2; + TileInfo t2 = GetTilesInfo((uintptr_t)rom_.GetRawData() + tpos); + tpos += 2; + TileInfo t3 = GetTilesInfo((uintptr_t)rom_.GetRawData() + tpos); + tpos += 2; + tiles16.push_back(Tile16(t0, t1, t2, t3)); } } +void Overworld::DecompressAllMapTiles() { + int lowest = 0x0FFFFF; + int highest = 0x0F8000; + // int npos = 0; + int sx = 0; + int sy = 0; + int c = 0; + // int furthestPtr = 0; + for (int i = 0; i < 160; i++) { + int p1 = (rom_.GetRawData()[(Constants::compressedAllMap32PointersHigh) + + 2 + (int)(3 * i)] + << 16) + + (rom_.GetRawData()[(Constants::compressedAllMap32PointersHigh) + + 1 + (int)(3 * i)] + << 8) + + (rom_.GetRawData()[(Constants::compressedAllMap32PointersHigh + + (int)(3 * i))]); + p1 = rom_.SnesToPc(p1); + + int p2 = (rom_.GetRawData()[(Constants::compressedAllMap32PointersLow) + 2 + + (int)(3 * i)] + << 16) + + (rom_.GetRawData()[(Constants::compressedAllMap32PointersLow) + 1 + + (int)(3 * i)] + << 8) + + (rom_.GetRawData()[(Constants::compressedAllMap32PointersLow + + (int)(3 * i))]); + p2 = rom_.SnesToPc(p2); + + int ttpos = 0; + unsigned int compressedSize1 = 0; + unsigned int compressedSize2 = 0; + unsigned int compressedLength1 = 0; + unsigned int compressedLength2 = 0; + + if (p1 >= highest) { + highest = p1; + } + if (p2 >= highest) { + highest = p2; + } + + if (p1 <= lowest) { + if (p1 > 0x0F8000) { + lowest = p1; + } + } + if (p2 <= lowest) { + if (p2 > 0x0F8000) { + lowest = p2; + } + } + + auto bytes = alttp_compressor_.DecompressOverworld( + rom_.GetRawData(), p2, 1000, &compressedSize1, &compressedLength1); + auto bytes2 = alttp_compressor_.DecompressOverworld( + rom_.GetRawData(), p1, 1000, &compressedSize2, &compressedLength2); + + for (int y = 0; y < 16; y++) { + for (int x = 0; x < 16; x++) { + ushort tidD = (ushort)((bytes2[ttpos] << 8) + bytes[ttpos]); + + int tpos = tidD; + if (tpos < tiles32.size()) { + // map16tiles[npos] = new Tile32(tiles32[tpos].tile0, + // tiles32[tpos].tile1, tiles32[tpos].tile2, tiles32[tpos].tile3); + + if (i < 64) { + allmapsTilesLW[(x * 2) + (sx * 32)][(y * 2) + (sy * 32)] = + tiles32[tpos].tile0_; + allmapsTilesLW[(x * 2) + 1 + (sx * 32)][(y * 2) + (sy * 32)] = + tiles32[tpos].tile1_; + allmapsTilesLW[(x * 2) + (sx * 32)][(y * 2) + 1 + (sy * 32)] = + tiles32[tpos].tile2_; + allmapsTilesLW[(x * 2) + 1 + (sx * 32)][(y * 2) + 1 + (sy * 32)] = + tiles32[tpos].tile3_; + } else if (i < 128 && i >= 64) { + allmapsTilesDW[(x * 2) + (sx * 32)][(y * 2) + (sy * 32)] = + tiles32[tpos].tile0_; + allmapsTilesDW[(x * 2) + 1 + (sx * 32)][(y * 2) + (sy * 32)] = + tiles32[tpos].tile1_; + allmapsTilesDW[(x * 2) + (sx * 32)][(y * 2) + 1 + (sy * 32)] = + tiles32[tpos].tile2_; + allmapsTilesDW[(x * 2) + 1 + (sx * 32)][(y * 2) + 1 + (sy * 32)] = + tiles32[tpos].tile3_; + } else { + allmapsTilesSP[(x * 2) + (sx * 32)][(y * 2) + (sy * 32)] = + tiles32[tpos].tile0_; + allmapsTilesSP[(x * 2) + 1 + (sx * 32)][(y * 2) + (sy * 32)] = + tiles32[tpos].tile1_; + allmapsTilesSP[(x * 2) + (sx * 32)][(y * 2) + 1 + (sy * 32)] = + tiles32[tpos].tile2_; + allmapsTilesSP[(x * 2) + 1 + (sx * 32)][(y * 2) + 1 + (sy * 32)] = + tiles32[tpos].tile3_; + } + } + + 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::LoadOverworldMap() { + // GFX.overworldMapBitmap = new Bitmap( + // 128, 128, 128, PixelFormat.Format8bppIndexed, GFX.overworldMapPointer); + // GFX.owactualMapBitmap = new Bitmap( + // 512, 512, 512, PixelFormat.Format8bppIndexed, GFX.owactualMapPointer); + + // Mode 7 + byte* ptr = (byte*)overworldMapPointer.get(); + + int pos = 0; + for (int sy = 0; sy < 16; sy++) { + for (int sx = 0; sx < 16; sx++) { + for (int y = 0; y < 8; y++) { + for (int x = 0; x < 8; x++) { + ptr[x + (sx * 8) + (y * 128) + (sy * 1024)] = + rom_.GetRawData()[0x0C4000 + pos]; + pos++; + } + } + } + } + + // ColorPalette cp = overworldMapBitmap.Palette; + // for (int i = 0; i < 256; i += 2) + // { + // //55B27 = US LW + // //55C27 = US DW + // cp.Entries[i / 2] = getColor((short)((ROM.DATA[0x55B27 + i + 1] << 8) + + // ROM.DATA[0x55B27 + i])); + + // int k = 0; + // int j = 0; + // for (int y = 10; y < 14; y++) + // { + // for (int x = 0; x < 15; x++) + // { + // cp.Entries[145 + k] = Palettes.globalSprite_Palettes[0][j]; + // k++; + // j++; + // } + // k++; + // } + // } + + // overworldMapBitmap.Palette = cp; + // owactualMapBitmap.Palette = cp; +} + } // namespace Data -} // namespace Applicationß +} // namespace Application } // namespace yaze \ No newline at end of file diff --git a/src/Application/Data/Overworld.h b/src/Application/Data/Overworld.h index 04764162..c1afcb50 100644 --- a/src/Application/Data/Overworld.h +++ b/src/Application/Data/Overworld.h @@ -5,117 +5,61 @@ #include #include "Core/Constants.h" +#include "Tile.h" +#include "Utils/Bitmap.h" +#include "Utils/Compression.h" +#include "Utils/ROM.h" namespace yaze { namespace Application { namespace Data { -class TileInfo { - public: - unsigned short o; - unsigned short v; - unsigned short h; // o = over, v = vertical mirror, h = horizontal mirror - std::byte palette; - unsigned short id; - // vhopppcc cccccccc - TileInfo() {} - TileInfo(unsigned short id, std::byte palette, unsigned short v, - unsigned short h, unsigned short o) {} - unsigned short toShort() { - unsigned short value = 0; - // vhopppcc cccccccc - if (o == 1) { - value |= 0x2000; - }; - if (h == 1) { - value |= 0x4000; - }; - if (v == 1) { - value |= 0x8000; - }; - value |= (unsigned short)(((unsigned short)palette << 10) & 0x1C00); - value |= (unsigned short)(id & 0x3FF); - return value; - } -}; - -class Tile32 { - //[0,1] - //[2,3] - unsigned short tile0_; - unsigned short tile1_; - unsigned short tile2_; - unsigned short tile3_; - - public: - Tile32(unsigned short tile0, unsigned short tile1, unsigned short tile2, - unsigned short tile3) - : tile0_(tile0), tile1_(tile1), tile2_(tile2), tile3_(tile3) {} - - explicit Tile32(unsigned long tiles) - : tile0_(tiles), - tile1_(tiles >> 16), - tile2_(tiles >> 32), - tile3_(tiles >> 48) {} - - unsigned long getLongValue() { - return ((unsigned long)tile3_ << 48) | ((unsigned long)tile2_ << 32) | - ((unsigned long)tile1_ << 16) | (unsigned long)(tile0_); - } -}; - -class Tile16 { - public: - TileInfo tile0_; - TileInfo tile1_; - TileInfo tile2_; - TileInfo tile3_; - std::vector tiles_info; - //[0,1] - //[2,3] - - Tile16(TileInfo tile0, TileInfo tile1, TileInfo tile2, TileInfo tile3) - : tile0_(tile0), tile1_(tile1), tile2_(tile2), tile3_(tile3) { - tiles_info.push_back(tile0_); - tiles_info.push_back(tile1_); - tiles_info.push_back(tile2_); - tiles_info.push_back(tile3_); - } - - explicit Tile16(unsigned long tiles) { - // tile0_ = GFX.gettilesinfo((unsigned short)tiles); - // tile1_ = GFX.gettilesinfo((unsigned short)(tiles >> 16)); - // tile2_ = GFX.gettilesinfo((unsigned short)(tiles >> 32)); - // tile3_ = GFX.gettilesinfo((unsigned short)(tiles >> 48)); - } - - unsigned long getLongValue() { - return ((unsigned long)(tile3_.toShort()) << 48) | - ((unsigned long)(tile2_.toShort()) << 32) | - ((unsigned long)(tile1_.toShort()) << 16) | - (unsigned long)((tile0_.toShort())); - ; - } -}; +using ushort = ushort; +using byte = unsigned char; class Overworld { public: - Overworld(); + Overworld(Utils::ROM rom); private: - void AssembleMap32Tiles(); - void AssembleMap16Tiles(); + Utils::ROM rom_; + Utils::ALTTPCompression alttp_compressor_; std::vector tiles16; std::vector tiles32; std::vector map16tiles; - std::vector tileLeftEntrance; - std::vector tileRightEntrance; + std::vector tileLeftEntrance; + std::vector tileRightEntrance; int map32address[4] = { Core::Constants::map32TilesTL, Core::Constants::map32TilesTR, Core::Constants::map32TilesBL, Core::Constants::map32TilesBR}; + + std::unique_ptr overworldMapPointer; + Utils::Bitmap overworldMapBitmap; + + std::unique_ptr owactualMapPointer; + Utils::Bitmap owactualMapBitmap; + + enum Dimension { + map32TilesTL = 0, + map32TilesTR = 1, + map32TilesBL = 2, + map32TilesBR = 3 + }; + + unsigned short **allmapsTilesLW; + + // 64 maps * (32*32 tiles) ushort[512, 512] + std::vector> allmapsTilesDW; // 64 maps * (32*32 tiles) + std::vector> allmapsTilesSP; // 32 maps * (32*32 tiles) + + ushort GenerateTile32(int i, int k, int dimension); + void AssembleMap32Tiles(); + void AssembleMap16Tiles(); + void DecompressAllMapTiles(); + void LoadOverworldMap(); }; } // namespace Data diff --git a/src/Application/Data/Tile.cc b/src/Application/Data/Tile.cc new file mode 100644 index 00000000..2cc164e3 --- /dev/null +++ b/src/Application/Data/Tile.cc @@ -0,0 +1,26 @@ +#include "Tile.h" + +namespace yaze { +namespace Application { +namespace Data { + +ushort TileInfo::toShort() { + ushort value = 0; + // vhopppcc cccccccc + if (over_ == 1) { + value |= 0x2000; + }; + if (horizontal_mirror_ == 1) { + value |= 0x4000; + }; + if (vertical_mirror_ == 1) { + value |= 0x8000; + }; + value |= (ushort)((palette_ << 10) & 0x1C00); + value |= (ushort)(id_ & 0x3FF); + return value; +} + +} // namespace Data +} // namespace Application +} // namespace yaze diff --git a/src/Application/Data/Tile.h b/src/Application/Data/Tile.h new file mode 100644 index 00000000..393c42c0 --- /dev/null +++ b/src/Application/Data/Tile.h @@ -0,0 +1,91 @@ +#ifndef YAZE_APPLICATION_DATA_TILE_H +#define YAZE_APPLICATION_DATA_TILE_H + +#include + +namespace yaze { +namespace Application { +namespace Data { + +using byte = unsigned char; +using ushort = unsigned short; + +class TileInfo { + public: + ushort id_; + ushort over_; + ushort vertical_mirror_; + ushort horizontal_mirror_; + byte palette_; + TileInfo() {} // vhopppcc cccccccc + TileInfo(ushort id, byte palette, ushort v, ushort h, ushort o) + : id_(id), + palette_(palette), + vertical_mirror_(v), + horizontal_mirror_(h), + over_(o) {} + ushort toShort(); +}; + +class Tile32 { + public: + //[0,1] + //[2,3] + ushort tile0_; + ushort tile1_; + ushort tile2_; + ushort tile3_; + + Tile32(ushort tile0, ushort tile1, ushort tile2, ushort tile3) + : tile0_(tile0), tile1_(tile1), tile2_(tile2), tile3_(tile3) {} + + explicit Tile32(unsigned long tiles) + : tile0_(tiles), + tile1_(tiles >> 16), + tile2_(tiles >> 32), + tile3_(tiles >> 48) {} + + unsigned long getLongValue() { + return ((unsigned long)tile3_ << 48) | ((unsigned long)tile2_ << 32) | + ((unsigned long)tile1_ << 16) | (unsigned long)(tile0_); + } +}; + +class Tile16 { + public: + TileInfo tile0_; + TileInfo tile1_; + TileInfo tile2_; + TileInfo tile3_; + std::vector tiles_info; + //[0,1] + //[2,3] + + Tile16(TileInfo tile0, TileInfo tile1, TileInfo tile2, TileInfo tile3) + : tile0_(tile0), tile1_(tile1), tile2_(tile2), tile3_(tile3) { + tiles_info.push_back(tile0_); + tiles_info.push_back(tile1_); + tiles_info.push_back(tile2_); + tiles_info.push_back(tile3_); + } + + explicit Tile16(unsigned long tiles) { + // tile0_ = GFX.gettilesinfo((ushort)tiles); + // tile1_ = GFX.gettilesinfo((ushort)(tiles >> 16)); + // tile2_ = GFX.gettilesinfo((ushort)(tiles >> 32)); + // tile3_ = GFX.gettilesinfo((ushort)(tiles >> 48)); + } + + unsigned long getLongValue() { + return ((unsigned long)(tile3_.toShort()) << 48) | + ((unsigned long)(tile2_.toShort()) << 32) | + ((unsigned long)(tile1_.toShort()) << 16) | + (unsigned long)((tile0_.toShort())); + ; + } +}; +} // namespace Data +} // namespace Application +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/Application/Utils/Bitmap.cc b/src/Application/Utils/Bitmap.cc new file mode 100644 index 00000000..4b758090 --- /dev/null +++ b/src/Application/Utils/Bitmap.cc @@ -0,0 +1 @@ +#include "Bitmap.h" \ No newline at end of file diff --git a/src/Application/Utils/Bitmap.h b/src/Application/Utils/Bitmap.h new file mode 100644 index 00000000..42346275 --- /dev/null +++ b/src/Application/Utils/Bitmap.h @@ -0,0 +1,19 @@ +#ifndef YAZE_APPLICATION_UTILS_BITMAP_H +#define YAZE_APPLICATION_UTILS_BITMAP_H + +#include +#include + +namespace yaze { +namespace Application { +namespace Utils { +class Bitmap { + + +}; + +} // namespace Utils +} // namespace Application +} // namespace yaze + +#endif \ No newline at end of file