From 4ce3f3771459ae40b06dabada0e088c4c2552017 Mon Sep 17 00:00:00 2001 From: Ian Brown Date: Tue, 23 Mar 2021 00:05:58 +0000 Subject: [PATCH] texture chunks --- CuttownTest/gameData.cpp | 2 +- snowlib/World.cpp | 2 +- snowlib/World.h | 4 ++++ snowlib/WorldReader.cpp | 27 +++++++++++++++++++++++++++ snowlib/WorldReader.h | 7 +++++++ 5 files changed, 40 insertions(+), 2 deletions(-) diff --git a/CuttownTest/gameData.cpp b/CuttownTest/gameData.cpp index 1b0a15a..ba532ff 100644 --- a/CuttownTest/gameData.cpp +++ b/CuttownTest/gameData.cpp @@ -44,7 +44,7 @@ void GameData::read(QString rootDir, QString worldName) gobName = worldName.toUpper() + ".GOB"; QString gobFile = lmpDir + "/" + gobName; worldGob = new GobFile(gobFile.toStdString(), gameType); - world = WorldReader().readWorld(worldGob, worldName.toLower().toStdString().c_str()); + world = WorldReader(gameType).readWorld(worldGob, worldName.toLower().toStdString().c_str()); } } diff --git a/snowlib/World.cpp b/snowlib/World.cpp index d72f981..5d1a870 100644 --- a/snowlib/World.cpp +++ b/snowlib/World.cpp @@ -1,6 +1,6 @@ #include "World.h" -World::World() +World::World() : textureChunkOffsets(100*100, 0) { topoStartCol = 0; topoStartRow = 0; diff --git a/snowlib/World.h b/snowlib/World.h index b32a93c..f757540 100644 --- a/snowlib/World.h +++ b/snowlib/World.h @@ -60,4 +60,8 @@ public: // All of the topo patches. This collection owns the patches. std::vector topoPatches; + // The texture chunk offsets. 2D array with a 100 x 100 dimension. + std::vector textureChunkOffsets; + + void setTextureChunkOffset(int x, int y, int addr) { textureChunkOffsets.at(y * 100 + x) = addr; } }; diff --git a/snowlib/WorldReader.cpp b/snowlib/WorldReader.cpp index d77f50b..b24d153 100644 --- a/snowlib/WorldReader.cpp +++ b/snowlib/WorldReader.cpp @@ -50,6 +50,33 @@ void WorldReader::decodeWorldFile(World* world, const unsigned char* data, int d int offset68 = DataUtil::getLEInt(data, 0x68); int worldTexOffsetsOffset = DataUtil::getLEInt(data, 0x6C); + readTextureChunkOffsets(world, data, dataLength, worldTexOffsetsOffset, texMinx, texMiny, texMaxx+1, texMaxy); +} + +void WorldReader::readTextureChunkOffsets(World* world, const unsigned char* data, int dataLength, int worldTexOffsetsOffset, int texMinx, int texMiny, int texMaxx, int texMaxy) +{ + for (int y = texMiny; y <= texMaxy; ++y) + { + for (int x = texMinx; x <= texMaxx; ++x) + { + int cellOffset = ((y - texMiny) * 100 + x - texMinx) * 8; + // This test is needed to deal with town.world in BGDA which addresses textures outside of the maximum x range. + if (dataLength >= cellOffset + 4) + { + int addr; + if (GameType::CHAMPIONS_RTA == gameType || GameType::JL_HEROES == gameType) + { + // TODO: Figure out what this should really be + addr = 0x800; + } + else + { + addr = DataUtil::getLEInt(data, cellOffset); + } + world->setTextureChunkOffset(x, y, addr); + } + } + } } void WorldReader::decodeTopography(World* world, const unsigned char* data, int dataLength) diff --git a/snowlib/WorldReader.h b/snowlib/WorldReader.h index 7fdf46e..3163ae3 100644 --- a/snowlib/WorldReader.h +++ b/snowlib/WorldReader.h @@ -1,5 +1,7 @@ #pragma once +#include "GameType.h" + class World; class LmpRepository; class TopoPatch; @@ -7,10 +9,15 @@ class TopoPatch; class WorldReader { public: + WorldReader(GameType gameType) : gameType(gameType) {} World* readWorld(LmpRepository* lmpRepository, const char* name); private: + GameType gameType; + void decodeWorldFile(World* world, const unsigned char* data, int dataLength); void decodeTopography(World* world, const unsigned char* data, int dataLength); TopoPatch* readTopoPatch(const unsigned char* data, int offset); + void readTextureChunkOffsets(World* world, const unsigned char* data, int dataLength, int worldTexOffsetsOffset, int texMinx, int texMiny, int texMaxx, int texMaxy); + }; \ No newline at end of file