iw4x-client/src/Components/Modules/AssetInterfaces/IXAnimParts.cpp

355 lines
9.0 KiB
C++
Raw Normal View History

2016-07-11 11:14:58 -04:00
#include <STDInclude.hpp>
#define IW4X_ANIM_VERSION 1
2016-07-11 11:14:58 -04:00
namespace Assets
{
void IXAnimParts::load(Game::XAssetHeader* header, std::string name, Components::ZoneBuilder::Zone* builder)
2016-07-11 11:14:58 -04:00
{
Components::FileSystem::File animFile(fmt::sprintf("xanim/%s.iw4xAnim", name.data()));
if (animFile.exists())
2016-07-11 11:14:58 -04:00
{
Utils::Stream::Reader reader(builder->getAllocator(), animFile.getBuffer());
2016-07-11 11:14:58 -04:00
if (reader.read<__int64>() != *reinterpret_cast<__int64*>("IW4xAnim"))
{
Components::Logger::Error(0, "Reading animation '%s' failed, header is invalid!", name.data());
}
int version = reader.read<int>();
if (version != IW4X_ANIM_VERSION)
{
Components::Logger::Error(0, "Reading animation '%s' failed, expected version is %d, but it was %d!", name.data(), IW4X_ANIM_VERSION, version);
}
Game::XAnimParts* xanim = reader.readArray<Game::XAnimParts>();
2016-07-11 11:14:58 -04:00
if (xanim)
{
if (xanim->name)
{
xanim->name = reader.readCString();
2016-07-11 11:14:58 -04:00
}
if (xanim->tagnames)
{
xanim->tagnames = builder->getAllocator()->allocateArray<short>(xanim->boneCount[Game::XAnimPartType::PART_TYPE_ALL]);
2016-07-11 11:14:58 -04:00
for (int i = 0; i < xanim->boneCount[Game::XAnimPartType::PART_TYPE_ALL]; ++i)
{
xanim->tagnames[i] = Game::SL_GetString(reader.readCString(), 0);
2016-07-11 11:14:58 -04:00
}
}
if (xanim->notetracks)
{
xanim->notetracks = reader.readArray<Game::XAnimNotifyInfo>(xanim->notetrackCount);
2016-07-11 11:14:58 -04:00
for (int i = 0; i < xanim->notetrackCount; ++i)
{
xanim->notetracks[i].name = Game::SL_GetString(reader.readCString(), 0);
2016-07-11 11:14:58 -04:00
}
}
if (xanim->dataByte)
{
xanim->dataByte = reader.readArray<char>(xanim->dataByteCount);
2016-07-11 11:14:58 -04:00
}
if (xanim->dataShort)
{
xanim->dataShort = reader.readArray<short>(xanim->dataShortCount);
2016-07-11 11:14:58 -04:00
}
if (xanim->dataInt)
{
xanim->dataInt = reader.readArray<int>(xanim->dataIntCount);
2016-07-11 11:14:58 -04:00
}
if (xanim->randomDataByte)
{
xanim->randomDataByte = reader.readArray<char>(xanim->randomDataByteCount);
2016-07-11 11:14:58 -04:00
}
if (xanim->randomDataShort)
{
xanim->randomDataShort = reader.readArray<short>(xanim->randomDataShortCount);
2016-07-11 11:14:58 -04:00
}
if (xanim->randomDataInt)
{
xanim->randomDataInt = reader.readArray<int>(xanim->randomDataIntCount);
2016-07-11 11:14:58 -04:00
}
if (xanim->indices.data)
{
if (xanim->framecount < 256)
{
xanim->indices._1 = reader.readArray<char>(xanim->indexcount);
2016-07-11 11:14:58 -04:00
}
else
{
xanim->indices._2 = reader.readArray<unsigned short>(xanim->indexcount);
2016-07-11 11:14:58 -04:00
}
}
if (!reader.end())
2016-07-11 11:14:58 -04:00
{
Components::Logger::Error(0, "Reading animation '%s' failed, remaining raw data found!", name.data());
}
header->xanim = xanim;
}
}
}
void IXAnimParts::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
2016-07-11 11:14:58 -04:00
{
Game::XAnimParts* asset = header.xanim;
if (asset->tagnames)
{
for (char i = 0; i < asset->boneCount[Game::XAnimPartType::PART_TYPE_ALL]; ++i)
{
builder->addScriptString(asset->tagnames[i]);
2016-07-11 11:14:58 -04:00
}
}
if (asset->notetracks)
{
for (char i = 0; i < asset->notetrackCount; ++i)
{
builder->addScriptString(asset->notetracks[i].name);
2016-07-11 11:14:58 -04:00
}
}
}
void IXAnimParts::saveXAnimDeltaPart(Game::XAnimDeltaPart* delta, unsigned short framecount, Components::ZoneBuilder::Zone* builder)
2016-07-11 11:14:58 -04:00
{
AssertSize(Game::XAnimDeltaPart, 12);
2016-07-11 11:14:58 -04:00
Utils::Stream* buffer = builder->getBuffer();
Game::XAnimDeltaPart* destDelta = buffer->dest<Game::XAnimDeltaPart>();
buffer->save(delta);
2016-07-11 11:14:58 -04:00
if (delta->trans)
{
buffer->align(Utils::Stream::ALIGN_4);
buffer->save(delta->trans, 4);
2016-07-11 11:14:58 -04:00
if (delta->trans->size)
{
buffer->save(&delta->trans->u.frames, 28);
2016-07-11 11:14:58 -04:00
if (framecount > 0xFF)
{
buffer->saveArray(delta->trans->u.frames.indices._2, delta->trans->size + 1);
2016-07-11 11:14:58 -04:00
}
else
{
buffer->saveArray(delta->trans->u.frames.indices._1, delta->trans->size + 1);
2016-07-11 11:14:58 -04:00
}
if (delta->trans->u.frames.frames._1)
{
if (delta->trans->smallTrans)
{
buffer->save(delta->trans->u.frames.frames._1, 3, delta->trans->size + 1);
2016-07-11 11:14:58 -04:00
}
else
{
buffer->align(Utils::Stream::ALIGN_4);
buffer->save(delta->trans->u.frames.frames._1, 6, delta->trans->size + 1);
2016-07-11 11:14:58 -04:00
}
}
}
else
{
buffer->save(delta->trans->u.frame0, 12);
2016-07-11 11:14:58 -04:00
}
Utils::Stream::ClearPointer(&destDelta->trans);
}
if (delta->quat2)
{
buffer->align(Utils::Stream::ALIGN_4);
buffer->save(delta->quat2, 4);
2016-07-11 11:14:58 -04:00
if (delta->quat2->size)
{
buffer->save(&delta->quat2->u.frames, 4);
2016-07-11 11:14:58 -04:00
if (framecount > 0xFF)
{
buffer->save(delta->quat2->u.frames.indices, 2, delta->quat2->size + 1);
2016-07-11 11:14:58 -04:00
}
else
{
buffer->save(delta->quat2->u.frames.indices, 1, delta->quat2->size + 1);
2016-07-11 11:14:58 -04:00
}
if (delta->quat2->u.frames.frames)
{
buffer->align(Utils::Stream::ALIGN_4);
buffer->save(delta->quat2->u.frames.frames, 4, delta->quat2->size + 1);
2016-07-11 11:14:58 -04:00
}
}
else
{
buffer->save(delta->quat2->u.frame0, 4);
2016-07-11 11:14:58 -04:00
}
Utils::Stream::ClearPointer(&destDelta->quat2);
}
if (delta->quat)
{
buffer->align(Utils::Stream::ALIGN_4);
buffer->save(delta->quat, 4);
2016-07-11 11:14:58 -04:00
if (delta->quat->size)
{
buffer->save(&delta->quat->u.frames, 4);
2016-07-11 11:14:58 -04:00
if (framecount > 0xFF)
{
buffer->save(delta->quat->u.frames.indices, 2, delta->quat->size + 1);
2016-07-11 11:14:58 -04:00
}
else
{
buffer->save(delta->quat->u.frames.indices, 1, delta->quat->size + 1);
2016-07-11 11:14:58 -04:00
}
if (delta->quat->u.frames.frames)
{
buffer->align(Utils::Stream::ALIGN_4);
buffer->save(delta->quat->u.frames.frames, 4, delta->quat->size + 1);
2016-07-11 11:14:58 -04:00
}
}
else
{
buffer->save(delta->quat->u.frame0, 4);
2016-07-11 11:14:58 -04:00
}
Utils::Stream::ClearPointer(&destDelta->quat);
}
}
void IXAnimParts::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
2016-07-11 11:14:58 -04:00
{
AssertSize(Game::XAnimParts, 88);
2016-07-11 11:14:58 -04:00
Utils::Stream* buffer = builder->getBuffer();
2016-07-11 11:14:58 -04:00
Game::XAnimParts* asset = header.xanim;
Game::XAnimParts* dest = buffer->dest<Game::XAnimParts>();
buffer->save(asset, sizeof(Game::XAnimParts));
2016-07-11 11:14:58 -04:00
buffer->pushBlock(Game::XFILE_BLOCK_VIRTUAL);
2016-07-11 11:14:58 -04:00
if (asset->name)
{
buffer->saveString(builder->getAssetName(this->getType(), asset->name));
2016-07-11 11:14:58 -04:00
Utils::Stream::ClearPointer(&dest->name);
}
if (asset->tagnames)
{
buffer->align(Utils::Stream::ALIGN_2);
2016-07-11 11:14:58 -04:00
unsigned short* destTagnames = buffer->dest<unsigned short>();
buffer->saveArray(asset->tagnames, asset->boneCount[Game::XAnimPartType::PART_TYPE_ALL]);
2016-07-11 11:14:58 -04:00
for (char i = 0; i < asset->boneCount[Game::XAnimPartType::PART_TYPE_ALL]; ++i)
{
builder->mapScriptString(&destTagnames[i]);
2016-07-11 11:14:58 -04:00
}
Utils::Stream::ClearPointer(&dest->tagnames);
}
if (asset->notetracks)
{
AssertSize(Game::XAnimNotifyInfo, 8);
buffer->align(Utils::Stream::ALIGN_4);
2016-07-11 11:14:58 -04:00
Game::XAnimNotifyInfo* destNotetracks = buffer->dest<Game::XAnimNotifyInfo>();
buffer->saveArray(asset->notetracks, asset->notetrackCount);
2016-07-11 11:14:58 -04:00
for (char i = 0; i < asset->notetrackCount; ++i)
{
builder->mapScriptString(&destNotetracks[i].name);
2016-07-11 11:14:58 -04:00
}
Utils::Stream::ClearPointer(&dest->notetracks);
}
if (asset->delta)
{
AssertSize(Game::XAnimDeltaPart, 12);
buffer->align(Utils::Stream::ALIGN_4);
2016-07-11 11:14:58 -04:00
this->saveXAnimDeltaPart(asset->delta, asset->framecount, builder);
2016-07-11 11:14:58 -04:00
Utils::Stream::ClearPointer(&dest->delta);
}
if (asset->dataByte)
{
buffer->saveArray(asset->dataByte, asset->dataByteCount);
2016-07-11 11:14:58 -04:00
Utils::Stream::ClearPointer(&dest->dataByte);
}
if (asset->dataShort)
{
buffer->align(Utils::Stream::ALIGN_2);
buffer->saveArray(asset->dataShort, asset->dataShortCount);
2016-07-11 11:14:58 -04:00
Utils::Stream::ClearPointer(&dest->dataShort);
}
if (asset->dataInt)
{
buffer->align(Utils::Stream::ALIGN_4);
buffer->saveArray(asset->dataInt, asset->dataIntCount);
2016-07-11 11:14:58 -04:00
Utils::Stream::ClearPointer(&dest->dataInt);
}
if (asset->randomDataShort)
{
buffer->align(Utils::Stream::ALIGN_2);
buffer->saveArray(asset->randomDataShort, asset->randomDataShortCount);
2016-07-11 11:14:58 -04:00
Utils::Stream::ClearPointer(&dest->randomDataShort);
}
if (asset->randomDataByte)
{
buffer->saveArray(asset->randomDataByte, asset->randomDataByteCount);
2016-07-11 11:14:58 -04:00
Utils::Stream::ClearPointer(&dest->randomDataByte);
}
if (asset->randomDataInt)
{
buffer->align(Utils::Stream::ALIGN_4);
buffer->saveArray(asset->randomDataInt, asset->randomDataIntCount);
2016-07-11 11:14:58 -04:00
Utils::Stream::ClearPointer(&dest->randomDataInt);
}
if (asset->indices.data)
{
if (asset->framecount > 0xFF)
{
buffer->align(Utils::Stream::ALIGN_2);
buffer->saveArray(asset->indices._2, asset->indexcount);
2016-07-11 11:14:58 -04:00
}
else
{
buffer->saveArray(asset->indices._1, asset->indexcount);
2016-07-11 11:14:58 -04:00
}
Utils::Stream::ClearPointer(&dest->indices.data);
}
buffer->popBlock();
2016-07-11 11:14:58 -04:00
}
}