[ZoneBuilder] Added IFxWorld interface, should work fully

This commit is contained in:
TheApadayo 2016-12-22 00:42:53 -05:00
parent 8f42168ec3
commit 296af1716a
6 changed files with 332 additions and 2 deletions

View File

@ -384,6 +384,7 @@ namespace Components
if (ZoneBuilder::IsEnabled())
{
AssetHandler::RegisterInterface(new Assets::IXModel());
AssetHandler::RegisterInterface(new Assets::IFxWorld());
AssetHandler::RegisterInterface(new Assets::IMapEnts());
AssetHandler::RegisterInterface(new Assets::IRawFile());
AssetHandler::RegisterInterface(new Assets::IComWorld());

View File

@ -71,6 +71,7 @@ namespace Components
}
#include "AssetInterfaces\IXModel.hpp"
#include "AssetInterfaces\IFxWorld.hpp"
#include "AssetInterfaces\IMapEnts.hpp"
#include "AssetInterfaces\IRawFile.hpp"
#include "AssetInterfaces\IComWorld.hpp"

View File

@ -0,0 +1,177 @@
#include <StdInclude.hpp>
namespace Assets
{
void IFxWorld::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
{
AssertSize(Game::FxWorld, 116);
Utils::Stream* buffer = builder->getBuffer();
SAVE_LOG_ENTER("FxWorld");
Game::FxWorld* asset = header.fxWorld;
Game::FxWorld* dest = buffer->dest<Game::FxWorld>();
buffer->save(asset);
buffer->pushBlock(Game::XFILE_BLOCK_VIRTUAL);
if (asset->name)
{
buffer->saveString(builder->getAssetName(this->getType(), asset->name));
Utils::Stream::ClearPointer(&dest->name);
}
// saveFxGlassSystem
{
AssertSize(Game::FxGlassSystem, 112);
if(asset->glassSys.defs)
{
AssertSize(Game::FxGlassDef, 36);
buffer->align(Utils::Stream::ALIGN_4);
Game::FxGlassDef* glassDefTable = buffer->dest<Game::FxGlassDef>();
buffer->saveArray(asset->glassSys.defs, asset->glassSys.defCount);
for (unsigned int i = 0; i < asset->glassSys.defCount; ++i)
{
Game::FxGlassDef* glassDef = &asset->glassSys.defs[i];
Game::FxGlassDef* destGlassDef = &glassDefTable[i];
if (glassDef->physPreset)
{
destGlassDef->physPreset = builder->requireAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, glassDef->physPreset->name).physPreset;
}
if (glassDef->material)
{
destGlassDef->material = builder->requireAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, glassDef->material->name).material;
}
if (glassDef->materialShattered)
{
destGlassDef->materialShattered = builder->requireAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, glassDef->materialShattered->name).material;
}
}
}
buffer->pushBlock(Game::XFILE_BLOCK_RUNTIME);
if (asset->glassSys.piecePlaces)
{
AssertSize(Game::FxGlassPiecePlace, 32);
buffer->align(Utils::Stream::ALIGN_4);
buffer->saveArray(asset->glassSys.piecePlaces, asset->glassSys.pieceLimit);
Utils::Stream::ClearPointer(&dest->glassSys.piecePlaces);
}
if (asset->glassSys.pieceStates)
{
AssertSize(Game::FxGlassPieceState, 32);
buffer->align(Utils::Stream::ALIGN_4);
buffer->saveArray(asset->glassSys.pieceStates, asset->glassSys.pieceLimit);
Utils::Stream::ClearPointer(&dest->glassSys.pieceStates);
}
if (asset->glassSys.pieceDynamics)
{
AssertSize(Game::FxGlassPieceDynamics, 36);
buffer->align(Utils::Stream::ALIGN_4);
buffer->saveArray(asset->glassSys.pieceDynamics, asset->glassSys.pieceLimit);
Utils::Stream::ClearPointer(&dest->glassSys.pieceDynamics);
}
if (asset->glassSys.geoData)
{
AssertSize(Game::FxGlassGeometryData, 4);
buffer->align(Utils::Stream::ALIGN_4);
buffer->saveArray(asset->glassSys.geoData, asset->glassSys.geoDataLimit);
Utils::Stream::ClearPointer(&dest->glassSys.geoData);
}
if (asset->glassSys.isInUse)
{
buffer->align(Utils::Stream::ALIGN_4);
buffer->saveArray(asset->glassSys.isInUse, asset->glassSys.pieceWordCount);
Utils::Stream::ClearPointer(&dest->glassSys.isInUse);
}
if (asset->glassSys.cellBits)
{
buffer->align(Utils::Stream::ALIGN_4);
buffer->saveArray(asset->glassSys.cellBits, asset->glassSys.pieceWordCount * asset->glassSys.cellCount);
Utils::Stream::ClearPointer(&dest->glassSys.cellBits);
}
if (asset->glassSys.visData)
{
buffer->align(Utils::Stream::ALIGN_16);
buffer->save(asset->glassSys.visData, 1, (asset->glassSys.pieceLimit + 15) & 0xFFFFFFF0);
Utils::Stream::ClearPointer(&dest->glassSys.visData);
}
if (asset->glassSys.linkOrg)
{
buffer->align(Utils::Stream::ALIGN_4);
buffer->saveArray(asset->glassSys.linkOrg, asset->glassSys.pieceLimit);
Utils::Stream::ClearPointer(&dest->glassSys.linkOrg);
}
if (asset->glassSys.halfThickness)
{
buffer->align(Utils::Stream::ALIGN_16);
buffer->save(asset->glassSys.halfThickness, 1, ((4 * asset->glassSys.pieceLimit) + 12) & 0xFFFFFFF0);
Utils::Stream::ClearPointer(&dest->glassSys.halfThickness);
}
buffer->popBlock();
if (asset->glassSys.lightingHandles)
{
buffer->align(Utils::Stream::ALIGN_2);
buffer->saveArray(asset->glassSys.lightingHandles, asset->glassSys.initPieceCount);
Utils::Stream::ClearPointer(&dest->glassSys.lightingHandles);
}
if (asset->glassSys.initPieceStates)
{
AssertSize(Game::FxGlassInitPieceState, 52);
buffer->align(Utils::Stream::ALIGN_4);
buffer->saveArray(asset->glassSys.initPieceStates, asset->glassSys.initPieceCount);
Utils::Stream::ClearPointer(&dest->glassSys.initPieceStates);
}
if (asset->glassSys.initGeoData)
{
buffer->align(Utils::Stream::ALIGN_4);
buffer->saveArray(asset->glassSys.initGeoData, asset->glassSys.initGeoDataCount);
Utils::Stream::ClearPointer(&dest->glassSys.initGeoData);
}
}
}
void IFxWorld::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
{
Game::FxWorld* asset = header.fxWorld;
if (asset->glassSys.defs)
{
for (unsigned int i = 0; i < asset->glassSys.defCount; ++i)
{
builder->loadAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, asset->glassSys.defs[i].physPreset->name);
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->glassSys.defs[i].material->name);
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->glassSys.defs[i].materialShattered->name);
}
}
}
void IFxWorld::load(Game::XAssetHeader* /*header*/, std::string name, Components::ZoneBuilder::Zone* /*builder*/)
{
Game::FxWorld* map = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FX_MAP, name.data()).fxWorld;
if (map) return;
Components::Logger::Error("Missing fx_map %s... you can't make them yet you idiot.", name.data());
}
}

View File

@ -0,0 +1,12 @@
namespace Assets
{
class IFxWorld : public Components::AssetHandler::IAsset
{
public:
virtual Game::XAssetType getType() override { return Game::XAssetType::ASSET_TYPE_FX_MAP; };
virtual void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
virtual void mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
virtual void load(Game::XAssetHeader* header, std::string name, Components::ZoneBuilder::Zone* builder) override;
};
}

View File

@ -3211,6 +3211,144 @@ namespace Game
ComPrimaryLight* lights;
};
#pragma pack(push, 4)
struct FxGlassDef
{
float halfThickness;
float texVecs[2][2];
GfxColor color;
Material *material;
Material *materialShattered;
PhysPreset *physPreset;
};
#pragma pack(pop)
struct FxSpatialFrame
{
float quat[4];
float origin[3];
};
union FxGlassPiecePlace
{
struct
{
FxSpatialFrame frame;
float radius;
};
unsigned int nextFree;
};
struct FxGlassPieceState
{
float texCoordOrigin[2];
unsigned int supportMask;
unsigned __int16 initIndex;
unsigned __int16 geoDataStart;
unsigned __int16 lightingIndex;
char defIndex;
char pad[3];
char vertCount;
char holeDataCount;
char crackDataCount;
char fanDataCount;
unsigned __int16 flags;
float areaX2;
};
struct FxGlassPieceDynamics
{
char pad[36];
};
struct FxGlassVertex
{
__int16 x;
__int16 y;
};
struct FxGlassHoleHeader
{
unsigned __int16 uniqueVertCount;
char touchVert;
char pad[1];
};
struct FxGlassCrackHeader
{
unsigned __int16 uniqueVertCount;
char beginVertIndex;
char endVertIndex;
};
union FxGlassGeometryData
{
FxGlassVertex vert;
FxGlassHoleHeader hole;
FxGlassCrackHeader crack;
char asBytes[4];
__int16 anonymous[2];
};
#pragma pack(push, 4)
struct FxGlassInitPieceState //Note, on MW3 this is missing 4 bytes, just not sure whats missing yet
{
/*
FxSpatialFrame frame;
float radius;
float texCoordOrigin[2];
unsigned int supportMask;
float areaX2;
unsigned __int16 lightingIndex;
char defIndex;
char vertCount;
char fanDataCount;
*/
char pad[52];
};
#pragma pack(pop)
#pragma pack(push, 8)
struct FxGlassSystem
{
int time;
int prevTime;
unsigned int defCount;
unsigned int pieceLimit;
unsigned int pieceWordCount;
unsigned int initPieceCount;
unsigned int cellCount;
unsigned int activePieceCount;
unsigned int firstFreePiece;
unsigned int geoDataLimit;
unsigned int geoDataCount;
unsigned int initGeoDataCount;
FxGlassDef *defs;
FxGlassPiecePlace *piecePlaces;
FxGlassPieceState *pieceStates;
FxGlassPieceDynamics *pieceDynamics;
FxGlassGeometryData *geoData;
unsigned int *isInUse;
unsigned int *cellBits;
char *visData;
float (*linkOrg)[3];
float *halfThickness;
unsigned __int16 *lightingHandles;
FxGlassInitPieceState *initPieceStates;
FxGlassGeometryData *initGeoData;
bool needToCompactData;
char initCount;
float effectChanceAccum;
int lastPieceDeletionTime;
};
#pragma pack(pop)
struct FxWorld
{
const char * name;
FxGlassSystem glassSys;
};
union XAssetHeader
{
void *data;
@ -3241,6 +3379,7 @@ namespace Game
GameWorldSp* gameWorldSp;
TracerDef* tracer;
VehicleDef* vehicle;
FxWorld* fxWorld;
GfxWorld* gfxWorld;
GfxLightDef* lightDef;
SndCurve* sndCurve;

View File

@ -112,8 +112,8 @@ namespace Utils
char* Stream::save(Game::XFILE_BLOCK_TYPES stream, const void * _str, size_t size, size_t count)
{
// Only those seem to actually write data.
// As I'm not sure though, I'll still write the data
// Use IncreaseBlockSize to fill virtual streams
// everything else is allocated at runtime but XFILE_BLOCK_RUNTIME is the only one that actually allocates anything
// clearly half of this stuff is unused
if (stream != Game::XFILE_BLOCK_TEMP && stream != Game::XFILE_BLOCK_VIRTUAL && stream != Game::XFILE_BLOCK_PHYSICAL && stream != Game::XFILE_BLOCK_INVALID)
{
this->increaseBlockSize(stream, size * count);