Added support for the remaining DKCR formats; DKCR repacking works now

This commit is contained in:
Aruki 2017-06-26 20:34:58 -06:00
parent 87906aafb9
commit 46b65a5bcd
12 changed files with 456 additions and 41 deletions

View File

@ -364,6 +364,13 @@ TString SanitizeName(TString Name, bool Directory, bool RootDir /*= false*/)
if (NumLeadingSpaces > 0) if (NumLeadingSpaces > 0)
Name = Name.ChopFront(NumLeadingSpaces); Name = Name.ChopFront(NumLeadingSpaces);
// Ensure the name is below the character limit
if (Name.Size() > 255)
{
u32 ChopNum = Name.Size() - 255;
Name = Name.ChopBack(ChopNum);
}
return Name; return Name;
} }

View File

@ -207,6 +207,7 @@ CSetCharacterDependency* CSetCharacterDependency::BuildTree(const SSetCharacter&
pTree->AddDependency(rkChar.pSkeleton); pTree->AddDependency(rkChar.pSkeleton);
pTree->AddDependency(rkChar.pSkin); pTree->AddDependency(rkChar.pSkin);
pTree->AddDependency(rkChar.AnimDataID); pTree->AddDependency(rkChar.AnimDataID);
pTree->AddDependency(rkChar.CollisionPrimitivesID);
const std::vector<CAssetID> *pkParticleVectors[5] = { const std::vector<CAssetID> *pkParticleVectors[5] = {
&rkChar.GenericParticles, &rkChar.ElectricParticles, &rkChar.GenericParticles, &rkChar.ElectricParticles,

View File

@ -174,16 +174,13 @@ CAssetID CGameProject::FindNamedResource(const TString& rkName) const
CPackage* CGameProject::FindPackage(const TString& rkName) const CPackage* CGameProject::FindPackage(const TString& rkName) const
{ {
if (mGame == eCorruptionProto || mGame == eCorruption) for (u32 iPkg = 0; iPkg < mPackages.size(); iPkg++)
{ {
for (u32 iPkg = 0; iPkg < mPackages.size(); iPkg++) CPackage *pPackage = mPackages[iPkg];
{
CPackage *pPackage = mPackages[iPkg];
if (pPackage->Name() == rkName) if (pPackage->Name() == rkName)
{ {
return pPackage; return pPackage;
}
} }
} }

View File

@ -7,7 +7,7 @@ CCamera::CCamera()
: mMode(eFreeCamera) : mMode(eFreeCamera)
, mPosition(0) , mPosition(0)
, mAspectRatio(1.7777777f) , mAspectRatio(1.7777777f)
, mYaw(-Math::skHalfPi) , mYaw(Math::skHalfPi)
, mPitch(0.f) , mPitch(0.f)
, mMoveSpeed(1.f) , mMoveSpeed(1.f)
, mLookSpeed(1.f) , mLookSpeed(1.f)
@ -26,7 +26,7 @@ CCamera::CCamera(CVector3f Position, CVector3f /*Target*/)
, mMoveSpeed(1.f) , mMoveSpeed(1.f)
, mLookSpeed(1.f) , mLookSpeed(1.f)
, mPosition(Position) , mPosition(Position)
, mYaw(-Math::skHalfPi) , mYaw(Math::skHalfPi)
, mPitch(0.f) , mPitch(0.f)
{ {
} }
@ -75,7 +75,7 @@ void CCamera::Zoom(float Amount)
void CCamera::Snap(CVector3f Position) void CCamera::Snap(CVector3f Position)
{ {
mPosition = Position; mPosition = Position;
mYaw = -Math::skHalfPi; mYaw = Math::skHalfPi;
mPitch = 0.0f; mPitch = 0.0f;
mTransformDirty = true; mTransformDirty = true;
mViewDirty = true; mViewDirty = true;

View File

@ -69,6 +69,7 @@ struct SSetCharacter
TResPtr<CSkeleton> pSkeleton; TResPtr<CSkeleton> pSkeleton;
std::vector<SOverlayModel> OverlayModels; std::vector<SOverlayModel> OverlayModels;
CAssetID AnimDataID; CAssetID AnimDataID;
CAssetID CollisionPrimitivesID;
std::vector<CAssetID> GenericParticles; std::vector<CAssetID> GenericParticles;
std::vector<CAssetID> ElectricParticles; std::vector<CAssetID> ElectricParticles;
@ -76,6 +77,7 @@ struct SSetCharacter
std::vector<CAssetID> SpawnParticles; std::vector<CAssetID> SpawnParticles;
std::vector<CAssetID> EffectParticles; std::vector<CAssetID> EffectParticles;
std::vector<CAssetID> SoundEffects; std::vector<CAssetID> SoundEffects;
std::vector<CAssetID> DKDependencies;
CAssetID SpatialPrimitives; CAssetID SpatialPrimitives;
std::set<u32> UsedAnimationIndices; std::set<u32> UsedAnimationIndices;
}; };
@ -149,7 +151,7 @@ public:
} }
} }
else else if (Game() <= eCorruption)
{ {
const SSetCharacter& rkChar = mCharacters[0]; const SSetCharacter& rkChar = mCharacters[0];
std::set<CAnimPrimitive> PrimitiveSet; std::set<CAnimPrimitive> PrimitiveSet;
@ -165,19 +167,27 @@ public:
if (pAnimData) if (pAnimData)
pAnimData->AddTransitionDependencies(pTree); pAnimData->AddTransitionDependencies(pTree);
// Event particles/sounds
for (auto Iter = PrimitiveSet.begin(); Iter != PrimitiveSet.end(); Iter++) for (auto Iter = PrimitiveSet.begin(); Iter != PrimitiveSet.end(); Iter++)
{ {
const CAnimPrimitive& rkPrim = *Iter; const CAnimPrimitive& rkPrim = *Iter;
pTree->AddDependency(rkPrim.Animation()); pTree->AddDependency(rkPrim.Animation());
} }
// Event sounds
for (u32 iSound = 0; iSound < rkChar.SoundEffects.size(); iSound++) for (u32 iSound = 0; iSound < rkChar.SoundEffects.size(); iSound++)
{ {
pTree->AddDependency(rkChar.SoundEffects[iSound]); pTree->AddDependency(rkChar.SoundEffects[iSound]);
} }
} }
else
{
const SSetCharacter& rkChar = mCharacters[0];
for (u32 iDep = 0; iDep < rkChar.DKDependencies.size(); iDep++)
pTree->AddDependency(rkChar.DKDependencies[iDep]);
}
return pTree; return pTree;
} }

View File

@ -98,17 +98,137 @@ CAnimSet* CAnimSetLoader::LoadCorruptionCHAR(IInputStream& rCHAR)
CAnimSet* CAnimSetLoader::LoadReturnsCHAR(IInputStream& rCHAR) CAnimSet* CAnimSetLoader::LoadReturnsCHAR(IInputStream& rCHAR)
{ {
// For now, we only read enough to fetch the model rCHAR.Skip(0x14);
rCHAR.Seek(0x16, SEEK_CUR); u8 Flag = rCHAR.ReadByte();
rCHAR.Skip(1);
pSet->mCharacters.emplace_back( SSetCharacter() );; pSet->mCharacters.emplace_back( SSetCharacter() );;
SSetCharacter& rChar = pSet->mCharacters.back(); SSetCharacter& rChar = pSet->mCharacters.back();
// Character Header
rChar.ID = 0; rChar.ID = 0;
rChar.Name = rCHAR.ReadString(); rChar.Name = rCHAR.ReadString();
rCHAR.Seek(0x14, SEEK_CUR); rChar.pSkeleton = gpResourceStore->LoadResource<CSkeleton>( rCHAR.ReadLongLong() );
rCHAR.ReadString(); rChar.CollisionPrimitivesID = rCHAR.ReadLongLong();
rChar.pModel = gpResourceStore->LoadResource<CModel>(rCHAR.ReadLongLong());
u32 NumModels = rCHAR.ReadLong();
for (u32 ModelIdx = 0; ModelIdx < NumModels; ModelIdx++)
{
rCHAR.ReadString();
CAssetID ModelID(rCHAR, eReturns);
CAssetID SkinID(rCHAR, eReturns);
rCHAR.Skip(0x18);
if (ModelIdx == 0)
{
rChar.pModel = gpResourceStore->LoadResource<CModel>(ModelID);
rChar.pSkin = gpResourceStore->LoadResource<CSkin>(SkinID);
}
else
{
rChar.DKDependencies.push_back(ModelID);
rChar.DKDependencies.push_back(SkinID);
}
}
// Animations
u32 NumAnims = rCHAR.ReadLong();
for (u32 AnimIdx = 0; AnimIdx < NumAnims; AnimIdx++)
{
rCHAR.ReadString();
CAssetID AnimID(rCHAR, eReturns);
rCHAR.Skip(0x25);
rChar.DKDependencies.push_back(AnimID);
}
// The only other thing we care about right now is the dependency list. If this file doesn't have a dependency list, exit out.
if ((Flag & 0x10) == 0)
return pSet;
// Anim ID Map
if (Flag & 0x20)
{
u32 NumIDs = rCHAR.ReadLong();
rCHAR.Skip(NumIDs * 4);
}
// Transitions
if (Flag & 0x80)
{
u32 NumAdditiveAnims = rCHAR.ReadLong();
rCHAR.Skip(NumAdditiveAnims * 0x10);
u32 NumTransitionTypes = rCHAR.ReadLong();
for (u32 TypeIdx = 0; TypeIdx < NumTransitionTypes; TypeIdx++)
{
u16 Type = rCHAR.ReadShort();
switch (Type)
{
case 0:
break;
case 1:
case 2:
rCHAR.Skip(9);
break;
case 3:
rCHAR.Skip(0xC);
break;
default:
Log::FileError(rCHAR.GetSourceString(), rCHAR.Tell() - 2, "Invalid transition type: " + TString::FromInt32(Type, 0, 10));
return pSet;
}
}
u32 NumFullTransitions = rCHAR.ReadLong();
rCHAR.Skip(NumFullTransitions * 0xC);
u32 NumHalfTransitions = rCHAR.ReadLong();
rCHAR.Skip(NumHalfTransitions * 0x8);
rCHAR.Skip(0x8);
}
// Transform Bits
if (Flag & 0x40)
{
u32 NumTransformBits = rCHAR.ReadLong();
rCHAR.Skip(NumTransformBits);
}
u32 NumUnknown = rCHAR.ReadLong();
rCHAR.Skip(NumUnknown * 4);
// Skel Joint Sets
u32 NumSkelJointSets = rCHAR.ReadLong();
for (u32 SetIdx = 0; SetIdx < NumSkelJointSets; SetIdx++)
{
rCHAR.Skip(4);
u32 NumUnknown2 = rCHAR.ReadLong();
rCHAR.Skip(0x20 + NumUnknown2);
}
// Resources
if (Flag & 0x10)
{
// Don't need the extensions
u32 NumExtensions = rCHAR.ReadLong();
rCHAR.Skip(NumExtensions * 4);
u32 NumResources = rCHAR.ReadLong();
for (u32 ResIdx = 0; ResIdx < NumResources; ResIdx++)
{
CAssetID ResID(rCHAR, eReturns);
rCHAR.Skip(3);
rChar.DKDependencies.push_back(ResID);
}
}
return pSet; return pSet;
} }

View File

@ -100,9 +100,11 @@ public:
case eWorld: pRes = CWorldLoader::LoadMLVL(rInput, pEntry); break; case eWorld: pRes = CWorldLoader::LoadMLVL(rInput, pEntry); break;
case eStateMachine: case eStateMachine:
// AFSM and FSMC currently unsupported // AFSM currently unsupported
if (pEntry->Game() == eCorruptionProto || pEntry->Game() == eCorruption) if (pEntry->Game() == eCorruptionProto || pEntry->Game() == eCorruption)
pRes = CUnsupportedFormatLoader::LoadFSM2(rInput, pEntry); pRes = CUnsupportedFormatLoader::LoadFSM2(rInput, pEntry);
else if (pEntry->Game() == eReturns)
pRes = CUnsupportedFormatLoader::LoadFSMC(rInput, pEntry);
break; break;
case eBurstFireData: case eBurstFireData:
@ -114,6 +116,7 @@ public:
case eParticleDecal: case eParticleDecal:
case eParticleWeapon: case eParticleWeapon:
case eParticleCollisionResponse: case eParticleCollisionResponse:
case eParticleTransform:
case eUserEvaluatorData: case eUserEvaluatorData:
pRes = CUnsupportedParticleLoader::LoadParticle(rInput, pEntry); pRes = CUnsupportedParticleLoader::LoadParticle(rInput, pEntry);
break; break;

View File

@ -333,6 +333,22 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadFSM2(IInputStream& rFSM2, CResou
return pOut; return pOut;
} }
CDependencyGroup* CUnsupportedFormatLoader::LoadFSMC(IInputStream& rFSMC, CResourceEntry *pEntry)
{
CFourCC Magic = rFSMC.ReadLong();
ASSERT(Magic == FOURCC('FSMC'));
CDependencyGroup *pGroup = new CDependencyGroup(pEntry);
std::list<CAssetID> AssetList;
PerformCheating(rFSMC, pEntry->Game(), AssetList);
for (auto Iter = AssetList.begin(); Iter != AssetList.end(); Iter++)
pGroup->AddDependency(*Iter);
return pGroup;
}
CDependencyGroup* CUnsupportedFormatLoader::LoadHIER(IInputStream& rHIER, CResourceEntry *pEntry) CDependencyGroup* CUnsupportedFormatLoader::LoadHIER(IInputStream& rHIER, CResourceEntry *pEntry)
{ {
CFourCC Magic = rHIER.ReadLong(); CFourCC Magic = rHIER.ReadLong();

View File

@ -20,6 +20,7 @@ public:
static CDependencyGroup* LoadDUMB(IInputStream& rDUMB, CResourceEntry *pEntry); static CDependencyGroup* LoadDUMB(IInputStream& rDUMB, CResourceEntry *pEntry);
static CDependencyGroup* LoadFRME(IInputStream& rFRME, CResourceEntry *pEntry); static CDependencyGroup* LoadFRME(IInputStream& rFRME, CResourceEntry *pEntry);
static CDependencyGroup* LoadFSM2(IInputStream& rFSM2, CResourceEntry *pEntry); static CDependencyGroup* LoadFSM2(IInputStream& rFSM2, CResourceEntry *pEntry);
static CDependencyGroup* LoadFSMC(IInputStream& rFSMC, CResourceEntry *pEntry);
static CDependencyGroup* LoadHIER(IInputStream& rHIER, CResourceEntry *pEntry); static CDependencyGroup* LoadHIER(IInputStream& rHIER, CResourceEntry *pEntry);
static CDependencyGroup* LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry); static CDependencyGroup* LoadHINT(IInputStream& rHINT, CResourceEntry *pEntry);
static CMapArea* LoadMAPA(IInputStream& rMAPA, CResourceEntry *pEntry); static CMapArea* LoadMAPA(IInputStream& rMAPA, CResourceEntry *pEntry);

View File

@ -11,15 +11,24 @@ bool CUnsupportedParticleLoader::ParseParticleParameter(IInputStream& rPART)
switch (Param.ToLong()) switch (Param.ToLong())
{ {
// Bool // Bool Constant
case FOURCC('AAPH'): case FOURCC('AAPH'):
case FOURCC('CIND'): case FOURCC('CIND'):
case FOURCC('DBPS'): case FOURCC('DBPS'):
case FOURCC('DDIT'):
case FOURCC('DFOG'):
case FOURCC('EMTU'):
case FOURCC('FXBI'):
case FOURCC('FXBT'):
case FOURCC('FXLL'): case FOURCC('FXLL'):
case FOURCC('INDM'): case FOURCC('INDM'):
case FOURCC('INDP'):
case FOURCC('ITPE'):
case FOURCC('LINE'): case FOURCC('LINE'):
case FOURCC('LIT_'): case FOURCC('LIT_'):
case FOURCC('MBLR'): case FOURCC('MBLR'):
case FOURCC('NTIK'):
case FOURCC('ONET'):
case FOURCC('OPTS'): case FOURCC('OPTS'):
case FOURCC('ORNT'): case FOURCC('ORNT'):
case FOURCC('ORTC'): case FOURCC('ORTC'):
@ -30,6 +39,7 @@ bool CUnsupportedParticleLoader::ParseParticleParameter(IInputStream& rPART)
case FOURCC('PMUS'): case FOURCC('PMUS'):
case FOURCC('RDOP'): case FOURCC('RDOP'):
case FOURCC('RSOP'): case FOURCC('RSOP'):
case FOURCC('SCNV'):
case FOURCC('SORT'): case FOURCC('SORT'):
case FOURCC('STOP'): case FOURCC('STOP'):
case FOURCC('VGD1'): case FOURCC('VGD1'):
@ -42,7 +52,7 @@ bool CUnsupportedParticleLoader::ParseParticleParameter(IInputStream& rPART)
case FOURCC('VMD4'): case FOURCC('VMD4'):
case FOURCC('VMPC'): case FOURCC('VMPC'):
case FOURCC('ZBUF'): case FOURCC('ZBUF'):
ParseBoolFunction(rPART); ParseBool(rPART);
break; break;
// Bitfield // Bitfield
@ -55,22 +65,32 @@ bool CUnsupportedParticleLoader::ParseParticleParameter(IInputStream& rPART)
case FOURCC('AMSC'): case FOURCC('AMSC'):
case FOURCC('CSSD'): case FOURCC('CSSD'):
case FOURCC('HJAK'): case FOURCC('HJAK'):
case FOURCC('IAV0'):
case FOURCC('IAV1'):
case FOURCC('IAV2'):
case FOURCC('IAV3'):
case FOURCC('LFOT'): case FOURCC('LFOT'):
case FOURCC('LTME'): case FOURCC('LTME'):
case FOURCC('LTYP'): case FOURCC('LTYP'):
case FOURCC('MAXP'): case FOURCC('MAXP'):
case FOURCC('MBDM'): case FOURCC('MBDM'):
case FOURCC('MBSP'): case FOURCC('MBSP'):
case FOURCC('MSLT'):
case FOURCC('NCSY'): case FOURCC('NCSY'):
case FOURCC('NDSY'): case FOURCC('NDSY'):
case FOURCC('PBDM'): case FOURCC('PBDM'):
case FOURCC('PISY'): case FOURCC('PISY'):
case FOURCC('PSLT'): case FOURCC('PSLT'):
case FOURCC('PSWT'): case FOURCC('PSWT'):
case FOURCC('PWGT'):
case FOURCC('SCTR'):
case FOURCC('SEED'): case FOURCC('SEED'):
case FOURCC('SESD'): case FOURCC('SESD'):
case FOURCC('SISY'): case FOURCC('SISY'):
case FOURCC('SSSD'): case FOURCC('SSSD'):
case FOURCC('SSWT'):
case FOURCC('SVI0'):
case FOURCC('SVI1'):
case FOURCC('VSPC'): case FOURCC('VSPC'):
case FOURCC('XJAK'): case FOURCC('XJAK'):
case FOURCC('XTAD'): case FOURCC('XTAD'):
@ -87,6 +107,7 @@ bool CUnsupportedParticleLoader::ParseParticleParameter(IInputStream& rPART)
case FOURCC('ADV7'): case FOURCC('ADV7'):
case FOURCC('ADV8'): case FOURCC('ADV8'):
case FOURCC('ADV9'): case FOURCC('ADV9'):
case FOURCC('DBIS'):
case FOURCC('EADV'): case FOURCC('EADV'):
case FOURCC('FXBR'): case FOURCC('FXBR'):
case FOURCC('GRTE'): case FOURCC('GRTE'):
@ -99,11 +120,15 @@ bool CUnsupportedParticleLoader::ParseParticleParameter(IInputStream& rPART)
case FOURCC('ROTA'): case FOURCC('ROTA'):
case FOURCC('SIZE'): case FOURCC('SIZE'):
case FOURCC('SVEO'): case FOURCC('SVEO'):
case FOURCC('SVR0'):
case FOURCC('SVR1'):
case FOURCC('SVR2'):
case FOURCC('WIDT'): case FOURCC('WIDT'):
ParseFloatFunction(rPART); ParseFloatFunction(rPART);
break; break;
// Vector // Vector
case FOURCC('FXBM'):
case FOURCC('FXBO'): case FOURCC('FXBO'):
case FOURCC('ILOC'): case FOURCC('ILOC'):
case FOURCC('IVEC'): case FOURCC('IVEC'):
@ -111,16 +136,21 @@ bool CUnsupportedParticleLoader::ParseParticleParameter(IInputStream& rPART)
case FOURCC('LOFF'): case FOURCC('LOFF'):
case FOURCC('PMOP'): case FOURCC('PMOP'):
case FOURCC('PMOV'): case FOURCC('PMOV'):
case FOURCC('PMPV'):
case FOURCC('PMRT'): case FOURCC('PMRT'):
case FOURCC('PMSC'): case FOURCC('PMSC'):
case FOURCC('POFS'): case FOURCC('POFS'):
case FOURCC('PSIV'): case FOURCC('PSIV'):
case FOURCC('PSOV'): case FOURCC('PSOV'):
case FOURCC('SAXS'):
case FOURCC('SEPO'): case FOURCC('SEPO'):
case FOURCC('SSPO'): case FOURCC('SSPO'):
case FOURCC('SVV0'):
case FOURCC('SVV1'):
case FOURCC('VAV1'): case FOURCC('VAV1'):
case FOURCC('VAV2'): case FOURCC('VAV2'):
case FOURCC('VAV3'): case FOURCC('VAV3'):
case FOURCC('VAV4'):
ParseVectorFunction(rPART); ParseVectorFunction(rPART);
break; break;
@ -134,9 +164,15 @@ bool CUnsupportedParticleLoader::ParseParticleParameter(IInputStream& rPART)
break; break;
// Color // Color
case FOURCC('CAV0'):
case FOURCC('CAV1'):
case FOURCC('CAV2'):
case FOURCC('CAV3'):
case FOURCC('COLR'): case FOURCC('COLR'):
case FOURCC('LCLR'): case FOURCC('LCLR'):
case FOURCC('PMCL'): case FOURCC('PMCL'):
case FOURCC('SVC0'):
case FOURCC('SVC1'):
ParseColorFunction(rPART); ParseColorFunction(rPART);
break; break;
@ -160,6 +196,15 @@ bool CUnsupportedParticleLoader::ParseParticleParameter(IInputStream& rPART)
case FOURCC('ICTS'): case FOURCC('ICTS'):
case FOURCC('IDTS'): case FOURCC('IDTS'):
case FOURCC('IITS'): case FOURCC('IITS'):
case FOURCC('MDL1'):
case FOURCC('MDL2'):
case FOURCC('MDL3'):
case FOURCC('MDL4'):
case FOURCC('MDL5'):
case FOURCC('MDL6'):
case FOURCC('MDL7'):
case FOURCC('MDL8'):
case FOURCC('MDL9'):
case FOURCC('PMDL'): case FOURCC('PMDL'):
case FOURCC('SELC'): case FOURCC('SELC'):
case FOURCC('SSWH'): case FOURCC('SSWH'):
@ -184,7 +229,7 @@ bool CUnsupportedParticleLoader::ParseElectricParameter(IInputStream& rELSC)
switch (Param.ToLong()) switch (Param.ToLong())
{ {
case FOURCC('ZERY'): case FOURCC('ZERY'):
ParseBoolFunction(rELSC); ParseBool(rELSC);
break; break;
case FOURCC('DFLG'): case FOURCC('DFLG'):
@ -272,7 +317,7 @@ bool CUnsupportedParticleLoader::ParseSpawnParameter(IInputStream& rSPSC)
case FOURCC('IGLT'): case FOURCC('IGLT'):
case FOURCC('VMD1'): case FOURCC('VMD1'):
case FOURCC('VMD2'): case FOURCC('VMD2'):
ParseBoolFunction(rSPSC); ParseBool(rSPSC);
break; break;
case FOURCC('GIVL'): case FOURCC('GIVL'):
@ -331,13 +376,15 @@ bool CUnsupportedParticleLoader::ParseSwooshParameter(IInputStream& rSWHC)
case FOURCC('CROS'): case FOURCC('CROS'):
case FOURCC('LLRD'): case FOURCC('LLRD'):
case FOURCC('ORNT'): case FOURCC('ORNT'):
case FOURCC('PTMG'):
case FOURCC('SCNV'):
case FOURCC('SROT'): case FOURCC('SROT'):
case FOURCC('TEXW'): case FOURCC('TEXW'):
case FOURCC('VLS1'): case FOURCC('VLS1'):
case FOURCC('VLS2'): case FOURCC('VLS2'):
case FOURCC('WIRE'): case FOURCC('WIRE'):
case FOURCC('ZBUF'): case FOURCC('ZBUF'):
ParseBoolFunction(rSWHC); ParseBool(rSWHC);
break; break;
case FOURCC('DFLG'): case FOURCC('DFLG'):
@ -405,7 +452,7 @@ bool CUnsupportedParticleLoader::ParseDecalParameter(IInputStream& rDPSC)
case FOURCC('2ADD'): case FOURCC('2ADD'):
case FOURCC('DMAB'): case FOURCC('DMAB'):
case FOURCC('DMOO'): case FOURCC('DMOO'):
ParseBoolFunction(rDPSC); ParseBool(rDPSC);
break; break;
case FOURCC('1LFT'): case FOURCC('1LFT'):
@ -489,7 +536,7 @@ bool CUnsupportedParticleLoader::ParseWeaponParameter(IInputStream& rWPSC)
case FOURCC('SWTR'): case FOURCC('SWTR'):
case FOURCC('TCND'): case FOURCC('TCND'):
case FOURCC('VMD2'): case FOURCC('VMD2'):
ParseBoolFunction(rWPSC); ParseBool(rWPSC);
break; break;
case FOURCC('PSLT'): case FOURCC('PSLT'):
@ -798,8 +845,60 @@ bool CUnsupportedParticleLoader::ParseUserEvaluatorParameter(IInputStream& rUSRC
return true; return true;
} }
bool CUnsupportedParticleLoader::ParseTransformParameter(IInputStream& rXFSC)
{
u32 ParamOffset = rXFSC.Tell();
CFourCC Param = rXFSC.ReadLong();
if (Param == FOURCC('_END')) return false;
switch (Param.ToLong())
{
case FOURCC('IAV0'):
case FOURCC('IAV1'):
case FOURCC('IAV2'):
case FOURCC('IAV3'):
ParseIntFunction(rXFSC);
break;
case FOURCC('ADV1'):
case FOURCC('ADV2'):
case FOURCC('ADV3'):
case FOURCC('ADV4'):
case FOURCC('ADV5'):
case FOURCC('ADV6'):
case FOURCC('ADV7'):
case FOURCC('ADV8'):
case FOURCC('ADV9'):
case FOURCC('EFSC'):
ParseFloatFunction(rXFSC);
break;
case FOURCC('EOFS'):
case FOURCC('SOFS'):
case FOURCC('VAV1'):
case FOURCC('VAV2'):
case FOURCC('VAV3'):
case FOURCC('VAV4'):
ParseVectorFunction(rXFSC);
break;
case FOURCC('EROT'):
case FOURCC('ROT0'):
case FOURCC('SROT'):
ParseRotationFunction(rXFSC);
break;
default:
Log::FileError(rXFSC.GetSourceString(), ParamOffset, "Unknown XFSC parameter: " + Param.ToString());
DEBUG_BREAK;
return false;
}
return true;
}
// ************ FUNCTION LOADING ************ // ************ FUNCTION LOADING ************
void CUnsupportedParticleLoader::ParseBoolFunction(IInputStream& rFile) void CUnsupportedParticleLoader::ParseBool(IInputStream& rFile)
{ {
u32 FuncOffset = rFile.Tell(); u32 FuncOffset = rFile.Tell();
CFourCC Func = rFile.ReadLong(); CFourCC Func = rFile.ReadLong();
@ -813,6 +912,38 @@ void CUnsupportedParticleLoader::ParseBoolFunction(IInputStream& rFile)
case FOURCC('NONE'): case FOURCC('NONE'):
break; break;
default:
Log::FileError(rFile.GetSourceString(), FuncOffset, "Unknown bool constant function: " + Func.ToString());
DEBUG_BREAK;
break;
}
}
void CUnsupportedParticleLoader::ParseBoolFunction(IInputStream& rFile)
{
u32 FuncOffset = rFile.Tell();
CFourCC Func = rFile.ReadLong();
switch (Func.ToLong())
{
case FOURCC('CNST'):
rFile.Seek(0x1, SEEK_CUR);
break;
case FOURCC('MIRR'):
case FOURCC('P50H'):
break;
case FOURCC('EQUL'):
case FOURCC('LTHN'):
ParseFloatFunction(rFile);
ParseFloatFunction(rFile);
break;
case FOURCC('NORM'):
ParseVectorFunction(rFile);
break;
default: default:
Log::FileError(rFile.GetSourceString(), FuncOffset, "Unknown bool function: " + Func.ToString()); Log::FileError(rFile.GetSourceString(), FuncOffset, "Unknown bool function: " + Func.ToString());
DEBUG_BREAK; DEBUG_BREAK;
@ -837,6 +968,10 @@ void CUnsupportedParticleLoader::ParseIntFunction(IInputStream& rFile)
case FOURCC('GAPC'): case FOURCC('GAPC'):
case FOURCC('GEMT'): case FOURCC('GEMT'):
case FOURCC('GTCP'): case FOURCC('GTCP'):
case FOURCC('PAP0'):
case FOURCC('PAP1'):
case FOURCC('PAP2'):
case FOURCC('PAP3'):
case FOURCC('PCRT'): case FOURCC('PCRT'):
case FOURCC('PDET'): case FOURCC('PDET'):
break; break;
@ -897,6 +1032,12 @@ void CUnsupportedParticleLoader::ParseIntFunction(IInputStream& rFile)
ParseFloatFunction(rFile); ParseFloatFunction(rFile);
break; break;
case FOURCC('BNID'):
rFile.Seek(0x4, SEEK_CUR);
rFile.ReadString();
ParseBool(rFile);
break;
default: default:
Log::FileError(rFile.GetSourceString(), FuncOffset, "Unknown int function: " + Func.ToString()); Log::FileError(rFile.GetSourceString(), FuncOffset, "Unknown int function: " + Func.ToString());
DEBUG_BREAK; DEBUG_BREAK;
@ -924,6 +1065,15 @@ void CUnsupportedParticleLoader::ParseFloatFunction(IInputStream& rFile)
case FOURCC('PAP9'): case FOURCC('PAP9'):
case FOURCC('PEA0'): case FOURCC('PEA0'):
case FOURCC('PRLW'): case FOURCC('PRLW'):
case FOURCC('PSA0'):
case FOURCC('PSA1'):
case FOURCC('PSA2'):
case FOURCC('PSC0'):
case FOURCC('PSC1'):
case FOURCC('PSI0'):
case FOURCC('PSI1'):
case FOURCC('PSV0'):
case FOURCC('PSV1'):
case FOURCC('PSLL'): case FOURCC('PSLL'):
break; break;
@ -954,7 +1104,6 @@ void CUnsupportedParticleLoader::ParseFloatFunction(IInputStream& rFile)
ParseFloatFunction(rFile); ParseFloatFunction(rFile);
break; break;
case FOURCC('CEXT'):
case FOURCC('OCSP'): case FOURCC('OCSP'):
ParseIntFunction(rFile); ParseIntFunction(rFile);
break; break;
@ -1063,10 +1212,21 @@ void CUnsupportedParticleLoader::ParseFloatFunction(IInputStream& rFile)
break; break;
case FOURCC('TOCS'): case FOURCC('TOCS'):
ParseBool(rFile);
ParseIntFunction(rFile);
ParseIntFunction(rFile);
ParseIntFunction(rFile);
break;
case FOURCC('CREL'):
ParseBoolFunction(rFile); ParseBoolFunction(rFile);
ParseFloatFunction(rFile);
ParseFloatFunction(rFile);
break;
case FOURCC('CEXT'):
ParseIntFunction(rFile); ParseIntFunction(rFile);
ParseIntFunction(rFile); if (mpGroup->Game() >= eReturns) ParseFloatFunction(rFile);
ParseIntFunction(rFile);
break; break;
default: default:
@ -1146,10 +1306,12 @@ void CUnsupportedParticleLoader::ParseVectorFunction(IInputStream& rFile)
ParseVectorFunction(rFile); ParseVectorFunction(rFile);
break; break;
case FOURCC('CMPS'):
case FOURCC('NONE'): case FOURCC('NONE'):
case FOURCC('PAP1'): case FOURCC('PAP1'):
case FOURCC('PAP2'): case FOURCC('PAP2'):
case FOURCC('PAP3'): case FOURCC('PAP3'):
case FOURCC('PAP4'):
case FOURCC('PENV'): case FOURCC('PENV'):
case FOURCC('PETR'): case FOURCC('PETR'):
case FOURCC('PEVL'): case FOURCC('PEVL'):
@ -1160,10 +1322,11 @@ void CUnsupportedParticleLoader::ParseVectorFunction(IInputStream& rFile)
case FOURCC('PLOC'): case FOURCC('PLOC'):
case FOURCC('PNCV'): case FOURCC('PNCV'):
case FOURCC('PSOF'): case FOURCC('PSOF'):
case FOURCC('PSOU'):
case FOURCC('PSOR'): case FOURCC('PSOR'):
case FOURCC('PSOU'):
case FOURCC('PSTR'): case FOURCC('PSTR'):
case FOURCC('PVEL'): case FOURCC('PVEL'):
case FOURCC('SLOC'):
break; break;
case FOURCC('PULS'): case FOURCC('PULS'):
@ -1178,6 +1341,28 @@ void CUnsupportedParticleLoader::ParseVectorFunction(IInputStream& rFile)
ParseFloatFunction(rFile); ParseFloatFunction(rFile);
break; break;
case FOURCC('BNPS'):
case FOURCC('BNSC'):
ParseIntFunction(rFile);
break;
case FOURCC('CVEC'):
ParseBoolFunction(rFile);
ParseVectorFunction(rFile);
ParseVectorFunction(rFile);
break;
case FOURCC('IRTV'):
case FOURCC('ROTV'):
ParseRotationFunction(rFile);
ParseVectorFunction(rFile);
break;
case FOURCC('VEXT'):
ParseIntFunction(rFile);
ParseVectorFunction(rFile);
break;
default: default:
Log::FileError(rFile.GetSourceString(), FuncOffset, "Unknown vector function: " + Func.ToString()); Log::FileError(rFile.GetSourceString(), FuncOffset, "Unknown vector function: " + Func.ToString());
DEBUG_BREAK; DEBUG_BREAK;
@ -1200,7 +1385,7 @@ void CUnsupportedParticleLoader::ParseModVectorFunction(IInputStream& rFile)
ParseVectorFunction(rFile); ParseVectorFunction(rFile);
ParseFloatFunction(rFile); ParseFloatFunction(rFile);
ParseFloatFunction(rFile); ParseFloatFunction(rFile);
ParseBoolFunction(rFile); ParseBool(rFile);
break; break;
case FOURCC('BOXV'): case FOURCC('BOXV'):
@ -1228,7 +1413,7 @@ void CUnsupportedParticleLoader::ParseModVectorFunction(IInputStream& rFile)
ParseFloatFunction(rFile); ParseFloatFunction(rFile);
ParseFloatFunction(rFile); ParseFloatFunction(rFile);
ParseFloatFunction(rFile); ParseFloatFunction(rFile);
ParseBoolFunction(rFile); ParseBool(rFile);
break; break;
case FOURCC('EXPL'): case FOURCC('EXPL'):
@ -1330,6 +1515,10 @@ void CUnsupportedParticleLoader::ParseColorFunction(IInputStream& rFile)
break; break;
case FOURCC('NONE'): case FOURCC('NONE'):
case FOURCC('PAP0'):
case FOURCC('PAP1'):
case FOURCC('PAP2'):
case FOURCC('PAP3'):
case FOURCC('PCOL'): case FOURCC('PCOL'):
break; break;
@ -1352,6 +1541,64 @@ void CUnsupportedParticleLoader::ParseColorFunction(IInputStream& rFile)
} }
} }
void CUnsupportedParticleLoader::ParseRotationFunction(IInputStream& rFile)
{
u32 FuncOffset = rFile.Tell();
CFourCC Func = rFile.ReadLong();
switch (Func.ToLong())
{
case FOURCC('NONE'):
case FOURCC('RLCL'):
case FOURCC('RSYS'):
break;
case FOURCC('CNST'):
rFile.Seek(0x10, SEEK_CUR);
break;
case FOURCC('BNRT'):
ParseIntFunction(rFile);
break;
case FOURCC('CROT'):
ParseBoolFunction(rFile);
ParseRotationFunction(rFile);
ParseRotationFunction(rFile);
break;
case FOURCC('ISWT'):
case FOURCC('RADD'):
case FOURCC('RADN'):
case FOURCC('RSBN'):
case FOURCC('RSUB'):
ParseRotationFunction(rFile);
ParseRotationFunction(rFile);
break;
case FOURCC('KPIN'):
ParseRotationFunction(rFile);
break;
case FOURCC('RAXZ'):
ParseVectorFunction(rFile);
ParseVectorFunction(rFile);
ParseRotationFunction(rFile);
break;
case FOURCC('REUL'):
ParseFloatFunction(rFile);
ParseFloatFunction(rFile);
ParseFloatFunction(rFile);
break;
default:
Log::FileError(rFile.GetSourceString(), FuncOffset, "Unknown rotation function: " + Func.ToString());
DEBUG_BREAK;
break;
}
}
void CUnsupportedParticleLoader::ParseUVFunction(IInputStream& rFile) void CUnsupportedParticleLoader::ParseUVFunction(IInputStream& rFile)
{ {
u32 FuncOffset = rFile.Tell(); u32 FuncOffset = rFile.Tell();
@ -1373,7 +1620,7 @@ void CUnsupportedParticleLoader::ParseUVFunction(IInputStream& rFile)
ParseIntFunction(rFile); ParseIntFunction(rFile);
ParseIntFunction(rFile); ParseIntFunction(rFile);
ParseIntFunction(rFile); ParseIntFunction(rFile);
ParseBoolFunction(rFile); ParseBool(rFile);
break; break;
case FOURCC('TEXP'): case FOURCC('TEXP'):
@ -1415,7 +1662,7 @@ void CUnsupportedParticleLoader::ParseEmitterFunction(IInputStream& rFile)
ParseVectorFunction(rFile); ParseVectorFunction(rFile);
ParseVectorFunction(rFile); ParseVectorFunction(rFile);
ParseFloatFunction(rFile); ParseFloatFunction(rFile);
ParseBoolFunction(rFile); ParseBool(rFile);
break; break;
case FOURCC('PLNE'): case FOURCC('PLNE'):
@ -1540,15 +1787,24 @@ void CUnsupportedParticleLoader::ParseKeyframeEmitterData(IInputStream& rFile, c
// ************ STATIC ************ // ************ STATIC ************
CDependencyGroup* CUnsupportedParticleLoader::LoadParticle(IInputStream& rFile, CResourceEntry *pEntry) CDependencyGroup* CUnsupportedParticleLoader::LoadParticle(IInputStream& rFile, CResourceEntry *pEntry)
{ {
CFourCC Magic = rFile.ReadLong();
// Loop through particle functions
CUnsupportedParticleLoader Loader; CUnsupportedParticleLoader Loader;
Loader.mpGroup = new CDependencyGroup(pEntry); Loader.mpGroup = new CDependencyGroup(pEntry);
if (pEntry->Game() >= eReturns) // Validate DKCR asset header
return Loader.mpGroup; if (pEntry->Game() == eReturns)
{
u32 AssetHeader = rFile.ReadLong();
if (AssetHeader != 0x6E190001)
{
Log::Error("Invalid DKCR particle header: " + TString::HexString(AssetHeader));
return Loader.mpGroup;
}
}
CFourCC Magic = rFile.ReadLong();
// Loop through particle functions
while (true) while (true)
{ {
bool ShouldContinue = false; bool ShouldContinue = false;
@ -1565,6 +1821,7 @@ CDependencyGroup* CUnsupportedParticleLoader::LoadParticle(IInputStream& rFile,
case FOURCC('CRSM'): ShouldContinue = Loader.ParseCollisionResponseParameter(rFile); break; case FOURCC('CRSM'): ShouldContinue = Loader.ParseCollisionResponseParameter(rFile); break;
case FOURCC('BFRE'): ShouldContinue = Loader.ParseBurstFireParameter(rFile); break; case FOURCC('BFRE'): ShouldContinue = Loader.ParseBurstFireParameter(rFile); break;
case FOURCC('USER'): ShouldContinue = Loader.ParseUserEvaluatorParameter(rFile); break; case FOURCC('USER'): ShouldContinue = Loader.ParseUserEvaluatorParameter(rFile); break;
case FOURCC('XFSM'): ShouldContinue = Loader.ParseTransformParameter(rFile); break;
default: default:
Log::Error("Unrecognized particle system magic: " + Magic.ToString()); Log::Error("Unrecognized particle system magic: " + Magic.ToString());

View File

@ -21,8 +21,10 @@ class CUnsupportedParticleLoader
bool ParseCollisionResponseParameter(IInputStream& rCRSC); bool ParseCollisionResponseParameter(IInputStream& rCRSC);
bool ParseBurstFireParameter(IInputStream& rBFRC); bool ParseBurstFireParameter(IInputStream& rBFRC);
bool ParseUserEvaluatorParameter(IInputStream& rUSRC); bool ParseUserEvaluatorParameter(IInputStream& rUSRC);
bool ParseTransformParameter(IInputStream& rXFSC);
// Function Loading // Function Loading
void ParseBool(IInputStream& rFile);
void ParseBoolFunction(IInputStream& rFile); void ParseBoolFunction(IInputStream& rFile);
void ParseBitfieldFunction(IInputStream& rFile); void ParseBitfieldFunction(IInputStream& rFile);
void ParseIntFunction(IInputStream& rFile); void ParseIntFunction(IInputStream& rFile);
@ -30,6 +32,7 @@ class CUnsupportedParticleLoader
void ParseVectorFunction(IInputStream& rFile); void ParseVectorFunction(IInputStream& rFile);
void ParseModVectorFunction(IInputStream& rFile); void ParseModVectorFunction(IInputStream& rFile);
void ParseColorFunction(IInputStream& rFile); void ParseColorFunction(IInputStream& rFile);
void ParseRotationFunction(IInputStream& rFile);
void ParseUVFunction(IInputStream& rFile); void ParseUVFunction(IInputStream& rFile);
void ParseEmitterFunction(IInputStream& rFile); void ParseEmitterFunction(IInputStream& rFile);
void ParseSoundFunction(IInputStream& rFile); void ParseSoundFunction(IInputStream& rFile);

View File

@ -230,7 +230,7 @@
<property ID="0x05439A08" name="WPSC"/> <property ID="0x05439A08" name="WPSC"/>
<property ID="0x0547FF5F" name="UnknownStruct2"/> <property ID="0x0547FF5F" name="UnknownStruct2"/>
<property ID="0x05486319" name="Skin (No Holos)"/> <property ID="0x05486319" name="Skin (No Holos)"/>
<property ID="0x054A1E34" name="Unknown"/> <property ID="0x054A1E34" name="Close When Used"/>
<property ID="0x054F1A14" name="Unknown"/> <property ID="0x054F1A14" name="Unknown"/>
<property ID="0x05577977" name="Unknown"/> <property ID="0x05577977" name="Unknown"/>
<property ID="0x055B8291" name="Unknown"/> <property ID="0x055B8291" name="Unknown"/>