mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-20 10:25:40 +00:00
Rewrote SCAN asset handling + loading
This commit is contained in:
@@ -2,9 +2,10 @@
|
||||
#define CANIMATIONPARAMETERS_H
|
||||
|
||||
#include "Core/Resource/TResPtr.h"
|
||||
#include "Core/Resource/Model/CModel.h"
|
||||
#include <Common/EGame.h>
|
||||
|
||||
class CModel;
|
||||
|
||||
class CAnimationParameters
|
||||
{
|
||||
EGame mGame;
|
||||
|
||||
@@ -381,12 +381,12 @@ void CResTypeInfo::CResTypeInfoFactory::InitTypes()
|
||||
{
|
||||
CResTypeInfo *pType = new CResTypeInfo(EResourceType::StringTable, "String Table", "strg");
|
||||
AddExtension(pType, "STRG", EGame::PrimeDemo, EGame::DKCReturns);
|
||||
pType->mCanBeSerialized = true;
|
||||
}
|
||||
{
|
||||
CResTypeInfo *pType = new CResTypeInfo(EResourceType::Texture, "Texture", "txtr");
|
||||
AddExtension(pType, "TXTR", EGame::PrimeDemo, EGame::DKCReturns);
|
||||
pType->mCanHaveDependencies = false;
|
||||
pType->mCanBeSerialized = true;
|
||||
}
|
||||
{
|
||||
CResTypeInfo *pType = new CResTypeInfo(EResourceType::Tweaks, "Tweak Data", "ctwk");
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
#ifndef CSCAN_H
|
||||
#define CSCAN_H
|
||||
|
||||
#include "CResource.h"
|
||||
#include "TResPtr.h"
|
||||
#include "Core/Resource/Animation/CAnimationParameters.h"
|
||||
#include "Core/Resource/StringTable/CStringTable.h"
|
||||
#include <Common/EGame.h>
|
||||
|
||||
class CScan : public CResource
|
||||
{
|
||||
DECLARE_RESOURCE_TYPE(Scan)
|
||||
friend class CScanLoader;
|
||||
|
||||
public:
|
||||
// This likely needs revising when MP2/MP3 support is added
|
||||
enum class ELogbookCategory
|
||||
{
|
||||
None,
|
||||
PirateData,
|
||||
ChozoLore,
|
||||
Creatures,
|
||||
Research
|
||||
};
|
||||
|
||||
struct SScanInfoSecondaryModel
|
||||
{
|
||||
CAssetID ModelID;
|
||||
CAnimationParameters AnimParams;
|
||||
TString AttachBoneName;
|
||||
};
|
||||
|
||||
private:
|
||||
// Common
|
||||
TResPtr<CStringTable> mpStringTable;
|
||||
bool mIsSlow;
|
||||
bool mIsImportant;
|
||||
ELogbookCategory mCategory;
|
||||
|
||||
// MP1
|
||||
CAssetID mFrameID;
|
||||
CAssetID mScanImageTextures[4];
|
||||
|
||||
// MP2/3
|
||||
bool mUseLogbookModelPostScan;
|
||||
CAssetID mPostOverrideTexture;
|
||||
float mLogbookDefaultRotX;
|
||||
float mLogbookDefaultRotZ;
|
||||
float mLogbookScale;
|
||||
CAssetID mLogbookModel;
|
||||
CAnimationParameters mLogbookAnimParams;
|
||||
CAnimationParameters mUnknownAnimParams;
|
||||
std::vector<SScanInfoSecondaryModel> mSecondaryModels;
|
||||
|
||||
// MP3
|
||||
std::vector<CAssetID> mDependencyList;
|
||||
|
||||
public:
|
||||
CScan(CResourceEntry *pEntry = 0)
|
||||
: CResource(pEntry)
|
||||
, mpStringTable(nullptr)
|
||||
, mIsSlow(false)
|
||||
, mIsImportant(false)
|
||||
, mCategory(ELogbookCategory::None)
|
||||
{}
|
||||
|
||||
CDependencyTree* BuildDependencyTree() const
|
||||
{
|
||||
CDependencyTree *pTree = new CDependencyTree();
|
||||
|
||||
// Corruption's SCAN has a list of all assets - just grab that
|
||||
if (Game() >= EGame::CorruptionProto)
|
||||
{
|
||||
for (uint32 iDep = 0; iDep < mDependencyList.size(); iDep++)
|
||||
{
|
||||
pTree->AddDependency(mDependencyList[iDep]);
|
||||
}
|
||||
|
||||
return pTree;
|
||||
}
|
||||
|
||||
// Otherwise add all the dependencies we need from the properties
|
||||
if (Game() <= EGame::Prime)
|
||||
pTree->AddDependency(mFrameID);
|
||||
|
||||
pTree->AddDependency(mpStringTable);
|
||||
|
||||
if (Game() <= EGame::Prime)
|
||||
{
|
||||
for (uint32 iImg = 0; iImg < 4; iImg++)
|
||||
pTree->AddDependency(mScanImageTextures[iImg]);
|
||||
}
|
||||
|
||||
else if (Game() <= EGame::Echoes)
|
||||
{
|
||||
pTree->AddDependency(mPostOverrideTexture);
|
||||
pTree->AddDependency(mLogbookModel);
|
||||
pTree->AddCharacterDependency(mLogbookAnimParams);
|
||||
pTree->AddCharacterDependency(mUnknownAnimParams);
|
||||
|
||||
for (uint32 iSec = 0; iSec < mSecondaryModels.size(); iSec++)
|
||||
{
|
||||
const SScanInfoSecondaryModel& rkSecModel = mSecondaryModels[iSec];
|
||||
pTree->AddDependency(rkSecModel.ModelID);
|
||||
pTree->AddCharacterDependency(rkSecModel.AnimParams);
|
||||
}
|
||||
}
|
||||
|
||||
return pTree;
|
||||
}
|
||||
|
||||
// Accessors
|
||||
inline CStringTable* ScanText() const { return mpStringTable; }
|
||||
inline bool IsImportant() const { return mIsImportant; }
|
||||
inline bool IsSlow() const { return mIsSlow; }
|
||||
inline ELogbookCategory LogbookCategory() const { return mCategory; }
|
||||
inline CAssetID GuiFrame() const { return mFrameID; }
|
||||
inline CAssetID ScanImage(uint32 ImgIndex) const { return mScanImageTextures[ImgIndex]; }
|
||||
inline CAssetID LogbookDisplayAssetID() const { return (mLogbookAnimParams.ID().IsValid() ? mLogbookAnimParams.ID() : mLogbookModel); }
|
||||
};
|
||||
|
||||
#endif // CSCAN_H
|
||||
@@ -1,306 +1,83 @@
|
||||
#include "CScanLoader.h"
|
||||
#include "Core/GameProject/CResourceStore.h"
|
||||
#include "CScriptLoader.h"
|
||||
#include <Common/Log.h>
|
||||
|
||||
CScanLoader::CScanLoader()
|
||||
CScan* CScanLoader::LoadScanMP1(IInputStream& SCAN, CResourceEntry* pEntry)
|
||||
{
|
||||
}
|
||||
|
||||
CScan* CScanLoader::LoadScanMP1(IInputStream& rSCAN)
|
||||
{
|
||||
// Basic support at the moment - don't read animation/scan image data
|
||||
mpScan->mFrameID = CAssetID(rSCAN, k32Bit);
|
||||
mpScan->mpStringTable = gpResourceStore->LoadResource(rSCAN.ReadLong(), EResourceType::StringTable);
|
||||
mpScan->mIsSlow = (rSCAN.ReadLong() != 0);
|
||||
mpScan->mCategory = (CScan::ELogbookCategory) rSCAN.ReadLong();
|
||||
mpScan->mIsImportant = (rSCAN.ReadByte() == 1);
|
||||
|
||||
for (uint32 iImg = 0; iImg < 4; iImg++)
|
||||
{
|
||||
mpScan->mScanImageTextures[iImg] = CAssetID(rSCAN, k32Bit);
|
||||
rSCAN.Seek(0x18, SEEK_CUR);
|
||||
}
|
||||
|
||||
return mpScan;
|
||||
}
|
||||
|
||||
CScan* CScanLoader::LoadScanMP2(IInputStream& rSCAN)
|
||||
{
|
||||
// The SCAN format in MP2 embeds a SNFO object using the same format as SCLY
|
||||
// However since the contents of the file are consistent there's no need to delegate to CScriptLoader
|
||||
rSCAN.Skip(0x1);
|
||||
uint32 NumInstances = rSCAN.ReadLong();
|
||||
|
||||
if (NumInstances != 1)
|
||||
{
|
||||
errorf("%s: SCAN has multiple instances", *rSCAN.GetSourceString());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32 ScanInfoStart = rSCAN.Tell();
|
||||
|
||||
CFourCC SNFO(rSCAN);
|
||||
if (SNFO != FOURCC('SNFO'))
|
||||
{
|
||||
errorf("%s [0x%X]: Unrecognized SCAN object type: %s", *rSCAN.GetSourceString(), ScanInfoStart, *SNFO.ToString());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint16 InstanceSize = rSCAN.ReadShort();
|
||||
uint32 InstanceEnd = rSCAN.Tell() + InstanceSize;
|
||||
rSCAN.Skip(0x4);
|
||||
|
||||
uint16 NumConnections = rSCAN.ReadShort();
|
||||
if (NumConnections > 0)
|
||||
{
|
||||
warnf("%s [0x%X]: SNFO object in SCAN has connections", *rSCAN.GetSourceString(), ScanInfoStart);
|
||||
rSCAN.Skip(NumConnections * 0xC);
|
||||
}
|
||||
|
||||
uint32 BasePropID = rSCAN.ReadLong();
|
||||
if (BasePropID != 0xFFFFFFFF)
|
||||
{
|
||||
errorf("%s [0x%X]: Invalid base property ID: 0x%08X", *rSCAN.GetSourceString(), rSCAN.Tell() - 4, BasePropID);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rSCAN.Skip(0x2);
|
||||
uint16 NumProperties = rSCAN.ReadShort();
|
||||
|
||||
switch (NumProperties)
|
||||
{
|
||||
case 0x14:
|
||||
case 0xB:
|
||||
mpScan = new CScan(mpEntry);
|
||||
LoadParamsMP2(rSCAN, NumProperties);
|
||||
break;
|
||||
case 0x12:
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
mpScan = new CScan(mpEntry);
|
||||
LoadParamsMP3(rSCAN, NumProperties);
|
||||
break;
|
||||
default:
|
||||
errorf("%s [0x%X]: Invalid SNFO property count: 0x%X", *rSCAN.GetSourceString(), rSCAN.Tell() - 2, NumProperties);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Load MP3 dependency list
|
||||
if (mpScan->Game() == EGame::Corruption)
|
||||
{
|
||||
rSCAN.GoTo(InstanceEnd);
|
||||
uint32 NumDeps = rSCAN.ReadLong();
|
||||
|
||||
for (uint32 DepIdx = 0; DepIdx < NumDeps; DepIdx++)
|
||||
{
|
||||
rSCAN.Skip(4);
|
||||
CAssetID ID(rSCAN, mpScan->Game());
|
||||
mpScan->mDependencyList.push_back(ID);
|
||||
}
|
||||
}
|
||||
|
||||
return mpScan;
|
||||
}
|
||||
|
||||
void CScanLoader::LoadParamsMP2(IInputStream& rSCAN, uint16 NumProperties)
|
||||
{
|
||||
// Function begins after the SNFO property count
|
||||
mpScan->mSecondaryModels.resize(9);
|
||||
|
||||
for (uint32 iProp = 0; iProp < NumProperties; iProp++)
|
||||
{
|
||||
uint32 PropertyID = rSCAN.ReadLong();
|
||||
uint16 PropertySize = rSCAN.ReadShort();
|
||||
uint32 Next = rSCAN.Tell() + PropertySize;
|
||||
|
||||
switch (PropertyID)
|
||||
{
|
||||
case 0x2F5B6423:
|
||||
mpScan->mpStringTable = gpResourceStore->LoadResource(rSCAN.ReadLong(), EResourceType::StringTable);
|
||||
break;
|
||||
|
||||
case 0xC308A322:
|
||||
mpScan->mIsSlow = (rSCAN.ReadLong() != 0);
|
||||
break;
|
||||
|
||||
case 0x7B714814:
|
||||
mpScan->mIsImportant = rSCAN.ReadBool();
|
||||
break;
|
||||
|
||||
case 0x1733B1EC:
|
||||
mpScan->mUseLogbookModelPostScan = rSCAN.ReadBool();
|
||||
break;
|
||||
|
||||
case 0x53336141:
|
||||
mpScan->mPostOverrideTexture = CAssetID(rSCAN, mVersion);
|
||||
break;
|
||||
|
||||
case 0x3DE0BA64:
|
||||
mpScan->mLogbookDefaultRotX = rSCAN.ReadFloat();
|
||||
break;
|
||||
|
||||
case 0x2ADD6628:
|
||||
mpScan->mLogbookDefaultRotZ = rSCAN.ReadFloat();
|
||||
break;
|
||||
|
||||
case 0xD0C15066:
|
||||
mpScan->mLogbookScale = rSCAN.ReadFloat();
|
||||
break;
|
||||
|
||||
case 0xB7ADC418:
|
||||
mpScan->mLogbookModel = CAssetID(rSCAN, mVersion);
|
||||
break;
|
||||
|
||||
case 0x15694EE1:
|
||||
mpScan->mLogbookAnimParams = CAnimationParameters(rSCAN, mVersion);
|
||||
break;
|
||||
|
||||
case 0x58F9FE99:
|
||||
mpScan->mUnknownAnimParams = CAnimationParameters(rSCAN, mVersion);
|
||||
break;
|
||||
|
||||
case 0x1C5B4A3A:
|
||||
LoadScanInfoSecondaryModel( rSCAN, mpScan->mSecondaryModels[0] );
|
||||
break;
|
||||
|
||||
case 0x8728A0EE:
|
||||
LoadScanInfoSecondaryModel( rSCAN, mpScan->mSecondaryModels[1] );
|
||||
break;
|
||||
|
||||
case 0xF1CD99D3:
|
||||
LoadScanInfoSecondaryModel( rSCAN, mpScan->mSecondaryModels[2] );
|
||||
break;
|
||||
|
||||
case 0x6ABE7307:
|
||||
LoadScanInfoSecondaryModel( rSCAN, mpScan->mSecondaryModels[3] );
|
||||
break;
|
||||
|
||||
case 0x1C07EBA9:
|
||||
LoadScanInfoSecondaryModel( rSCAN, mpScan->mSecondaryModels[4] );
|
||||
break;
|
||||
|
||||
case 0x8774017D:
|
||||
LoadScanInfoSecondaryModel( rSCAN, mpScan->mSecondaryModels[5] );
|
||||
break;
|
||||
|
||||
case 0xF1913840:
|
||||
LoadScanInfoSecondaryModel( rSCAN, mpScan->mSecondaryModels[6] );
|
||||
break;
|
||||
|
||||
case 0x6AE2D294:
|
||||
LoadScanInfoSecondaryModel( rSCAN, mpScan->mSecondaryModels[7] );
|
||||
break;
|
||||
|
||||
case 0x1CE2091C:
|
||||
LoadScanInfoSecondaryModel( rSCAN, mpScan->mSecondaryModels[8] );
|
||||
break;
|
||||
}
|
||||
|
||||
rSCAN.GoTo(Next);
|
||||
}
|
||||
|
||||
mpScan->mCategory = CScan::ELogbookCategory::None;
|
||||
}
|
||||
|
||||
void CScanLoader::LoadParamsMP3(IInputStream& rSCAN, uint16 NumProperties)
|
||||
{
|
||||
// Function begins after the SNFO property count
|
||||
for (uint32 iProp = 0; iProp < NumProperties; iProp++)
|
||||
{
|
||||
uint32 PropertyID = rSCAN.ReadLong();
|
||||
uint16 PropertySize = rSCAN.ReadShort();
|
||||
uint32 Next = rSCAN.Tell() + PropertySize;
|
||||
|
||||
switch (PropertyID)
|
||||
{
|
||||
case 0x2F5B6423:
|
||||
mpScan->mpStringTable = gpResourceStore->LoadResource(rSCAN.ReadLongLong(), EResourceType::StringTable);
|
||||
break;
|
||||
|
||||
case 0xC308A322:
|
||||
mpScan->mIsSlow = (rSCAN.ReadLong() != 0);
|
||||
break;
|
||||
|
||||
case 0x7B714814:
|
||||
mpScan->mIsImportant = (rSCAN.ReadByte() != 0);
|
||||
break;
|
||||
}
|
||||
|
||||
rSCAN.GoTo(Next);
|
||||
}
|
||||
|
||||
mpScan->mCategory = CScan::ELogbookCategory::None;
|
||||
}
|
||||
|
||||
void CScanLoader::LoadScanInfoSecondaryModel(IInputStream& rSCAN, CScan::SScanInfoSecondaryModel& rSecondaryModel)
|
||||
{
|
||||
uint16 NumProperties = rSCAN.ReadShort();
|
||||
|
||||
for (uint32 iProp = 0; iProp < NumProperties; iProp++)
|
||||
{
|
||||
uint32 PropertyID = rSCAN.ReadLong();
|
||||
uint16 PropertySize = rSCAN.ReadShort();
|
||||
uint32 Next = rSCAN.Tell() + PropertySize;
|
||||
|
||||
switch (PropertyID)
|
||||
{
|
||||
case 0x1F7921BC:
|
||||
rSecondaryModel.ModelID = CAssetID(rSCAN, mVersion);
|
||||
break;
|
||||
|
||||
case 0xCDD202D1:
|
||||
rSecondaryModel.AnimParams = CAnimationParameters(rSCAN, mVersion);
|
||||
break;
|
||||
|
||||
case 0x3EA2BED8:
|
||||
rSecondaryModel.AttachBoneName = rSCAN.ReadString();
|
||||
break;
|
||||
}
|
||||
|
||||
rSCAN.GoTo(Next);
|
||||
}
|
||||
}
|
||||
|
||||
// ************ STATIC/PUBLIC ************
|
||||
CScan* CScanLoader::LoadSCAN(IInputStream& rSCAN, CResourceEntry *pEntry)
|
||||
{
|
||||
if (!rSCAN.IsValid()) return nullptr;
|
||||
|
||||
/* Switching to EGame enum here isn't really useful unfortunately
|
||||
* because the MP1 demo can be 1, 2, or 3, while MP1 is 5 and MP2+ is 2
|
||||
* MP1 is the only one that starts with 5 so that is a consistent check for now
|
||||
* Better version checks will be implemented when the other versions are
|
||||
* better-understood. */
|
||||
uint32 FileVersion = rSCAN.ReadLong();
|
||||
uint32 Magic = rSCAN.ReadLong();
|
||||
|
||||
// Echoes+
|
||||
if (FileVersion == FOURCC('SCAN'))
|
||||
{
|
||||
// The MP2 load function will check for MP3
|
||||
CScanLoader Loader;
|
||||
Loader.mVersion = EGame::Echoes;
|
||||
Loader.mpEntry = pEntry;
|
||||
if (Magic == 0x01000000) rSCAN.Seek(-4, SEEK_CUR); // The version number isn't present in the Echoes demo
|
||||
return Loader.LoadScanMP2(rSCAN);
|
||||
}
|
||||
// Validate magic
|
||||
uint Magic = SCAN.ReadLong();
|
||||
|
||||
if (Magic != 0x0BADBEEF)
|
||||
{
|
||||
errorf("%s: Invalid SCAN magic: 0x%08X", *rSCAN.GetSourceString(), Magic);
|
||||
errorf("Invalid magic in SCAN asset: 0x%08X", Magic);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (FileVersion != 5)
|
||||
{
|
||||
errorf("%s: Unsupported SCAN version: 0x%X", *rSCAN.GetSourceString(), FileVersion);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// MP1 SCAN - read the file!
|
||||
CScanLoader Loader;
|
||||
Loader.mVersion = EGame::Prime;
|
||||
Loader.mpScan = new CScan(pEntry);
|
||||
Loader.mpEntry = pEntry;
|
||||
return Loader.LoadScanMP1(rSCAN);
|
||||
// The SCAN format in MP2 and later games uses the script loader to load SCAN parameters.
|
||||
// The MP1 format is not loaded the same way, as far as I'm aware, and is loaded the same
|
||||
// way as a normal file format... however, since we support all games, we need to support
|
||||
// the script object method for proper MP2/3 support (including dealing with property names/IDs).
|
||||
// So, it's simplest to use the script loader to load the MP1 SCAN format as well... that enables
|
||||
// us to just create one class for all SCAN assets that works for every game.
|
||||
mpScan = new CScan(pEntry);
|
||||
CScriptLoader::LoadStructData(SCAN, mpScan->ScanData());
|
||||
return mpScan;
|
||||
}
|
||||
|
||||
CScan* CScanLoader::LoadScanMP2(IInputStream& SCAN, CResourceEntry* pEntry)
|
||||
{
|
||||
// Validate version
|
||||
uint Version = SCAN.ReadLong();
|
||||
|
||||
if (Version != 2)
|
||||
{
|
||||
errorf("Unrecognized SCAN version: %d", Version);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// The SCAN format in MP2 embeds a ScannableObjectInfo script object using the same file format as SCLY.
|
||||
// As such we use CScriptLoader to load parameters, but since we don't actually want to create a script
|
||||
// object, we will skip past the script object/layer header and just load the properties directly.
|
||||
SCAN.Skip(0x17);
|
||||
mpScan = new CScan(pEntry);
|
||||
CScriptLoader::LoadStructData(SCAN, mpScan->ScanData());
|
||||
return mpScan;
|
||||
}
|
||||
|
||||
// ************ STATIC/PUBLIC ************
|
||||
CScan* CScanLoader::LoadSCAN(IInputStream& SCAN, CResourceEntry *pEntry)
|
||||
{
|
||||
if (!SCAN.IsValid()) return nullptr;
|
||||
|
||||
// MP1 SCAN format starts with a version number and then follows with a magic.
|
||||
// The demo can be 1, 2, or 3, while the final build is 5.
|
||||
// The MP2 SCAN format starts with a 'SCAN' magic.
|
||||
uint VersionCheck = SCAN.ReadLong();
|
||||
|
||||
// Echoes+
|
||||
if (VersionCheck == FOURCC('SCAN'))
|
||||
{
|
||||
CScanLoader Loader;
|
||||
return Loader.LoadScanMP2(SCAN, pEntry);
|
||||
}
|
||||
// MP1
|
||||
else if (VersionCheck <= 5)
|
||||
{
|
||||
if (VersionCheck == 5)
|
||||
{
|
||||
CScanLoader Loader;
|
||||
return Loader.LoadScanMP1(SCAN, pEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
errorf("%s: Unsupported SCAN version: %d", VersionCheck);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorf("Failed to identify SCAN version: 0x%X", VersionCheck);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,15 +7,10 @@
|
||||
class CScanLoader
|
||||
{
|
||||
TResPtr<CScan> mpScan;
|
||||
CResourceEntry *mpEntry;
|
||||
EGame mVersion;
|
||||
|
||||
CScanLoader();
|
||||
CScan* LoadScanMP1(IInputStream& rSCAN);
|
||||
CScan* LoadScanMP2(IInputStream& rSCAN);
|
||||
void LoadParamsMP2(IInputStream& rSCAN, uint16 NumProperties);
|
||||
void LoadParamsMP3(IInputStream& rSCAN, uint16 NumProperties);
|
||||
void LoadScanInfoSecondaryModel(IInputStream& rSCAN, CScan::SScanInfoSecondaryModel& rSecondaryModel);
|
||||
CScanLoader() {}
|
||||
CScan* LoadScanMP1(IInputStream& SCAN, CResourceEntry* pEntry);
|
||||
CScan* LoadScanMP2(IInputStream& SCAN, CResourceEntry* pEntry);
|
||||
|
||||
public:
|
||||
static CScan* LoadSCAN(IInputStream& rSCAN, CResourceEntry *pEntry);
|
||||
|
||||
51
src/Core/Resource/Scan/CScan.cpp
Normal file
51
src/Core/Resource/Scan/CScan.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "CScan.h"
|
||||
|
||||
CScan::CScan(CResourceEntry* pEntry /*= 0*/)
|
||||
: CResource(pEntry)
|
||||
{
|
||||
CGameTemplate* pGameTemplate = NGameList::GetGameTemplate( Game() );
|
||||
mpTemplate = pGameTemplate->FindMiscTemplate("ScannableObjectInfo");
|
||||
ASSERT( mpTemplate != nullptr );
|
||||
|
||||
CStructProperty* pProperties = mpTemplate->Properties();
|
||||
mPropertyData.resize( pProperties->DataSize() );
|
||||
pProperties->Construct( mPropertyData.data() );
|
||||
}
|
||||
|
||||
CStructRef CScan::ScanData() const
|
||||
{
|
||||
return CStructRef((void*) mPropertyData.data(), mpTemplate->Properties());
|
||||
}
|
||||
|
||||
/** Convenience property accessors */
|
||||
CAssetRef CScan::ScanStringPropertyRef() const
|
||||
{
|
||||
const uint kStringIdMP1 = 0x1;
|
||||
const uint kStringIdMP2 = 0x2F5B6423;
|
||||
|
||||
IProperty* pProperty = mpTemplate->Properties()->ChildByID(
|
||||
Game() <= EGame::Prime ? kStringIdMP1 : kStringIdMP2
|
||||
);
|
||||
|
||||
return CAssetRef( (void*) mPropertyData.data(), pProperty );
|
||||
}
|
||||
|
||||
CBoolRef CScan::IsCriticalPropertyRef() const
|
||||
{
|
||||
const uint kIsCriticalIdMP1 = 0x4;
|
||||
const uint kIsCriticalIdMP2 = 0x7B714814;
|
||||
|
||||
IProperty* pProperty = mpTemplate->Properties()->ChildByID(
|
||||
Game() <= EGame::Prime ? kIsCriticalIdMP1 : kIsCriticalIdMP2
|
||||
);
|
||||
|
||||
return CBoolRef( (void*) mPropertyData.data(), pProperty );
|
||||
}
|
||||
|
||||
/** CResource interface */
|
||||
CDependencyTree* CScan::BuildDependencyTree() const
|
||||
{
|
||||
CDependencyTree* pTree = new CDependencyTree();
|
||||
pTree->ParseProperties(Entry(), ScanData().Property(), ScanData().DataPointer());
|
||||
return pTree;
|
||||
}
|
||||
34
src/Core/Resource/Scan/CScan.h
Normal file
34
src/Core/Resource/Scan/CScan.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef CSCAN_H
|
||||
#define CSCAN_H
|
||||
|
||||
#include <Common/Common.h>
|
||||
#include "Core/Resource/Animation/CAnimationParameters.h"
|
||||
#include "Core/Resource/Script/CGameTemplate.h"
|
||||
#include "Core/Resource/Script/NGameList.h"
|
||||
|
||||
/** Scannable object parameters from SCAN assets */
|
||||
class CScan : public CResource
|
||||
{
|
||||
DECLARE_RESOURCE_TYPE(Scan)
|
||||
friend class CScanLoader;
|
||||
friend class CScanCooker;
|
||||
|
||||
/** Script template specifying scan data layout */
|
||||
CScriptTemplate* mpTemplate;
|
||||
|
||||
/** Scan property data */
|
||||
std::vector<uint8> mPropertyData;
|
||||
|
||||
public:
|
||||
CScan(CResourceEntry* pEntry = 0);
|
||||
CStructRef ScanData() const;
|
||||
|
||||
/** Convenience property accessors */
|
||||
CAssetRef ScanStringPropertyRef() const;
|
||||
CBoolRef IsCriticalPropertyRef() const;
|
||||
|
||||
/** CResource interface */
|
||||
virtual CDependencyTree* BuildDependencyTree() const override;
|
||||
};
|
||||
|
||||
#endif // CSCAN_H
|
||||
14
src/Core/Resource/Scan/ELogbookCategory.h
Normal file
14
src/Core/Resource/Scan/ELogbookCategory.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef ELOGBOOKCATEGORY_H
|
||||
#define ELOGBOOKCATEGORY_H
|
||||
|
||||
/** Logbook category for scannable objects in MP1, used in SCAN and SAVW */
|
||||
enum class ELogbookCategory
|
||||
{
|
||||
None = 0,
|
||||
SpacePirateData = 1,
|
||||
ChozoLore = 2,
|
||||
Creatures = 3,
|
||||
Research = 4
|
||||
};
|
||||
|
||||
#endif // ELOGBOOKCATEGORY_H
|
||||
60
src/Core/Resource/Scan/SScanParametersMP1.h
Normal file
60
src/Core/Resource/Scan/SScanParametersMP1.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef SSCANPARAMETERSMP1_H
|
||||
#define SSCANPARAMETERSMP1_H
|
||||
|
||||
#include "ELogbookCategory.h"
|
||||
#include <Common/Common.h>
|
||||
|
||||
/** Struct mapping to SCAN property layout in MP1 */
|
||||
enum class EScanSpeed
|
||||
{
|
||||
Normal = 0,
|
||||
Slow = 1,
|
||||
};
|
||||
|
||||
enum class EScanImagePane
|
||||
{
|
||||
Pane0 = 0,
|
||||
Pane1 = 1,
|
||||
Pane2 = 2,
|
||||
Pane3 = 3,
|
||||
Pane01 = 4,
|
||||
Pane12 = 5,
|
||||
Pane23 = 6,
|
||||
Pane012 = 7,
|
||||
Pane123 = 8,
|
||||
Pane0123 = 9,
|
||||
Pane4 = 10,
|
||||
Pane5 = 11,
|
||||
Pane6 = 12,
|
||||
Pane7 = 13,
|
||||
Pane45 = 14,
|
||||
Pane56 = 15,
|
||||
Pane67 = 16,
|
||||
Pane456 = 17,
|
||||
Pane567 = 18,
|
||||
Pane4567 = 19,
|
||||
None = -1
|
||||
};
|
||||
|
||||
struct SScanImage
|
||||
{
|
||||
CAssetID Texture;
|
||||
float AppearPercentage;
|
||||
EScanImagePane Pane;
|
||||
int32 AnimationCellWidth;
|
||||
int32 AnimationCellHeight;
|
||||
float AnimationSwapInterval;
|
||||
float FadeDuration;
|
||||
};
|
||||
|
||||
struct SScanParametersMP1
|
||||
{
|
||||
CAssetID GuiFrame;
|
||||
CAssetID String;
|
||||
EScanSpeed Speed;
|
||||
ELogbookCategory LogbookCategory;
|
||||
bool IsCritical;
|
||||
SScanImage ScanImages[4];
|
||||
};
|
||||
|
||||
#endif // SSCANPARAMETERSMP1_H
|
||||
@@ -2,6 +2,7 @@
|
||||
#define CANIMATIONSETPROPERTY_H
|
||||
|
||||
#include "IProperty.h"
|
||||
#include "Core/Resource/Animation/CAnimationParameters.h"
|
||||
|
||||
class CAnimationSetProperty : public TSerializeableTypedProperty< CAnimationParameters, EPropertyType::AnimationSet >
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#ifndef IPROPERTY_H
|
||||
#define IPROPERTY_H
|
||||
|
||||
#include "Core/Resource/Animation/CAnimationParameters.h"
|
||||
#include <Common/Common.h>
|
||||
#include <Common/CFourCC.h>
|
||||
#include <Common/Math/CVector3f.h>
|
||||
|
||||
Reference in New Issue
Block a user