starting world reading
This commit is contained in:
parent
4ce3f37714
commit
85da6224e0
5
buildscripts/generate_vs2019_64_laptop.cmd
Normal file
5
buildscripts/generate_vs2019_64_laptop.cmd
Normal file
|
@ -0,0 +1,5 @@
|
|||
@echo off
|
||||
mkdir build_vs2019
|
||||
pushd build_vs2019
|
||||
"C:\Program Files\CMake\bin\cmake" -G "Visual Studio 16 2019" -A x64 -DADDITIONAL_FIND_PATH="C:\Qt6\6.0.2\msvc2019_64" -DVCPKG_TARGET_TRIPLET=x64-windows -DCMAKE_TOOLCHAIN_FILE="C:\dev\vcpkg\scripts\buildsystems\vcpkg.cmake" ../..
|
||||
popd
|
|
@ -5,16 +5,53 @@
|
|||
class DataUtil
|
||||
{
|
||||
public:
|
||||
static int getLEInt(const unsigned char* data, int offset){
|
||||
DataUtil(const unsigned char* p_in, int offset_in) : p(p_in), offset(offset_in)
|
||||
{
|
||||
}
|
||||
|
||||
float getLEFloat()
|
||||
{
|
||||
const float f = *(float*)(p + offset);
|
||||
offset += 4;
|
||||
return f;
|
||||
}
|
||||
|
||||
int getLEInt()
|
||||
{
|
||||
const int i = *(int32_t*)(p + offset);
|
||||
offset += 4;
|
||||
return i;
|
||||
}
|
||||
|
||||
unsigned short getLEUShort()
|
||||
{
|
||||
const unsigned short s = *(uint16_t*)(p + offset);
|
||||
offset += 2;
|
||||
return s;
|
||||
}
|
||||
|
||||
static int getLEInt(const unsigned char* data, int offset)
|
||||
{
|
||||
return *(int32_t *)(data + offset);
|
||||
}
|
||||
|
||||
static short getLEShort(const unsigned char* data, int offset){
|
||||
static short getLEShort(const unsigned char* data, int offset)
|
||||
{
|
||||
return *(int16_t *)(data + offset);
|
||||
}
|
||||
|
||||
static unsigned short getLEUShort(const unsigned char* data, int offset){
|
||||
static unsigned short getLEUShort(const unsigned char* data, int offset)
|
||||
{
|
||||
return *(uint16_t *)(data + offset);
|
||||
}
|
||||
|
||||
static float getLEFloat(const unsigned char* data, int offset)
|
||||
{
|
||||
return *(float*)(data + offset);
|
||||
}
|
||||
|
||||
private:
|
||||
const unsigned char* p;
|
||||
int offset;
|
||||
};
|
||||
|
||||
|
|
|
@ -7,6 +7,17 @@
|
|||
class Mesh
|
||||
{
|
||||
public:
|
||||
Mesh() {
|
||||
positions = normals = nullptr;
|
||||
uvCoords = nullptr;
|
||||
numVertices = 0;
|
||||
}
|
||||
~Mesh() {
|
||||
delete positions; positions = nullptr;
|
||||
delete normals; normals = nullptr;
|
||||
delete uvCoords; uvCoords = nullptr;
|
||||
}
|
||||
|
||||
std::vector<int> triangleIndices;
|
||||
FloatVector* positions;
|
||||
FloatVector* normals;
|
||||
|
|
|
@ -1,12 +1,21 @@
|
|||
#pragma once
|
||||
#include <vector>
|
||||
|
||||
class Texture;
|
||||
class AnimData;
|
||||
#include "Texture.h"
|
||||
#include "AnimData.h"
|
||||
class Mesh;
|
||||
|
||||
class TexturedMesh
|
||||
{
|
||||
public:
|
||||
TexturedMesh() {
|
||||
meshList = nullptr;
|
||||
texture = nullptr;
|
||||
}
|
||||
~TexturedMesh() {
|
||||
delete meshList; meshList = nullptr;
|
||||
delete texture; texture = nullptr;
|
||||
}
|
||||
std::vector<Mesh*>* meshList;
|
||||
Texture* texture;
|
||||
};
|
||||
|
@ -14,6 +23,12 @@ public:
|
|||
class Model
|
||||
{
|
||||
public:
|
||||
Model() {
|
||||
animData = nullptr;
|
||||
}
|
||||
~Model() {
|
||||
delete animData; animData = nullptr;
|
||||
}
|
||||
std::vector<TexturedMesh*> texturedMeshList;
|
||||
AnimData* animData;
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
struct FloatVector
|
||||
{
|
||||
FloatVector(){}
|
||||
FloatVector() : x(0.0f), y(0.0f), z(0.0f){}
|
||||
FloatVector(float xx, float yy, float zz) : x(xx), y(yy), z(zz){}
|
||||
|
||||
float x;
|
||||
|
@ -10,6 +10,30 @@ struct FloatVector
|
|||
float z;
|
||||
};
|
||||
|
||||
struct FloatRect
|
||||
{
|
||||
FloatRect() : x0(0.0f), y0(0.0f), x1(0.0f), y1(0.0f) {}
|
||||
FloatRect(float xx0, float yy0, float xx1, float yy1) : x0(xx0), y0(yy0), x1(xx1), y1(yy1) {}
|
||||
|
||||
float x0;
|
||||
float y0;
|
||||
float x1;
|
||||
float y1;
|
||||
};
|
||||
|
||||
struct FloatBox
|
||||
{
|
||||
FloatBox() : x0(0.0f), y0(0.0f), z0(0.0f), x1(0.0f), y1(0.0f), z1(0.0f) {}
|
||||
FloatBox(float xx0, float yy0, float zz0, float xx1, float yy1, float zz1) : x0(xx0), y0(yy0), z0(zz0), x1(xx1), y1(yy1), z1(zz1) {}
|
||||
|
||||
float x0;
|
||||
float y0;
|
||||
float z0;
|
||||
float x1;
|
||||
float y1;
|
||||
float z1;
|
||||
};
|
||||
|
||||
struct ShortVector
|
||||
{
|
||||
ShortVector(short xx, short yy, short zz) : x(xx), y(yy), z(zz){}
|
||||
|
@ -30,7 +54,7 @@ struct SByteVector
|
|||
|
||||
struct Point
|
||||
{
|
||||
Point(){}
|
||||
Point() : x(0), y(0){}
|
||||
Point(int xx, int yy) : x(xx), y(yy){}
|
||||
|
||||
int x;
|
||||
|
|
|
@ -18,10 +18,17 @@ World::~World()
|
|||
{
|
||||
delete patch;
|
||||
}
|
||||
for (auto& element : elements)
|
||||
{
|
||||
delete element;
|
||||
}
|
||||
}
|
||||
|
||||
TopoPatch::TopoPatch(int width, int height)
|
||||
{
|
||||
minHeight = 0;
|
||||
maxHeight = 0;
|
||||
x0 = y0 = 0;
|
||||
w = width;
|
||||
h = height;
|
||||
heights = new int[w * h];
|
||||
|
@ -29,5 +36,5 @@ TopoPatch::TopoPatch(int width, int height)
|
|||
|
||||
TopoPatch::~TopoPatch()
|
||||
{
|
||||
delete[] heights;
|
||||
delete[] heights; heights = nullptr;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "VertexDefs.h"
|
||||
#include "Model.h"
|
||||
|
||||
class TopoPatch
|
||||
{
|
||||
|
@ -18,13 +21,35 @@ class TopoElement
|
|||
public:
|
||||
int llx, lly, urx, ury;
|
||||
int int8;
|
||||
TopoPatch* patch;
|
||||
std::shared_ptr<TopoPatch> patch;
|
||||
int flags;
|
||||
int x0, y0;
|
||||
int baseHeight;
|
||||
double cos_alpha, sin_alpha;
|
||||
};
|
||||
|
||||
class WorldElement
|
||||
{
|
||||
public:
|
||||
FloatBox boundingBox;
|
||||
TexturedMesh mesh;
|
||||
|
||||
// The position before rotation
|
||||
FloatVector pos;
|
||||
|
||||
bool usesRotFlags;
|
||||
int xyzRotFlags;
|
||||
|
||||
double cosAlpha;
|
||||
double sinAlpha;
|
||||
// Whether we should flip the y axis (when not using rot flags)
|
||||
bool negYaxis;
|
||||
|
||||
// Store info to access again
|
||||
int VifDataOffset;
|
||||
int VifDataLength;
|
||||
};
|
||||
|
||||
class World
|
||||
{
|
||||
public:
|
||||
|
@ -60,6 +85,9 @@ public:
|
|||
// All of the topo patches. This collection owns the patches.
|
||||
std::vector<TopoPatch*> topoPatches;
|
||||
|
||||
// All of the elements. This collection owns the elements.
|
||||
std::vector<WorldElement*> elements;
|
||||
|
||||
// The texture chunk offsets. 2D array with a 100 x 100 dimension.
|
||||
std::vector<int> textureChunkOffsets;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "World.h"
|
||||
#include "LmpRepository.h"
|
||||
#include "DataUtil.h"
|
||||
#include "VifDecoder.h"
|
||||
|
||||
World* WorldReader::readWorld(LmpRepository* lmpRepository, const char* name)
|
||||
{
|
||||
|
@ -51,6 +52,66 @@ void WorldReader::decodeWorldFile(World* world, const unsigned char* data, int d
|
|||
int worldTexOffsetsOffset = DataUtil::getLEInt(data, 0x6C);
|
||||
|
||||
readTextureChunkOffsets(world, data, dataLength, worldTexOffsetsOffset, texMinx, texMiny, texMaxx+1, texMaxy);
|
||||
readElements(world, data, dataLength, elementBase, numElements, texMinx, texMiny);
|
||||
}
|
||||
|
||||
void WorldReader::readElements(World* world, const unsigned char* data, int dataLength, int elementBase, int numElements, int texMinx, int texMiny)
|
||||
{
|
||||
for (int idx = 0; idx < numElements; ++idx) {
|
||||
auto element = new WorldElement();
|
||||
int elementSize = 0x38;
|
||||
if (GameType::CHAMPIONS_RTA == gameType || GameType::JL_HEROES == gameType) {
|
||||
elementSize = 0x3C;
|
||||
}
|
||||
int elementOffset = elementBase + idx * elementSize;
|
||||
|
||||
DataUtil reader(data, elementOffset);
|
||||
|
||||
int vifDataOffset = reader.getLEInt();
|
||||
|
||||
if (GameType::DARK_ALLIANCE == gameType) {
|
||||
int Tex2 = reader.getLEInt();
|
||||
}
|
||||
int vifLen = reader.getLEInt();
|
||||
float x1 = reader.getLEFloat();
|
||||
float y1 = reader.getLEFloat();
|
||||
float z1 = reader.getLEFloat();
|
||||
float x2 = reader.getLEFloat();
|
||||
float y2 = reader.getLEFloat();
|
||||
float z2 = reader.getLEFloat();
|
||||
|
||||
element->boundingBox = FloatBox(x1, y1, z1, x2 - x1, y2 - y1, z2 - z1);
|
||||
|
||||
int textureNum = reader.getLEInt() / 0x40;
|
||||
|
||||
int texCellxy = reader.getLEUShort();
|
||||
int y = texCellxy / 100;
|
||||
int x = texCellxy % 100;
|
||||
if (GameType::CHAMPIONS_RTA == gameType || GameType::JL_HEROES == gameType) {
|
||||
x += texMinx;
|
||||
y += texMiny;
|
||||
}
|
||||
if (textureNum != 0) {
|
||||
// TODO
|
||||
}
|
||||
int texWidth = 100;
|
||||
int texHeight = 100;
|
||||
/*
|
||||
if (element.Texture != null)
|
||||
{
|
||||
texWidth = element.Texture.PixelWidth;
|
||||
texHeight = element.Texture.PixelHeight;
|
||||
}
|
||||
*/
|
||||
unsigned char nregs = data[vifDataOffset + 0x10];
|
||||
int vifStartOffset = (nregs + 2) * 0x10;
|
||||
int vifDataLength = vifLen * 0x10 - vifStartOffset;
|
||||
|
||||
element->mesh.meshList = VifDecoder().decode(data, vifDataOffset + vifStartOffset);
|
||||
|
||||
|
||||
world->elements.push_back(element);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldReader::readTextureChunkOffsets(World* world, const unsigned char* data, int dataLength, int worldTexOffsetsOffset, int texMinx, int texMiny, int texMaxx, int texMaxy)
|
||||
|
@ -91,7 +152,7 @@ void WorldReader::decodeTopography(World* world, const unsigned char* data, int
|
|||
int topoArrayOffset = DataUtil::getLEInt(data, 0x20);
|
||||
|
||||
// Allows us to quickly look up patches from the offsets stored in the file.
|
||||
std::unordered_map<int, TopoPatch*> patchAddressMap;
|
||||
std::unordered_map<int, std::shared_ptr<TopoPatch>> patchAddressMap;
|
||||
|
||||
world->topoElements.resize(numTopoElements);
|
||||
for (int el = 0; el < numTopoElements; ++el){
|
||||
|
@ -138,11 +199,11 @@ void WorldReader::decodeTopography(World* world, const unsigned char* data, int
|
|||
}
|
||||
}
|
||||
|
||||
TopoPatch* WorldReader::readTopoPatch(const unsigned char* data, int offset)
|
||||
std::shared_ptr<TopoPatch> WorldReader::readTopoPatch(const unsigned char* data, int offset)
|
||||
{
|
||||
int w = DataUtil::getLEInt(data, offset + 8);
|
||||
int h = DataUtil::getLEInt(data, offset + 0x0c);
|
||||
TopoPatch* patch = new TopoPatch(w, h);
|
||||
auto patch = std::make_shared<TopoPatch>(w, h);
|
||||
patch->x0 = DataUtil::getLEInt(data, offset);
|
||||
patch->y0 = DataUtil::getLEInt(data, offset + 4);
|
||||
patch->minHeight = DataUtil::getLEShort(data, offset + 0x10);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "GameType.h"
|
||||
|
||||
class World;
|
||||
|
@ -17,7 +18,7 @@ private:
|
|||
|
||||
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);
|
||||
std::shared_ptr<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);
|
||||
|
||||
void readElements(World* world, const unsigned char* data, int dataLength, int elementBase, int numElements, int texMinx, int texMiny);
|
||||
};
|
Reference in a new issue