Changed EGame to an enum class. Created NGameList and NPropertyMap to change how templates are managed/saved/loaded. Added support for property map keeping track of ID/type pairs.
This commit is contained in:
parent
42d021e757
commit
84d689e104
|
@ -8,14 +8,11 @@
|
||||||
|
|
||||||
/* This header declares a macro, ASSERT(Expression). ASSERT evaluates the input expression and verifies that
|
/* This header declares a macro, ASSERT(Expression). ASSERT evaluates the input expression and verifies that
|
||||||
* it is true. If the expression is false, an error message will be printed to the log with info on what went
|
* it is true. If the expression is false, an error message will be printed to the log with info on what went
|
||||||
* wrong and (in debug builds) trigger a debug break. Application execution is not aborted, but if an assert
|
* wrong and (in debug builds) trigger a debug break. Application execution is aborted. In public release builds,
|
||||||
* fails then there is usually a decent chance of the application crashing regardless.
|
* asserts are compiled out entirely, so neither log messages nor debug breaks will occur.
|
||||||
*
|
*
|
||||||
* Note that in public release builds, asserts are compiled out entirely, so neither log messages nor debug breaks
|
* Alternatively, this file also declares an ENSURE macro, which is guaranteed always executes and will never be
|
||||||
* will occur.
|
* compiled out, regardless of build configuration.
|
||||||
*
|
|
||||||
* LOG_ONLY_ASSERT is similar to a regular assert, but doesn't trigger a debug break. It can be useful for debugging,
|
|
||||||
* but shouldn't be used as a permanent error check.
|
|
||||||
*/
|
*/
|
||||||
#define __FILE_SHORT__ strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__
|
#define __FILE_SHORT__ strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__
|
||||||
|
|
||||||
|
@ -27,39 +24,30 @@
|
||||||
#define CONDITIONAL_BREAK(Condition) {}
|
#define CONDITIONAL_BREAK(Condition) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ASSERT_CHECK_BEGIN(Expression) \
|
||||||
|
{ \
|
||||||
|
if (!(Expression)) \
|
||||||
|
{
|
||||||
|
|
||||||
|
#define ASSERT_CHECK_END \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WRITE_FAILURE_TO_LOG(Expression) \
|
||||||
|
Log::Write(TString(__FILE_SHORT__) + "(" + TString::FromInt32(__LINE__, 0, 10) + "): ASSERT FAILED: " + #Expression);
|
||||||
|
|
||||||
|
// ENSURE macro always executes, never gets compiled out
|
||||||
|
#define ENSURE(Expression) \
|
||||||
|
ASSERT_CHECK_BEGIN(Expression) \
|
||||||
|
WRITE_FAILURE_TO_LOG(Expression) \
|
||||||
|
DEBUG_BREAK \
|
||||||
|
abort(); \
|
||||||
|
ASSERT_CHECK_END
|
||||||
|
|
||||||
#if !PUBLIC_RELEASE
|
#if !PUBLIC_RELEASE
|
||||||
|
#define ASSERT(Expression) ENSURE(Expression)
|
||||||
// Development Build
|
|
||||||
#define ASSERT_CHECK_BEGIN(Expression) \
|
|
||||||
{ \
|
|
||||||
if (!(Expression)) \
|
|
||||||
{
|
|
||||||
|
|
||||||
#define ASSERT_CHECK_END \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define WRITE_FAILURE_TO_LOG(Expression) \
|
|
||||||
Log::Write(TString(__FILE_SHORT__) + "(" + TString::FromInt32(__LINE__, 0, 10) + "): ASSERT FAILED: " + #Expression);
|
|
||||||
|
|
||||||
#define LOG_ONLY_ASSERT(Expression) \
|
|
||||||
ASSERT_CHECK_BEGIN(Expression) \
|
|
||||||
WRITE_FAILURE_TO_LOG(Expression) \
|
|
||||||
ASSERT_CHECK_END
|
|
||||||
|
|
||||||
#define ASSERT(Expression) \
|
|
||||||
ASSERT_CHECK_BEGIN(Expression) \
|
|
||||||
WRITE_FAILURE_TO_LOG(Expression) \
|
|
||||||
DEBUG_BREAK \
|
|
||||||
ASSERT_CHECK_END
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// Public Release Build
|
|
||||||
#define BREAK_ONLY_ASSERT(Expression) {}
|
|
||||||
#define LOG_ONLY_ASSERT(Expression) {}
|
|
||||||
#define ASSERT(Expression) {}
|
#define ASSERT(Expression) {}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // ASSERT_H
|
#endif // ASSERT_H
|
||||||
|
|
|
@ -52,7 +52,7 @@ CAssetID::CAssetID(IInputStream& rInput, EIDLength Length)
|
||||||
|
|
||||||
CAssetID::CAssetID(IInputStream& rInput, EGame Game)
|
CAssetID::CAssetID(IInputStream& rInput, EGame Game)
|
||||||
{
|
{
|
||||||
*this = CAssetID(rInput, (Game <= eEchoes ? e32Bit : e64Bit));
|
*this = CAssetID(rInput, (Game <= EGame::Echoes ? e32Bit : e64Bit));
|
||||||
}
|
}
|
||||||
|
|
||||||
TString CAssetID::ToString(EIDLength ForcedLength /*= eInvalidIDLength*/) const
|
TString CAssetID::ToString(EIDLength ForcedLength /*= eInvalidIDLength*/) const
|
||||||
|
|
|
@ -49,9 +49,9 @@ public:
|
||||||
static CAssetID FromString(const TString& rkString);
|
static CAssetID FromString(const TString& rkString);
|
||||||
static CAssetID RandomID();
|
static CAssetID RandomID();
|
||||||
|
|
||||||
inline static EIDLength GameIDLength(EGame Game) { return (Game == eUnknownGame ? eInvalidIDLength : (Game <= eEchoes ? e32Bit : e64Bit)); }
|
inline static EIDLength GameIDLength(EGame Game) { return (Game == EGame::Invalid ? eInvalidIDLength : (Game <= EGame::Echoes ? e32Bit : e64Bit)); }
|
||||||
inline static CAssetID InvalidID(EIDLength IDLength) { return (IDLength == e32Bit ? skInvalidID32 : skInvalidID64); }
|
inline static CAssetID InvalidID(EIDLength IDLength) { return (IDLength == e32Bit ? skInvalidID32 : skInvalidID64); }
|
||||||
inline static CAssetID InvalidID(EGame Game) { return InvalidID(Game <= eEchoes ? e32Bit : e64Bit); }
|
inline static CAssetID InvalidID(EGame Game) { return InvalidID(Game <= EGame::Echoes ? e32Bit : e64Bit); }
|
||||||
|
|
||||||
static CAssetID skInvalidID32;
|
static CAssetID skInvalidID32;
|
||||||
static CAssetID skInvalidID64;
|
static CAssetID skInvalidID64;
|
||||||
|
|
|
@ -2,77 +2,91 @@
|
||||||
#include "CFourCC.h"
|
#include "CFourCC.h"
|
||||||
#include "Common/Serialization/IArchive.h"
|
#include "Common/Serialization/IArchive.h"
|
||||||
|
|
||||||
CFourCC GetGameID(EGame Game)
|
|
||||||
{
|
|
||||||
switch (Game)
|
|
||||||
{
|
|
||||||
case ePrimeDemo: return "MP1D";
|
|
||||||
case ePrime: return "MPRM";
|
|
||||||
case eEchoesDemo: return "MP2D";
|
|
||||||
case eEchoes: return "MP2E";
|
|
||||||
case eCorruptionProto: return "MP3P";
|
|
||||||
case eCorruption: return "MP3C";
|
|
||||||
case eReturns: return "DKCR";
|
|
||||||
default: return "UNKN";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EGame GetGameForID(const CFourCC& rkID)
|
|
||||||
{
|
|
||||||
if (rkID == "MP1D") return ePrimeDemo;
|
|
||||||
if (rkID == "MPRM") return ePrime;
|
|
||||||
if (rkID == "MP2D") return eEchoesDemo;
|
|
||||||
if (rkID == "MP2E") return eEchoes;
|
|
||||||
if (rkID == "MP3P") return eCorruptionProto;
|
|
||||||
if (rkID == "MP3C") return eCorruption;
|
|
||||||
if (rkID == "DKCR") return eReturns;
|
|
||||||
return eUnknownGame;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString GetGameName(EGame Game)
|
TString GetGameName(EGame Game)
|
||||||
{
|
{
|
||||||
switch (Game)
|
static const TString skGameNames[EGame::Max] =
|
||||||
{
|
{
|
||||||
case ePrimeDemo: return "Metroid Prime Kiosk Demo";
|
"Metroid Prime Demo",
|
||||||
case ePrime: return "Metroid Prime";
|
"Metroid Prime",
|
||||||
case eEchoesDemo: return "Metroid Prime 2: Echoes Demo";
|
"Metroid Prime 2: Echoes Demo",
|
||||||
case eEchoes: return "Metroid Prime 2: Echoes";
|
"Metroid Prime 2: Echoes",
|
||||||
case eCorruptionProto: return "Metroid Prime 3: Corruption Prototype";
|
"Metroid Prime 3: Corruption E3 2006 Prototype",
|
||||||
case eCorruption: return "Metroid Prime 3: Corruption";
|
"Metroid Prime 3: Corruption",
|
||||||
case eReturns: return "Donkey Kong Country Returns";
|
"Donkey Kong Country Returns"
|
||||||
default: return "Unknown Game";
|
};
|
||||||
}
|
|
||||||
|
int GameIdx = (int) Game;
|
||||||
|
return (GameIdx >= 0 && GameIdx < (int) EGame::Max) ? skGameNames[GameIdx] : "Unknown Game";
|
||||||
}
|
}
|
||||||
|
|
||||||
TString GetGameShortName(EGame Game)
|
TString GetGameShortName(EGame Game)
|
||||||
{
|
{
|
||||||
switch (Game)
|
static const TString skGameNames[EGame::Max] = {
|
||||||
|
"MP1Demo",
|
||||||
|
"MP1",
|
||||||
|
"MP2Demo",
|
||||||
|
"MP2",
|
||||||
|
"MP3Proto",
|
||||||
|
"MP3",
|
||||||
|
"DKCR"
|
||||||
|
};
|
||||||
|
|
||||||
|
int GameIdx = (int) Game;
|
||||||
|
return (GameIdx >= 0 && GameIdx < (int) EGame::Max) ? skGameNames[GameIdx] : "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
CFourCC GameTo4CC(EGame Game)
|
||||||
|
{
|
||||||
|
static const CFourCC skGame4CCs[EGame::Max] =
|
||||||
{
|
{
|
||||||
case ePrimeDemo: return "MP1Demo";
|
FOURCC('MP1D'), FOURCC('MPRM'),
|
||||||
case ePrime: return "MP1";
|
FOURCC('MP2D'), FOURCC('MP2E'),
|
||||||
case eEchoesDemo: return "MP2Demo";
|
FOURCC('MP3P'), FOURCC('MP3C'),
|
||||||
case eEchoes: return "MP2";
|
FOURCC('DKCR')
|
||||||
case eCorruptionProto: return "MP3Proto";
|
};
|
||||||
case eCorruption: return "MP3";
|
|
||||||
case eReturns: return "DKCR";
|
int GameIdx = (int) Game;
|
||||||
default: return "Unknown";
|
return (GameIdx >= 0 && GameIdx < (int) EGame::Max) ? skGame4CCs[GameIdx] : FOURCC('UNKN');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EGame GameFrom4CC(CFourCC GameId)
|
||||||
|
{
|
||||||
|
static const std::unordered_map<u32, EGame> skIdToGame =
|
||||||
|
{
|
||||||
|
{ FOURCC('MP1D'), EGame::PrimeDemo },
|
||||||
|
{ FOURCC('MPRM'), EGame::Prime },
|
||||||
|
{ FOURCC('MP2D'), EGame::EchoesDemo },
|
||||||
|
{ FOURCC('MP2E'), EGame::Echoes },
|
||||||
|
{ FOURCC('MP3P'), EGame::CorruptionProto },
|
||||||
|
{ FOURCC('MP3C'), EGame::Corruption },
|
||||||
|
{ FOURCC('DKCR'), EGame::DKCReturns }
|
||||||
|
};
|
||||||
|
auto MapFindIter = skIdToGame.find(GameId.ToLong());
|
||||||
|
return (MapFindIter != skIdToGame.end() ? MapFindIter->second : EGame::Invalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Serialize(IArchive& rArc, EGame& rGame)
|
void Serialize(IArchive& rArc, EGame& rGame)
|
||||||
{
|
{
|
||||||
CFourCC GameID = GetGameID(rGame);
|
// We serialize EGame as a fourCC in binary formats as a future-proofing measure.
|
||||||
rArc.SerializePrimitive(GameID, 0);
|
// Additionally, older versions of IArchive always serialized EGame as a fourCC.
|
||||||
if (rArc.IsReader()) rGame = GetGameForID(GameID);
|
if (rArc.ArchiveVersion() < IArchive::eArVer_GameEnumClass || rArc.IsBinaryFormat())
|
||||||
}
|
{
|
||||||
|
CFourCC GameId;
|
||||||
|
|
||||||
// ERegion
|
if (rArc.IsWriter())
|
||||||
const char* GetRegionName(ERegion Region)
|
{
|
||||||
{
|
GameId = GameTo4CC(rGame);
|
||||||
return TEnumReflection<ERegion>::ConvertValueToString(Region);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ERegion GetRegionForName(const char* pkName)
|
rArc.SerializePrimitive(GameId, 0);
|
||||||
{
|
|
||||||
return TEnumReflection<ERegion>::ConvertStringToValue(pkName);
|
if (rArc.IsReader())
|
||||||
|
{
|
||||||
|
rGame = GameFrom4CC(GameId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DefaultEnumSerialize<EGame>(rArc, rGame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,24 +7,27 @@
|
||||||
class CFourCC;
|
class CFourCC;
|
||||||
class IArchive;
|
class IArchive;
|
||||||
|
|
||||||
// Note: A lot of code does inequality comparisons on EGame, ie. "if (Game <= eEchoes)", which means that the
|
//@todo I'm not really happy with EGame being in Common (would like Common to be more
|
||||||
// enum values need to be in chronological order. It'd be more convenient if the values were fourCCs, but we can't do that.
|
// generic so it's more reusable between different projects) but atm can't think of
|
||||||
enum EGame
|
// any other decent way to integrate it with IArchive unfortunately
|
||||||
|
enum class EGame
|
||||||
{
|
{
|
||||||
ePrimeDemo,
|
PrimeDemo,
|
||||||
ePrime,
|
Prime,
|
||||||
eEchoesDemo,
|
EchoesDemo,
|
||||||
eEchoes,
|
Echoes,
|
||||||
eCorruptionProto,
|
CorruptionProto,
|
||||||
eCorruption,
|
Corruption,
|
||||||
eReturns,
|
DKCReturns,
|
||||||
eUnknownGame = -1
|
|
||||||
|
Max,
|
||||||
|
Invalid = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
CFourCC GetGameID(EGame Game);
|
|
||||||
EGame GetGameForID(const CFourCC& rkID);
|
|
||||||
TString GetGameName(EGame Game);
|
TString GetGameName(EGame Game);
|
||||||
TString GetGameShortName(EGame Game);
|
TString GetGameShortName(EGame Game);
|
||||||
|
CFourCC GameTo4CC(EGame Game);
|
||||||
|
EGame GameFrom4CC(CFourCC GameId);
|
||||||
void Serialize(IArchive& rArc, EGame& rGame);
|
void Serialize(IArchive& rArc, EGame& rGame);
|
||||||
|
|
||||||
// ERegion
|
// ERegion
|
||||||
|
@ -35,7 +38,5 @@ enum class ERegion
|
||||||
JPN,
|
JPN,
|
||||||
Unknown = -1
|
Unknown = -1
|
||||||
};
|
};
|
||||||
const char* GetRegionName(ERegion Region);
|
|
||||||
ERegion GetRegionForName(const char* pkName);
|
|
||||||
|
|
||||||
#endif // EGAME_H
|
#endif // EGAME_H
|
||||||
|
|
|
@ -7,32 +7,44 @@
|
||||||
namespace NBasics
|
namespace NBasics
|
||||||
{
|
{
|
||||||
|
|
||||||
/** Remove an element from a vector */
|
/** Remove an element from a container */
|
||||||
template<typename T>
|
template<typename T, typename ContainerT>
|
||||||
bool VectorRemoveOne(std::vector<T>& Vector, const T& kElement)
|
bool ContainerRemoveOne(ContainerT& Container, const T& kElement)
|
||||||
{
|
{
|
||||||
for (auto Iter = Vector.begin(); Iter != Vector.end(); Iter++)
|
for (auto Iter = Container.begin(); Iter != Container.end(); Iter++)
|
||||||
{
|
{
|
||||||
if (*Iter == kElement)
|
if (*Iter == kElement)
|
||||||
{
|
{
|
||||||
Vector.erase(Iter);
|
Container.erase(Iter);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Remove all occurrences of an element from a vector. Returns the number of elements that were removed. */
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
int VectorRemoveAll(std::vector<T>& Vector, const T& kElement)
|
inline bool VectorRemoveOne(std::vector<T>& Vector, const T& kElement)
|
||||||
|
{
|
||||||
|
return ContainerRemoveOne< T, std::vector<T> >(Vector, kElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline bool ListRemoveOne(std::list<T>& List, const T& kElement)
|
||||||
|
{
|
||||||
|
return ContainerRemoveOne< T, std::list<T> >(List, kElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove all occurrences of an element from a container. Returns the number of elements that were removed. */
|
||||||
|
template<typename T, typename ContainerT>
|
||||||
|
int ContainerRemoveAll(ContainerT& Container, const T& kElement)
|
||||||
{
|
{
|
||||||
int NumRemoved = 0;
|
int NumRemoved = 0;
|
||||||
|
|
||||||
for (auto Iter = Vector.begin(); Iter != Vector.end(); Iter++)
|
for (auto Iter = Container.begin(); Iter != Container.end(); Iter++)
|
||||||
{
|
{
|
||||||
if (*Iter == kElement)
|
if (*Iter == kElement)
|
||||||
{
|
{
|
||||||
Iter = Vector.erase(Iter);
|
Iter = Container.erase(Iter);
|
||||||
NumRemoved++;
|
NumRemoved++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +52,18 @@ int VectorRemoveAll(std::vector<T>& Vector, const T& kElement)
|
||||||
return NumRemoved;
|
return NumRemoved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline int VectorRemoveAll(std::vector<T>& Vector, const T& kElement)
|
||||||
|
{
|
||||||
|
return ContainerRemoveAll< T, std::vector<T> >(Vector, kElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline int ListRemoveAll(std::list<T>& List, const T& kElement)
|
||||||
|
{
|
||||||
|
return ContainerRemoveAll< T, std::list<T> >(List, kElement);
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns whether the vector contains the given element */
|
/** Returns whether the vector contains the given element */
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool VectorContains(std::vector<T>& Vector, const T& kElement)
|
bool VectorContains(std::vector<T>& Vector, const T& kElement)
|
||||||
|
|
|
@ -18,7 +18,7 @@ class CBinaryWriter : public IArchive
|
||||||
bool mOwnsStream;
|
bool mOwnsStream;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CBinaryWriter(const TString& rkFilename, u32 Magic, u16 FileVersion = 0, EGame Game = eUnknownGame)
|
CBinaryWriter(const TString& rkFilename, u32 Magic, u16 FileVersion = 0, EGame Game = EGame::Invalid)
|
||||||
: IArchive()
|
: IArchive()
|
||||||
, mMagic(Magic)
|
, mMagic(Magic)
|
||||||
, mOwnsStream(true)
|
, mOwnsStream(true)
|
||||||
|
@ -36,7 +36,7 @@ public:
|
||||||
SerializeVersion();
|
SerializeVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
CBinaryWriter(IOutputStream *pStream, u16 FileVersion = 0, EGame Game = eUnknownGame)
|
CBinaryWriter(IOutputStream *pStream, u16 FileVersion = 0, EGame Game = EGame::Invalid)
|
||||||
: IArchive()
|
: IArchive()
|
||||||
, mMagic(0)
|
, mMagic(0)
|
||||||
, mOwnsStream(false)
|
, mOwnsStream(false)
|
||||||
|
|
|
@ -22,13 +22,13 @@ void CSerialVersion::Read(IInputStream& rInput)
|
||||||
mArchiveVersion = rInput.ReadShort();
|
mArchiveVersion = rInput.ReadShort();
|
||||||
mFileVersion = rInput.ReadShort();
|
mFileVersion = rInput.ReadShort();
|
||||||
CFourCC GameID(rInput);
|
CFourCC GameID(rInput);
|
||||||
mGame = GetGameForID(GameID);
|
mGame = GameFrom4CC(GameID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSerialVersion::Write(IOutputStream& rOutput)
|
void CSerialVersion::Write(IOutputStream& rOutput)
|
||||||
{
|
{
|
||||||
rOutput.WriteShort(mArchiveVersion);
|
rOutput.WriteShort(mArchiveVersion);
|
||||||
rOutput.WriteShort(mFileVersion);
|
rOutput.WriteShort(mFileVersion);
|
||||||
CFourCC GameID = GetGameID(mGame);
|
CFourCC GameID = GameTo4CC(mGame);
|
||||||
GameID.Write(rOutput);
|
GameID.Write(rOutput);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ class CXMLWriter : public IArchive
|
||||||
bool mSaved;
|
bool mSaved;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CXMLWriter(const TString& rkFileName, const TString& rkRootName, u16 FileVersion = 0, EGame Game = eUnknownGame)
|
CXMLWriter(const TString& rkFileName, const TString& rkRootName, u16 FileVersion = 0, EGame Game = EGame::Invalid)
|
||||||
: IArchive()
|
: IArchive()
|
||||||
, mOutFilename(rkFileName)
|
, mOutFilename(rkFileName)
|
||||||
, mpAttributeName(nullptr)
|
, mpAttributeName(nullptr)
|
||||||
|
|
|
@ -342,6 +342,7 @@ public:
|
||||||
eArVer_32BitBinarySize,
|
eArVer_32BitBinarySize,
|
||||||
eArVer_Refactor,
|
eArVer_Refactor,
|
||||||
eArVer_MapAttributes,
|
eArVer_MapAttributes,
|
||||||
|
eArVer_GameEnumClass,
|
||||||
// Insert new versions before this line
|
// Insert new versions before this line
|
||||||
eArVer_Max
|
eArVer_Max
|
||||||
};
|
};
|
||||||
|
@ -350,7 +351,7 @@ public:
|
||||||
IArchive()
|
IArchive()
|
||||||
: mFileVersion(0)
|
: mFileVersion(0)
|
||||||
, mArchiveVersion(skCurrentArchiveVersion)
|
, mArchiveVersion(skCurrentArchiveVersion)
|
||||||
, mGame(eUnknownGame)
|
, mGame(EGame::Invalid)
|
||||||
, mArchiveFlags(0)
|
, mArchiveFlags(0)
|
||||||
{
|
{
|
||||||
// hack to reduce allocations
|
// hack to reduce allocations
|
||||||
|
@ -364,7 +365,15 @@ public:
|
||||||
{
|
{
|
||||||
*this << SerialParameter("ArchiveVer", mArchiveVersion, SH_Attribute)
|
*this << SerialParameter("ArchiveVer", mArchiveVersion, SH_Attribute)
|
||||||
<< SerialParameter("FileVer", mFileVersion, SH_Attribute | SH_Optional, (u16) 0)
|
<< SerialParameter("FileVer", mFileVersion, SH_Attribute | SH_Optional, (u16) 0)
|
||||||
<< SerialParameter("Game", mGame, SH_Attribute | SH_Optional, eUnknownGame);
|
<< SerialParameter("Game", mGame, SH_Attribute | SH_Optional, EGame::Invalid);
|
||||||
|
|
||||||
|
if (IsReader())
|
||||||
|
{
|
||||||
|
if (mArchiveVersion > skCurrentArchiveVersion)
|
||||||
|
{
|
||||||
|
mArchiveVersion = skCurrentArchiveVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -765,22 +774,11 @@ public:
|
||||||
return CSerialVersion(mArchiveVersion, mFileVersion, mGame);
|
return CSerialVersion(mArchiveVersion, mFileVersion, mGame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the last object of a requested type in the parameter stack. Returns nullptr if the wasn't one.
|
/** Utility function for class versioning */
|
||||||
* This function will not return the current object being serialized. */
|
u32 SerializeClassVersion(u32 CurrentVersion)
|
||||||
template<typename ValType>
|
|
||||||
ValType* FindParentObject() const
|
|
||||||
{
|
{
|
||||||
for (int ParmIdx = mParmStack.size() - 2; ParmIdx >= 0; ParmIdx--)
|
*this << SerialParameter("ClassVer", CurrentVersion, SH_Attribute | SH_Optional, (u32) 0);
|
||||||
{
|
return CurrentVersion;
|
||||||
const SParmStackEntry& kEntry = mParmStack[ParmIdx];
|
|
||||||
|
|
||||||
if (kEntry.TypeID == typeid(ValType).hash_code())
|
|
||||||
{
|
|
||||||
return static_cast<ValType*>(kEntry.pDataPointer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -794,7 +792,7 @@ class TIsPrimitive : std::conditional< SerialType<T,IArchive>::Type == SerialTyp
|
||||||
#include <codegen/EnumReflection.h>
|
#include <codegen/EnumReflection.h>
|
||||||
|
|
||||||
template<typename T, typename = typename std::enable_if< std::is_enum<T>::value >::type>
|
template<typename T, typename = typename std::enable_if< std::is_enum<T>::value >::type>
|
||||||
inline void Serialize(IArchive& Arc, T& Val)
|
inline void DefaultEnumSerialize(IArchive& Arc, T& Val)
|
||||||
{
|
{
|
||||||
if (Arc.IsTextFormat())
|
if (Arc.IsTextFormat())
|
||||||
{
|
{
|
||||||
|
@ -815,6 +813,12 @@ inline void Serialize(IArchive& Arc, T& Val)
|
||||||
Arc.SerializePrimitive((u32&) Val, 0);
|
Arc.SerializePrimitive((u32&) Val, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T, typename = typename std::enable_if< std::is_enum<T>::value >::type>
|
||||||
|
inline void Serialize(IArchive& Arc, T& Val)
|
||||||
|
{
|
||||||
|
DefaultEnumSerialize(Arc, Val);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Container serialize methods
|
// Container serialize methods
|
||||||
|
@ -964,16 +968,16 @@ inline void SerializeMap_Internal(IArchive& Arc, MapType& Map)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename KeyType, typename ValType>
|
template<typename KeyType, typename ValType, typename HashFunc>
|
||||||
inline void Serialize(IArchive& Arc, std::map<KeyType, ValType>& Map)
|
inline void Serialize(IArchive& Arc, std::map<KeyType, ValType, HashFunc>& Map)
|
||||||
{
|
{
|
||||||
SerializeMap_Internal<KeyType, ValType, std::map<KeyType, ValType> >(Arc, Map);
|
SerializeMap_Internal<KeyType, ValType, std::map<KeyType, ValType, HashFunc> >(Arc, Map);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename KeyType, typename ValType>
|
template<typename KeyType, typename ValType, typename HashFunc>
|
||||||
inline void Serialize(IArchive& Arc, std::unordered_map<KeyType, ValType>& Map)
|
inline void Serialize(IArchive& Arc, std::unordered_map<KeyType, ValType, HashFunc>& Map)
|
||||||
{
|
{
|
||||||
SerializeMap_Internal<KeyType, ValType, std::unordered_map<KeyType, ValType> >(Arc, Map);
|
SerializeMap_Internal<KeyType, ValType, std::unordered_map<KeyType, ValType, HashFunc> >(Arc, Map);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Smart pointer serialize methods
|
// Smart pointer serialize methods
|
||||||
|
|
|
@ -20,9 +20,9 @@ void CAreaAttributes::SetObject(CScriptObject *pObj)
|
||||||
mGame = pTemplate->GameTemplate()->Game();
|
mGame = pTemplate->GameTemplate()->Game();
|
||||||
mNeedSky = CBoolRef(pObj->PropertyData(), pProperties->ChildByIndex(1));
|
mNeedSky = CBoolRef(pObj->PropertyData(), pProperties->ChildByIndex(1));
|
||||||
|
|
||||||
if (mGame == ePrime)
|
if (mGame == EGame::Prime)
|
||||||
mOverrideSky = CAssetRef(pObj->PropertyData(), pProperties->ChildByIndex(7));
|
mOverrideSky = CAssetRef(pObj->PropertyData(), pProperties->ChildByIndex(7));
|
||||||
else if (mGame > ePrime)
|
else if (mGame > EGame::Prime)
|
||||||
mOverrideSky = CAssetRef(pObj->PropertyData(), pProperties->ChildByID(0xD208C9FA));
|
mOverrideSky = CAssetRef(pObj->PropertyData(), pProperties->ChildByID(0xD208C9FA));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,13 +41,13 @@ void CAudioManager::LoadAssets()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load audio lookup table + sfx name list
|
// Load audio lookup table + sfx name list
|
||||||
TString AudioLookupName = (mpProject->Game() < eEchoesDemo ? "sound_lookup" : "sound_lookup_ATBL");
|
TString AudioLookupName = (mpProject->Game() < EGame::EchoesDemo ? "sound_lookup" : "sound_lookup_ATBL");
|
||||||
CAssetID AudioLookupID = mpProject->FindNamedResource(AudioLookupName);
|
CAssetID AudioLookupID = mpProject->FindNamedResource(AudioLookupName);
|
||||||
|
|
||||||
if (AudioLookupID.IsValid())
|
if (AudioLookupID.IsValid())
|
||||||
mpAudioLookupTable = mpProject->ResourceStore()->LoadResource<CAudioLookupTable>(AudioLookupID);
|
mpAudioLookupTable = mpProject->ResourceStore()->LoadResource<CAudioLookupTable>(AudioLookupID);
|
||||||
|
|
||||||
if (mpProject->Game() >= eEchoesDemo)
|
if (mpProject->Game() >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
CAssetID SfxNameListID = mpProject->FindNamedResource("audio_name_lookup_STLC");
|
CAssetID SfxNameListID = mpProject->FindNamedResource("audio_name_lookup_STLC");
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ SSoundInfo CAudioManager::GetSoundInfo(u32 SoundID)
|
||||||
if (Iter != mSfxIdMap.end())
|
if (Iter != mSfxIdMap.end())
|
||||||
Out.pAudioGroup = Iter->second;
|
Out.pAudioGroup = Iter->second;
|
||||||
|
|
||||||
if (mpProject->Game() >= eEchoesDemo)
|
if (mpProject->Game() >= EGame::EchoesDemo)
|
||||||
Out.Name = mpSfxNameList->StringByIndex(Out.DefineID);
|
Out.Name = mpSfxNameList->StringByIndex(Out.DefineID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ void CAudioManager::LogSoundInfo(u32 SoundID)
|
||||||
|
|
||||||
if (SoundInfo.DefineID != 0xFFFF)
|
if (SoundInfo.DefineID != 0xFFFF)
|
||||||
{
|
{
|
||||||
if (mpProject->Game() >= eEchoesDemo)
|
if (mpProject->Game() >= EGame::EchoesDemo)
|
||||||
Log::Write("Sound Name: " + SoundInfo.Name);
|
Log::Write("Sound Name: " + SoundInfo.Name);
|
||||||
|
|
||||||
Log::Write("Sound ID: " + TString::HexString(SoundInfo.SoundID, 4));
|
Log::Write("Sound ID: " + TString::HexString(SoundInfo.SoundID, 4));
|
||||||
|
|
|
@ -22,7 +22,7 @@ public:
|
||||||
{
|
{
|
||||||
if (InStruct.IsValid())
|
if (InStruct.IsValid())
|
||||||
{
|
{
|
||||||
if (Game <= ePrime)
|
if (Game <= EGame::Prime)
|
||||||
{
|
{
|
||||||
mWorldLightingOptions = TEnumRef<EWorldLightingOptions>(InStruct.DataPointer(), InStruct.Property()->ChildByIndex(0x7));
|
mWorldLightingOptions = TEnumRef<EWorldLightingOptions>(InStruct.DataPointer(), InStruct.Property()->ChildByIndex(0x7));
|
||||||
mLightLayer = CIntRef(InStruct.DataPointer(), InStruct.Property()->ChildByIndex(0xD));
|
mLightLayer = CIntRef(InStruct.DataPointer(), InStruct.Property()->ChildByIndex(0xD));
|
||||||
|
|
|
@ -249,7 +249,9 @@ HEADERS += \
|
||||||
Resource/Script/Property/CColorProperty.h \
|
Resource/Script/Property/CColorProperty.h \
|
||||||
Resource/Script/Property/CStructProperty.h \
|
Resource/Script/Property/CStructProperty.h \
|
||||||
Resource/Script/Property/CGuidProperty.h \
|
Resource/Script/Property/CGuidProperty.h \
|
||||||
Resource/Script/CGameTemplate.h
|
Resource/Script/CGameTemplate.h \
|
||||||
|
Resource/Script/NPropertyMap.h \
|
||||||
|
Resource/Script/NGameList.h
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
@ -359,7 +361,9 @@ SOURCES += \
|
||||||
Resource/Script/Property/IProperty.cpp \
|
Resource/Script/Property/IProperty.cpp \
|
||||||
Resource/Script/Property/CStructProperty.cpp \
|
Resource/Script/Property/CStructProperty.cpp \
|
||||||
Resource/Script/Property/CFlagsProperty.cpp \
|
Resource/Script/Property/CFlagsProperty.cpp \
|
||||||
Resource/Script/CGameTemplate.cpp
|
Resource/Script/CGameTemplate.cpp \
|
||||||
|
Resource/Script/NPropertyMap.cpp \
|
||||||
|
Resource/Script/NGameList.cpp
|
||||||
|
|
||||||
# Codegen
|
# Codegen
|
||||||
CODEGEN_DIR = $$EXTERNALS_DIR/CodeGen
|
CODEGEN_DIR = $$EXTERNALS_DIR/CodeGen
|
||||||
|
|
|
@ -43,7 +43,7 @@ void ApplyGeneratedName(CResourceEntry *pEntry, const TString& rkDir, const TStr
|
||||||
|
|
||||||
// trying to keep these as consistent with Retro's naming scheme as possible, and
|
// trying to keep these as consistent with Retro's naming scheme as possible, and
|
||||||
// for some reason in MP3 they started using all lowercase folder names...
|
// for some reason in MP3 they started using all lowercase folder names...
|
||||||
if (pEntry->Game() >= eCorruptionProto)
|
if (pEntry->Game() >= EGame::CorruptionProto)
|
||||||
SanitizedDir = SanitizedDir.ToLower();
|
SanitizedDir = SanitizedDir.ToLower();
|
||||||
|
|
||||||
pNewDir = pEntry->ResourceStore()->GetVirtualDirectory(SanitizedDir, true);
|
pNewDir = pEntry->ResourceStore()->GetVirtualDirectory(SanitizedDir, true);
|
||||||
|
@ -245,9 +245,9 @@ void GenerateAssetNames(CGameProject *pProj)
|
||||||
{
|
{
|
||||||
CMaterialPass *pPass = pMat->Pass(iPass);
|
CMaterialPass *pPass = pMat->Pass(iPass);
|
||||||
|
|
||||||
bool IsLightmap = ( (pArea->Game() <= eEchoes && pMat->Options().HasFlag(CMaterial::eLightmap) && iPass == 0) ||
|
bool IsLightmap = ( (pArea->Game() <= EGame::Echoes && pMat->Options().HasFlag(CMaterial::eLightmap) && iPass == 0) ||
|
||||||
(pArea->Game() >= eCorruptionProto && pPass->Type() == "DIFF") );
|
(pArea->Game() >= EGame::CorruptionProto && pPass->Type() == "DIFF") );
|
||||||
bool IsBloomLightmap = (pArea->Game() >= eCorruptionProto && pPass->Type() == "BLOL");
|
bool IsBloomLightmap = (pArea->Game() >= EGame::CorruptionProto && pPass->Type() == "BLOL");
|
||||||
|
|
||||||
TString TexName;
|
TString TexName;
|
||||||
|
|
||||||
|
@ -292,7 +292,7 @@ void GenerateAssetNames(CGameProject *pProj)
|
||||||
|
|
||||||
if (Name.StartsWith("POI_", false))
|
if (Name.StartsWith("POI_", false))
|
||||||
{
|
{
|
||||||
TIDString ScanIDString = (pProj->Game() <= ePrime ? "0x4:0x0" : "0xBDBEC295:0xB94E9BE7");
|
TIDString ScanIDString = (pProj->Game() <= EGame::Prime ? "0x4:0x0" : "0xBDBEC295:0xB94E9BE7");
|
||||||
CAssetProperty *pScanProperty = TPropCast<CAssetProperty>(pProperties->ChildByIDString(ScanIDString));
|
CAssetProperty *pScanProperty = TPropCast<CAssetProperty>(pProperties->ChildByIDString(ScanIDString));
|
||||||
ASSERT(pScanProperty); // Temporary assert to remind myself later to update this code when uncooked properties are added to the template
|
ASSERT(pScanProperty); // Temporary assert to remind myself later to update this code when uncooked properties are added to the template
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ void GenerateAssetNames(CGameProject *pProj)
|
||||||
|
|
||||||
if (Name.EndsWith(".STRG", false))
|
if (Name.EndsWith(".STRG", false))
|
||||||
{
|
{
|
||||||
u32 StringPropID = (pProj->Game() <= ePrime ? 0x4 : 0x9182250C);
|
u32 StringPropID = (pProj->Game() <= EGame::Prime ? 0x4 : 0x9182250C);
|
||||||
CAssetProperty *pStringProperty = TPropCast<CAssetProperty>(pProperties->ChildByID(StringPropID));
|
CAssetProperty *pStringProperty = TPropCast<CAssetProperty>(pProperties->ChildByID(StringPropID));
|
||||||
ASSERT(pStringProperty); // Temporary assert to remind myself later to update this code when uncooked properties are added to the template
|
ASSERT(pStringProperty); // Temporary assert to remind myself later to update this code when uncooked properties are added to the template
|
||||||
|
|
||||||
|
@ -353,7 +353,7 @@ void GenerateAssetNames(CGameProject *pProj)
|
||||||
else if (pInst->ObjectTypeID() == 0x0 || pInst->ObjectTypeID() == FOURCC('ACTR') ||
|
else if (pInst->ObjectTypeID() == 0x0 || pInst->ObjectTypeID() == FOURCC('ACTR') ||
|
||||||
pInst->ObjectTypeID() == 0x8 || pInst->ObjectTypeID() == FOURCC('PLAT'))
|
pInst->ObjectTypeID() == 0x8 || pInst->ObjectTypeID() == FOURCC('PLAT'))
|
||||||
{
|
{
|
||||||
u32 ModelPropID = (pProj->Game() <= ePrime ? (pInst->ObjectTypeID() == 0x0 ? 0xA : 0x6) : 0xC27FFA8F);
|
u32 ModelPropID = (pProj->Game() <= EGame::Prime ? (pInst->ObjectTypeID() == 0x0 ? 0xA : 0x6) : 0xC27FFA8F);
|
||||||
CAssetProperty *pModelProperty = TPropCast<CAssetProperty>(pProperties->ChildByID(ModelPropID));
|
CAssetProperty *pModelProperty = TPropCast<CAssetProperty>(pProperties->ChildByID(ModelPropID));
|
||||||
ASSERT(pModelProperty); // Temporary assert to remind myself later to update this code when uncooked properties are added to the template
|
ASSERT(pModelProperty); // Temporary assert to remind myself later to update this code when uncooked properties are added to the template
|
||||||
|
|
||||||
|
@ -415,8 +415,8 @@ void GenerateAssetNames(CGameProject *pProj)
|
||||||
{
|
{
|
||||||
CMaterialPass *pPass = pMat->Pass(iPass);
|
CMaterialPass *pPass = pMat->Pass(iPass);
|
||||||
|
|
||||||
bool IsLightmap = ( (pMat->Version() <= eEchoes && pMat->Options().HasFlag(CMaterial::eLightmap) && iPass == 0) ||
|
bool IsLightmap = ( (pMat->Version() <= EGame::Echoes && pMat->Options().HasFlag(CMaterial::eLightmap) && iPass == 0) ||
|
||||||
(pMat->Version() >= eCorruptionProto && pPass->Type() == "DIFF") );
|
(pMat->Version() >= EGame::CorruptionProto && pPass->Type() == "DIFF") );
|
||||||
|
|
||||||
if (IsLightmap)
|
if (IsLightmap)
|
||||||
{
|
{
|
||||||
|
@ -485,7 +485,7 @@ void GenerateAssetNames(CGameProject *pProj)
|
||||||
// Generate animation format names
|
// Generate animation format names
|
||||||
// Hacky syntax because animsets are under eAnimSet in MP1/2 and eCharacter in MP3/DKCR
|
// Hacky syntax because animsets are under eAnimSet in MP1/2 and eCharacter in MP3/DKCR
|
||||||
Log::Write("Processing animation data");
|
Log::Write("Processing animation data");
|
||||||
CResourceIterator *pIter = (pProj->Game() <= eEchoes ? (CResourceIterator*) new TResourceIterator<eAnimSet> : (CResourceIterator*) new TResourceIterator<eCharacter>);
|
CResourceIterator *pIter = (pProj->Game() <= EGame::Echoes ? (CResourceIterator*) new TResourceIterator<eAnimSet> : (CResourceIterator*) new TResourceIterator<eCharacter>);
|
||||||
CResourceIterator& It = *pIter;
|
CResourceIterator& It = *pIter;
|
||||||
|
|
||||||
for (; It; ++It)
|
for (; It; ++It)
|
||||||
|
@ -505,7 +505,7 @@ void GenerateAssetNames(CGameProject *pProj)
|
||||||
if (pkChar->pSkeleton) ApplyGeneratedName(pkChar->pSkeleton->Entry(), SetDir, CharName);
|
if (pkChar->pSkeleton) ApplyGeneratedName(pkChar->pSkeleton->Entry(), SetDir, CharName);
|
||||||
if (pkChar->pSkin) ApplyGeneratedName(pkChar->pSkin->Entry(), SetDir, CharName);
|
if (pkChar->pSkin) ApplyGeneratedName(pkChar->pSkin->Entry(), SetDir, CharName);
|
||||||
|
|
||||||
if (pProj->Game() >= eCorruptionProto && pProj->Game() <= eCorruption && pkChar->ID == 0)
|
if (pProj->Game() >= EGame::CorruptionProto && pProj->Game() <= EGame::Corruption && pkChar->ID == 0)
|
||||||
{
|
{
|
||||||
CResourceEntry *pAnimDataEntry = gpResourceStore->FindEntry( pkChar->AnimDataID );
|
CResourceEntry *pAnimDataEntry = gpResourceStore->FindEntry( pkChar->AnimDataID );
|
||||||
|
|
||||||
|
@ -607,7 +607,7 @@ void GenerateAssetNames(CGameProject *pProj)
|
||||||
CScan *pScan = (CScan*) It->Load();
|
CScan *pScan = (CScan*) It->Load();
|
||||||
TString ScanName;
|
TString ScanName;
|
||||||
|
|
||||||
if (pProj->Game() >= eEchoesDemo)
|
if (pProj->Game() >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
CAssetID DisplayAsset = pScan->LogbookDisplayAssetID();
|
CAssetID DisplayAsset = pScan->LogbookDisplayAssetID();
|
||||||
CResourceEntry *pEntry = pStore->FindEntry(DisplayAsset);
|
CResourceEntry *pEntry = pStore->FindEntry(DisplayAsset);
|
||||||
|
@ -622,7 +622,7 @@ void GenerateAssetNames(CGameProject *pProj)
|
||||||
|
|
||||||
ApplyGeneratedName(pScan->Entry(), It->DirectoryPath(), ScanName);
|
ApplyGeneratedName(pScan->Entry(), It->DirectoryPath(), ScanName);
|
||||||
|
|
||||||
if (!ScanName.IsEmpty() && pProj->Game() <= ePrime)
|
if (!ScanName.IsEmpty() && pProj->Game() <= EGame::Prime)
|
||||||
{
|
{
|
||||||
CAssetID FrameID = pScan->GuiFrame();
|
CAssetID FrameID = pScan->GuiFrame();
|
||||||
CResourceEntry *pEntry = pStore->FindEntry(FrameID);
|
CResourceEntry *pEntry = pStore->FindEntry(FrameID);
|
||||||
|
|
|
@ -36,7 +36,7 @@ bool CAssetNameMap::SaveAssetNames(TString Path /*= ""*/)
|
||||||
if (Path.IsEmpty())
|
if (Path.IsEmpty())
|
||||||
Path = DefaultNameMapPath(mIDLength);
|
Path = DefaultNameMapPath(mIDLength);
|
||||||
|
|
||||||
EGame Game = (mIDLength == e32Bit ? ePrime : eCorruption);
|
EGame Game = (mIDLength == e32Bit ? EGame::Prime : EGame::Corruption);
|
||||||
CXMLWriter Writer(Path, "AssetNameMap", 0, Game);
|
CXMLWriter Writer(Path, "AssetNameMap", 0, Game);
|
||||||
Serialize(Writer);
|
Serialize(Writer);
|
||||||
return Writer.Save();
|
return Writer.Save();
|
||||||
|
@ -58,7 +58,7 @@ bool CAssetNameMap::GetNameInfo(CAssetID ID, TString& rOutDirectory, TString& rO
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EGame Game = (ID.Length() == e32Bit ? ePrime : eCorruption);
|
EGame Game = (ID.Length() == e32Bit ? EGame::Prime : EGame::Corruption);
|
||||||
rOutDirectory = CResourceStore::StaticDefaultResourceDirPath(Game);
|
rOutDirectory = CResourceStore::StaticDefaultResourceDirPath(Game);
|
||||||
rOutName = ID.ToString();
|
rOutName = ID.ToString();
|
||||||
rOutAutoGenDir = true;
|
rOutAutoGenDir = true;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "Core/Resource/Script/CGameTemplate.h"
|
#include "Core/Resource/Script/CGameTemplate.h"
|
||||||
#include "Core/Resource/Script/CScriptLayer.h"
|
#include "Core/Resource/Script/CScriptLayer.h"
|
||||||
#include "Core/Resource/Script/CScriptObject.h"
|
#include "Core/Resource/Script/CScriptObject.h"
|
||||||
|
#include "Core/Resource/Script/NGameList.h"
|
||||||
|
|
||||||
// ************ IDependencyNode ************
|
// ************ IDependencyNode ************
|
||||||
IDependencyNode::~IDependencyNode()
|
IDependencyNode::~IDependencyNode()
|
||||||
|
@ -203,7 +204,7 @@ void CScriptInstanceDependency::ParseStructDependencies(CScriptInstanceDependenc
|
||||||
if (ID.IsValid())
|
if (ID.IsValid())
|
||||||
{
|
{
|
||||||
// Character sets are removed starting in MP3, so we only need char property dependencies in Echoes and earlier
|
// Character sets are removed starting in MP3, so we only need char property dependencies in Echoes and earlier
|
||||||
if (pStruct->Game() <= eEchoes)
|
if (pStruct->Game() <= EGame::Echoes)
|
||||||
{
|
{
|
||||||
CCharPropertyDependency *pDep = new CCharPropertyDependency(pProp->IDString(true), ID, Params.CharacterIndex());
|
CCharPropertyDependency *pDep = new CCharPropertyDependency(pProp->IDString(true), ID, Params.CharacterIndex());
|
||||||
pInst->mChildren.push_back(pDep);
|
pInst->mChildren.push_back(pDep);
|
||||||
|
@ -298,7 +299,7 @@ CSetAnimationDependency* CSetAnimationDependency::BuildTree(const CAnimSet *pkOw
|
||||||
const CAnimPrimitive& rkPrim = *Iter;
|
const CAnimPrimitive& rkPrim = *Iter;
|
||||||
pTree->AddDependency(rkPrim.Animation());
|
pTree->AddDependency(rkPrim.Animation());
|
||||||
|
|
||||||
if (pkOwnerSet->Game() >= eEchoesDemo)
|
if (pkOwnerSet->Game() >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
CAnimEventData *pEvents = pkOwnerSet->AnimationEventData(rkPrim.ID());
|
CAnimEventData *pEvents = pkOwnerSet->AnimationEventData(rkPrim.ID());
|
||||||
ASSERT(pEvents && !pEvents->Entry());
|
ASSERT(pEvents && !pEvents->Entry());
|
||||||
|
@ -345,7 +346,7 @@ void CAreaDependencyTree::AddScriptLayer(CScriptLayer *pLayer, const std::vector
|
||||||
ASSERT(pTree != nullptr);
|
ASSERT(pTree != nullptr);
|
||||||
|
|
||||||
// Note: MP2+ need to track all instances (not just instances with dependencies) to be able to build the layer module list
|
// Note: MP2+ need to track all instances (not just instances with dependencies) to be able to build the layer module list
|
||||||
if (pTree->NumChildren() > 0 || pLayer->Area()->Game() >= eEchoesDemo)
|
if (pTree->NumChildren() > 0 || pLayer->Area()->Game() >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
mChildren.push_back(pTree);
|
mChildren.push_back(pTree);
|
||||||
pTree->GetAllResourceReferences(UsedIDs);
|
pTree->GetAllResourceReferences(UsedIDs);
|
||||||
|
@ -360,7 +361,7 @@ void CAreaDependencyTree::AddScriptLayer(CScriptLayer *pLayer, const std::vector
|
||||||
|
|
||||||
void CAreaDependencyTree::GetModuleDependencies(EGame Game, std::vector<TString>& rModuleDepsOut, std::vector<u32>& rModuleLayerOffsetsOut) const
|
void CAreaDependencyTree::GetModuleDependencies(EGame Game, std::vector<TString>& rModuleDepsOut, std::vector<u32>& rModuleLayerOffsetsOut) const
|
||||||
{
|
{
|
||||||
CGameTemplate *pGame = CGameTemplate::GetGameTemplate(Game);
|
CGameTemplate *pGame = NGameList::GetGameTemplate(Game);
|
||||||
|
|
||||||
// Output module list will be split per-script layer
|
// Output module list will be split per-script layer
|
||||||
// The output offset list contains two offsets per layer - start index and end index
|
// The output offset list contains two offsets per layer - start index and end index
|
||||||
|
|
|
@ -29,7 +29,7 @@ CGameExporter::CGameExporter(EDiscType DiscType, EGame Game, bool FrontEnd, EReg
|
||||||
, mFrontEnd(FrontEnd)
|
, mFrontEnd(FrontEnd)
|
||||||
, mpProgress(nullptr)
|
, mpProgress(nullptr)
|
||||||
{
|
{
|
||||||
ASSERT(mGame != eUnknownGame);
|
ASSERT(mGame != EGame::Invalid);
|
||||||
ASSERT(mRegion != ERegion::Unknown);
|
ASSERT(mRegion != ERegion::Unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,15 +116,15 @@ bool CGameExporter::ShouldExportDiscNode(const nod::Node *pkNode, bool IsInRoot)
|
||||||
|
|
||||||
switch (mGame)
|
switch (mGame)
|
||||||
{
|
{
|
||||||
case ePrime:
|
case EGame::Prime:
|
||||||
return ( (mDiscType == eDT_WiiDeAsobu && pkNode->getName() == "MP1JPN") ||
|
return ( (mDiscType == eDT_WiiDeAsobu && pkNode->getName() == "MP1JPN") ||
|
||||||
(mDiscType == eDT_Trilogy && pkNode->getName() == "MP1") );
|
(mDiscType == eDT_Trilogy && pkNode->getName() == "MP1") );
|
||||||
|
|
||||||
case eEchoes:
|
case EGame::Echoes:
|
||||||
return ( (mDiscType == eDT_WiiDeAsobu && pkNode->getName() == "MP2JPN") ||
|
return ( (mDiscType == eDT_WiiDeAsobu && pkNode->getName() == "MP2JPN") ||
|
||||||
(mDiscType == eDT_Trilogy && pkNode->getName() == "MP2") );
|
(mDiscType == eDT_Trilogy && pkNode->getName() == "MP2") );
|
||||||
|
|
||||||
case eCorruption:
|
case EGame::Corruption:
|
||||||
return (mDiscType == eDT_Trilogy && pkNode->getName() == "MP3");
|
return (mDiscType == eDT_Trilogy && pkNode->getName() == "MP3");
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -144,15 +144,15 @@ bool CGameExporter::ShouldExportDiscNode(const nod::Node *pkNode, bool IsInRoot)
|
||||||
|
|
||||||
switch (mGame)
|
switch (mGame)
|
||||||
{
|
{
|
||||||
case ePrime:
|
case EGame::Prime:
|
||||||
return ( (mDiscType == eDT_WiiDeAsobu && pkNode->getName() == "rs5mp1jpn_p.dol") ||
|
return ( (mDiscType == eDT_WiiDeAsobu && pkNode->getName() == "rs5mp1jpn_p.dol") ||
|
||||||
(mDiscType == eDT_Trilogy && pkNode->getName() == "rs5mp1_p.dol") );
|
(mDiscType == eDT_Trilogy && pkNode->getName() == "rs5mp1_p.dol") );
|
||||||
|
|
||||||
case eEchoes:
|
case EGame::Echoes:
|
||||||
return ( (mDiscType == eDT_WiiDeAsobu && pkNode->getName() == "rs5mp2jpn_p.dol") ||
|
return ( (mDiscType == eDT_WiiDeAsobu && pkNode->getName() == "rs5mp2jpn_p.dol") ||
|
||||||
(mDiscType == eDT_Trilogy && pkNode->getName() == "rs5mp2_p.dol") );
|
(mDiscType == eDT_Trilogy && pkNode->getName() == "rs5mp2_p.dol") );
|
||||||
|
|
||||||
case eCorruption:
|
case EGame::Corruption:
|
||||||
return (mDiscType == eDT_Trilogy && pkNode->getName() == "rs5mp3_p.dol");
|
return (mDiscType == eDT_Trilogy && pkNode->getName() == "rs5mp3_p.dol");
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -278,7 +278,7 @@ void CGameExporter::LoadPaks()
|
||||||
CPackage *pPackage = new CPackage(mpProject, PakPath.GetFileName(false), RelPakPath);
|
CPackage *pPackage = new CPackage(mpProject, PakPath.GetFileName(false), RelPakPath);
|
||||||
|
|
||||||
// MP1-MP3Proto
|
// MP1-MP3Proto
|
||||||
if (mGame < eCorruption)
|
if (mGame < EGame::Corruption)
|
||||||
{
|
{
|
||||||
u32 PakVersion = Pak.ReadLong();
|
u32 PakVersion = Pak.ReadLong();
|
||||||
Pak.Seek(0x4, SEEK_CUR);
|
Pak.Seek(0x4, SEEK_CUR);
|
||||||
|
@ -396,7 +396,7 @@ void CGameExporter::LoadPaks()
|
||||||
mResourceMap[ResID] = SResourceInstance { PakPath, ResID, Type, Offset, Size, Compressed, false };
|
mResourceMap[ResID] = SResourceInstance { PakPath, ResID, Type, Offset, Size, Compressed, false };
|
||||||
|
|
||||||
// Check for duplicate resources (unnecessary for DKCR)
|
// Check for duplicate resources (unnecessary for DKCR)
|
||||||
if (mGame != eReturns)
|
if (mGame != EGame::DKCReturns)
|
||||||
{
|
{
|
||||||
if (Type == "MREA")
|
if (Type == "MREA")
|
||||||
{
|
{
|
||||||
|
@ -438,9 +438,9 @@ void CGameExporter::LoadResource(const SResourceInstance& rkResource, std::vecto
|
||||||
// Handle compression
|
// Handle compression
|
||||||
if (rkResource.Compressed)
|
if (rkResource.Compressed)
|
||||||
{
|
{
|
||||||
bool ZlibCompressed = (mGame <= eEchoesDemo || mGame == eReturns);
|
bool ZlibCompressed = (mGame <= EGame::EchoesDemo || mGame == EGame::DKCReturns);
|
||||||
|
|
||||||
if (mGame <= eCorruptionProto)
|
if (mGame <= EGame::CorruptionProto)
|
||||||
{
|
{
|
||||||
std::vector<u8> CompressedData(rkResource.PakSize);
|
std::vector<u8> CompressedData(rkResource.PakSize);
|
||||||
|
|
||||||
|
@ -686,14 +686,14 @@ TString CGameExporter::MakeWorldName(CAssetID WorldID)
|
||||||
{
|
{
|
||||||
// World names are basically formatted differently in every game...
|
// World names are basically formatted differently in every game...
|
||||||
// MP1 demo - Remove ! from the beginning
|
// MP1 demo - Remove ! from the beginning
|
||||||
if (mGame == ePrimeDemo)
|
if (mGame == EGame::PrimeDemo)
|
||||||
{
|
{
|
||||||
if (WorldName.StartsWith('!'))
|
if (WorldName.StartsWith('!'))
|
||||||
WorldName = WorldName.ChopFront(1);
|
WorldName = WorldName.ChopFront(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MP1 - Remove prefix characters and ending date
|
// MP1 - Remove prefix characters and ending date
|
||||||
else if (mGame == ePrime)
|
else if (mGame == EGame::Prime)
|
||||||
{
|
{
|
||||||
WorldName = WorldName.ChopFront(2);
|
WorldName = WorldName.ChopFront(2);
|
||||||
bool StartedDate = false;
|
bool StartedDate = false;
|
||||||
|
@ -712,7 +712,7 @@ TString CGameExporter::MakeWorldName(CAssetID WorldID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MP2 demo - Use text between the first and second underscores
|
// MP2 demo - Use text between the first and second underscores
|
||||||
else if (mGame == eEchoesDemo)
|
else if (mGame == EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
u32 UnderscoreA = WorldName.IndexOf('_');
|
u32 UnderscoreA = WorldName.IndexOf('_');
|
||||||
u32 UnderscoreB = WorldName.IndexOf('_', UnderscoreA + 1);
|
u32 UnderscoreB = WorldName.IndexOf('_', UnderscoreA + 1);
|
||||||
|
@ -722,7 +722,7 @@ TString CGameExporter::MakeWorldName(CAssetID WorldID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MP2 - Remove text before first underscore and after last underscore, strip remaining underscores (except multiplayer maps, which have one underscore)
|
// MP2 - Remove text before first underscore and after last underscore, strip remaining underscores (except multiplayer maps, which have one underscore)
|
||||||
else if (mGame == eEchoes)
|
else if (mGame == EGame::Echoes)
|
||||||
{
|
{
|
||||||
u32 FirstUnderscore = WorldName.IndexOf('_');
|
u32 FirstUnderscore = WorldName.IndexOf('_');
|
||||||
u32 LastUnderscore = WorldName.LastIndexOf('_');
|
u32 LastUnderscore = WorldName.LastIndexOf('_');
|
||||||
|
@ -736,7 +736,7 @@ TString CGameExporter::MakeWorldName(CAssetID WorldID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MP3 proto - Remove ! from the beginning and all text after last underscore
|
// MP3 proto - Remove ! from the beginning and all text after last underscore
|
||||||
else if (mGame == eCorruptionProto)
|
else if (mGame == EGame::CorruptionProto)
|
||||||
{
|
{
|
||||||
if (WorldName.StartsWith('!'))
|
if (WorldName.StartsWith('!'))
|
||||||
WorldName = WorldName.ChopFront(1);
|
WorldName = WorldName.ChopFront(1);
|
||||||
|
@ -746,7 +746,7 @@ TString CGameExporter::MakeWorldName(CAssetID WorldID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MP3 - Remove text after last underscore
|
// MP3 - Remove text after last underscore
|
||||||
else if (mGame == eCorruption)
|
else if (mGame == EGame::Corruption)
|
||||||
{
|
{
|
||||||
u32 LastUnderscore = WorldName.LastIndexOf('_');
|
u32 LastUnderscore = WorldName.LastIndexOf('_');
|
||||||
|
|
||||||
|
@ -755,7 +755,7 @@ TString CGameExporter::MakeWorldName(CAssetID WorldID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DKCR - Remove text prior to first underscore
|
// DKCR - Remove text prior to first underscore
|
||||||
else if (mGame == eReturns)
|
else if (mGame == EGame::DKCReturns)
|
||||||
{
|
{
|
||||||
u32 Underscore = WorldName.IndexOf('_');
|
u32 Underscore = WorldName.IndexOf('_');
|
||||||
WorldName = WorldName.ChopFront(Underscore + 1);
|
WorldName = WorldName.ChopFront(Underscore + 1);
|
||||||
|
|
|
@ -24,7 +24,7 @@ bool CGameInfo::LoadGameInfo(TString Path)
|
||||||
|
|
||||||
bool CGameInfo::SaveGameInfo(TString Path /*= ""*/)
|
bool CGameInfo::SaveGameInfo(TString Path /*= ""*/)
|
||||||
{
|
{
|
||||||
ASSERT(mGame != eUnknownGame); // can't save game info that was never loaded
|
ASSERT(mGame != EGame::Invalid); // can't save game info that was never loaded
|
||||||
|
|
||||||
if (Path.IsEmpty()) Path = GetDefaultGameInfoPath(mGame);
|
if (Path.IsEmpty()) Path = GetDefaultGameInfoPath(mGame);
|
||||||
CXMLWriter Writer(Path, "GameInfo", 0, mGame);
|
CXMLWriter Writer(Path, "GameInfo", 0, mGame);
|
||||||
|
@ -35,7 +35,7 @@ bool CGameInfo::SaveGameInfo(TString Path /*= ""*/)
|
||||||
void CGameInfo::Serialize(IArchive& rArc)
|
void CGameInfo::Serialize(IArchive& rArc)
|
||||||
{
|
{
|
||||||
// Validate game
|
// Validate game
|
||||||
if (rArc.IsReader() && mGame != eUnknownGame)
|
if (rArc.IsReader() && mGame != EGame::Invalid)
|
||||||
{
|
{
|
||||||
ASSERT(mGame == rArc.Game());
|
ASSERT(mGame == rArc.Game());
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ void CGameInfo::Serialize(IArchive& rArc)
|
||||||
// Serialize data
|
// Serialize data
|
||||||
rArc << SerialParameter("GameBuilds", mBuilds);
|
rArc << SerialParameter("GameBuilds", mBuilds);
|
||||||
|
|
||||||
if (mGame <= ePrime)
|
if (mGame <= EGame::Prime)
|
||||||
rArc << SerialParameter("AreaNameMap", mAreaNameMap);
|
rArc << SerialParameter("AreaNameMap", mAreaNameMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,9 +69,9 @@ TString CGameInfo::GetAreaName(const CAssetID &rkID) const
|
||||||
// ************ STATIC ************
|
// ************ STATIC ************
|
||||||
EGame CGameInfo::RoundGame(EGame Game)
|
EGame CGameInfo::RoundGame(EGame Game)
|
||||||
{
|
{
|
||||||
if (Game == ePrimeDemo) return ePrime;
|
if (Game == EGame::PrimeDemo) return EGame::Prime;
|
||||||
if (Game == eEchoesDemo) return eEchoes;
|
if (Game == EGame::EchoesDemo) return EGame::Echoes;
|
||||||
if (Game == eCorruptionProto) return eCorruption;
|
if (Game == EGame::CorruptionProto) return EGame::Corruption;
|
||||||
return Game;
|
return Game;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ TString CGameInfo::GetDefaultGameInfoPath(EGame Game)
|
||||||
{
|
{
|
||||||
Game = RoundGame(Game);
|
Game = RoundGame(Game);
|
||||||
|
|
||||||
if (Game == eUnknownGame)
|
if (Game == EGame::Invalid)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
TString GameName = GetGameShortName(Game);
|
TString GameName = GetGameShortName(Game);
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
const TString gkGameInfoDir = "../resources/gameinfo";
|
const TString gkGameInfoDir = "../resources/gameinfo";
|
||||||
const TString gkGameInfoExt = "xml";
|
const TString gkGameInfoExt = "xml";
|
||||||
|
|
||||||
|
//@todo merge this class into CGameTemplate
|
||||||
|
// they serve similar purposes, no real reason for them to be different classes
|
||||||
class CGameInfo
|
class CGameInfo
|
||||||
{
|
{
|
||||||
EGame mGame;
|
EGame mGame;
|
||||||
|
@ -36,7 +38,7 @@ class CGameInfo
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CGameInfo()
|
CGameInfo()
|
||||||
: mGame(eUnknownGame)
|
: mGame(EGame::Invalid)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool LoadGameInfo(EGame Game);
|
bool LoadGameInfo(EGame Game);
|
||||||
|
|
|
@ -45,7 +45,7 @@ class CGameProject
|
||||||
// Private Constructor
|
// Private Constructor
|
||||||
CGameProject()
|
CGameProject()
|
||||||
: mProjectName("Unnamed Project")
|
: mProjectName("Unnamed Project")
|
||||||
, mGame(eUnknownGame)
|
, mGame(EGame::Invalid)
|
||||||
, mRegion(ERegion::Unknown)
|
, mRegion(ERegion::Unknown)
|
||||||
, mGameID("000000")
|
, mGameID("000000")
|
||||||
, mBuildVersion(0.f)
|
, mBuildVersion(0.f)
|
||||||
|
@ -103,8 +103,8 @@ public:
|
||||||
inline TString GameID() const { return mGameID; }
|
inline TString GameID() const { return mGameID; }
|
||||||
inline float BuildVersion() const { return mBuildVersion; }
|
inline float BuildVersion() const { return mBuildVersion; }
|
||||||
inline bool IsWiiBuild() const { return mBuildVersion >= 3.f; }
|
inline bool IsWiiBuild() const { return mBuildVersion >= 3.f; }
|
||||||
inline bool IsTrilogy() const { return mGame <= eCorruption && mBuildVersion >= 3.593f; }
|
inline bool IsTrilogy() const { return mGame <= EGame::Corruption && mBuildVersion >= 3.593f; }
|
||||||
inline bool IsWiiDeAsobu() const { return mGame <= eCorruption && mBuildVersion >= 3.570f && mBuildVersion < 3.593f; }
|
inline bool IsWiiDeAsobu() const { return mGame <= EGame::Corruption && mBuildVersion >= 3.570f && mBuildVersion < 3.593f; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CGAMEPROJECT_H
|
#endif // CGAMEPROJECT_H
|
||||||
|
|
|
@ -29,7 +29,7 @@ bool CPackage::Save()
|
||||||
TString DefPath = DefinitionPath(false);
|
TString DefPath = DefinitionPath(false);
|
||||||
FileUtil::MakeDirectory(DefPath.GetFileDirectory());
|
FileUtil::MakeDirectory(DefPath.GetFileDirectory());
|
||||||
|
|
||||||
CXMLWriter Writer(DefPath, "PackageDefinition", 0, mpProject ? mpProject->Game() : eUnknownGame);
|
CXMLWriter Writer(DefPath, "PackageDefinition", 0, mpProject ? mpProject->Game() : EGame::Invalid);
|
||||||
Serialize(Writer);
|
Serialize(Writer);
|
||||||
return Writer.Save();
|
return Writer.Save();
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ void CPackage::Cook(IProgressNotifier *pProgress)
|
||||||
}
|
}
|
||||||
|
|
||||||
EGame Game = mpProject->Game();
|
EGame Game = mpProject->Game();
|
||||||
u32 Alignment = (Game <= eCorruptionProto ? 0x20 : 0x40);
|
u32 Alignment = (Game <= EGame::CorruptionProto ? 0x20 : 0x40);
|
||||||
u32 AlignmentMinusOne = Alignment - 1;
|
u32 AlignmentMinusOne = Alignment - 1;
|
||||||
|
|
||||||
u32 TocOffset = 0;
|
u32 TocOffset = 0;
|
||||||
|
@ -92,7 +92,7 @@ void CPackage::Cook(IProgressNotifier *pProgress)
|
||||||
u32 ResDataSize = 0;
|
u32 ResDataSize = 0;
|
||||||
|
|
||||||
// Write MP1 pak header
|
// Write MP1 pak header
|
||||||
if (Game <= eCorruptionProto)
|
if (Game <= EGame::CorruptionProto)
|
||||||
{
|
{
|
||||||
Pak.WriteLong(0x00030005); // Major/Minor Version
|
Pak.WriteLong(0x00030005); // Major/Minor Version
|
||||||
Pak.WriteLong(0); // Unknown
|
Pak.WriteLong(0); // Unknown
|
||||||
|
@ -188,7 +188,7 @@ void CPackage::Cook(IProgressNotifier *pProgress)
|
||||||
// Update table info
|
// Update table info
|
||||||
SResourceTableInfo& rTableInfo = ResourceTableData[ResIdx];
|
SResourceTableInfo& rTableInfo = ResourceTableData[ResIdx];
|
||||||
rTableInfo.pEntry = pEntry;
|
rTableInfo.pEntry = pEntry;
|
||||||
rTableInfo.Offset = (Game <= eEchoes ? AssetOffset : AssetOffset - ResDataOffset);
|
rTableInfo.Offset = (Game <= EGame::Echoes ? AssetOffset : AssetOffset - ResDataOffset);
|
||||||
|
|
||||||
// Load resource data
|
// Load resource data
|
||||||
CFileInStream CookedAsset(pEntry->CookedAssetPath(), IOUtil::eBigEndian);
|
CFileInStream CookedAsset(pEntry->CookedAssetPath(), IOUtil::eBigEndian);
|
||||||
|
@ -201,12 +201,12 @@ void CPackage::Cook(IProgressNotifier *pProgress)
|
||||||
// Check if this asset should be compressed; there are a few resource types that are
|
// Check if this asset should be compressed; there are a few resource types that are
|
||||||
// always compressed, and some types that are compressed if they're over a certain size
|
// always compressed, and some types that are compressed if they're over a certain size
|
||||||
EResType Type = pEntry->ResourceType();
|
EResType Type = pEntry->ResourceType();
|
||||||
u32 CompressThreshold = (Game <= eCorruptionProto ? 0x400 : 0x80);
|
u32 CompressThreshold = (Game <= EGame::CorruptionProto ? 0x400 : 0x80);
|
||||||
|
|
||||||
bool ShouldAlwaysCompress = (Type == eTexture || Type == eModel || Type == eSkin ||
|
bool ShouldAlwaysCompress = (Type == eTexture || Type == eModel || Type == eSkin ||
|
||||||
Type == eAnimSet || Type == eAnimation || Type == eFont);
|
Type == eAnimSet || Type == eAnimation || Type == eFont);
|
||||||
|
|
||||||
if (Game >= eCorruption)
|
if (Game >= EGame::Corruption)
|
||||||
{
|
{
|
||||||
ShouldAlwaysCompress = ShouldAlwaysCompress ||
|
ShouldAlwaysCompress = ShouldAlwaysCompress ||
|
||||||
(Type == eCharacter || Type == eSourceAnimData || Type == eScan ||
|
(Type == eCharacter || Type == eSourceAnimData || Type == eScan ||
|
||||||
|
@ -234,7 +234,7 @@ void CPackage::Cook(IProgressNotifier *pProgress)
|
||||||
std::vector<u8> CompressedData(ResourceData.size() * 2);
|
std::vector<u8> CompressedData(ResourceData.size() * 2);
|
||||||
bool Success = false;
|
bool Success = false;
|
||||||
|
|
||||||
if (Game <= eEchoesDemo || Game == eReturns)
|
if (Game <= EGame::EchoesDemo || Game == EGame::DKCReturns)
|
||||||
Success = CompressionUtil::CompressZlib(ResourceData.data(), ResourceData.size(), CompressedData.data(), CompressedData.size(), CompressedSize);
|
Success = CompressionUtil::CompressZlib(ResourceData.data(), ResourceData.size(), CompressedData.data(), CompressedData.size(), CompressedSize);
|
||||||
else
|
else
|
||||||
Success = CompressionUtil::CompressLZOSegmented(ResourceData.data(), ResourceData.size(), CompressedData.data(), CompressedSize, false);
|
Success = CompressionUtil::CompressLZOSegmented(ResourceData.data(), ResourceData.size(), CompressedData.data(), CompressedSize, false);
|
||||||
|
@ -242,7 +242,7 @@ void CPackage::Cook(IProgressNotifier *pProgress)
|
||||||
// Make sure that the compressed data is actually smaller, accounting for padding + uncompressed size value
|
// Make sure that the compressed data is actually smaller, accounting for padding + uncompressed size value
|
||||||
if (Success)
|
if (Success)
|
||||||
{
|
{
|
||||||
u32 CompressionHeaderSize = (Game <= eCorruptionProto ? 4 : 0x10);
|
u32 CompressionHeaderSize = (Game <= EGame::CorruptionProto ? 4 : 0x10);
|
||||||
u32 PaddedUncompressedSize = (ResourceSize + AlignmentMinusOne) & ~AlignmentMinusOne;
|
u32 PaddedUncompressedSize = (ResourceSize + AlignmentMinusOne) & ~AlignmentMinusOne;
|
||||||
u32 PaddedCompressedSize = (CompressedSize + CompressionHeaderSize + AlignmentMinusOne) & ~AlignmentMinusOne;
|
u32 PaddedCompressedSize = (CompressedSize + CompressionHeaderSize + AlignmentMinusOne) & ~AlignmentMinusOne;
|
||||||
Success = (PaddedCompressedSize < PaddedUncompressedSize);
|
Success = (PaddedCompressedSize < PaddedUncompressedSize);
|
||||||
|
@ -252,7 +252,7 @@ void CPackage::Cook(IProgressNotifier *pProgress)
|
||||||
if (Success)
|
if (Success)
|
||||||
{
|
{
|
||||||
// Write MP1/2 compressed asset
|
// Write MP1/2 compressed asset
|
||||||
if (Game <= eCorruptionProto)
|
if (Game <= EGame::CorruptionProto)
|
||||||
{
|
{
|
||||||
Pak.WriteLong(ResourceSize);
|
Pak.WriteLong(ResourceSize);
|
||||||
}
|
}
|
||||||
|
@ -292,7 +292,7 @@ void CPackage::Cook(IProgressNotifier *pProgress)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Write table of contents for real
|
// Write table of contents for real
|
||||||
if (Game >= eCorruption)
|
if (Game >= EGame::Corruption)
|
||||||
{
|
{
|
||||||
Pak.Seek(TocOffset, SEEK_SET);
|
Pak.Seek(TocOffset, SEEK_SET);
|
||||||
Pak.WriteLong(3); // Always 3 pak sections
|
Pak.WriteLong(3); // Always 3 pak sections
|
||||||
|
|
|
@ -618,7 +618,7 @@ CGameProject* CResourceEntry::Project() const
|
||||||
|
|
||||||
EGame CResourceEntry::Game() const
|
EGame CResourceEntry::Game() const
|
||||||
{
|
{
|
||||||
return mpStore ? mpStore->Game() : eUnknownGame;
|
return mpStore ? mpStore->Game() : EGame::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CResourceEntry::SetFlag(EResEntryFlag Flag)
|
void CResourceEntry::SetFlag(EResEntryFlag Flag)
|
||||||
|
|
|
@ -18,7 +18,7 @@ CResourceStore *gpEditorStore = nullptr;
|
||||||
// Constructor for editor store
|
// Constructor for editor store
|
||||||
CResourceStore::CResourceStore(const TString& rkDatabasePath)
|
CResourceStore::CResourceStore(const TString& rkDatabasePath)
|
||||||
: mpProj(nullptr)
|
: mpProj(nullptr)
|
||||||
, mGame(ePrime)
|
, mGame(EGame::Prime)
|
||||||
, mDatabaseCacheDirty(false)
|
, mDatabaseCacheDirty(false)
|
||||||
{
|
{
|
||||||
mpDatabaseRoot = new CVirtualDirectory(this);
|
mpDatabaseRoot = new CVirtualDirectory(this);
|
||||||
|
@ -29,7 +29,7 @@ CResourceStore::CResourceStore(const TString& rkDatabasePath)
|
||||||
// Main constructor for game projects and game exporter
|
// Main constructor for game projects and game exporter
|
||||||
CResourceStore::CResourceStore(CGameProject *pProject)
|
CResourceStore::CResourceStore(CGameProject *pProject)
|
||||||
: mpProj(nullptr)
|
: mpProj(nullptr)
|
||||||
, mGame(eUnknownGame)
|
, mGame(EGame::Invalid)
|
||||||
, mpDatabaseRoot(nullptr)
|
, mpDatabaseRoot(nullptr)
|
||||||
, mDatabaseCacheDirty(false)
|
, mDatabaseCacheDirty(false)
|
||||||
{
|
{
|
||||||
|
@ -218,7 +218,7 @@ void CResourceStore::CloseProject()
|
||||||
delete mpDatabaseRoot;
|
delete mpDatabaseRoot;
|
||||||
mpDatabaseRoot = nullptr;
|
mpDatabaseRoot = nullptr;
|
||||||
mpProj = nullptr;
|
mpProj = nullptr;
|
||||||
mGame = eUnknownGame;
|
mGame = EGame::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
CVirtualDirectory* CResourceStore::GetVirtualDirectory(const TString& rkPath, bool AllowCreate)
|
CVirtualDirectory* CResourceStore::GetVirtualDirectory(const TString& rkPath, bool AllowCreate)
|
||||||
|
@ -622,5 +622,5 @@ bool CResourceStore::IsValidResourcePath(const TString& rkPath, const TString& r
|
||||||
|
|
||||||
TString CResourceStore::StaticDefaultResourceDirPath(EGame Game)
|
TString CResourceStore::StaticDefaultResourceDirPath(EGame Game)
|
||||||
{
|
{
|
||||||
return (Game < eCorruptionProto ? "Uncategorized/" : "uncategorized/");
|
return (Game < EGame::CorruptionProto ? "Uncategorized/" : "uncategorized/");
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// ************ CCharacterUsageMap ************
|
// ************ CCharacterUsageMap ************
|
||||||
bool CCharacterUsageMap::IsCharacterUsed(const CAssetID& rkID, u32 CharacterIndex) const
|
bool CCharacterUsageMap::IsCharacterUsed(const CAssetID& rkID, u32 CharacterIndex) const
|
||||||
{
|
{
|
||||||
if (mpStore->Game() >= eCorruptionProto) return true;
|
if (mpStore->Game() >= EGame::CorruptionProto) return true;
|
||||||
auto Find = mUsageMap.find(rkID);
|
auto Find = mUsageMap.find(rkID);
|
||||||
if (Find == mUsageMap.end()) return false;
|
if (Find == mUsageMap.end()) return false;
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ void CPackageDependencyListBuilder::AddDependency(CResourceEntry *pCurEntry, con
|
||||||
|
|
||||||
// Is this entry valid?
|
// Is this entry valid?
|
||||||
bool IsValid = ResType != eMidi &&
|
bool IsValid = ResType != eMidi &&
|
||||||
(ResType != eAudioGroup || mGame >= eEchoesDemo) &&
|
(ResType != eAudioGroup || mGame >= EGame::EchoesDemo) &&
|
||||||
(ResType != eWorld || !pCurEntry) &&
|
(ResType != eWorld || !pCurEntry) &&
|
||||||
(ResType != eArea || !pCurEntry || pCurEntry->ResourceType() == eWorld);
|
(ResType != eArea || !pCurEntry || pCurEntry->ResourceType() == eWorld);
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ void CPackageDependencyListBuilder::AddDependency(CResourceEntry *pCurEntry, con
|
||||||
// New area - toggle duplicates and find character usages
|
// New area - toggle duplicates and find character usages
|
||||||
if (ResType == eArea)
|
if (ResType == eArea)
|
||||||
{
|
{
|
||||||
if (mGame <= eEchoes)
|
if (mGame <= EGame::Echoes)
|
||||||
mCharacterUsageMap.FindUsagesForArea(mpWorld, pEntry);
|
mCharacterUsageMap.FindUsagesForArea(mpWorld, pEntry);
|
||||||
|
|
||||||
mAreaUsedAssets.clear();
|
mAreaUsedAssets.clear();
|
||||||
|
@ -417,7 +417,7 @@ void CAreaDependencyListBuilder::BuildDependencyList(std::list<CAssetID>& rAsset
|
||||||
CPropertyDependency *pDep = static_cast<CPropertyDependency*>(pInst->ChildByIndex(iDep));
|
CPropertyDependency *pDep = static_cast<CPropertyDependency*>(pInst->ChildByIndex(iDep));
|
||||||
|
|
||||||
// For MP3, exclude the CMDL/CSKR properties for the suit assets - only include default character assets
|
// For MP3, exclude the CMDL/CSKR properties for the suit assets - only include default character assets
|
||||||
if (mGame == eCorruption && mIsPlayerActor)
|
if (mGame == EGame::Corruption && mIsPlayerActor)
|
||||||
{
|
{
|
||||||
TString PropID = pDep->PropertyID();
|
TString PropID = pDep->PropertyID();
|
||||||
|
|
||||||
|
@ -467,7 +467,7 @@ void CAreaDependencyListBuilder::AddDependency(const CAssetID& rkID, std::list<C
|
||||||
EResType ResType = pEntry->ResourceType();
|
EResType ResType = pEntry->ResourceType();
|
||||||
|
|
||||||
// If this is an audio group, for MP1, save it in the output set. For MP2, treat audio groups as a normal dependency.
|
// If this is an audio group, for MP1, save it in the output set. For MP2, treat audio groups as a normal dependency.
|
||||||
if (mGame <= ePrime && ResType == eAudioGroup)
|
if (mGame <= EGame::Prime && ResType == eAudioGroup)
|
||||||
{
|
{
|
||||||
if (pAudioGroupsOut)
|
if (pAudioGroupsOut)
|
||||||
pAudioGroupsOut->insert(rkID);
|
pAudioGroupsOut->insert(rkID);
|
||||||
|
@ -534,7 +534,7 @@ void CAreaDependencyListBuilder::EvaluateDependencyNode(CResourceEntry *pCurEntr
|
||||||
else if (Type == eDNT_SetCharacter)
|
else if (Type == eDNT_SetCharacter)
|
||||||
{
|
{
|
||||||
// Note: For MP1/2 PlayerActor, always treat as if Empty Suit is the only used one
|
// Note: For MP1/2 PlayerActor, always treat as if Empty Suit is the only used one
|
||||||
const u32 kEmptySuitIndex = (mGame >= eEchoesDemo ? 3 : 5);
|
const u32 kEmptySuitIndex = (mGame >= EGame::EchoesDemo ? 3 : 5);
|
||||||
|
|
||||||
CSetCharacterDependency *pChar = static_cast<CSetCharacterDependency*>(pNode);
|
CSetCharacterDependency *pChar = static_cast<CSetCharacterDependency*>(pNode);
|
||||||
u32 SetIndex = pChar->CharSetIndex();
|
u32 SetIndex = pChar->CharSetIndex();
|
||||||
|
|
|
@ -481,7 +481,7 @@ bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
|
||||||
|
|
||||||
if (rkMat.Options() & CMaterial::ePunchthrough)
|
if (rkMat.Options() & CMaterial::ePunchthrough)
|
||||||
{
|
{
|
||||||
if (rkMat.Version() < eCorruptionProto)
|
if (rkMat.Version() < EGame::CorruptionProto)
|
||||||
{
|
{
|
||||||
ShaderCode << " if (Prev.a <= 0.25) discard;\n"
|
ShaderCode << " if (Prev.a <= 0.25) discard;\n"
|
||||||
<< " else Prev.a = 1.0;\n\n";
|
<< " else Prev.a = 1.0;\n\n";
|
||||||
|
|
|
@ -141,7 +141,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Animation dependencies
|
// Animation dependencies
|
||||||
if (Game() <= eEchoes)
|
if (Game() <= EGame::Echoes)
|
||||||
{
|
{
|
||||||
for (u32 iAnim = 0; iAnim < mAnimations.size(); iAnim++)
|
for (u32 iAnim = 0; iAnim < mAnimations.size(); iAnim++)
|
||||||
{
|
{
|
||||||
|
@ -151,7 +151,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Game() <= eCorruption)
|
else if (Game() <= EGame::Corruption)
|
||||||
{
|
{
|
||||||
const SSetCharacter& rkChar = mCharacters[0];
|
const SSetCharacter& rkChar = mCharacters[0];
|
||||||
std::set<CAnimPrimitive> PrimitiveSet;
|
std::set<CAnimPrimitive> PrimitiveSet;
|
||||||
|
@ -228,7 +228,7 @@ public:
|
||||||
{
|
{
|
||||||
ASSERT(Index >= 0 && Index < NumAnimations());
|
ASSERT(Index >= 0 && Index < NumAnimations());
|
||||||
|
|
||||||
if (Game() <= ePrime)
|
if (Game() <= EGame::Prime)
|
||||||
{
|
{
|
||||||
const CAnimPrimitive& rkPrim = mAnimPrimitives[Index];
|
const CAnimPrimitive& rkPrim = mAnimPrimitives[Index];
|
||||||
return rkPrim.Animation() ? rkPrim.Animation()->EventData() : nullptr;
|
return rkPrim.Animation() ? rkPrim.Animation()->EventData() : nullptr;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
CAnimationParameters::CAnimationParameters()
|
CAnimationParameters::CAnimationParameters()
|
||||||
: mGame(ePrime)
|
: mGame(EGame::Prime)
|
||||||
, mCharIndex(0)
|
, mCharIndex(0)
|
||||||
, mAnimIndex(0)
|
, mAnimIndex(0)
|
||||||
, mUnknown2(0)
|
, mUnknown2(0)
|
||||||
|
@ -30,20 +30,20 @@ CAnimationParameters::CAnimationParameters(IInputStream& rSCLY, EGame Game)
|
||||||
, mUnknown2(0)
|
, mUnknown2(0)
|
||||||
, mUnknown3(0)
|
, mUnknown3(0)
|
||||||
{
|
{
|
||||||
if (Game <= eEchoes)
|
if (Game <= EGame::Echoes)
|
||||||
{
|
{
|
||||||
mCharacterID = CAssetID(rSCLY, Game);
|
mCharacterID = CAssetID(rSCLY, Game);
|
||||||
mCharIndex = rSCLY.ReadLong();
|
mCharIndex = rSCLY.ReadLong();
|
||||||
mAnimIndex = rSCLY.ReadLong();
|
mAnimIndex = rSCLY.ReadLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Game <= eCorruption)
|
else if (Game <= EGame::Corruption)
|
||||||
{
|
{
|
||||||
mCharacterID = CAssetID(rSCLY, Game);
|
mCharacterID = CAssetID(rSCLY, Game);
|
||||||
mAnimIndex = rSCLY.ReadLong();
|
mAnimIndex = rSCLY.ReadLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Game == eReturns)
|
else if (Game == EGame::DKCReturns)
|
||||||
{
|
{
|
||||||
u8 Flags = rSCLY.ReadByte();
|
u8 Flags = rSCLY.ReadByte();
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ CAnimationParameters::CAnimationParameters(IInputStream& rSCLY, EGame Game)
|
||||||
|
|
||||||
void CAnimationParameters::Write(IOutputStream& rSCLY)
|
void CAnimationParameters::Write(IOutputStream& rSCLY)
|
||||||
{
|
{
|
||||||
if (mGame <= eEchoes)
|
if (mGame <= EGame::Echoes)
|
||||||
{
|
{
|
||||||
if (mCharacterID.IsValid())
|
if (mCharacterID.IsValid())
|
||||||
{
|
{
|
||||||
|
@ -96,7 +96,7 @@ void CAnimationParameters::Write(IOutputStream& rSCLY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (mGame <= eCorruption)
|
else if (mGame <= EGame::Corruption)
|
||||||
{
|
{
|
||||||
if (mCharacterID.IsValid())
|
if (mCharacterID.IsValid())
|
||||||
{
|
{
|
||||||
|
@ -144,12 +144,12 @@ void CAnimationParameters::Serialize(IArchive& rArc)
|
||||||
|
|
||||||
rArc << SerialParameter("AnimationSetAsset", mCharacterID);
|
rArc << SerialParameter("AnimationSetAsset", mCharacterID);
|
||||||
|
|
||||||
if (mGame <= eEchoes)
|
if (mGame <= EGame::Echoes)
|
||||||
rArc << SerialParameter("CharacterID", mCharIndex);
|
rArc << SerialParameter("CharacterID", mCharIndex);
|
||||||
|
|
||||||
rArc << SerialParameter("AnimationID", mAnimIndex);
|
rArc << SerialParameter("AnimationID", mAnimIndex);
|
||||||
|
|
||||||
if (mGame >= eReturns)
|
if (mGame >= EGame::DKCReturns)
|
||||||
{
|
{
|
||||||
rArc << SerialParameter("Unknown0", mUnknown2)
|
rArc << SerialParameter("Unknown0", mUnknown2)
|
||||||
<< SerialParameter("Unknown1", mUnknown3);
|
<< SerialParameter("Unknown1", mUnknown3);
|
||||||
|
|
|
@ -56,7 +56,7 @@ CMetaTransTrans::CMetaTransTrans(EMetaTransitionType Type, IInputStream& rInput,
|
||||||
ASSERT(Type == eMTT_Trans || Type == eMTT_PhaseTrans);
|
ASSERT(Type == eMTT_Trans || Type == eMTT_PhaseTrans);
|
||||||
mType = Type;
|
mType = Type;
|
||||||
|
|
||||||
if (Game <= eEchoes)
|
if (Game <= EGame::Echoes)
|
||||||
{
|
{
|
||||||
mUnknownA = rInput.ReadFloat();
|
mUnknownA = rInput.ReadFloat();
|
||||||
mUnknownB = rInput.ReadLong();
|
mUnknownB = rInput.ReadLong();
|
||||||
|
|
|
@ -42,7 +42,7 @@ CDependencyTree* CGameArea::BuildDependencyTree() const
|
||||||
|
|
||||||
pTree->AddDependency(mPathID);
|
pTree->AddDependency(mPathID);
|
||||||
|
|
||||||
if (Game() >= eEchoesDemo)
|
if (Game() >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
pTree->AddDependency(mPortalAreaID);
|
pTree->AddDependency(mPortalAreaID);
|
||||||
pTree->AddDependency(mpPoiToWorldMap);
|
pTree->AddDependency(mpPoiToWorldMap);
|
||||||
|
@ -224,7 +224,7 @@ CScriptObject* CGameArea::SpawnInstance(CScriptTemplate *pTemplate,
|
||||||
pInstance->SetRotation(rkRotation.ToEuler());
|
pInstance->SetRotation(rkRotation.ToEuler());
|
||||||
pInstance->SetScale(rkScale);
|
pInstance->SetScale(rkScale);
|
||||||
pInstance->SetName(pTemplate->Name());
|
pInstance->SetName(pTemplate->Name());
|
||||||
if (pTemplate->Game() < eEchoesDemo) pInstance->SetActive(true);
|
if (pTemplate->Game() < EGame::EchoesDemo) pInstance->SetActive(true);
|
||||||
pLayer->AddInstance(pInstance, SuggestedLayerIndex);
|
pLayer->AddInstance(pInstance, SuggestedLayerIndex);
|
||||||
mObjectMap[InstanceID] = pInstance;
|
mObjectMap[InstanceID] = pInstance;
|
||||||
return pInstance;
|
return pInstance;
|
||||||
|
|
|
@ -21,7 +21,7 @@ ECollisionFlag CCollisionMaterial::SurfaceType(EGame Game) const
|
||||||
const ECollisionFlag* pkFlagArray;
|
const ECollisionFlag* pkFlagArray;
|
||||||
u32 Num;
|
u32 Num;
|
||||||
|
|
||||||
if (Game <= ePrime)
|
if (Game <= EGame::Prime)
|
||||||
{
|
{
|
||||||
pkFlagArray = skPrimeTypeHierarchy;
|
pkFlagArray = skPrimeTypeHierarchy;
|
||||||
Num = sizeof(skPrimeTypeHierarchy) / sizeof(ECollisionFlag);
|
Num = sizeof(skPrimeTypeHierarchy) / sizeof(ECollisionFlag);
|
||||||
|
@ -79,5 +79,5 @@ bool CCollisionMaterial::IsFloor() const
|
||||||
|
|
||||||
bool CCollisionMaterial::IsUnstandable(EGame Game) const
|
bool CCollisionMaterial::IsUnstandable(EGame Game) const
|
||||||
{
|
{
|
||||||
return HasFlag(eCF_JumpNotAllowed) || (Game >= eCorruptionProto && !HasFlag(eCF_Floor) && HasAnyFlags(eCF_Wall | eCF_Ceiling));
|
return HasFlag(eCF_JumpNotAllowed) || (Game >= EGame::CorruptionProto && !HasFlag(eCF_Floor) && HasAnyFlags(eCF_Wall | eCF_Ceiling));
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,7 @@ CStructProperty* CLight::GetProperties() const
|
||||||
if (!pProperties)
|
if (!pProperties)
|
||||||
{
|
{
|
||||||
pProperties = (CStructProperty*) IProperty::CreateIntrinsic(EPropertyType::Struct,
|
pProperties = (CStructProperty*) IProperty::CreateIntrinsic(EPropertyType::Struct,
|
||||||
ePrime,
|
EGame::Prime,
|
||||||
0,
|
0,
|
||||||
"Light");
|
"Light");
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ CMaterial::CMaterial()
|
||||||
, mShaderStatus(eNoShader)
|
, mShaderStatus(eNoShader)
|
||||||
, mRecalcHash(true)
|
, mRecalcHash(true)
|
||||||
, mEnableBloom(false)
|
, mEnableBloom(false)
|
||||||
, mVersion(eUnknownGame)
|
, mVersion(EGame::Invalid)
|
||||||
, mOptions(eNoSettings)
|
, mOptions(eNoSettings)
|
||||||
, mVtxDesc(eNoAttributes)
|
, mVtxDesc(eNoAttributes)
|
||||||
, mBlendSrcFac(GL_ONE)
|
, mBlendSrcFac(GL_ONE)
|
||||||
|
@ -34,7 +34,7 @@ CMaterial::CMaterial(EGame Version, FVertexDescription VtxDesc)
|
||||||
: mpShader(nullptr)
|
: mpShader(nullptr)
|
||||||
, mShaderStatus(eNoShader)
|
, mShaderStatus(eNoShader)
|
||||||
, mRecalcHash(true)
|
, mRecalcHash(true)
|
||||||
, mEnableBloom(Version == eCorruption)
|
, mEnableBloom(Version == EGame::Corruption)
|
||||||
, mVersion(Version)
|
, mVersion(Version)
|
||||||
, mOptions(eDepthWrite)
|
, mOptions(eDepthWrite)
|
||||||
, mVtxDesc(VtxDesc)
|
, mVtxDesc(VtxDesc)
|
||||||
|
@ -48,7 +48,7 @@ CMaterial::CMaterial(EGame Version, FVertexDescription VtxDesc)
|
||||||
mpShader = nullptr;
|
mpShader = nullptr;
|
||||||
mShaderStatus = eNoShader;
|
mShaderStatus = eNoShader;
|
||||||
mRecalcHash = true;
|
mRecalcHash = true;
|
||||||
mEnableBloom = (Version == eCorruption);
|
mEnableBloom = (Version == EGame::Corruption);
|
||||||
mVersion = Version;
|
mVersion = Version;
|
||||||
mOptions = eDepthWrite;
|
mOptions = eDepthWrite;
|
||||||
mVtxDesc = VtxDesc;
|
mVtxDesc = VtxDesc;
|
||||||
|
@ -245,7 +245,7 @@ u64 CMaterial::HashParameters()
|
||||||
{
|
{
|
||||||
CFNV1A Hash(CFNV1A::e64Bit);
|
CFNV1A Hash(CFNV1A::e64Bit);
|
||||||
|
|
||||||
Hash.HashLong(mVersion);
|
Hash.HashLong((int) mVersion);
|
||||||
Hash.HashLong(mOptions);
|
Hash.HashLong(mOptions);
|
||||||
Hash.HashLong(mVtxDesc);
|
Hash.HashLong(mVtxDesc);
|
||||||
Hash.HashData(mKonstColors, sizeof(CColor) * 4);
|
Hash.HashData(mKonstColors, sizeof(CColor) * 4);
|
||||||
|
|
|
@ -11,7 +11,7 @@ class CResTypeFilter
|
||||||
std::set<EResType> mAcceptedTypes;
|
std::set<EResType> mAcceptedTypes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CResTypeFilter() { }
|
CResTypeFilter() : mGame(EGame::Invalid) { }
|
||||||
CResTypeFilter(EGame Game, const TString& rkTypeList) { FromString(Game, rkTypeList); }
|
CResTypeFilter(EGame Game, const TString& rkTypeList) { FromString(Game, rkTypeList); }
|
||||||
|
|
||||||
void SetAcceptedTypes(EGame Game, const TStringList& rkTypes)
|
void SetAcceptedTypes(EGame Game, const TStringList& rkTypes)
|
||||||
|
|
|
@ -36,8 +36,8 @@ bool CResTypeInfo::IsInGame(EGame Game) const
|
||||||
CFourCC CResTypeInfo::CookedExtension(EGame Game) const
|
CFourCC CResTypeInfo::CookedExtension(EGame Game) const
|
||||||
{
|
{
|
||||||
// Default to MP1
|
// Default to MP1
|
||||||
if (Game == eUnknownGame)
|
if (Game == EGame::Invalid)
|
||||||
Game = ePrime;
|
Game = EGame::Prime;
|
||||||
|
|
||||||
for (u32 iGame = 0; iGame < mCookedExtensions.size(); iGame++)
|
for (u32 iGame = 0; iGame < mCookedExtensions.size(); iGame++)
|
||||||
{
|
{
|
||||||
|
@ -64,7 +64,7 @@ CResTypeInfo* CResTypeInfo::TypeForCookedExtension(EGame Game, CFourCC Ext)
|
||||||
{
|
{
|
||||||
// Extensions can vary between games, but we're not likely to be calling this function for different games very often.
|
// Extensions can vary between games, but we're not likely to be calling this function for different games very often.
|
||||||
// So, to speed things up a little, cache the lookup results in a map.
|
// So, to speed things up a little, cache the lookup results in a map.
|
||||||
static EGame sCachedGame = eUnknownGame;
|
static EGame sCachedGame = EGame::Invalid;
|
||||||
static std::map<CFourCC, CResTypeInfo*> sCachedTypeMap;
|
static std::map<CFourCC, CResTypeInfo*> sCachedTypeMap;
|
||||||
Ext = Ext.ToUpper();
|
Ext = Ext.ToUpper();
|
||||||
|
|
||||||
|
@ -154,16 +154,16 @@ CResTypeInfo::CResTypeInfoFactory::CResTypeInfoFactory()
|
||||||
|
|
||||||
void CResTypeInfo::CResTypeInfoFactory::AddExtension(CResTypeInfo *pType, CFourCC Ext, EGame FirstGame, EGame LastGame)
|
void CResTypeInfo::CResTypeInfoFactory::AddExtension(CResTypeInfo *pType, CFourCC Ext, EGame FirstGame, EGame LastGame)
|
||||||
{
|
{
|
||||||
ASSERT(FirstGame >= ePrimeDemo && LastGame <= eReturns && FirstGame <= LastGame);
|
ASSERT(FirstGame >= EGame::PrimeDemo && LastGame <= EGame::DKCReturns && FirstGame <= LastGame);
|
||||||
ASSERT(FirstGame != eUnknownGame && LastGame != eUnknownGame);
|
ASSERT(FirstGame != EGame::Invalid && LastGame != EGame::Invalid);
|
||||||
|
|
||||||
for (int iGame = FirstGame; iGame <= LastGame; iGame++)
|
for (int GameIdx = (int) FirstGame; GameIdx <= (int) LastGame; GameIdx++)
|
||||||
{
|
{
|
||||||
#if !PUBLIC_RELEASE
|
#if !PUBLIC_RELEASE
|
||||||
ASSERT(!pType->IsInGame((EGame) iGame));
|
ASSERT(!pType->IsInGame((EGame) GameIdx));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CResTypeInfo::SGameExtension Info { (EGame) iGame, Ext };
|
CResTypeInfo::SGameExtension Info { (EGame) GameIdx, Ext };
|
||||||
pType->mCookedExtensions.push_back(Info);
|
pType->mCookedExtensions.push_back(Info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,235 +176,235 @@ void CResTypeInfo::CResTypeInfoFactory::InitTypes()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eAnimation, "Animation", "ani");
|
CResTypeInfo *pType = new CResTypeInfo(eAnimation, "Animation", "ani");
|
||||||
AddExtension(pType, "ANIM", ePrimeDemo, eReturns);
|
AddExtension(pType, "ANIM", EGame::PrimeDemo, EGame::DKCReturns);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eAnimCollisionPrimData, "Animation Collision Primitive Data", "?");
|
CResTypeInfo *pType = new CResTypeInfo(eAnimCollisionPrimData, "Animation Collision Primitive Data", "?");
|
||||||
AddExtension(pType, "CPRM", eReturns, eReturns);
|
AddExtension(pType, "CPRM", EGame::DKCReturns, EGame::DKCReturns);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eAnimEventData, "Animation Event Data", "evnt");
|
CResTypeInfo *pType = new CResTypeInfo(eAnimEventData, "Animation Event Data", "evnt");
|
||||||
AddExtension(pType, "EVNT", ePrimeDemo, ePrime);
|
AddExtension(pType, "EVNT", EGame::PrimeDemo, EGame::Prime);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eAnimSet, "Animation Character Set", "acs");
|
CResTypeInfo *pType = new CResTypeInfo(eAnimSet, "Animation Character Set", "acs");
|
||||||
AddExtension(pType, "ANCS", ePrimeDemo, eEchoes);
|
AddExtension(pType, "ANCS", EGame::PrimeDemo, EGame::Echoes);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eArea, "Area", "mrea");
|
CResTypeInfo *pType = new CResTypeInfo(eArea, "Area", "mrea");
|
||||||
AddExtension(pType, "MREA", ePrimeDemo, eReturns);
|
AddExtension(pType, "MREA", EGame::PrimeDemo, EGame::DKCReturns);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eAudioAmplitudeData, "Audio Amplitude Data", "?");
|
CResTypeInfo *pType = new CResTypeInfo(eAudioAmplitudeData, "Audio Amplitude Data", "?");
|
||||||
AddExtension(pType, "CAAD", eCorruption, eCorruption);
|
AddExtension(pType, "CAAD", EGame::Corruption, EGame::Corruption);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eAudioGroup, "Audio Group", "agsc");
|
CResTypeInfo *pType = new CResTypeInfo(eAudioGroup, "Audio Group", "agsc");
|
||||||
AddExtension(pType, "AGSC", ePrimeDemo, eEchoes);
|
AddExtension(pType, "AGSC", EGame::PrimeDemo, EGame::Echoes);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eAudioMacro, "Audio Macro", "caud");
|
CResTypeInfo *pType = new CResTypeInfo(eAudioMacro, "Audio Macro", "caud");
|
||||||
AddExtension(pType, "CAUD", eCorruptionProto, eReturns);
|
AddExtension(pType, "CAUD", EGame::CorruptionProto, EGame::DKCReturns);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eAudioSample, "Audio Sample", "csmp");
|
CResTypeInfo *pType = new CResTypeInfo(eAudioSample, "Audio Sample", "csmp");
|
||||||
AddExtension(pType, "CSMP", eCorruptionProto, eReturns);
|
AddExtension(pType, "CSMP", EGame::CorruptionProto, EGame::DKCReturns);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eAudioLookupTable, "Audio Lookup Table", "atbl");
|
CResTypeInfo *pType = new CResTypeInfo(eAudioLookupTable, "Audio Lookup Table", "atbl");
|
||||||
AddExtension(pType, "ATBL", ePrimeDemo, eCorruption);
|
AddExtension(pType, "ATBL", EGame::PrimeDemo, EGame::Corruption);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eBinaryData, "Generic Data", "dat");
|
CResTypeInfo *pType = new CResTypeInfo(eBinaryData, "Generic Data", "dat");
|
||||||
AddExtension(pType, "DUMB", ePrimeDemo, eCorruption);
|
AddExtension(pType, "DUMB", EGame::PrimeDemo, EGame::Corruption);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eBurstFireData, "Burst Fire Data", "bfre.bfrc");
|
CResTypeInfo *pType = new CResTypeInfo(eBurstFireData, "Burst Fire Data", "bfre.bfrc");
|
||||||
AddExtension(pType, "BFRC", eCorruptionProto, eCorruption);
|
AddExtension(pType, "BFRC", EGame::CorruptionProto, EGame::Corruption);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eCharacter, "Character", "char");
|
CResTypeInfo *pType = new CResTypeInfo(eCharacter, "Character", "char");
|
||||||
AddExtension(pType, "CHAR", eCorruptionProto, eReturns);
|
AddExtension(pType, "CHAR", EGame::CorruptionProto, EGame::DKCReturns);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eDependencyGroup, "Dependency Group", "?");
|
CResTypeInfo *pType = new CResTypeInfo(eDependencyGroup, "Dependency Group", "?");
|
||||||
AddExtension(pType, "DGRP", ePrimeDemo, eReturns);
|
AddExtension(pType, "DGRP", EGame::PrimeDemo, EGame::DKCReturns);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eDynamicCollision, "Dynamic Collision", "dcln");
|
CResTypeInfo *pType = new CResTypeInfo(eDynamicCollision, "Dynamic Collision", "dcln");
|
||||||
AddExtension(pType, "DCLN", ePrimeDemo, eReturns);
|
AddExtension(pType, "DCLN", EGame::PrimeDemo, EGame::DKCReturns);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eFont, "Font", "rpff");
|
CResTypeInfo *pType = new CResTypeInfo(eFont, "Font", "rpff");
|
||||||
AddExtension(pType, "FONT", ePrimeDemo, eReturns);
|
AddExtension(pType, "FONT", EGame::PrimeDemo, EGame::DKCReturns);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eGuiFrame, "Gui Frame", "frme");
|
CResTypeInfo *pType = new CResTypeInfo(eGuiFrame, "Gui Frame", "frme");
|
||||||
AddExtension(pType, "FRME", ePrimeDemo, eReturns);
|
AddExtension(pType, "FRME", EGame::PrimeDemo, EGame::DKCReturns);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eGuiKeyFrame, "Gui Keyframe", "?");
|
CResTypeInfo *pType = new CResTypeInfo(eGuiKeyFrame, "Gui Keyframe", "?");
|
||||||
AddExtension(pType, "KFAM", ePrimeDemo, ePrimeDemo);
|
AddExtension(pType, "KFAM", EGame::PrimeDemo, EGame::PrimeDemo);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eHintSystem, "Hint System Data", "hint");
|
CResTypeInfo *pType = new CResTypeInfo(eHintSystem, "Hint System Data", "hint");
|
||||||
AddExtension(pType, "HINT", ePrime, eCorruption);
|
AddExtension(pType, "HINT", EGame::Prime, EGame::Corruption);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eMapArea, "Area Map", "mapa");
|
CResTypeInfo *pType = new CResTypeInfo(eMapArea, "Area Map", "mapa");
|
||||||
AddExtension(pType, "MAPA", ePrimeDemo, eCorruption);
|
AddExtension(pType, "MAPA", EGame::PrimeDemo, EGame::Corruption);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eMapWorld, "World Map", "mapw");
|
CResTypeInfo *pType = new CResTypeInfo(eMapWorld, "World Map", "mapw");
|
||||||
AddExtension(pType, "MAPW", ePrimeDemo, eCorruption);
|
AddExtension(pType, "MAPW", EGame::PrimeDemo, EGame::Corruption);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eMapUniverse, "Universe Map", "mapu");
|
CResTypeInfo *pType = new CResTypeInfo(eMapUniverse, "Universe Map", "mapu");
|
||||||
AddExtension(pType, "MAPU", ePrimeDemo, eEchoes);
|
AddExtension(pType, "MAPU", EGame::PrimeDemo, EGame::Echoes);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eMidi, "MIDI", "?");
|
CResTypeInfo *pType = new CResTypeInfo(eMidi, "MIDI", "?");
|
||||||
AddExtension(pType, "CSNG", ePrimeDemo, eEchoes);
|
AddExtension(pType, "CSNG", EGame::PrimeDemo, EGame::Echoes);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eModel, "Model", "cmdl");
|
CResTypeInfo *pType = new CResTypeInfo(eModel, "Model", "cmdl");
|
||||||
AddExtension(pType, "CMDL", ePrimeDemo, eReturns);
|
AddExtension(pType, "CMDL", EGame::PrimeDemo, EGame::DKCReturns);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eParticle, "Particle System", "gpsm.part");
|
CResTypeInfo *pType = new CResTypeInfo(eParticle, "Particle System", "gpsm.part");
|
||||||
AddExtension(pType, "PART", ePrimeDemo, eReturns);
|
AddExtension(pType, "PART", EGame::PrimeDemo, EGame::DKCReturns);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eParticleCollisionResponse, "Collision Response Particle System", "crsm.crsc");
|
CResTypeInfo *pType = new CResTypeInfo(eParticleCollisionResponse, "Collision Response Particle System", "crsm.crsc");
|
||||||
AddExtension(pType, "CRSC", ePrimeDemo, eCorruption);
|
AddExtension(pType, "CRSC", EGame::PrimeDemo, EGame::Corruption);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eParticleDecal, "Decal Particle System", "dpsm.dpsc");
|
CResTypeInfo *pType = new CResTypeInfo(eParticleDecal, "Decal Particle System", "dpsm.dpsc");
|
||||||
AddExtension(pType, "DPSC", ePrimeDemo, eCorruption);
|
AddExtension(pType, "DPSC", EGame::PrimeDemo, EGame::Corruption);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eParticleElectric, "Electric Particle System", "elsm.elsc");
|
CResTypeInfo *pType = new CResTypeInfo(eParticleElectric, "Electric Particle System", "elsm.elsc");
|
||||||
AddExtension(pType, "ELSC", ePrimeDemo, eCorruption);
|
AddExtension(pType, "ELSC", EGame::PrimeDemo, EGame::Corruption);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eParticleSorted, "Sorted Particle System", "srsm.srsc");
|
CResTypeInfo *pType = new CResTypeInfo(eParticleSorted, "Sorted Particle System", "srsm.srsc");
|
||||||
AddExtension(pType, "SRSC", eEchoesDemo, eEchoes);
|
AddExtension(pType, "SRSC", EGame::EchoesDemo, EGame::Echoes);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eParticleSpawn, "Spawn Particle System", "spsm.spsc");
|
CResTypeInfo *pType = new CResTypeInfo(eParticleSpawn, "Spawn Particle System", "spsm.spsc");
|
||||||
AddExtension(pType, "SPSC", eEchoesDemo, eReturns);
|
AddExtension(pType, "SPSC", EGame::EchoesDemo, EGame::DKCReturns);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eParticleSwoosh, "Swoosh Particle System", "swsh.swhc");
|
CResTypeInfo *pType = new CResTypeInfo(eParticleSwoosh, "Swoosh Particle System", "swsh.swhc");
|
||||||
AddExtension(pType, "SWHC", ePrimeDemo, eReturns);
|
AddExtension(pType, "SWHC", EGame::PrimeDemo, EGame::DKCReturns);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eParticleTransform, "Transform Particle System", "xfsm.xfsc");
|
CResTypeInfo *pType = new CResTypeInfo(eParticleTransform, "Transform Particle System", "xfsm.xfsc");
|
||||||
AddExtension(pType, "XFSC", eReturns, eReturns);
|
AddExtension(pType, "XFSC", EGame::DKCReturns, EGame::DKCReturns);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eParticleWeapon, "Weapon Particle System", "wpsm.wpsc");
|
CResTypeInfo *pType = new CResTypeInfo(eParticleWeapon, "Weapon Particle System", "wpsm.wpsc");
|
||||||
AddExtension(pType, "WPSC", ePrimeDemo, eCorruption);
|
AddExtension(pType, "WPSC", EGame::PrimeDemo, EGame::Corruption);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(ePathfinding, "Pathfinding Mesh", "path");
|
CResTypeInfo *pType = new CResTypeInfo(ePathfinding, "Pathfinding Mesh", "path");
|
||||||
AddExtension(pType, "PATH", ePrimeDemo, eCorruption);
|
AddExtension(pType, "PATH", EGame::PrimeDemo, EGame::Corruption);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(ePortalArea, "Portal Area", "?");
|
CResTypeInfo *pType = new CResTypeInfo(ePortalArea, "Portal Area", "?");
|
||||||
AddExtension(pType, "PTLA", eEchoesDemo, eCorruption);
|
AddExtension(pType, "PTLA", EGame::EchoesDemo, EGame::Corruption);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eRuleSet, "Rule Set", "rule");
|
CResTypeInfo *pType = new CResTypeInfo(eRuleSet, "Rule Set", "rule");
|
||||||
AddExtension(pType, "RULE", eEchoesDemo, eReturns);
|
AddExtension(pType, "RULE", EGame::EchoesDemo, EGame::DKCReturns);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eSaveArea, "Area Save Info", "sava");
|
CResTypeInfo *pType = new CResTypeInfo(eSaveArea, "Area Save Info", "sava");
|
||||||
AddExtension(pType, "SAVA", eCorruptionProto, eCorruption);
|
AddExtension(pType, "SAVA", EGame::CorruptionProto, EGame::Corruption);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eSaveWorld, "World Save Info", "savw");
|
CResTypeInfo *pType = new CResTypeInfo(eSaveWorld, "World Save Info", "savw");
|
||||||
AddExtension(pType, "SAVW", ePrime, eReturns);
|
AddExtension(pType, "SAVW", EGame::Prime, EGame::DKCReturns);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eScan, "Scan", "scan");
|
CResTypeInfo *pType = new CResTypeInfo(eScan, "Scan", "scan");
|
||||||
AddExtension(pType, "SCAN", ePrimeDemo, eCorruption);
|
AddExtension(pType, "SCAN", EGame::PrimeDemo, EGame::Corruption);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eSkeleton, "Skeleton", "cin");
|
CResTypeInfo *pType = new CResTypeInfo(eSkeleton, "Skeleton", "cin");
|
||||||
AddExtension(pType, "CINF", ePrimeDemo, eReturns);
|
AddExtension(pType, "CINF", EGame::PrimeDemo, EGame::DKCReturns);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eSkin, "Skin", "cskr");
|
CResTypeInfo *pType = new CResTypeInfo(eSkin, "Skin", "cskr");
|
||||||
AddExtension(pType, "CSKR", ePrimeDemo, eReturns);
|
AddExtension(pType, "CSKR", EGame::PrimeDemo, EGame::DKCReturns);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eSourceAnimData, "Source Animation Data", "sand");
|
CResTypeInfo *pType = new CResTypeInfo(eSourceAnimData, "Source Animation Data", "sand");
|
||||||
AddExtension(pType, "SAND", eCorruptionProto, eCorruption);
|
AddExtension(pType, "SAND", EGame::CorruptionProto, EGame::Corruption);
|
||||||
pType->mCanHaveDependencies = false; // all dependencies are added to the CHAR dependency tree
|
pType->mCanHaveDependencies = false; // all dependencies are added to the CHAR dependency tree
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eSpatialPrimitive, "Spatial Primitive", "?");
|
CResTypeInfo *pType = new CResTypeInfo(eSpatialPrimitive, "Spatial Primitive", "?");
|
||||||
AddExtension(pType, "CSPP", eEchoesDemo, eEchoes);
|
AddExtension(pType, "CSPP", EGame::EchoesDemo, EGame::Echoes);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eStateMachine, "State Machine", "afsm");
|
CResTypeInfo *pType = new CResTypeInfo(eStateMachine, "State Machine", "afsm");
|
||||||
AddExtension(pType, "AFSM", ePrimeDemo, eEchoes);
|
AddExtension(pType, "AFSM", EGame::PrimeDemo, EGame::Echoes);
|
||||||
AddExtension(pType, "FSM2", eCorruptionProto, eCorruption);
|
AddExtension(pType, "FSM2", EGame::CorruptionProto, EGame::Corruption);
|
||||||
AddExtension(pType, "FSMC", eReturns, eReturns);
|
AddExtension(pType, "FSMC", EGame::DKCReturns, EGame::DKCReturns);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eStateMachine2, "State Machine 2", "fsm2");
|
CResTypeInfo *pType = new CResTypeInfo(eStateMachine2, "State Machine 2", "fsm2");
|
||||||
AddExtension(pType, "FSM2", eEchoesDemo, eCorruption);
|
AddExtension(pType, "FSM2", EGame::EchoesDemo, EGame::Corruption);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eStaticGeometryMap, "Static Scan Map", "egmc");
|
CResTypeInfo *pType = new CResTypeInfo(eStaticGeometryMap, "Static Scan Map", "egmc");
|
||||||
AddExtension(pType, "EGMC", eEchoesDemo, eCorruption);
|
AddExtension(pType, "EGMC", EGame::EchoesDemo, EGame::Corruption);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eStreamedAudio, "Streamed Audio", "?");
|
CResTypeInfo *pType = new CResTypeInfo(eStreamedAudio, "Streamed Audio", "?");
|
||||||
AddExtension(pType, "STRM", eCorruptionProto, eReturns);
|
AddExtension(pType, "STRM", EGame::CorruptionProto, EGame::DKCReturns);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eStringList, "String List", "stlc");
|
CResTypeInfo *pType = new CResTypeInfo(eStringList, "String List", "stlc");
|
||||||
AddExtension(pType, "STLC", eEchoesDemo, eCorruptionProto);
|
AddExtension(pType, "STLC", EGame::EchoesDemo, EGame::CorruptionProto);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eStringTable, "String Table", "strg");
|
CResTypeInfo *pType = new CResTypeInfo(eStringTable, "String Table", "strg");
|
||||||
AddExtension(pType, "STRG", ePrimeDemo, eReturns);
|
AddExtension(pType, "STRG", EGame::PrimeDemo, EGame::DKCReturns);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eTexture, "Texture", "txtr");
|
CResTypeInfo *pType = new CResTypeInfo(eTexture, "Texture", "txtr");
|
||||||
AddExtension(pType, "TXTR", ePrimeDemo, eReturns);
|
AddExtension(pType, "TXTR", EGame::PrimeDemo, EGame::DKCReturns);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eTweak, "Tweak Data", "ctwk");
|
CResTypeInfo *pType = new CResTypeInfo(eTweak, "Tweak Data", "ctwk");
|
||||||
AddExtension(pType, "CTWK", ePrimeDemo, ePrime);
|
AddExtension(pType, "CTWK", EGame::PrimeDemo, EGame::Prime);
|
||||||
pType->mCanHaveDependencies = false;
|
pType->mCanHaveDependencies = false;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eUserEvaluatorData, "User Evaluator Data", "user.usrc");
|
CResTypeInfo *pType = new CResTypeInfo(eUserEvaluatorData, "User Evaluator Data", "user.usrc");
|
||||||
AddExtension(pType, "USRC", eCorruptionProto, eCorruption);
|
AddExtension(pType, "USRC", EGame::CorruptionProto, EGame::Corruption);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eWorld, "World", "mwld");
|
CResTypeInfo *pType = new CResTypeInfo(eWorld, "World", "mwld");
|
||||||
AddExtension(pType, "MLVL", ePrimeDemo, eReturns);
|
AddExtension(pType, "MLVL", EGame::PrimeDemo, EGame::DKCReturns);
|
||||||
pType->mCanBeSerialized = true;
|
pType->mCanBeSerialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
inline TString Source() const { return mpEntry ? mpEntry->CookedAssetPath(true).GetFileName() : ""; }
|
inline TString Source() const { return mpEntry ? mpEntry->CookedAssetPath(true).GetFileName() : ""; }
|
||||||
inline TString FullSource() const { return mpEntry ? mpEntry->CookedAssetPath(true) : ""; }
|
inline TString FullSource() const { return mpEntry ? mpEntry->CookedAssetPath(true) : ""; }
|
||||||
inline CAssetID ID() const { return mpEntry ? mpEntry->ID() : CAssetID::skInvalidID64; }
|
inline CAssetID ID() const { return mpEntry ? mpEntry->ID() : CAssetID::skInvalidID64; }
|
||||||
inline EGame Game() const { return mpEntry ? mpEntry->Game() : eUnknownGame; }
|
inline EGame Game() const { return mpEntry ? mpEntry->Game() : EGame::Invalid; }
|
||||||
inline bool IsReferenced() const { return mRefCount > 0; }
|
inline bool IsReferenced() const { return mRefCount > 0; }
|
||||||
inline void Lock() { mRefCount++; }
|
inline void Lock() { mRefCount++; }
|
||||||
inline void Release() { mRefCount--; }
|
inline void Release() { mRefCount--; }
|
||||||
|
|
|
@ -69,7 +69,7 @@ public:
|
||||||
CDependencyTree *pTree = new CDependencyTree();
|
CDependencyTree *pTree = new CDependencyTree();
|
||||||
|
|
||||||
// Corruption's SCAN has a list of all assets - just grab that
|
// Corruption's SCAN has a list of all assets - just grab that
|
||||||
if (Game() >= eCorruptionProto)
|
if (Game() >= EGame::CorruptionProto)
|
||||||
{
|
{
|
||||||
for (u32 iDep = 0; iDep < mDependencyList.size(); iDep++)
|
for (u32 iDep = 0; iDep < mDependencyList.size(); iDep++)
|
||||||
{
|
{
|
||||||
|
@ -80,18 +80,18 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise add all the dependencies we need from the properties
|
// Otherwise add all the dependencies we need from the properties
|
||||||
if (Game() <= ePrime)
|
if (Game() <= EGame::Prime)
|
||||||
pTree->AddDependency(mFrameID);
|
pTree->AddDependency(mFrameID);
|
||||||
|
|
||||||
pTree->AddDependency(mpStringTable);
|
pTree->AddDependency(mpStringTable);
|
||||||
|
|
||||||
if (Game() <= ePrime)
|
if (Game() <= EGame::Prime)
|
||||||
{
|
{
|
||||||
for (u32 iImg = 0; iImg < 4; iImg++)
|
for (u32 iImg = 0; iImg < 4; iImg++)
|
||||||
pTree->AddDependency(mScanImageTextures[iImg]);
|
pTree->AddDependency(mScanImageTextures[iImg]);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Game() <= eEchoes)
|
else if (Game() <= EGame::Echoes)
|
||||||
{
|
{
|
||||||
pTree->AddDependency(mPostOverrideTexture);
|
pTree->AddDependency(mPostOverrideTexture);
|
||||||
pTree->AddDependency(mLogbookModel);
|
pTree->AddDependency(mLogbookModel);
|
||||||
|
|
|
@ -46,7 +46,7 @@ public:
|
||||||
{
|
{
|
||||||
// STRGs can reference FONTs with the &font=; formatting tag and TXTRs with the &image=; tag
|
// STRGs can reference FONTs with the &font=; formatting tag and TXTRs with the &image=; tag
|
||||||
CDependencyTree *pTree = new CDependencyTree();
|
CDependencyTree *pTree = new CDependencyTree();
|
||||||
EIDLength IDLength = (Game() <= eEchoes ? e32Bit : e64Bit);
|
EIDLength IDLength = (Game() <= EGame::Echoes ? e32Bit : e64Bit);
|
||||||
|
|
||||||
for (u32 iLang = 0; iLang < mLangTables.size(); iLang++)
|
for (u32 iLang = 0; iLang < mLangTables.size(); iLang++)
|
||||||
{
|
{
|
||||||
|
@ -77,7 +77,7 @@ public:
|
||||||
// Font
|
// Font
|
||||||
if (TagName == "font")
|
if (TagName == "font")
|
||||||
{
|
{
|
||||||
if (Game() >= eCorruptionProto)
|
if (Game() >= EGame::CorruptionProto)
|
||||||
{
|
{
|
||||||
ASSERT(ParamString.StartsWith("0x"));
|
ASSERT(ParamString.StartsWith("0x"));
|
||||||
ParamString = ParamString.ChopFront(2);
|
ParamString = ParamString.ChopFront(2);
|
||||||
|
@ -126,7 +126,7 @@ public:
|
||||||
{
|
{
|
||||||
TString Param = *Iter;
|
TString Param = *Iter;
|
||||||
|
|
||||||
if (Game() >= eCorruptionProto)
|
if (Game() >= EGame::CorruptionProto)
|
||||||
{
|
{
|
||||||
ASSERT(Param.StartsWith("0x"));
|
ASSERT(Param.StartsWith("0x"));
|
||||||
Param = Param.ChopFront(2);
|
Param = Param.ChopFront(2);
|
||||||
|
|
|
@ -95,20 +95,20 @@ void CWorld::Serialize(IArchive& rArc)
|
||||||
rArc << SerialParameter("Name", mName)
|
rArc << SerialParameter("Name", mName)
|
||||||
<< SerialParameter("NameString", mpWorldName);
|
<< SerialParameter("NameString", mpWorldName);
|
||||||
|
|
||||||
if (rArc.Game() == eEchoesDemo || rArc.Game() == eEchoes)
|
if (rArc.Game() == EGame::EchoesDemo || rArc.Game() == EGame::Echoes)
|
||||||
rArc << SerialParameter("DarkNameString", mpDarkWorldName);
|
rArc << SerialParameter("DarkNameString", mpDarkWorldName);
|
||||||
|
|
||||||
rArc << SerialParameter("WorldSaveInfo", mpSaveWorld)
|
rArc << SerialParameter("WorldSaveInfo", mpSaveWorld)
|
||||||
<< SerialParameter("WorldMap", mpMapWorld)
|
<< SerialParameter("WorldMap", mpMapWorld)
|
||||||
<< SerialParameter("DefaultSkyModel", mpDefaultSkybox);
|
<< SerialParameter("DefaultSkyModel", mpDefaultSkybox);
|
||||||
|
|
||||||
if (rArc.Game() >= eEchoesDemo && rArc.Game() <= eCorruption)
|
if (rArc.Game() >= EGame::EchoesDemo && rArc.Game() <= EGame::Corruption)
|
||||||
rArc << SerialParameter("TempleKeyWorldIndex", mTempleKeyWorldIndex);
|
rArc << SerialParameter("TempleKeyWorldIndex", mTempleKeyWorldIndex);
|
||||||
|
|
||||||
if (rArc.Game() == eReturns)
|
if (rArc.Game() == EGame::DKCReturns)
|
||||||
rArc << SerialParameter("TimeAttackData", mTimeAttackData);
|
rArc << SerialParameter("TimeAttackData", mTimeAttackData);
|
||||||
|
|
||||||
if (rArc.Game() == ePrime)
|
if (rArc.Game() == EGame::Prime)
|
||||||
rArc << SerialParameter("MemoryRelays", mMemoryRelays);
|
rArc << SerialParameter("MemoryRelays", mMemoryRelays);
|
||||||
|
|
||||||
rArc << SerialParameter("Areas", mAreas);
|
rArc << SerialParameter("Areas", mAreas);
|
||||||
|
@ -165,7 +165,7 @@ void Serialize(IArchive& rArc, CWorld::SArea::SLayer& rLayer)
|
||||||
rArc << SerialParameter("Name", rLayer.LayerName)
|
rArc << SerialParameter("Name", rLayer.LayerName)
|
||||||
<< SerialParameter("Active", rLayer.Active);
|
<< SerialParameter("Active", rLayer.Active);
|
||||||
|
|
||||||
if (rArc.Game() >= eCorruption)
|
if (rArc.Game() >= EGame::Corruption)
|
||||||
{
|
{
|
||||||
rArc << SerialParameter("StateID", rLayer.LayerStateID);
|
rArc << SerialParameter("StateID", rLayer.LayerStateID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,14 +35,14 @@ void CAreaCooker::DetermineSectionNumbersPrime()
|
||||||
|
|
||||||
switch (mVersion)
|
switch (mVersion)
|
||||||
{
|
{
|
||||||
case ePrimeDemo:
|
case EGame::PrimeDemo:
|
||||||
case ePrime:
|
case EGame::Prime:
|
||||||
GeometrySections = 1 + (7 * OriginalMeshCount); // Accounting for materials
|
GeometrySections = 1 + (7 * OriginalMeshCount); // Accounting for materials
|
||||||
break;
|
break;
|
||||||
case eEchoesDemo:
|
case EGame::EchoesDemo:
|
||||||
GeometrySections = 2 + (9 * OriginalMeshCount); // Account for materials + AROT
|
GeometrySections = 2 + (9 * OriginalMeshCount); // Account for materials + AROT
|
||||||
break;
|
break;
|
||||||
case eEchoes:
|
case EGame::Echoes:
|
||||||
GeometrySections = 3 + (9 * OriginalMeshCount); // Acount for materials + AROT + an unknown section
|
GeometrySections = 3 + (9 * OriginalMeshCount); // Acount for materials + AROT + an unknown section
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -52,13 +52,13 @@ void CAreaCooker::DetermineSectionNumbersPrime()
|
||||||
|
|
||||||
// Set section numbers
|
// Set section numbers
|
||||||
u32 SecNum = GeometrySections;
|
u32 SecNum = GeometrySections;
|
||||||
if (mVersion <= ePrime) mAROTSecNum = SecNum++;
|
if (mVersion <= EGame::Prime) mAROTSecNum = SecNum++;
|
||||||
if (mVersion >= eEchoesDemo) mFFFFSecNum = SecNum++;
|
if (mVersion >= EGame::EchoesDemo) mFFFFSecNum = SecNum++;
|
||||||
|
|
||||||
if (mVersion >= eEchoesDemo)
|
if (mVersion >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
mSCLYSecNum = SecNum;
|
mSCLYSecNum = SecNum;
|
||||||
SecNum += (mVersion >= eEchoes ? mpArea->mScriptLayers.size() : 1);
|
SecNum += (mVersion >= EGame::Echoes ? mpArea->mScriptLayers.size() : 1);
|
||||||
mSCGNSecNum = SecNum++;
|
mSCGNSecNum = SecNum++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -70,7 +70,7 @@ void CAreaCooker::DetermineSectionNumbersPrime()
|
||||||
mVISISecNum = SecNum++;
|
mVISISecNum = SecNum++;
|
||||||
mPATHSecNum = SecNum++;
|
mPATHSecNum = SecNum++;
|
||||||
|
|
||||||
if (mVersion >= eEchoesDemo)
|
if (mVersion >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
mPTLASecNum = SecNum++;
|
mPTLASecNum = SecNum++;
|
||||||
mEGMCSecNum = SecNum++;
|
mEGMCSecNum = SecNum++;
|
||||||
|
@ -98,18 +98,18 @@ void CAreaCooker::WritePrimeHeader(IOutputStream& rOut)
|
||||||
rOut.WriteLong(GetMREAVersion(mVersion));
|
rOut.WriteLong(GetMREAVersion(mVersion));
|
||||||
mpArea->mTransform.Write(rOut);
|
mpArea->mTransform.Write(rOut);
|
||||||
rOut.WriteLong(mpArea->mOriginalWorldMeshCount);
|
rOut.WriteLong(mpArea->mOriginalWorldMeshCount);
|
||||||
if (mVersion >= eEchoes) rOut.WriteLong(mpArea->mScriptLayers.size());
|
if (mVersion >= EGame::Echoes) rOut.WriteLong(mpArea->mScriptLayers.size());
|
||||||
rOut.WriteLong(mpArea->mSectionDataBuffers.size());
|
rOut.WriteLong(mpArea->mSectionDataBuffers.size());
|
||||||
|
|
||||||
rOut.WriteLong(mGeometrySecNum);
|
rOut.WriteLong(mGeometrySecNum);
|
||||||
rOut.WriteLong(mSCLYSecNum);
|
rOut.WriteLong(mSCLYSecNum);
|
||||||
if (mVersion >= eEchoesDemo) rOut.WriteLong(mSCGNSecNum);
|
if (mVersion >= EGame::EchoesDemo) rOut.WriteLong(mSCGNSecNum);
|
||||||
rOut.WriteLong(mCollisionSecNum);
|
rOut.WriteLong(mCollisionSecNum);
|
||||||
rOut.WriteLong(mUnknownSecNum);
|
rOut.WriteLong(mUnknownSecNum);
|
||||||
rOut.WriteLong(mLightsSecNum);
|
rOut.WriteLong(mLightsSecNum);
|
||||||
rOut.WriteLong(mVISISecNum);
|
rOut.WriteLong(mVISISecNum);
|
||||||
rOut.WriteLong(mPATHSecNum);
|
rOut.WriteLong(mPATHSecNum);
|
||||||
if (mVersion <= ePrime) rOut.WriteLong(mAROTSecNum);
|
if (mVersion <= EGame::Prime) rOut.WriteLong(mAROTSecNum);
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -118,9 +118,9 @@ void CAreaCooker::WritePrimeHeader(IOutputStream& rOut)
|
||||||
rOut.WriteLong(mEGMCSecNum);
|
rOut.WriteLong(mEGMCSecNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mVersion >= eEchoesDemo)
|
if (mVersion >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
if (mVersion >= eEchoes) rOut.WriteLong(mCompressedBlocks.size());
|
if (mVersion >= EGame::Echoes) rOut.WriteLong(mCompressedBlocks.size());
|
||||||
rOut.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ void CAreaCooker::WritePrimeHeader(IOutputStream& rOut)
|
||||||
rOut.WriteLong(mSectionSizes[iSec]);
|
rOut.WriteLong(mSectionSizes[iSec]);
|
||||||
rOut.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
|
|
||||||
if (mVersion >= eEchoes)
|
if (mVersion >= EGame::Echoes)
|
||||||
WriteCompressionHeader(rOut);
|
WriteCompressionHeader(rOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ void CAreaCooker::WritePrimeSCLY(IOutputStream& rOut)
|
||||||
// This function covers both Prime 1 and the Echoes demo.
|
// This function covers both Prime 1 and the Echoes demo.
|
||||||
// The Echoes demo has a similar SCLY format but with minor layout differences and with SCGN.
|
// The Echoes demo has a similar SCLY format but with minor layout differences and with SCGN.
|
||||||
rOut.WriteFourCC( FOURCC('SCLY') );
|
rOut.WriteFourCC( FOURCC('SCLY') );
|
||||||
mVersion <= ePrime ? rOut.WriteLong(1) : rOut.WriteByte(1);
|
mVersion <= EGame::Prime ? rOut.WriteLong(1) : rOut.WriteByte(1);
|
||||||
|
|
||||||
u32 NumLayers = mpArea->mScriptLayers.size();
|
u32 NumLayers = mpArea->mScriptLayers.size();
|
||||||
rOut.WriteLong(NumLayers);
|
rOut.WriteLong(NumLayers);
|
||||||
|
@ -227,7 +227,7 @@ void CAreaCooker::WritePrimeSCLY(IOutputStream& rOut)
|
||||||
FinishSection(false);
|
FinishSection(false);
|
||||||
|
|
||||||
// SCGN
|
// SCGN
|
||||||
if (mVersion == eEchoesDemo)
|
if (mVersion == EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
rOut.WriteFourCC( FOURCC('SCGN') );
|
rOut.WriteFourCC( FOURCC('SCGN') );
|
||||||
rOut.WriteByte(1);
|
rOut.WriteByte(1);
|
||||||
|
@ -327,7 +327,7 @@ void CAreaCooker::FinishSection(bool SingleSectionBlock)
|
||||||
mSectionSizes.push_back(SecSize);
|
mSectionSizes.push_back(SecSize);
|
||||||
|
|
||||||
// Only track compressed blocks for MP2+. Write everything to one block for MP1.
|
// Only track compressed blocks for MP2+. Write everything to one block for MP1.
|
||||||
if (mVersion >= eEchoes)
|
if (mVersion >= EGame::Echoes)
|
||||||
{
|
{
|
||||||
// Finish the current block if this is a single section block OR if the new section would push the block over the size limit.
|
// Finish the current block if this is a single section block OR if the new section would push the block over the size limit.
|
||||||
if (mCurBlock.NumSections > 0 && (mCurBlock.DecompressedSize + SecSize > kSizeThreshold || SingleSectionBlock))
|
if (mCurBlock.NumSections > 0 && (mCurBlock.DecompressedSize + SecSize > kSizeThreshold || SingleSectionBlock))
|
||||||
|
@ -350,8 +350,8 @@ void CAreaCooker::FinishBlock()
|
||||||
if (mCurBlock.NumSections == 0) return;
|
if (mCurBlock.NumSections == 0) return;
|
||||||
|
|
||||||
std::vector<u8> CompressedBuf(mCompressedData.Size() * 2);
|
std::vector<u8> CompressedBuf(mCompressedData.Size() * 2);
|
||||||
bool EnableCompression = (mVersion >= eEchoes) && mpArea->mUsesCompression && !gkForceDisableCompression;
|
bool EnableCompression = (mVersion >= EGame::Echoes) && mpArea->mUsesCompression && !gkForceDisableCompression;
|
||||||
bool UseZlib = (mVersion == eReturns);
|
bool UseZlib = (mVersion == EGame::DKCReturns);
|
||||||
|
|
||||||
u32 CompressedSize = 0;
|
u32 CompressedSize = 0;
|
||||||
bool WriteCompressedData = false;
|
bool WriteCompressedData = false;
|
||||||
|
@ -394,7 +394,7 @@ bool CAreaCooker::CookMREA(CGameArea *pArea, IOutputStream& rOut)
|
||||||
Cooker.mpArea = pArea;
|
Cooker.mpArea = pArea;
|
||||||
Cooker.mVersion = pArea->Game();
|
Cooker.mVersion = pArea->Game();
|
||||||
|
|
||||||
if (Cooker.mVersion <= eEchoes)
|
if (Cooker.mVersion <= EGame::Echoes)
|
||||||
Cooker.DetermineSectionNumbersPrime();
|
Cooker.DetermineSectionNumbersPrime();
|
||||||
else
|
else
|
||||||
Cooker.DetermineSectionNumbersCorruption();
|
Cooker.DetermineSectionNumbersCorruption();
|
||||||
|
@ -413,13 +413,13 @@ bool CAreaCooker::CookMREA(CGameArea *pArea, IOutputStream& rOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write SCLY
|
// Write SCLY
|
||||||
if (Cooker.mVersion <= eEchoesDemo)
|
if (Cooker.mVersion <= EGame::EchoesDemo)
|
||||||
Cooker.WritePrimeSCLY(Cooker.mSectionData);
|
Cooker.WritePrimeSCLY(Cooker.mSectionData);
|
||||||
else
|
else
|
||||||
Cooker.WriteEchoesSCLY(Cooker.mSectionData);
|
Cooker.WriteEchoesSCLY(Cooker.mSectionData);
|
||||||
|
|
||||||
// Write post-SCLY data sections
|
// Write post-SCLY data sections
|
||||||
u32 PostSCLY = (Cooker.mVersion <= ePrime ? Cooker.mSCLYSecNum + 1 : Cooker.mSCGNSecNum + 1);
|
u32 PostSCLY = (Cooker.mVersion <= EGame::Prime ? Cooker.mSCLYSecNum + 1 : Cooker.mSCGNSecNum + 1);
|
||||||
for (u32 iSec = PostSCLY; iSec < pArea->mSectionDataBuffers.size(); iSec++)
|
for (u32 iSec = PostSCLY; iSec < pArea->mSectionDataBuffers.size(); iSec++)
|
||||||
{
|
{
|
||||||
if (iSec == Cooker.mModulesSecNum)
|
if (iSec == Cooker.mModulesSecNum)
|
||||||
|
@ -435,7 +435,7 @@ bool CAreaCooker::CookMREA(CGameArea *pArea, IOutputStream& rOut)
|
||||||
Cooker.FinishBlock();
|
Cooker.FinishBlock();
|
||||||
|
|
||||||
// Write to actual file
|
// Write to actual file
|
||||||
if (Cooker.mVersion <= eEchoes)
|
if (Cooker.mVersion <= EGame::Echoes)
|
||||||
Cooker.WritePrimeHeader(rOut);
|
Cooker.WritePrimeHeader(rOut);
|
||||||
else
|
else
|
||||||
Cooker.WriteCorruptionHeader(rOut);
|
Cooker.WriteCorruptionHeader(rOut);
|
||||||
|
@ -448,13 +448,13 @@ u32 CAreaCooker::GetMREAVersion(EGame Version)
|
||||||
{
|
{
|
||||||
switch (Version)
|
switch (Version)
|
||||||
{
|
{
|
||||||
case ePrimeDemo: return 0xC;
|
case EGame::PrimeDemo: return 0xC;
|
||||||
case ePrime: return 0xF;
|
case EGame::Prime: return 0xF;
|
||||||
case eEchoesDemo: return 0x15;
|
case EGame::EchoesDemo: return 0x15;
|
||||||
case eEchoes: return 0x19;
|
case EGame::Echoes: return 0x19;
|
||||||
case eCorruptionProto: return 0x1D;
|
case EGame::CorruptionProto: return 0x1D;
|
||||||
case eCorruption: return 0x1E;
|
case EGame::Corruption: return 0x1E;
|
||||||
case eReturns: return 0x20;
|
case EGame::DKCReturns: return 0x20;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,7 +161,7 @@ void CMaterialCooker::WriteMaterialPrime(IOutputStream& rOut)
|
||||||
bool HasKonst = (NumKonst > 0);
|
bool HasKonst = (NumKonst > 0);
|
||||||
u32 Flags;
|
u32 Flags;
|
||||||
|
|
||||||
if (mVersion <= ePrime)
|
if (mVersion <= EGame::Prime)
|
||||||
Flags = 0x1003;
|
Flags = 0x1003;
|
||||||
else
|
else
|
||||||
Flags = 0x4002;
|
Flags = 0x4002;
|
||||||
|
@ -178,13 +178,13 @@ void CMaterialCooker::WriteMaterialPrime(IOutputStream& rOut)
|
||||||
// Vertex description
|
// Vertex description
|
||||||
u32 VtxFlags = ConvertFromVertexDescription( mpMat->VtxDesc() );
|
u32 VtxFlags = ConvertFromVertexDescription( mpMat->VtxDesc() );
|
||||||
|
|
||||||
if (mVersion < eEchoes)
|
if (mVersion < EGame::Echoes)
|
||||||
VtxFlags &= 0x00FFFFFF;
|
VtxFlags &= 0x00FFFFFF;
|
||||||
|
|
||||||
rOut.WriteLong(VtxFlags);
|
rOut.WriteLong(VtxFlags);
|
||||||
|
|
||||||
// Echoes unknowns
|
// Echoes unknowns
|
||||||
if (mVersion == eEchoes)
|
if (mVersion == EGame::Echoes)
|
||||||
{
|
{
|
||||||
rOut.WriteLong(mpMat->EchoesUnknownA());
|
rOut.WriteLong(mpMat->EchoesUnknownA());
|
||||||
rOut.WriteLong(mpMat->EchoesUnknownB());
|
rOut.WriteLong(mpMat->EchoesUnknownB());
|
||||||
|
@ -359,10 +359,10 @@ void CMaterialCooker::WriteCookedMatSet(CMaterialSet *pSet, EGame Version, IOutp
|
||||||
|
|
||||||
switch (Version)
|
switch (Version)
|
||||||
{
|
{
|
||||||
case ePrimeDemo:
|
case EGame::PrimeDemo:
|
||||||
case ePrime:
|
case EGame::Prime:
|
||||||
case eEchoesDemo:
|
case EGame::EchoesDemo:
|
||||||
case eEchoes:
|
case EGame::Echoes:
|
||||||
Cooker.WriteMatSetPrime(rOut);
|
Cooker.WriteMatSetPrime(rOut);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -376,10 +376,10 @@ void CMaterialCooker::WriteCookedMaterial(CMaterial *pMat, EGame Version, IOutpu
|
||||||
|
|
||||||
switch (Version)
|
switch (Version)
|
||||||
{
|
{
|
||||||
case ePrimeDemo:
|
case EGame::PrimeDemo:
|
||||||
case ePrime:
|
case EGame::Prime:
|
||||||
case eEchoesDemo:
|
case EGame::EchoesDemo:
|
||||||
case eEchoes:
|
case EGame::Echoes:
|
||||||
Cooker.WriteMaterialPrime(rOut);
|
Cooker.WriteMaterialPrime(rOut);
|
||||||
break;
|
break;
|
||||||
// TODO: Corruption/Uncooked
|
// TODO: Corruption/Uncooked
|
||||||
|
|
|
@ -168,7 +168,7 @@ void CModelCooker::WriteModelPrime(IOutputStream& rOut)
|
||||||
{
|
{
|
||||||
CVertex *pVert = &pPrimitive->Vertices[iVert];
|
CVertex *pVert = &pPrimitive->Vertices[iVert];
|
||||||
|
|
||||||
if (mVersion == eEchoes)
|
if (mVersion == EGame::Echoes)
|
||||||
{
|
{
|
||||||
for (u32 iMtxAttribs = 0; iMtxAttribs < 8; iMtxAttribs++)
|
for (u32 iMtxAttribs = 0; iMtxAttribs < 8; iMtxAttribs++)
|
||||||
if (VtxAttribs & (ePosMtx << iMtxAttribs))
|
if (VtxAttribs & (ePosMtx << iMtxAttribs))
|
||||||
|
@ -232,10 +232,10 @@ bool CModelCooker::CookCMDL(CModel *pModel, IOutputStream& rOut)
|
||||||
|
|
||||||
switch (pModel->Game())
|
switch (pModel->Game())
|
||||||
{
|
{
|
||||||
case ePrimeDemo:
|
case EGame::PrimeDemo:
|
||||||
case ePrime:
|
case EGame::Prime:
|
||||||
case eEchoesDemo:
|
case EGame::EchoesDemo:
|
||||||
case eEchoes:
|
case EGame::Echoes:
|
||||||
Cooker.WriteModelPrime(rOut);
|
Cooker.WriteModelPrime(rOut);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -248,17 +248,17 @@ u32 CModelCooker::GetCMDLVersion(EGame Version)
|
||||||
{
|
{
|
||||||
switch (Version)
|
switch (Version)
|
||||||
{
|
{
|
||||||
case ePrimeDemo:
|
case EGame::PrimeDemo:
|
||||||
case ePrime:
|
case EGame::Prime:
|
||||||
return 0x2;
|
return 0x2;
|
||||||
case eEchoesDemo:
|
case EGame::EchoesDemo:
|
||||||
return 0x3;
|
return 0x3;
|
||||||
case eEchoes:
|
case EGame::Echoes:
|
||||||
return 0x4;
|
return 0x4;
|
||||||
case eCorruptionProto:
|
case EGame::CorruptionProto:
|
||||||
case eCorruption:
|
case EGame::Corruption:
|
||||||
return 0x5;
|
return 0x5;
|
||||||
case eReturns:
|
case EGame::DKCReturns:
|
||||||
return 0xA;
|
return 0xA;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -10,7 +10,7 @@ void CScriptCooker::WriteProperty(IOutputStream& rOut, IProperty* pProperty, boo
|
||||||
u32 SizeOffset = 0, PropStart = 0;
|
u32 SizeOffset = 0, PropStart = 0;
|
||||||
void* pData = (mpArrayItemData ? mpArrayItemData : mpObject->PropertyData());
|
void* pData = (mpArrayItemData ? mpArrayItemData : mpObject->PropertyData());
|
||||||
|
|
||||||
if (mGame >= eEchoesDemo && !InAtomicStruct)
|
if (mGame >= EGame::EchoesDemo && !InAtomicStruct)
|
||||||
{
|
{
|
||||||
rOut.WriteLong(pProperty->ID());
|
rOut.WriteLong(pProperty->ID());
|
||||||
SizeOffset = rOut.Tell();
|
SizeOffset = rOut.Tell();
|
||||||
|
@ -143,7 +143,7 @@ void CScriptCooker::WriteProperty(IOutputStream& rOut, IProperty* pProperty, boo
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mGame < eReturns)
|
if (mGame < EGame::DKCReturns)
|
||||||
{
|
{
|
||||||
rOut.WriteShort(0);
|
rOut.WriteShort(0);
|
||||||
rOut.WriteLong(0);
|
rOut.WriteLong(0);
|
||||||
|
@ -190,7 +190,7 @@ void CScriptCooker::WriteProperty(IOutputStream& rOut, IProperty* pProperty, boo
|
||||||
|
|
||||||
if (!pStruct->IsAtomic())
|
if (!pStruct->IsAtomic())
|
||||||
{
|
{
|
||||||
if (mGame <= ePrime)
|
if (mGame <= EGame::Prime)
|
||||||
rOut.WriteLong(PropertiesToWrite.size());
|
rOut.WriteLong(PropertiesToWrite.size());
|
||||||
else
|
else
|
||||||
rOut.WriteShort((u16) PropertiesToWrite.size());
|
rOut.WriteShort((u16) PropertiesToWrite.size());
|
||||||
|
@ -238,7 +238,7 @@ void CScriptCooker::WriteInstance(IOutputStream& rOut, CScriptObject *pInstance)
|
||||||
|
|
||||||
// Note the format is pretty much the same between games; the main difference is a
|
// Note the format is pretty much the same between games; the main difference is a
|
||||||
// number of fields changed size between MP1 and 2, but they're still the same fields
|
// number of fields changed size between MP1 and 2, but they're still the same fields
|
||||||
bool IsPrime1 = (mGame <= ePrime);
|
bool IsPrime1 = (mGame <= EGame::Prime);
|
||||||
|
|
||||||
u32 ObjectType = pInstance->ObjectTypeID();
|
u32 ObjectType = pInstance->ObjectTypeID();
|
||||||
IsPrime1 ? rOut.WriteByte((u8) ObjectType) : rOut.WriteLong(ObjectType);
|
IsPrime1 ? rOut.WriteByte((u8) ObjectType) : rOut.WriteLong(ObjectType);
|
||||||
|
@ -275,7 +275,7 @@ void CScriptCooker::WriteLayer(IOutputStream& rOut, CScriptLayer *pLayer)
|
||||||
{
|
{
|
||||||
ASSERT(pLayer->Area()->Game() == mGame);
|
ASSERT(pLayer->Area()->Game() == mGame);
|
||||||
|
|
||||||
rOut.WriteByte( mGame <= ePrime ? 0 : 1 ); // Version
|
rOut.WriteByte( mGame <= EGame::Prime ? 0 : 1 ); // Version
|
||||||
|
|
||||||
u32 InstanceCountOffset = rOut.Tell();
|
u32 InstanceCountOffset = rOut.Tell();
|
||||||
u32 NumWrittenInstances = 0;
|
u32 NumWrittenInstances = 0;
|
||||||
|
@ -291,7 +291,7 @@ void CScriptCooker::WriteLayer(IOutputStream& rOut, CScriptLayer *pLayer)
|
||||||
if (mWriteGeneratedSeparately)
|
if (mWriteGeneratedSeparately)
|
||||||
{
|
{
|
||||||
// GenericCreature instances in DKCR always write to both SCLY and SCGN
|
// GenericCreature instances in DKCR always write to both SCLY and SCGN
|
||||||
if (mGame == eReturns && pInstance->ObjectTypeID() == FOURCC('GCTR'))
|
if (mGame == EGame::DKCReturns && pInstance->ObjectTypeID() == FOURCC('GCTR'))
|
||||||
mGeneratedObjects.push_back(pInstance);
|
mGeneratedObjects.push_back(pInstance);
|
||||||
|
|
||||||
// Instances receiving a Generate/Activate message (MP2) or a
|
// Instances receiving a Generate/Activate message (MP2) or a
|
||||||
|
@ -302,7 +302,7 @@ void CScriptCooker::WriteLayer(IOutputStream& rOut, CScriptLayer *pLayer)
|
||||||
{
|
{
|
||||||
CLink *pLink = pInstance->Link(eIncoming, LinkIdx);
|
CLink *pLink = pInstance->Link(eIncoming, LinkIdx);
|
||||||
|
|
||||||
if (mGame <= eEchoes)
|
if (mGame <= EGame::Echoes)
|
||||||
{
|
{
|
||||||
if (pLink->State() == FOURCC('GRNT') && pLink->Message() == FOURCC('ACTV'))
|
if (pLink->State() == FOURCC('GRNT') && pLink->Message() == FOURCC('ACTV'))
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,7 +22,7 @@ public:
|
||||||
: mGame(Game)
|
: mGame(Game)
|
||||||
, mpObject(nullptr)
|
, mpObject(nullptr)
|
||||||
, mpArrayItemData(nullptr)
|
, mpArrayItemData(nullptr)
|
||||||
, mWriteGeneratedSeparately(WriteGeneratedObjectsSeparately && mGame >= eEchoesDemo)
|
, mWriteGeneratedSeparately(WriteGeneratedObjectsSeparately && mGame >= EGame::EchoesDemo)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void WriteInstance(IOutputStream& rOut, CScriptObject *pInstance);
|
void WriteInstance(IOutputStream& rOut, CScriptObject *pInstance);
|
||||||
|
|
|
@ -22,15 +22,15 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
|
||||||
|
|
||||||
WorldNameID.Write(rMLVL);
|
WorldNameID.Write(rMLVL);
|
||||||
|
|
||||||
if (Game == eEchoesDemo || Game == eEchoes)
|
if (Game == EGame::EchoesDemo || Game == EGame::Echoes)
|
||||||
{
|
{
|
||||||
DarkWorldNameID.Write(rMLVL);
|
DarkWorldNameID.Write(rMLVL);
|
||||||
}
|
}
|
||||||
if (Game >= eEchoesDemo && Game <= eCorruption)
|
if (Game >= EGame::EchoesDemo && Game <= EGame::Corruption)
|
||||||
{
|
{
|
||||||
rMLVL.WriteLong(pWorld->mTempleKeyWorldIndex);
|
rMLVL.WriteLong(pWorld->mTempleKeyWorldIndex);
|
||||||
}
|
}
|
||||||
if (Game == eReturns)
|
if (Game == EGame::DKCReturns)
|
||||||
{
|
{
|
||||||
const CWorld::STimeAttackData& rkData = pWorld->mTimeAttackData;
|
const CWorld::STimeAttackData& rkData = pWorld->mTimeAttackData;
|
||||||
rMLVL.WriteBool(rkData.HasTimeAttack);
|
rMLVL.WriteBool(rkData.HasTimeAttack);
|
||||||
|
@ -49,7 +49,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
|
||||||
DefaultSkyID.Write(rMLVL);
|
DefaultSkyID.Write(rMLVL);
|
||||||
|
|
||||||
// Memory Relays
|
// Memory Relays
|
||||||
if (Game == ePrime)
|
if (Game == EGame::Prime)
|
||||||
{
|
{
|
||||||
rMLVL.WriteLong( pWorld->mMemoryRelays.size() );
|
rMLVL.WriteLong( pWorld->mMemoryRelays.size() );
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
|
||||||
|
|
||||||
// Areas
|
// Areas
|
||||||
rMLVL.WriteLong(pWorld->mAreas.size());
|
rMLVL.WriteLong(pWorld->mAreas.size());
|
||||||
if (Game <= ePrime) rMLVL.WriteLong(1); // Unknown
|
if (Game <= EGame::Prime) rMLVL.WriteLong(1); // Unknown
|
||||||
std::set<CAssetID> AudioGroups;
|
std::set<CAssetID> AudioGroups;
|
||||||
|
|
||||||
for (u32 iArea = 0; iArea < pWorld->mAreas.size(); iArea++)
|
for (u32 iArea = 0; iArea < pWorld->mAreas.size(); iArea++)
|
||||||
|
@ -83,7 +83,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
|
||||||
rArea.AreaID.Write(rMLVL);
|
rArea.AreaID.Write(rMLVL);
|
||||||
|
|
||||||
// Attached Areas
|
// Attached Areas
|
||||||
if (Game <= eCorruption)
|
if (Game <= EGame::Corruption)
|
||||||
{
|
{
|
||||||
rMLVL.WriteLong( rArea.AttachedAreaIDs.size() );
|
rMLVL.WriteLong( rArea.AttachedAreaIDs.size() );
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dependencies
|
// Dependencies
|
||||||
if (Game <= eEchoes)
|
if (Game <= EGame::Echoes)
|
||||||
{
|
{
|
||||||
std::list<CAssetID> Dependencies;
|
std::list<CAssetID> Dependencies;
|
||||||
std::list<u32> LayerDependsOffsets;
|
std::list<u32> LayerDependsOffsets;
|
||||||
|
@ -117,7 +117,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Docks
|
// Docks
|
||||||
if (Game <= eCorruption)
|
if (Game <= EGame::Corruption)
|
||||||
{
|
{
|
||||||
rMLVL.WriteLong( rArea.Docks.size() );
|
rMLVL.WriteLong( rArea.Docks.size() );
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Module Dependencies
|
// Module Dependencies
|
||||||
if (Game == eEchoesDemo || Game == eEchoes)
|
if (Game == EGame::EchoesDemo || Game == EGame::Echoes)
|
||||||
{
|
{
|
||||||
std::vector<TString> ModuleNames;
|
std::vector<TString> ModuleNames;
|
||||||
std::vector<u32> ModuleLayerOffsets;
|
std::vector<u32> ModuleLayerOffsets;
|
||||||
|
@ -160,15 +160,15 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unknown
|
// Unknown
|
||||||
if (Game == eReturns)
|
if (Game == EGame::DKCReturns)
|
||||||
rMLVL.WriteLong(0);
|
rMLVL.WriteLong(0);
|
||||||
|
|
||||||
// Internal Name
|
// Internal Name
|
||||||
if (Game >= eEchoesDemo)
|
if (Game >= EGame::EchoesDemo)
|
||||||
rMLVL.WriteString(rArea.InternalName);
|
rMLVL.WriteString(rArea.InternalName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Game <= eCorruption)
|
if (Game <= EGame::Corruption)
|
||||||
{
|
{
|
||||||
// World Map
|
// World Map
|
||||||
CAssetID MapWorldID = pWorld->mpMapWorld ? pWorld->mpMapWorld->ID() : CAssetID::skInvalidID32;
|
CAssetID MapWorldID = pWorld->mpMapWorld ? pWorld->mpMapWorld->ID() : CAssetID::skInvalidID32;
|
||||||
|
@ -180,7 +180,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Audio Groups
|
// Audio Groups
|
||||||
if (Game <= ePrime)
|
if (Game <= EGame::Prime)
|
||||||
{
|
{
|
||||||
// Create sorted list of audio groups (sort by group ID)
|
// Create sorted list of audio groups (sort by group ID)
|
||||||
std::vector<CAudioGroup*> SortedAudioGroups;
|
std::vector<CAudioGroup*> SortedAudioGroups;
|
||||||
|
@ -244,7 +244,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
|
||||||
rMLVL.WriteString(LayerNames[iLyr]);
|
rMLVL.WriteString(LayerNames[iLyr]);
|
||||||
|
|
||||||
// Layer Saved State IDs
|
// Layer Saved State IDs
|
||||||
if (Game >= eCorruption)
|
if (Game >= EGame::Corruption)
|
||||||
{
|
{
|
||||||
rMLVL.WriteLong(LayerStateIDs.size());
|
rMLVL.WriteLong(LayerStateIDs.size());
|
||||||
|
|
||||||
|
@ -265,12 +265,12 @@ u32 CWorldCooker::GetMLVLVersion(EGame Version)
|
||||||
{
|
{
|
||||||
switch (Version)
|
switch (Version)
|
||||||
{
|
{
|
||||||
case ePrimeDemo: return 0xD;
|
case EGame::PrimeDemo: return 0xD;
|
||||||
case ePrime: return 0x11;
|
case EGame::Prime: return 0x11;
|
||||||
case eEchoesDemo: return 0x14;
|
case EGame::EchoesDemo: return 0x14;
|
||||||
case eEchoes: return 0x17;
|
case EGame::Echoes: return 0x17;
|
||||||
case eCorruption: return 0x19;
|
case EGame::Corruption: return 0x19;
|
||||||
case eReturns: return 0x1B;
|
case EGame::DKCReturns: return 0x1B;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,9 +47,9 @@ s32 CAnimEventLoader::LoadEventBase(IInputStream& rEVNT)
|
||||||
{
|
{
|
||||||
rEVNT.Skip(0x2);
|
rEVNT.Skip(0x2);
|
||||||
rEVNT.ReadString();
|
rEVNT.ReadString();
|
||||||
rEVNT.Skip(mGame < eCorruptionProto ? 0x13 : 0x17);
|
rEVNT.Skip(mGame < EGame::CorruptionProto ? 0x13 : 0x17);
|
||||||
s32 CharacterIndex = rEVNT.ReadLong();
|
s32 CharacterIndex = rEVNT.ReadLong();
|
||||||
rEVNT.Skip(mGame < eCorruptionProto ? 0x4 : 0x18);
|
rEVNT.Skip(mGame < EGame::CorruptionProto ? 0x4 : 0x18);
|
||||||
return CharacterIndex;
|
return CharacterIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,13 +69,13 @@ void CAnimEventLoader::LoadUserEvent(IInputStream& rEVNT)
|
||||||
void CAnimEventLoader::LoadEffectEvent(IInputStream& rEVNT)
|
void CAnimEventLoader::LoadEffectEvent(IInputStream& rEVNT)
|
||||||
{
|
{
|
||||||
s32 CharIndex = LoadEventBase(rEVNT);
|
s32 CharIndex = LoadEventBase(rEVNT);
|
||||||
rEVNT.Skip(mGame < eCorruptionProto ? 0x8 : 0x4);
|
rEVNT.Skip(mGame < EGame::CorruptionProto ? 0x8 : 0x4);
|
||||||
CAssetID ParticleID(rEVNT, mGame);
|
CAssetID ParticleID(rEVNT, mGame);
|
||||||
mpEventData->AddEvent(CharIndex, ParticleID);
|
mpEventData->AddEvent(CharIndex, ParticleID);
|
||||||
|
|
||||||
if (mGame <= ePrime)
|
if (mGame <= EGame::Prime)
|
||||||
rEVNT.ReadString();
|
rEVNT.ReadString();
|
||||||
else if (mGame <= eEchoes)
|
else if (mGame <= EGame::Echoes)
|
||||||
rEVNT.Skip(0x4);
|
rEVNT.Skip(0x4);
|
||||||
|
|
||||||
rEVNT.Skip(0x8);
|
rEVNT.Skip(0x8);
|
||||||
|
@ -86,11 +86,11 @@ void CAnimEventLoader::LoadSoundEvent(IInputStream& rEVNT)
|
||||||
s32 CharIndex = LoadEventBase(rEVNT);
|
s32 CharIndex = LoadEventBase(rEVNT);
|
||||||
|
|
||||||
// Metroid Prime 1/2
|
// Metroid Prime 1/2
|
||||||
if (mGame <= eEchoes)
|
if (mGame <= EGame::Echoes)
|
||||||
{
|
{
|
||||||
u32 SoundID = rEVNT.ReadLong() & 0xFFFF;
|
u32 SoundID = rEVNT.ReadLong() & 0xFFFF;
|
||||||
rEVNT.Skip(0x8);
|
rEVNT.Skip(0x8);
|
||||||
if (mGame >= eEchoes) rEVNT.Skip(0xC);
|
if (mGame >= EGame::Echoes) rEVNT.Skip(0xC);
|
||||||
|
|
||||||
if (SoundID != 0xFFFF)
|
if (SoundID != 0xFFFF)
|
||||||
{
|
{
|
||||||
|
@ -134,7 +134,7 @@ CAnimEventData* CAnimEventLoader::LoadEVNT(IInputStream& rEVNT, CResourceEntry *
|
||||||
{
|
{
|
||||||
CAnimEventLoader Loader;
|
CAnimEventLoader Loader;
|
||||||
Loader.mpEventData = new CAnimEventData(pEntry);
|
Loader.mpEventData = new CAnimEventData(pEntry);
|
||||||
Loader.mGame = ePrime;
|
Loader.mGame = EGame::Prime;
|
||||||
Loader.LoadEvents(rEVNT);
|
Loader.LoadEvents(rEVNT);
|
||||||
return Loader.mpEventData;
|
return Loader.mpEventData;
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ CAnimEventData* CAnimEventLoader::LoadAnimSetEvents(IInputStream& rANCS)
|
||||||
{
|
{
|
||||||
CAnimEventLoader Loader;
|
CAnimEventLoader Loader;
|
||||||
Loader.mpEventData = new CAnimEventData();
|
Loader.mpEventData = new CAnimEventData();
|
||||||
Loader.mGame = eEchoes;
|
Loader.mGame = EGame::Echoes;
|
||||||
Loader.LoadEvents(rANCS);
|
Loader.LoadEvents(rANCS);
|
||||||
return Loader.mpEventData;
|
return Loader.mpEventData;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ CAnimEventData* CAnimEventLoader::LoadCorruptionCharacterEventSet(IInputStream&
|
||||||
{
|
{
|
||||||
CAnimEventLoader Loader;
|
CAnimEventLoader Loader;
|
||||||
Loader.mpEventData = new CAnimEventData();
|
Loader.mpEventData = new CAnimEventData();
|
||||||
Loader.mGame = eCorruption;
|
Loader.mGame = EGame::Corruption;
|
||||||
|
|
||||||
// Read event set header
|
// Read event set header
|
||||||
rCHAR.Skip(0x4); // Skip animation ID
|
rCHAR.Skip(0x4); // Skip animation ID
|
||||||
|
|
|
@ -116,8 +116,8 @@ CAnimSet* CAnimSetLoader::LoadReturnsCHAR(IInputStream& rCHAR)
|
||||||
for (u32 ModelIdx = 0; ModelIdx < NumModels; ModelIdx++)
|
for (u32 ModelIdx = 0; ModelIdx < NumModels; ModelIdx++)
|
||||||
{
|
{
|
||||||
rCHAR.ReadString();
|
rCHAR.ReadString();
|
||||||
CAssetID ModelID(rCHAR, eReturns);
|
CAssetID ModelID(rCHAR, EGame::DKCReturns);
|
||||||
CAssetID SkinID(rCHAR, eReturns);
|
CAssetID SkinID(rCHAR, EGame::DKCReturns);
|
||||||
rCHAR.Skip(0x18);
|
rCHAR.Skip(0x18);
|
||||||
|
|
||||||
if (ModelIdx == 0)
|
if (ModelIdx == 0)
|
||||||
|
@ -138,7 +138,7 @@ CAnimSet* CAnimSetLoader::LoadReturnsCHAR(IInputStream& rCHAR)
|
||||||
for (u32 AnimIdx = 0; AnimIdx < NumAnims; AnimIdx++)
|
for (u32 AnimIdx = 0; AnimIdx < NumAnims; AnimIdx++)
|
||||||
{
|
{
|
||||||
TString AnimName = rCHAR.ReadString();
|
TString AnimName = rCHAR.ReadString();
|
||||||
CAssetID AnimID(rCHAR, eReturns);
|
CAssetID AnimID(rCHAR, EGame::DKCReturns);
|
||||||
rCHAR.Skip(0x25);
|
rCHAR.Skip(0x25);
|
||||||
rChar.DKDependencies.push_back(AnimID);
|
rChar.DKDependencies.push_back(AnimID);
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ CAnimSet* CAnimSetLoader::LoadReturnsCHAR(IInputStream& rCHAR)
|
||||||
|
|
||||||
for (u32 ResIdx = 0; ResIdx < NumResources; ResIdx++)
|
for (u32 ResIdx = 0; ResIdx < NumResources; ResIdx++)
|
||||||
{
|
{
|
||||||
CAssetID ResID(rCHAR, eReturns);
|
CAssetID ResID(rCHAR, EGame::DKCReturns);
|
||||||
rCHAR.Skip(3);
|
rCHAR.Skip(3);
|
||||||
rChar.DKDependencies.push_back(ResID);
|
rChar.DKDependencies.push_back(ResID);
|
||||||
}
|
}
|
||||||
|
@ -293,7 +293,7 @@ void CAnimSetLoader::LoadParticleResourceData(IInputStream& rFile, SSetCharacter
|
||||||
for (u32 iSwoosh = 0; iSwoosh < SwooshCount; iSwoosh++)
|
for (u32 iSwoosh = 0; iSwoosh < SwooshCount; iSwoosh++)
|
||||||
pChar->SwooshParticles.push_back( CAssetID(rFile, mGame) );
|
pChar->SwooshParticles.push_back( CAssetID(rFile, mGame) );
|
||||||
|
|
||||||
if (CharVersion >= 6 && mGame <= eEchoes) rFile.Seek(0x4, SEEK_CUR);
|
if (CharVersion >= 6 && mGame <= EGame::Echoes) rFile.Seek(0x4, SEEK_CUR);
|
||||||
|
|
||||||
u32 ElectricCount = rFile.ReadLong();
|
u32 ElectricCount = rFile.ReadLong();
|
||||||
pChar->ElectricParticles.reserve(ElectricCount);
|
pChar->ElectricParticles.reserve(ElectricCount);
|
||||||
|
@ -301,7 +301,7 @@ void CAnimSetLoader::LoadParticleResourceData(IInputStream& rFile, SSetCharacter
|
||||||
for (u32 iElec = 0; iElec < ElectricCount; iElec++)
|
for (u32 iElec = 0; iElec < ElectricCount; iElec++)
|
||||||
pChar->ElectricParticles.push_back( CAssetID(rFile, mGame) );
|
pChar->ElectricParticles.push_back( CAssetID(rFile, mGame) );
|
||||||
|
|
||||||
if (mGame >= eEchoes)
|
if (mGame >= EGame::Echoes)
|
||||||
{
|
{
|
||||||
u32 SpawnCount = rFile.ReadLong();
|
u32 SpawnCount = rFile.ReadLong();
|
||||||
pChar->SpawnParticles.reserve(SpawnCount);
|
pChar->SpawnParticles.reserve(SpawnCount);
|
||||||
|
@ -311,7 +311,7 @@ void CAnimSetLoader::LoadParticleResourceData(IInputStream& rFile, SSetCharacter
|
||||||
}
|
}
|
||||||
|
|
||||||
rFile.Seek(0x4, SEEK_CUR);
|
rFile.Seek(0x4, SEEK_CUR);
|
||||||
if (mGame >= eEchoes) rFile.Seek(0x4, SEEK_CUR);
|
if (mGame >= EGame::Echoes) rFile.Seek(0x4, SEEK_CUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimSetLoader::LoadAnimationSet(IInputStream& rANCS)
|
void CAnimSetLoader::LoadAnimationSet(IInputStream& rANCS)
|
||||||
|
@ -379,7 +379,7 @@ void CAnimSetLoader::LoadAnimationSet(IInputStream& rANCS)
|
||||||
|
|
||||||
// Skipping MP1 ANIM asset list
|
// Skipping MP1 ANIM asset list
|
||||||
// Events
|
// Events
|
||||||
if (mGame >= eEchoesDemo)
|
if (mGame >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
u32 EventDataCount = rANCS.ReadLong();
|
u32 EventDataCount = rANCS.ReadLong();
|
||||||
pSet->mAnimEvents.reserve(EventDataCount);
|
pSet->mAnimEvents.reserve(EventDataCount);
|
||||||
|
@ -410,7 +410,7 @@ void CAnimSetLoader::ProcessPrimitives()
|
||||||
for (u32 iTrans = 0; iTrans < pSet->mHalfTransitions.size(); iTrans++)
|
for (u32 iTrans = 0; iTrans < pSet->mHalfTransitions.size(); iTrans++)
|
||||||
pSet->mHalfTransitions[iTrans].pMetaTrans->GetUniquePrimitives(UniquePrimitives);
|
pSet->mHalfTransitions[iTrans].pMetaTrans->GetUniquePrimitives(UniquePrimitives);
|
||||||
|
|
||||||
if (mGame == eCorruptionProto || mGame == eCorruption)
|
if (mGame == EGame::CorruptionProto || mGame == EGame::Corruption)
|
||||||
{
|
{
|
||||||
CSourceAnimData *pAnimData = gpResourceStore->LoadResource<CSourceAnimData>( pSet->mCharacters[0].AnimDataID );
|
CSourceAnimData *pAnimData = gpResourceStore->LoadResource<CSourceAnimData>( pSet->mCharacters[0].AnimDataID );
|
||||||
|
|
||||||
|
@ -431,7 +431,7 @@ void CAnimSetLoader::ProcessPrimitives()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add used animation indices from the animset to the character's list
|
// Add used animation indices from the animset to the character's list
|
||||||
if (mGame <= eEchoes)
|
if (mGame <= EGame::Echoes)
|
||||||
{
|
{
|
||||||
// Add animations referenced by default transition
|
// Add animations referenced by default transition
|
||||||
if (pSet->mpDefaultTransition)
|
if (pSet->mpDefaultTransition)
|
||||||
|
@ -537,9 +537,9 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
||||||
|
|
||||||
pChar->ID = rANCS.ReadLong();
|
pChar->ID = rANCS.ReadLong();
|
||||||
u16 CharVersion = rANCS.ReadShort();
|
u16 CharVersion = rANCS.ReadShort();
|
||||||
if (iNode == 0 && Loader.mGame == eUnknownGame)
|
if (iNode == 0 && Loader.mGame == EGame::Invalid)
|
||||||
{
|
{
|
||||||
Loader.mGame = (CharVersion == 0xA) ? eEchoes : ePrime;
|
Loader.mGame = (CharVersion == 0xA) ? EGame::Echoes : EGame::Prime;
|
||||||
}
|
}
|
||||||
pChar->Name = rANCS.ReadString();
|
pChar->Name = rANCS.ReadString();
|
||||||
pChar->pModel = gpResourceStore->LoadResource<CModel>(rANCS.ReadLong());
|
pChar->pModel = gpResourceStore->LoadResource<CModel>(rANCS.ReadLong());
|
||||||
|
@ -554,7 +554,7 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
||||||
for (u32 iAnim = 0; iAnim < AnimCount; iAnim++)
|
for (u32 iAnim = 0; iAnim < AnimCount; iAnim++)
|
||||||
{
|
{
|
||||||
rANCS.Seek(0x4, SEEK_CUR);
|
rANCS.Seek(0x4, SEEK_CUR);
|
||||||
if (Loader.mGame == ePrime) rANCS.Seek(0x1, SEEK_CUR);
|
if (Loader.mGame == EGame::Prime) rANCS.Seek(0x1, SEEK_CUR);
|
||||||
rANCS.ReadString();
|
rANCS.ReadString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,8 +584,8 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
||||||
CAssetID ParticleID(rANCS, e32Bit);
|
CAssetID ParticleID(rANCS, e32Bit);
|
||||||
if (ParticleID.IsValid()) pChar->EffectParticles.push_back(ParticleID);
|
if (ParticleID.IsValid()) pChar->EffectParticles.push_back(ParticleID);
|
||||||
|
|
||||||
if (Loader.mGame == ePrime) rANCS.ReadString();
|
if (Loader.mGame == EGame::Prime) rANCS.ReadString();
|
||||||
if (Loader.mGame == eEchoes) rANCS.Seek(0x4, SEEK_CUR);
|
if (Loader.mGame == EGame::Echoes) rANCS.Seek(0x4, SEEK_CUR);
|
||||||
rANCS.Seek(0xC, SEEK_CUR);
|
rANCS.Seek(0xC, SEEK_CUR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -604,7 +604,7 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
||||||
pChar->UsedAnimationIndices.insert(AnimIndex);
|
pChar->UsedAnimationIndices.insert(AnimIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Loader.mGame == eEchoes)
|
if (Loader.mGame == EGame::Echoes)
|
||||||
{
|
{
|
||||||
pChar->SpatialPrimitives = rANCS.ReadLong();
|
pChar->SpatialPrimitives = rANCS.ReadLong();
|
||||||
rANCS.Seek(0x1, SEEK_CUR);
|
rANCS.Seek(0x1, SEEK_CUR);
|
||||||
|
@ -629,14 +629,14 @@ CAnimSet* CAnimSetLoader::LoadCHAR(IInputStream& rCHAR, CResourceEntry *pEntry)
|
||||||
|
|
||||||
if (Check == 0x5 || Check == 0x3)
|
if (Check == 0x5 || Check == 0x3)
|
||||||
{
|
{
|
||||||
Loader.mGame = eCorruption;
|
Loader.mGame = EGame::Corruption;
|
||||||
Loader.pSet = new CAnimSet(pEntry);
|
Loader.pSet = new CAnimSet(pEntry);
|
||||||
return Loader.LoadCorruptionCHAR(rCHAR);
|
return Loader.LoadCorruptionCHAR(rCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Check == 0x59)
|
if (Check == 0x59)
|
||||||
{
|
{
|
||||||
Loader.mGame = eReturns;
|
Loader.mGame = EGame::DKCReturns;
|
||||||
Loader.pSet = new CAnimSet(pEntry);
|
Loader.pSet = new CAnimSet(pEntry);
|
||||||
return Loader.LoadReturnsCHAR(rCHAR);
|
return Loader.LoadReturnsCHAR(rCHAR);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ EGame CAnimationLoader::UncompressedCheckVersion()
|
||||||
u32 Start = mpInput->Tell();
|
u32 Start = mpInput->Tell();
|
||||||
bool Echoes = UncompressedCheckEchoes();
|
bool Echoes = UncompressedCheckEchoes();
|
||||||
mpInput->Seek(Start, SEEK_SET);
|
mpInput->Seek(Start, SEEK_SET);
|
||||||
return (Echoes ? eEchoes : ePrime);
|
return (Echoes ? EGame::Echoes : EGame::Prime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimationLoader::ReadUncompressedANIM()
|
void CAnimationLoader::ReadUncompressedANIM()
|
||||||
|
@ -75,13 +75,13 @@ void CAnimationLoader::ReadUncompressedANIM()
|
||||||
NumBoneChannels++;
|
NumBoneChannels++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mGame == eUnknownGame)
|
if (mGame == EGame::Invalid)
|
||||||
mGame = UncompressedCheckVersion();
|
mGame = UncompressedCheckVersion();
|
||||||
|
|
||||||
// Echoes only - rotation channel indices
|
// Echoes only - rotation channel indices
|
||||||
std::vector<u8> RotationIndices;
|
std::vector<u8> RotationIndices;
|
||||||
|
|
||||||
if (mGame == eEchoes)
|
if (mGame == EGame::Echoes)
|
||||||
{
|
{
|
||||||
u32 NumRotationIndices = mpInput->ReadLong();
|
u32 NumRotationIndices = mpInput->ReadLong();
|
||||||
RotationIndices.resize(NumRotationIndices);
|
RotationIndices.resize(NumRotationIndices);
|
||||||
|
@ -125,7 +125,7 @@ void CAnimationLoader::ReadUncompressedANIM()
|
||||||
// Echoes only - scale channel indices
|
// Echoes only - scale channel indices
|
||||||
std::vector<u8> ScaleIndices;
|
std::vector<u8> ScaleIndices;
|
||||||
|
|
||||||
if (mGame == eEchoes)
|
if (mGame == EGame::Echoes)
|
||||||
{
|
{
|
||||||
u32 NumScaleIndices = mpInput->ReadLong();
|
u32 NumScaleIndices = mpInput->ReadLong();
|
||||||
ScaleIndices.resize(NumScaleIndices);
|
ScaleIndices.resize(NumScaleIndices);
|
||||||
|
@ -161,7 +161,7 @@ void CAnimationLoader::ReadUncompressedANIM()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read bone transforms
|
// Read bone transforms
|
||||||
if (mGame == eEchoes)
|
if (mGame == EGame::Echoes)
|
||||||
{
|
{
|
||||||
mpInput->Seek(0x4, SEEK_CUR); // Skipping scale key count
|
mpInput->Seek(0x4, SEEK_CUR); // Skipping scale key count
|
||||||
mpAnim->mScaleChannels.resize(NumScaleChannels);
|
mpAnim->mScaleChannels.resize(NumScaleChannels);
|
||||||
|
@ -197,7 +197,7 @@ void CAnimationLoader::ReadUncompressedANIM()
|
||||||
mpAnim->mTranslationChannels[iTrans][iKey] = CVector3f(*mpInput);
|
mpAnim->mTranslationChannels[iTrans][iKey] = CVector3f(*mpInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mGame == ePrime)
|
if (mGame == EGame::Prime)
|
||||||
{
|
{
|
||||||
mpAnim->mpEventData = gpResourceStore->LoadResource<CAnimEventData>(mpInput->ReadLong());
|
mpAnim->mpEventData = gpResourceStore->LoadResource<CAnimEventData>(mpInput->ReadLong());
|
||||||
}
|
}
|
||||||
|
@ -208,10 +208,10 @@ void CAnimationLoader::ReadCompressedANIM()
|
||||||
// Header
|
// Header
|
||||||
mpInput->Seek(0x4, SEEK_CUR); // Skip alloc size
|
mpInput->Seek(0x4, SEEK_CUR); // Skip alloc size
|
||||||
|
|
||||||
if (mGame == eUnknownGame)
|
if (mGame == EGame::Invalid)
|
||||||
mGame = (mpInput->PeekShort() == 0x0101 ? eEchoes : ePrime);
|
mGame = (mpInput->PeekShort() == 0x0101 ? EGame::Echoes : EGame::Prime);
|
||||||
|
|
||||||
if (mGame == ePrime)
|
if (mGame == EGame::Prime)
|
||||||
{
|
{
|
||||||
mpAnim->mpEventData = gpResourceStore->LoadResource<CAnimEventData>(mpInput->ReadLong());
|
mpAnim->mpEventData = gpResourceStore->LoadResource<CAnimEventData>(mpInput->ReadLong());
|
||||||
mpInput->Seek(0x4, SEEK_CUR); // Skip unknown
|
mpInput->Seek(0x4, SEEK_CUR); // Skip unknown
|
||||||
|
@ -224,7 +224,7 @@ void CAnimationLoader::ReadCompressedANIM()
|
||||||
|
|
||||||
mRotationDivisor = mpInput->ReadLong();
|
mRotationDivisor = mpInput->ReadLong();
|
||||||
mTranslationMultiplier = mpInput->ReadFloat();
|
mTranslationMultiplier = mpInput->ReadFloat();
|
||||||
if (mGame == eEchoes) mScaleMultiplier = mpInput->ReadFloat();
|
if (mGame == EGame::Echoes) mScaleMultiplier = mpInput->ReadFloat();
|
||||||
u32 NumBoneChannels = mpInput->ReadLong();
|
u32 NumBoneChannels = mpInput->ReadLong();
|
||||||
mpInput->Seek(0x4, SEEK_CUR); // Skip unknown value
|
mpInput->Seek(0x4, SEEK_CUR); // Skip unknown value
|
||||||
|
|
||||||
|
@ -238,7 +238,7 @@ void CAnimationLoader::ReadCompressedANIM()
|
||||||
for (u32 iBit = 0; iBit < NumKeys; iBit++)
|
for (u32 iBit = 0; iBit < NumKeys; iBit++)
|
||||||
mKeyFlags[iBit] = BitStream.ReadBit();
|
mKeyFlags[iBit] = BitStream.ReadBit();
|
||||||
}
|
}
|
||||||
mpInput->Seek(mGame == ePrime ? 0x8 : 0x4, SEEK_CUR);
|
mpInput->Seek(mGame == EGame::Prime ? 0x8 : 0x4, SEEK_CUR);
|
||||||
|
|
||||||
// Read bone channel descriptors
|
// Read bone channel descriptors
|
||||||
mCompressedChannels.resize(NumBoneChannels);
|
mCompressedChannels.resize(NumBoneChannels);
|
||||||
|
@ -249,7 +249,7 @@ void CAnimationLoader::ReadCompressedANIM()
|
||||||
for (u32 iChan = 0; iChan < NumBoneChannels; iChan++)
|
for (u32 iChan = 0; iChan < NumBoneChannels; iChan++)
|
||||||
{
|
{
|
||||||
SCompressedChannel& rChan = mCompressedChannels[iChan];
|
SCompressedChannel& rChan = mCompressedChannels[iChan];
|
||||||
rChan.BoneID = (mGame == ePrime ? mpInput->ReadLong() : mpInput->ReadByte());
|
rChan.BoneID = (mGame == EGame::Prime ? mpInput->ReadLong() : mpInput->ReadByte());
|
||||||
|
|
||||||
// Read rotation parameters
|
// Read rotation parameters
|
||||||
rChan.NumRotationKeys = mpInput->ReadShort();
|
rChan.NumRotationKeys = mpInput->ReadShort();
|
||||||
|
@ -284,7 +284,7 @@ void CAnimationLoader::ReadCompressedANIM()
|
||||||
// Read scale parameters
|
// Read scale parameters
|
||||||
u8 ScaleIdx = 0xFF;
|
u8 ScaleIdx = 0xFF;
|
||||||
|
|
||||||
if (mGame == eEchoes)
|
if (mGame == EGame::Echoes)
|
||||||
{
|
{
|
||||||
rChan.NumScaleKeys = mpInput->ReadShort();
|
rChan.NumScaleKeys = mpInput->ReadShort();
|
||||||
|
|
||||||
|
@ -465,7 +465,7 @@ CQuaternion CAnimationLoader::DequantizeRotation(bool Sign, s16 X, s16 Y, s16 Z)
|
||||||
CAnimation* CAnimationLoader::LoadANIM(IInputStream& rANIM, CResourceEntry *pEntry)
|
CAnimation* CAnimationLoader::LoadANIM(IInputStream& rANIM, CResourceEntry *pEntry)
|
||||||
{
|
{
|
||||||
// MP3/DKCR unsupported
|
// MP3/DKCR unsupported
|
||||||
if (pEntry->Game() > eEchoes)
|
if (pEntry->Game() > EGame::Echoes)
|
||||||
return new CAnimation(pEntry);
|
return new CAnimation(pEntry);
|
||||||
|
|
||||||
u32 CompressionType = rANIM.ReadLong();
|
u32 CompressionType = rANIM.ReadLong();
|
||||||
|
|
|
@ -81,7 +81,7 @@ void CAreaLoader::ReadGeometryPrime()
|
||||||
CModel *pModel = CModelLoader::LoadWorldModel(*mpMREA, *mpSectionMgr, *mpArea->mpMaterialSet, mVersion);
|
CModel *pModel = CModelLoader::LoadWorldModel(*mpMREA, *mpSectionMgr, *mpArea->mpMaterialSet, mVersion);
|
||||||
FileModels.push_back(pModel);
|
FileModels.push_back(pModel);
|
||||||
|
|
||||||
if (mVersion <= ePrime)
|
if (mVersion <= EGame::Prime)
|
||||||
mpArea->AddWorldModel(pModel);
|
mpArea->AddWorldModel(pModel);
|
||||||
|
|
||||||
// For Echoes+, load surface mesh IDs, then skip to the start of the next mesh
|
// For Echoes+, load surface mesh IDs, then skip to the start of the next mesh
|
||||||
|
@ -101,7 +101,7 @@ void CAreaLoader::ReadGeometryPrime()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split meshes
|
// Split meshes
|
||||||
if (mVersion >= eEchoesDemo)
|
if (mVersion >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
std::vector<CModel*> SplitModels;
|
std::vector<CModel*> SplitModels;
|
||||||
CModelLoader::BuildWorldMeshes(FileModels, SplitModels, true);
|
CModelLoader::BuildWorldMeshes(FileModels, SplitModels, true);
|
||||||
|
@ -124,7 +124,7 @@ void CAreaLoader::ReadSCLYPrime()
|
||||||
Log::FileError(mpMREA->GetSourceString(), mpMREA->Tell() - 4, "Invalid SCLY magic: " + SCLY.ToString());
|
Log::FileError(mpMREA->GetSourceString(), mpMREA->Tell() - 4, "Invalid SCLY magic: " + SCLY.ToString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mpMREA->Seek(mVersion <= ePrime ? 4 : 1, SEEK_CUR); // Skipping unknown value which is always 1
|
mpMREA->Seek(mVersion <= EGame::Prime ? 4 : 1, SEEK_CUR); // Skipping unknown value which is always 1
|
||||||
|
|
||||||
// Read layer sizes
|
// Read layer sizes
|
||||||
mNumLayers = mpMREA->ReadLong();
|
mNumLayers = mpMREA->ReadLong();
|
||||||
|
@ -145,7 +145,7 @@ void CAreaLoader::ReadSCLYPrime()
|
||||||
// SCGN
|
// SCGN
|
||||||
CScriptLayer *pGenLayer = nullptr;
|
CScriptLayer *pGenLayer = nullptr;
|
||||||
|
|
||||||
if (mVersion >= eEchoesDemo)
|
if (mVersion >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
mpSectionMgr->ToSection(mScriptGeneratorBlockNum);
|
mpSectionMgr->ToSection(mScriptGeneratorBlockNum);
|
||||||
CFourCC SCGN = mpMREA->ReadFourCC();
|
CFourCC SCGN = mpMREA->ReadFourCC();
|
||||||
|
@ -252,7 +252,7 @@ void CAreaLoader::ReadHeaderEchoes()
|
||||||
// This function reads the header for Echoes and the Echoes demo disc
|
// This function reads the header for Echoes and the Echoes demo disc
|
||||||
mpArea->mTransform = CTransform4f(*mpMREA);
|
mpArea->mTransform = CTransform4f(*mpMREA);
|
||||||
mNumMeshes = mpMREA->ReadLong();
|
mNumMeshes = mpMREA->ReadLong();
|
||||||
if (mVersion == eEchoes) mNumLayers = mpMREA->ReadLong();
|
if (mVersion == EGame::Echoes) mNumLayers = mpMREA->ReadLong();
|
||||||
u32 numBlocks = mpMREA->ReadLong();
|
u32 numBlocks = mpMREA->ReadLong();
|
||||||
|
|
||||||
mGeometryBlockNum = mpMREA->ReadLong();
|
mGeometryBlockNum = mpMREA->ReadLong();
|
||||||
|
@ -266,13 +266,13 @@ void CAreaLoader::ReadHeaderEchoes()
|
||||||
mFFFFBlockNum = mpMREA->ReadLong();
|
mFFFFBlockNum = mpMREA->ReadLong();
|
||||||
mPTLABlockNum = mpMREA->ReadLong();
|
mPTLABlockNum = mpMREA->ReadLong();
|
||||||
mEGMCBlockNum = mpMREA->ReadLong();
|
mEGMCBlockNum = mpMREA->ReadLong();
|
||||||
if (mVersion == eEchoes) mClusters.resize(mpMREA->ReadLong());
|
if (mVersion == EGame::Echoes) mClusters.resize(mpMREA->ReadLong());
|
||||||
mpMREA->SeekToBoundary(32);
|
mpMREA->SeekToBoundary(32);
|
||||||
|
|
||||||
mpSectionMgr = new CSectionMgrIn(numBlocks, mpMREA);
|
mpSectionMgr = new CSectionMgrIn(numBlocks, mpMREA);
|
||||||
mpMREA->SeekToBoundary(32);
|
mpMREA->SeekToBoundary(32);
|
||||||
|
|
||||||
if (mVersion == eEchoes)
|
if (mVersion == EGame::Echoes)
|
||||||
{
|
{
|
||||||
ReadCompressedBlocks();
|
ReadCompressedBlocks();
|
||||||
Decompress();
|
Decompress();
|
||||||
|
@ -440,7 +440,7 @@ void CAreaLoader::ReadDependenciesCorruption()
|
||||||
|
|
||||||
for (u32 DepIdx = 0; DepIdx < NumLayerDeps; DepIdx++)
|
for (u32 DepIdx = 0; DepIdx < NumLayerDeps; DepIdx++)
|
||||||
{
|
{
|
||||||
CAssetID AssetID(*mpMREA, eCorruption);
|
CAssetID AssetID(*mpMREA, EGame::Corruption);
|
||||||
mpMREA->Skip(4);
|
mpMREA->Skip(4);
|
||||||
mpArea->mExtraLayerDeps[LayerIdx].push_back(AssetID);
|
mpArea->mExtraLayerDeps[LayerIdx].push_back(AssetID);
|
||||||
}
|
}
|
||||||
|
@ -452,7 +452,7 @@ void CAreaLoader::ReadDependenciesCorruption()
|
||||||
|
|
||||||
for (u32 DepIdx = 0; DepIdx < NumAreaDeps; DepIdx++)
|
for (u32 DepIdx = 0; DepIdx < NumAreaDeps; DepIdx++)
|
||||||
{
|
{
|
||||||
CAssetID AssetID(*mpMREA, eCorruption);
|
CAssetID AssetID(*mpMREA, EGame::Corruption);
|
||||||
mpMREA->Skip(4);
|
mpMREA->Skip(4);
|
||||||
mpArea->mExtraAreaDeps.push_back(AssetID);
|
mpArea->mExtraAreaDeps.push_back(AssetID);
|
||||||
}
|
}
|
||||||
|
@ -562,7 +562,7 @@ void CAreaLoader::Decompress()
|
||||||
{
|
{
|
||||||
// This function decompresses compressed clusters into a buffer.
|
// This function decompresses compressed clusters into a buffer.
|
||||||
// It should be called at the beginning of the first compressed cluster.
|
// It should be called at the beginning of the first compressed cluster.
|
||||||
if (mVersion < eEchoes) return;
|
if (mVersion < EGame::Echoes) return;
|
||||||
|
|
||||||
// Decompress clusters
|
// Decompress clusters
|
||||||
mpDecmpBuffer = new u8[mTotalDecmpSize];
|
mpDecmpBuffer = new u8[mTotalDecmpSize];
|
||||||
|
@ -699,7 +699,7 @@ void CAreaLoader::SetUpObjects(CScriptLayer *pGenLayer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove "-component" garbage from MP1 instance names
|
// Remove "-component" garbage from MP1 instance names
|
||||||
if (mVersion <= ePrime)
|
if (mVersion <= EGame::Prime)
|
||||||
{
|
{
|
||||||
TString InstanceName = pInst->InstanceName();
|
TString InstanceName = pInst->InstanceName();
|
||||||
|
|
||||||
|
@ -747,8 +747,8 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
|
||||||
|
|
||||||
switch (Loader.mVersion)
|
switch (Loader.mVersion)
|
||||||
{
|
{
|
||||||
case ePrimeDemo:
|
case EGame::PrimeDemo:
|
||||||
case ePrime:
|
case EGame::Prime:
|
||||||
Loader.ReadHeaderPrime();
|
Loader.ReadHeaderPrime();
|
||||||
Loader.ReadGeometryPrime();
|
Loader.ReadGeometryPrime();
|
||||||
Loader.ReadSCLYPrime();
|
Loader.ReadSCLYPrime();
|
||||||
|
@ -756,7 +756,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
|
||||||
Loader.ReadLightsPrime();
|
Loader.ReadLightsPrime();
|
||||||
Loader.ReadPATH();
|
Loader.ReadPATH();
|
||||||
break;
|
break;
|
||||||
case eEchoesDemo:
|
case EGame::EchoesDemo:
|
||||||
Loader.ReadHeaderEchoes();
|
Loader.ReadHeaderEchoes();
|
||||||
Loader.ReadGeometryPrime();
|
Loader.ReadGeometryPrime();
|
||||||
Loader.ReadSCLYPrime();
|
Loader.ReadSCLYPrime();
|
||||||
|
@ -766,7 +766,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
|
||||||
Loader.ReadPTLA();
|
Loader.ReadPTLA();
|
||||||
Loader.ReadEGMC();
|
Loader.ReadEGMC();
|
||||||
break;
|
break;
|
||||||
case eEchoes:
|
case EGame::Echoes:
|
||||||
Loader.ReadHeaderEchoes();
|
Loader.ReadHeaderEchoes();
|
||||||
Loader.ReadGeometryPrime();
|
Loader.ReadGeometryPrime();
|
||||||
Loader.ReadSCLYEchoes();
|
Loader.ReadSCLYEchoes();
|
||||||
|
@ -776,7 +776,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
|
||||||
Loader.ReadPTLA();
|
Loader.ReadPTLA();
|
||||||
Loader.ReadEGMC();
|
Loader.ReadEGMC();
|
||||||
break;
|
break;
|
||||||
case eCorruptionProto:
|
case EGame::CorruptionProto:
|
||||||
Loader.ReadHeaderCorruption();
|
Loader.ReadHeaderCorruption();
|
||||||
Loader.ReadGeometryPrime();
|
Loader.ReadGeometryPrime();
|
||||||
Loader.ReadDependenciesCorruption();
|
Loader.ReadDependenciesCorruption();
|
||||||
|
@ -787,14 +787,14 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
|
||||||
Loader.ReadPTLA();
|
Loader.ReadPTLA();
|
||||||
Loader.ReadEGMC();
|
Loader.ReadEGMC();
|
||||||
break;
|
break;
|
||||||
case eCorruption:
|
case EGame::Corruption:
|
||||||
case eReturns:
|
case EGame::DKCReturns:
|
||||||
Loader.ReadHeaderCorruption();
|
Loader.ReadHeaderCorruption();
|
||||||
Loader.ReadGeometryCorruption();
|
Loader.ReadGeometryCorruption();
|
||||||
Loader.ReadDependenciesCorruption();
|
Loader.ReadDependenciesCorruption();
|
||||||
Loader.ReadSCLYEchoes();
|
Loader.ReadSCLYEchoes();
|
||||||
Loader.ReadCollision();
|
Loader.ReadCollision();
|
||||||
if (Loader.mVersion == eCorruption)
|
if (Loader.mVersion == EGame::Corruption)
|
||||||
{
|
{
|
||||||
Loader.ReadLightsCorruption();
|
Loader.ReadLightsCorruption();
|
||||||
Loader.ReadPATH();
|
Loader.ReadPATH();
|
||||||
|
@ -817,13 +817,13 @@ EGame CAreaLoader::GetFormatVersion(u32 Version)
|
||||||
{
|
{
|
||||||
switch (Version)
|
switch (Version)
|
||||||
{
|
{
|
||||||
case 0xC: return ePrimeDemo;
|
case 0xC: return EGame::PrimeDemo;
|
||||||
case 0xF: return ePrime;
|
case 0xF: return EGame::Prime;
|
||||||
case 0x15: return eEchoesDemo;
|
case 0x15: return EGame::EchoesDemo;
|
||||||
case 0x19: return eEchoes;
|
case 0x19: return EGame::Echoes;
|
||||||
case 0x1D: return eCorruptionProto;
|
case 0x1D: return EGame::CorruptionProto;
|
||||||
case 0x1E: return eCorruption;
|
case 0x1E: return EGame::Corruption;
|
||||||
case 0x20: return eReturns;
|
case 0x20: return EGame::DKCReturns;
|
||||||
default: return eUnknownGame;
|
default: return EGame::Invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,11 @@ CAudioGroup* CAudioGroupLoader::LoadAGSC(IInputStream& rAGSC, CResourceEntry *pE
|
||||||
// For now we only load sound define IDs and the group ID!
|
// For now we only load sound define IDs and the group ID!
|
||||||
// Version check
|
// Version check
|
||||||
u32 Check = rAGSC.PeekLong();
|
u32 Check = rAGSC.PeekLong();
|
||||||
EGame Game = (Check == 0x1 ? eEchoes : ePrime);
|
EGame Game = (Check == 0x1 ? EGame::Echoes : EGame::Prime);
|
||||||
CAudioGroup *pOut = new CAudioGroup(pEntry);
|
CAudioGroup *pOut = new CAudioGroup(pEntry);
|
||||||
|
|
||||||
// Read header, navigate to Proj chunk
|
// Read header, navigate to Proj chunk
|
||||||
if (Game == ePrime)
|
if (Game == EGame::Prime)
|
||||||
{
|
{
|
||||||
rAGSC.ReadString();
|
rAGSC.ReadString();
|
||||||
pOut->mGroupName = rAGSC.ReadString();
|
pOut->mGroupName = rAGSC.ReadString();
|
||||||
|
@ -38,7 +38,7 @@ CAudioGroup* CAudioGroupLoader::LoadAGSC(IInputStream& rAGSC, CResourceEntry *pE
|
||||||
rAGSC.Seek(0x14, SEEK_CUR);
|
rAGSC.Seek(0x14, SEEK_CUR);
|
||||||
u32 SfxTableStart = rAGSC.ReadLong();
|
u32 SfxTableStart = rAGSC.ReadLong();
|
||||||
|
|
||||||
if (Game == ePrime)
|
if (Game == EGame::Prime)
|
||||||
pOut->mGroupID = GroupID;
|
pOut->mGroupID = GroupID;
|
||||||
else
|
else
|
||||||
ASSERT(pOut->mGroupID == GroupID);
|
ASSERT(pOut->mGroupID == GroupID);
|
||||||
|
|
|
@ -39,10 +39,10 @@ void CCollisionLoader::ParseOBBNode(IInputStream& rDCLN)
|
||||||
void CCollisionLoader::ReadPropertyFlags(IInputStream& rSrc)
|
void CCollisionLoader::ReadPropertyFlags(IInputStream& rSrc)
|
||||||
{
|
{
|
||||||
CCollisionMaterial Material;
|
CCollisionMaterial Material;
|
||||||
u64 RawFlags = (mVersion <= ePrime ? rSrc.ReadLong() : rSrc.ReadLongLong());
|
u64 RawFlags = (mVersion <= EGame::Prime ? rSrc.ReadLong() : rSrc.ReadLongLong());
|
||||||
Material.mRawFlags = RawFlags;
|
Material.mRawFlags = RawFlags;
|
||||||
|
|
||||||
if (mVersion <= ePrime)
|
if (mVersion <= EGame::Prime)
|
||||||
{
|
{
|
||||||
if (RawFlags & 0x00000001) Material |= eCF_Unknown;
|
if (RawFlags & 0x00000001) Material |= eCF_Unknown;
|
||||||
if (RawFlags & 0x00000002) Material |= eCF_Stone;
|
if (RawFlags & 0x00000002) Material |= eCF_Stone;
|
||||||
|
@ -71,7 +71,7 @@ void CCollisionLoader::ReadPropertyFlags(IInputStream& rSrc)
|
||||||
if (RawFlags & 0x80000000) Material |= eCF_Floor;
|
if (RawFlags & 0x80000000) Material |= eCF_Floor;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (mVersion <= eCorruption)
|
else if (mVersion <= EGame::Corruption)
|
||||||
{
|
{
|
||||||
if (RawFlags & 0x00000001) Material |= eCF_Unknown;
|
if (RawFlags & 0x00000001) Material |= eCF_Unknown;
|
||||||
if (RawFlags & 0x00000002) Material |= eCF_Stone;
|
if (RawFlags & 0x00000002) Material |= eCF_Stone;
|
||||||
|
@ -105,7 +105,7 @@ void CCollisionLoader::ReadPropertyFlags(IInputStream& rSrc)
|
||||||
if (RawFlags & 0x0400000000000000) Material |= eCF_JumpNotAllowed;
|
if (RawFlags & 0x0400000000000000) Material |= eCF_JumpNotAllowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (mVersion == eReturns)
|
else if (mVersion == EGame::DKCReturns)
|
||||||
{
|
{
|
||||||
if (RawFlags & 0x10000000) Material |= eCF_FlippedTri;
|
if (RawFlags & 0x10000000) Material |= eCF_FlippedTri;
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ void CCollisionLoader::LoadCollisionIndices(IInputStream &rFile, bool BuildAABox
|
||||||
}
|
}
|
||||||
|
|
||||||
// Echoes introduces a new data chunk; don't know what it is yet, skipping for now
|
// Echoes introduces a new data chunk; don't know what it is yet, skipping for now
|
||||||
if (mVersion >= eEchoes)
|
if (mVersion >= EGame::Echoes)
|
||||||
{
|
{
|
||||||
u32 UnknownCount = rFile.ReadLong();
|
u32 UnknownCount = rFile.ReadLong();
|
||||||
rFile.Seek(UnknownCount * 2, SEEK_CUR);
|
rFile.Seek(UnknownCount * 2, SEEK_CUR);
|
||||||
|
@ -236,12 +236,12 @@ CCollisionMeshGroup* CCollisionLoader::LoadDCLN(IInputStream& rDCLN, CResourceEn
|
||||||
Loader.mpMesh = new CCollisionMesh;
|
Loader.mpMesh = new CCollisionMesh;
|
||||||
Loader.mpMesh->mOctreeLoaded = false;
|
Loader.mpMesh->mOctreeLoaded = false;
|
||||||
|
|
||||||
if (Loader.mVersion == eReturns)
|
if (Loader.mVersion == EGame::DKCReturns)
|
||||||
Loader.mpMesh->mAABox = CAABox(rDCLN);
|
Loader.mpMesh->mAABox = CAABox(rDCLN);
|
||||||
|
|
||||||
// Read indices and return
|
// Read indices and return
|
||||||
rDCLN.Seek(0x4, SEEK_CUR);
|
rDCLN.Seek(0x4, SEEK_CUR);
|
||||||
Loader.LoadCollisionIndices(rDCLN, Loader.mVersion != eReturns);
|
Loader.LoadCollisionIndices(rDCLN, Loader.mVersion != EGame::DKCReturns);
|
||||||
Loader.mpGroup->AddMesh(Loader.mpMesh);
|
Loader.mpGroup->AddMesh(Loader.mpMesh);
|
||||||
|
|
||||||
// Parse OBB tree
|
// Parse OBB tree
|
||||||
|
@ -254,10 +254,10 @@ EGame CCollisionLoader::GetFormatVersion(u32 Version)
|
||||||
{
|
{
|
||||||
switch (Version)
|
switch (Version)
|
||||||
{
|
{
|
||||||
case 0x2: return ePrime;
|
case 0x2: return EGame::Prime;
|
||||||
case 0x3: return ePrime;
|
case 0x3: return EGame::Prime;
|
||||||
case 0x4: return eEchoes;
|
case 0x4: return EGame::Echoes;
|
||||||
case 0x5: return eReturns;
|
case 0x5: return EGame::DKCReturns;
|
||||||
default: return eUnknownGame;
|
default: return EGame::Invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ EGame CDependencyGroupLoader::VersionTest(IInputStream& rDGRP, u32 DepCount)
|
||||||
rDGRP.Seek(DepCount * 8, SEEK_CUR);
|
rDGRP.Seek(DepCount * 8, SEEK_CUR);
|
||||||
u32 Remaining = rDGRP.Size() - rDGRP.Tell();
|
u32 Remaining = rDGRP.Size() - rDGRP.Tell();
|
||||||
|
|
||||||
EGame Game = eCorruptionProto;
|
EGame Game = EGame::CorruptionProto;
|
||||||
|
|
||||||
if (Remaining < 32)
|
if (Remaining < 32)
|
||||||
{
|
{
|
||||||
|
@ -25,7 +25,7 @@ EGame CDependencyGroupLoader::VersionTest(IInputStream& rDGRP, u32 DepCount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsEOF) Game = ePrimeDemo;
|
if (IsEOF) Game = EGame::PrimeDemo;
|
||||||
}
|
}
|
||||||
|
|
||||||
rDGRP.Seek(Start, SEEK_SET);
|
rDGRP.Seek(Start, SEEK_SET);
|
||||||
|
|
|
@ -13,12 +13,12 @@ CFont* CFontLoader::LoadFont(IInputStream& rFONT)
|
||||||
mpFont->mLineHeight = rFONT.ReadLong();
|
mpFont->mLineHeight = rFONT.ReadLong();
|
||||||
mpFont->mVerticalOffset = rFONT.ReadLong();
|
mpFont->mVerticalOffset = rFONT.ReadLong();
|
||||||
mpFont->mLineMargin = rFONT.ReadLong();
|
mpFont->mLineMargin = rFONT.ReadLong();
|
||||||
if (mVersion > ePrimeDemo) rFONT.Seek(0x4, SEEK_CUR);
|
if (mVersion > EGame::PrimeDemo) rFONT.Seek(0x4, SEEK_CUR);
|
||||||
rFONT.Seek(0x2, SEEK_CUR);
|
rFONT.Seek(0x2, SEEK_CUR);
|
||||||
mpFont->mDefaultSize = rFONT.ReadLong();
|
mpFont->mDefaultSize = rFONT.ReadLong();
|
||||||
mpFont->mFontName = rFONT.ReadString();
|
mpFont->mFontName = rFONT.ReadString();
|
||||||
|
|
||||||
if (mVersion <= eEchoes) mpFont->mpFontTexture = gpResourceStore->LoadResource(rFONT.ReadLong(), eTexture);
|
if (mVersion <= EGame::Echoes) mpFont->mpFontTexture = gpResourceStore->LoadResource(rFONT.ReadLong(), eTexture);
|
||||||
else mpFont->mpFontTexture = gpResourceStore->LoadResource(rFONT.ReadLongLong(), eTexture);
|
else mpFont->mpFontTexture = gpResourceStore->LoadResource(rFONT.ReadLongLong(), eTexture);
|
||||||
|
|
||||||
mpFont->mTextureFormat = rFONT.ReadLong();
|
mpFont->mTextureFormat = rFONT.ReadLong();
|
||||||
|
@ -39,7 +39,7 @@ CFont* CFontLoader::LoadFont(IInputStream& rFONT)
|
||||||
Glyph.TexCoords[2] = CVector2f(TexCoordL, TexCoordD); // Lower-left
|
Glyph.TexCoords[2] = CVector2f(TexCoordL, TexCoordD); // Lower-left
|
||||||
Glyph.TexCoords[3] = CVector2f(TexCoordR, TexCoordD); // Lower-right
|
Glyph.TexCoords[3] = CVector2f(TexCoordR, TexCoordD); // Lower-right
|
||||||
|
|
||||||
if (mVersion <= ePrime)
|
if (mVersion <= EGame::Prime)
|
||||||
{
|
{
|
||||||
Glyph.RGBAChannel = 0;
|
Glyph.RGBAChannel = 0;
|
||||||
Glyph.LeftPadding = rFONT.ReadLong();
|
Glyph.LeftPadding = rFONT.ReadLong();
|
||||||
|
@ -50,7 +50,7 @@ CFont* CFontLoader::LoadFont(IInputStream& rFONT)
|
||||||
Glyph.BaseOffset = rFONT.ReadLong();
|
Glyph.BaseOffset = rFONT.ReadLong();
|
||||||
Glyph.KerningIndex = rFONT.ReadLong();
|
Glyph.KerningIndex = rFONT.ReadLong();
|
||||||
}
|
}
|
||||||
else if (mVersion >= eEchoes)
|
else if (mVersion >= EGame::Echoes)
|
||||||
{
|
{
|
||||||
Glyph.RGBAChannel = rFONT.ReadByte();
|
Glyph.RGBAChannel = rFONT.ReadByte();
|
||||||
Glyph.LeftPadding = rFONT.ReadByte();
|
Glyph.LeftPadding = rFONT.ReadByte();
|
||||||
|
@ -92,7 +92,7 @@ CFont* CFontLoader::LoadFONT(IInputStream& rFONT, CResourceEntry *pEntry)
|
||||||
|
|
||||||
u32 FileVersion = rFONT.ReadLong();
|
u32 FileVersion = rFONT.ReadLong();
|
||||||
EGame Version = GetFormatVersion(FileVersion);
|
EGame Version = GetFormatVersion(FileVersion);
|
||||||
if (Version == eUnknownGame)
|
if (Version == EGame::Invalid)
|
||||||
{
|
{
|
||||||
Log::FileError(rFONT.GetSourceString(), "Unsupported FONT version: " + TString::HexString(FileVersion, 0));
|
Log::FileError(rFONT.GetSourceString(), "Unsupported FONT version: " + TString::HexString(FileVersion, 0));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -108,10 +108,10 @@ EGame CFontLoader::GetFormatVersion(u32 Version)
|
||||||
{
|
{
|
||||||
switch (Version)
|
switch (Version)
|
||||||
{
|
{
|
||||||
case 1: return ePrimeDemo;
|
case 1: return EGame::PrimeDemo;
|
||||||
case 2: return ePrime;
|
case 2: return EGame::Prime;
|
||||||
case 4: return eEchoes;
|
case 4: return EGame::Echoes;
|
||||||
case 5: return eCorruption;
|
case 5: return EGame::Corruption;
|
||||||
default: return eUnknownGame;
|
default: return EGame::Invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ CMaterial* CMaterialLoader::ReadPrimeMaterial()
|
||||||
pMat->mVtxDesc = ConvertToVertexDescription( mpFile->ReadLong() );
|
pMat->mVtxDesc = ConvertToVertexDescription( mpFile->ReadLong() );
|
||||||
|
|
||||||
// Unknowns
|
// Unknowns
|
||||||
if (mVersion >= eEchoesDemo)
|
if (mVersion >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
pMat->mEchoesUnknownA = mpFile->ReadLong();
|
pMat->mEchoesUnknownA = mpFile->ReadLong();
|
||||||
pMat->mEchoesUnknownB = mpFile->ReadLong();
|
pMat->mEchoesUnknownB = mpFile->ReadLong();
|
||||||
|
@ -648,7 +648,7 @@ CMaterialSet* CMaterialLoader::LoadMaterialSet(IInputStream& rMat, EGame Version
|
||||||
Loader.mpFile = &rMat;
|
Loader.mpFile = &rMat;
|
||||||
Loader.mVersion = Version;
|
Loader.mVersion = Version;
|
||||||
|
|
||||||
if ((Version >= ePrimeDemo) && (Version <= eEchoes))
|
if ((Version >= EGame::PrimeDemo) && (Version <= EGame::Echoes))
|
||||||
Loader.ReadPrimeMatSet();
|
Loader.ReadPrimeMatSet();
|
||||||
else
|
else
|
||||||
Loader.ReadCorruptionMatSet();
|
Loader.ReadCorruptionMatSet();
|
||||||
|
|
|
@ -52,7 +52,7 @@ void CModelLoader::LoadAttribArrays(IInputStream& rModel)
|
||||||
if (mFlags & eShortNormals) // Shorts
|
if (mFlags & eShortNormals) // Shorts
|
||||||
{
|
{
|
||||||
mNormals.resize(mpSectionMgr->CurrentSectionSize() / 0x6);
|
mNormals.resize(mpSectionMgr->CurrentSectionSize() / 0x6);
|
||||||
float Divisor = (mVersion < eReturns) ? 32768.f : 16384.f;
|
float Divisor = (mVersion < EGame::DKCReturns) ? 32768.f : 16384.f;
|
||||||
|
|
||||||
for (u32 iVtx = 0; iVtx < mNormals.size(); iVtx++)
|
for (u32 iVtx = 0; iVtx < mNormals.size(); iVtx++)
|
||||||
{
|
{
|
||||||
|
@ -93,7 +93,7 @@ void CModelLoader::LoadAttribArrays(IInputStream& rModel)
|
||||||
if (mFlags & eHasTex1)
|
if (mFlags & eHasTex1)
|
||||||
{
|
{
|
||||||
mTex1.resize(mpSectionMgr->CurrentSectionSize() / 0x4);
|
mTex1.resize(mpSectionMgr->CurrentSectionSize() / 0x4);
|
||||||
float Divisor = (mVersion < eReturns) ? 32768.f : 8192.f;
|
float Divisor = (mVersion < EGame::DKCReturns) ? 32768.f : 8192.f;
|
||||||
|
|
||||||
for (u32 iVtx = 0; iVtx < mTex1.size(); iVtx++)
|
for (u32 iVtx = 0; iVtx < mTex1.size(); iVtx++)
|
||||||
{
|
{
|
||||||
|
@ -122,7 +122,7 @@ SSurface* CModelLoader::LoadSurface(IInputStream& rModel)
|
||||||
SSurface *pSurf = new SSurface;
|
SSurface *pSurf = new SSurface;
|
||||||
|
|
||||||
// Surface header
|
// Surface header
|
||||||
if (mVersion < eReturns)
|
if (mVersion < EGame::DKCReturns)
|
||||||
LoadSurfaceHeaderPrime(rModel, pSurf);
|
LoadSurfaceHeaderPrime(rModel, pSurf);
|
||||||
else
|
else
|
||||||
LoadSurfaceHeaderDKCR(rModel, pSurf);
|
LoadSurfaceHeaderDKCR(rModel, pSurf);
|
||||||
|
@ -172,7 +172,7 @@ SSurface* CModelLoader::LoadSurface(IInputStream& rModel)
|
||||||
Vtx.Color[iClr] = mColors[rModel.ReadShort() & 0xFFFF];
|
Vtx.Color[iClr] = mColors[rModel.ReadShort() & 0xFFFF];
|
||||||
|
|
||||||
// Tex Coords - these are done a bit differently in DKCR than in the Prime series
|
// Tex Coords - these are done a bit differently in DKCR than in the Prime series
|
||||||
if (mVersion < eReturns)
|
if (mVersion < EGame::DKCReturns)
|
||||||
{
|
{
|
||||||
// Tex0
|
// Tex0
|
||||||
if (VtxDesc & eTex0)
|
if (VtxDesc & eTex0)
|
||||||
|
@ -238,7 +238,7 @@ void CModelLoader::LoadSurfaceHeaderPrime(IInputStream& rModel, SSurface *pSurf)
|
||||||
u32 ExtraSize = rModel.ReadLong();
|
u32 ExtraSize = rModel.ReadLong();
|
||||||
pSurf->ReflectionDirection = CVector3f(rModel);
|
pSurf->ReflectionDirection = CVector3f(rModel);
|
||||||
|
|
||||||
if (mVersion >= eEchoesDemo)
|
if (mVersion >= EGame::EchoesDemo)
|
||||||
rModel.Seek(0x4, SEEK_CUR); // Skipping unknown values
|
rModel.Seek(0x4, SEEK_CUR); // Skipping unknown values
|
||||||
|
|
||||||
bool HasAABox = (ExtraSize >= 0x18); // MREAs have a set of bounding box coordinates here.
|
bool HasAABox = (ExtraSize >= 0x18); // MREAs have a set of bounding box coordinates here.
|
||||||
|
@ -446,7 +446,7 @@ CModel* CModelLoader::LoadCMDL(IInputStream& rCMDL, CResourceEntry *pEntry)
|
||||||
// The rest is common to all CMDL versions
|
// The rest is common to all CMDL versions
|
||||||
Loader.mVersion = GetFormatVersion(Version);
|
Loader.mVersion = GetFormatVersion(Version);
|
||||||
|
|
||||||
if (Loader.mVersion == eUnknownGame)
|
if (Loader.mVersion == EGame::Invalid)
|
||||||
{
|
{
|
||||||
Log::FileError(rCMDL.GetSourceString(), "Unsupported CMDL version: " + TString::HexString(Magic, 0));
|
Log::FileError(rCMDL.GetSourceString(), "Unsupported CMDL version: " + TString::HexString(Magic, 0));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -464,13 +464,13 @@ CModel* CModelLoader::LoadCMDL(IInputStream& rCMDL, CResourceEntry *pEntry)
|
||||||
{
|
{
|
||||||
Loader.mMaterials[iSet] = CMaterialLoader::LoadMaterialSet(rCMDL, Loader.mVersion);
|
Loader.mMaterials[iSet] = CMaterialLoader::LoadMaterialSet(rCMDL, Loader.mVersion);
|
||||||
|
|
||||||
if (Loader.mVersion < eCorruptionProto)
|
if (Loader.mVersion < EGame::CorruptionProto)
|
||||||
Loader.mpSectionMgr->ToNextSection();
|
Loader.mpSectionMgr->ToNextSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
pModel->mMaterialSets = Loader.mMaterials;
|
pModel->mMaterialSets = Loader.mMaterials;
|
||||||
pModel->mHasOwnMaterials = true;
|
pModel->mHasOwnMaterials = true;
|
||||||
if (Loader.mVersion >= eCorruptionProto) Loader.mpSectionMgr->ToNextSection();
|
if (Loader.mVersion >= EGame::CorruptionProto) Loader.mpSectionMgr->ToNextSection();
|
||||||
|
|
||||||
// Mesh
|
// Mesh
|
||||||
Loader.LoadAttribArrays(rCMDL);
|
Loader.LoadAttribArrays(rCMDL);
|
||||||
|
@ -499,7 +499,7 @@ CModel* CModelLoader::LoadWorldModel(IInputStream& rMREA, CSectionMgrIn& rBlockM
|
||||||
Loader.mpSectionMgr = &rBlockMgr;
|
Loader.mpSectionMgr = &rBlockMgr;
|
||||||
Loader.mVersion = Version;
|
Loader.mVersion = Version;
|
||||||
Loader.mFlags = eShortNormals;
|
Loader.mFlags = eShortNormals;
|
||||||
if (Version != eCorruptionProto) Loader.mFlags |= eHasTex1;
|
if (Version != EGame::CorruptionProto) Loader.mFlags |= eHasTex1;
|
||||||
Loader.mMaterials.resize(1);
|
Loader.mMaterials.resize(1);
|
||||||
Loader.mMaterials[0] = &rMatSet;
|
Loader.mMaterials[0] = &rMatSet;
|
||||||
|
|
||||||
|
@ -534,7 +534,7 @@ CModel* CModelLoader::LoadCorruptionWorldModel(IInputStream& rMREA, CSectionMgrI
|
||||||
Loader.mFlags = eShortNormals;
|
Loader.mFlags = eShortNormals;
|
||||||
Loader.mMaterials.resize(1);
|
Loader.mMaterials.resize(1);
|
||||||
Loader.mMaterials[0] = &rMatSet;
|
Loader.mMaterials[0] = &rMatSet;
|
||||||
if (Version == eReturns) Loader.mFlags |= eHasTex1;
|
if (Version == EGame::DKCReturns) Loader.mFlags |= eHasTex1;
|
||||||
|
|
||||||
// Corruption/DKCR MREAs split the mesh header and surface offsets away from the actual geometry data so I need two section numbers to read it
|
// Corruption/DKCR MREAs split the mesh header and surface offsets away from the actual geometry data so I need two section numbers to read it
|
||||||
rBlockMgr.ToSection(HeaderSecNum);
|
rBlockMgr.ToSection(HeaderSecNum);
|
||||||
|
@ -638,11 +638,11 @@ EGame CModelLoader::GetFormatVersion(u32 Version)
|
||||||
{
|
{
|
||||||
switch (Version)
|
switch (Version)
|
||||||
{
|
{
|
||||||
case 0x2: return ePrime;
|
case 0x2: return EGame::Prime;
|
||||||
case 0x3: return eEchoesDemo;
|
case 0x3: return EGame::EchoesDemo;
|
||||||
case 0x4: return eEchoes;
|
case 0x4: return EGame::Echoes;
|
||||||
case 0x5: return eCorruption;
|
case 0x5: return EGame::Corruption;
|
||||||
case 0xA: return eReturns;
|
case 0xA: return EGame::DKCReturns;
|
||||||
default: return eUnknownGame;
|
default: return EGame::Invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,11 +101,11 @@ public:
|
||||||
|
|
||||||
case eStateMachine:
|
case eStateMachine:
|
||||||
// AFSM currently unsupported
|
// AFSM currently unsupported
|
||||||
if (pEntry->Game() <= eEchoes)
|
if (pEntry->Game() <= EGame::Echoes)
|
||||||
pRes = new CDependencyGroup(pEntry);
|
pRes = new CDependencyGroup(pEntry);
|
||||||
else if (pEntry->Game() <= eCorruption)
|
else if (pEntry->Game() <= EGame::Corruption)
|
||||||
pRes = CUnsupportedFormatLoader::LoadFSM2(rInput, pEntry);
|
pRes = CUnsupportedFormatLoader::LoadFSM2(rInput, pEntry);
|
||||||
else if (pEntry->Game() == eReturns)
|
else if (pEntry->Game() == EGame::DKCReturns)
|
||||||
pRes = CUnsupportedFormatLoader::LoadFSMC(rInput, pEntry);
|
pRes = CUnsupportedFormatLoader::LoadFSMC(rInput, pEntry);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ CScan* CScanLoader::LoadScanMP2(IInputStream& rSCAN)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load MP3 dependency list
|
// Load MP3 dependency list
|
||||||
if (mpScan->Game() == eCorruption)
|
if (mpScan->Game() == EGame::Corruption)
|
||||||
{
|
{
|
||||||
rSCAN.GoTo(InstanceEnd);
|
rSCAN.GoTo(InstanceEnd);
|
||||||
u32 NumDeps = rSCAN.ReadLong();
|
u32 NumDeps = rSCAN.ReadLong();
|
||||||
|
@ -275,7 +275,7 @@ CScan* CScanLoader::LoadSCAN(IInputStream& rSCAN, CResourceEntry *pEntry)
|
||||||
{
|
{
|
||||||
// The MP2 load function will check for MP3
|
// The MP2 load function will check for MP3
|
||||||
CScanLoader Loader;
|
CScanLoader Loader;
|
||||||
Loader.mVersion = eEchoes;
|
Loader.mVersion = EGame::Echoes;
|
||||||
Loader.mpEntry = pEntry;
|
Loader.mpEntry = pEntry;
|
||||||
if (Magic == 0x01000000) rSCAN.Seek(-4, SEEK_CUR); // The version number isn't present in the Echoes demo
|
if (Magic == 0x01000000) rSCAN.Seek(-4, SEEK_CUR); // The version number isn't present in the Echoes demo
|
||||||
return Loader.LoadScanMP2(rSCAN);
|
return Loader.LoadScanMP2(rSCAN);
|
||||||
|
@ -295,7 +295,7 @@ CScan* CScanLoader::LoadSCAN(IInputStream& rSCAN, CResourceEntry *pEntry)
|
||||||
|
|
||||||
// MP1 SCAN - read the file!
|
// MP1 SCAN - read the file!
|
||||||
CScanLoader Loader;
|
CScanLoader Loader;
|
||||||
Loader.mVersion = ePrime;
|
Loader.mVersion = EGame::Prime;
|
||||||
Loader.mpScan = new CScan(pEntry);
|
Loader.mpScan = new CScan(pEntry);
|
||||||
Loader.mpEntry = pEntry;
|
Loader.mpEntry = pEntry;
|
||||||
return Loader.LoadScanMP1(rSCAN);
|
return Loader.LoadScanMP1(rSCAN);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "CTemplateLoader.h"
|
#include "CTemplateLoader.h"
|
||||||
#include "Core/GameProject/CResourceStore.h"
|
#include "Core/GameProject/CResourceStore.h"
|
||||||
#include "Core/Resource/Script/CGameTemplate.h"
|
#include "Core/Resource/Script/CGameTemplate.h"
|
||||||
|
#include "Core/Resource/Script/NGameList.h"
|
||||||
#include "Core/Resource/Script/Property/CArrayProperty.h"
|
#include "Core/Resource/Script/Property/CArrayProperty.h"
|
||||||
#include "Core/Resource/Script/Property/CAssetProperty.h"
|
#include "Core/Resource/Script/Property/CAssetProperty.h"
|
||||||
#include "Core/Resource/Script/Property/CEnumProperty.h"
|
#include "Core/Resource/Script/Property/CEnumProperty.h"
|
||||||
|
@ -202,7 +203,7 @@ void CScriptLoader::ReadProperty(IProperty *pProp, u32 Size, IInputStream& rSCLY
|
||||||
{
|
{
|
||||||
CStructProperty* pStruct = TPropCast<CStructProperty>(pProp);
|
CStructProperty* pStruct = TPropCast<CStructProperty>(pProp);
|
||||||
|
|
||||||
if (mVersion < eEchoesDemo)
|
if (mVersion < EGame::EchoesDemo)
|
||||||
LoadStructMP1(rSCLY, pStruct);
|
LoadStructMP1(rSCLY, pStruct);
|
||||||
else
|
else
|
||||||
LoadStructMP2(rSCLY, pStruct);
|
LoadStructMP2(rSCLY, pStruct);
|
||||||
|
@ -447,7 +448,7 @@ CScriptLayer* CScriptLoader::LoadLayer(IInputStream& rSCLY, CGameArea *pArea, EG
|
||||||
|
|
||||||
CScriptLoader Loader;
|
CScriptLoader Loader;
|
||||||
Loader.mVersion = Version;
|
Loader.mVersion = Version;
|
||||||
Loader.mpGameTemplate = CGameTemplate::GetGameTemplate(Version);
|
Loader.mpGameTemplate = NGameList::GetGameTemplate(Version);
|
||||||
Loader.mpArea = pArea;
|
Loader.mpArea = pArea;
|
||||||
|
|
||||||
if (!Loader.mpGameTemplate)
|
if (!Loader.mpGameTemplate)
|
||||||
|
@ -456,10 +457,7 @@ CScriptLayer* CScriptLoader::LoadLayer(IInputStream& rSCLY, CGameArea *pArea, EG
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Loader.mpGameTemplate->IsLoadedSuccessfully())
|
if (Version <= EGame::Prime)
|
||||||
CTemplateLoader::LoadGameTemplates(Version);
|
|
||||||
|
|
||||||
if (Version <= ePrime)
|
|
||||||
return Loader.LoadLayerMP1(rSCLY);
|
return Loader.LoadLayerMP1(rSCLY);
|
||||||
else
|
else
|
||||||
return Loader.LoadLayerMP2(rSCLY);
|
return Loader.LoadLayerMP2(rSCLY);
|
||||||
|
@ -470,8 +468,8 @@ CScriptObject* CScriptLoader::LoadInstance(IInputStream& rSCLY, CGameArea *pArea
|
||||||
if (!rSCLY.IsValid()) return nullptr;
|
if (!rSCLY.IsValid()) return nullptr;
|
||||||
|
|
||||||
CScriptLoader Loader;
|
CScriptLoader Loader;
|
||||||
Loader.mVersion = (ForceReturnsFormat ? eReturns : Version);
|
Loader.mVersion = (ForceReturnsFormat ? EGame::DKCReturns : Version);
|
||||||
Loader.mpGameTemplate = CGameTemplate::GetGameTemplate(Version);
|
Loader.mpGameTemplate = NGameList::GetGameTemplate(Version);
|
||||||
Loader.mpArea = pArea;
|
Loader.mpArea = pArea;
|
||||||
Loader.mpLayer = pLayer;
|
Loader.mpLayer = pLayer;
|
||||||
|
|
||||||
|
@ -481,10 +479,7 @@ CScriptObject* CScriptLoader::LoadInstance(IInputStream& rSCLY, CGameArea *pArea
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Loader.mpGameTemplate->IsLoadedSuccessfully())
|
if (Loader.mVersion <= EGame::Prime)
|
||||||
CTemplateLoader::LoadGameTemplates(Version);
|
|
||||||
|
|
||||||
if (Loader.mVersion <= ePrime)
|
|
||||||
return Loader.LoadObjectMP1(rSCLY);
|
return Loader.LoadObjectMP1(rSCLY);
|
||||||
else
|
else
|
||||||
return Loader.LoadObjectMP2(rSCLY);
|
return Loader.LoadObjectMP2(rSCLY);
|
||||||
|
|
|
@ -60,12 +60,12 @@ CSkeleton* CSkeletonLoader::LoadCINF(IInputStream& rCINF, CResourceEntry *pEntry
|
||||||
// rotation value in MP2. The max bone count is 100 so the linked bone count will not be higher
|
// rotation value in MP2. The max bone count is 100 so the linked bone count will not be higher
|
||||||
// than that. Additionally, every bone links to its parent at least and every skeleton (as far as I
|
// than that. Additionally, every bone links to its parent at least and every skeleton (as far as I
|
||||||
// know) has at least two bones so the linked bone count will never be 0.
|
// know) has at least two bones so the linked bone count will never be 0.
|
||||||
if (Game == eUnknownGame)
|
if (Game == EGame::Invalid)
|
||||||
{
|
{
|
||||||
u32 Check = rCINF.PeekLong();
|
u32 Check = rCINF.PeekLong();
|
||||||
Game = ((Check > 100 || Check == 0) ? eEchoes : ePrime);
|
Game = ((Check > 100 || Check == 0) ? EGame::Echoes : EGame::Prime);
|
||||||
}
|
}
|
||||||
if (Game >= eEchoes)
|
if (Game >= EGame::Echoes)
|
||||||
{
|
{
|
||||||
pBone->mRotation = CQuaternion(rCINF);
|
pBone->mRotation = CQuaternion(rCINF);
|
||||||
pBone->mLocalRotation = CQuaternion(rCINF);
|
pBone->mLocalRotation = CQuaternion(rCINF);
|
||||||
|
|
|
@ -44,11 +44,11 @@ void CStringLoader::LoadPrimeSTRG(IInputStream& rSTRG)
|
||||||
{
|
{
|
||||||
mpStringTable->mLangTables[iLang].Language = CFourCC(rSTRG);
|
mpStringTable->mLangTables[iLang].Language = CFourCC(rSTRG);
|
||||||
LangOffsets[iLang] = rSTRG.ReadLong();
|
LangOffsets[iLang] = rSTRG.ReadLong();
|
||||||
if (mVersion == eEchoes) rSTRG.Seek(0x4, SEEK_CUR); // Skipping strings size
|
if (mVersion == EGame::Echoes) rSTRG.Seek(0x4, SEEK_CUR); // Skipping strings size
|
||||||
}
|
}
|
||||||
|
|
||||||
// String names
|
// String names
|
||||||
if (mVersion == eEchoes)
|
if (mVersion == EGame::Echoes)
|
||||||
LoadNameTable(rSTRG);
|
LoadNameTable(rSTRG);
|
||||||
|
|
||||||
// Strings
|
// Strings
|
||||||
|
@ -56,7 +56,7 @@ void CStringLoader::LoadPrimeSTRG(IInputStream& rSTRG)
|
||||||
for (u32 iLang = 0; iLang < NumLanguages; iLang++)
|
for (u32 iLang = 0; iLang < NumLanguages; iLang++)
|
||||||
{
|
{
|
||||||
rSTRG.Seek(StringsStart + LangOffsets[iLang], SEEK_SET);
|
rSTRG.Seek(StringsStart + LangOffsets[iLang], SEEK_SET);
|
||||||
if (mVersion == ePrime) rSTRG.Seek(0x4, SEEK_CUR); // Skipping strings size
|
if (mVersion == EGame::Prime) rSTRG.Seek(0x4, SEEK_CUR); // Skipping strings size
|
||||||
|
|
||||||
u32 LangStart = rSTRG.Tell();
|
u32 LangStart = rSTRG.Tell();
|
||||||
CStringTable::SLangTable* pLang = &mpStringTable->mLangTables[iLang];
|
CStringTable::SLangTable* pLang = &mpStringTable->mLangTables[iLang];
|
||||||
|
@ -160,7 +160,7 @@ CStringTable* CStringLoader::LoadSTRG(IInputStream& rSTRG, CResourceEntry *pEntr
|
||||||
if (!rSTRG.IsValid()) return nullptr;
|
if (!rSTRG.IsValid()) return nullptr;
|
||||||
|
|
||||||
u32 Magic = rSTRG.ReadLong();
|
u32 Magic = rSTRG.ReadLong();
|
||||||
EGame Version = eUnknownGame;
|
EGame Version = EGame::Invalid;
|
||||||
|
|
||||||
if (Magic != 0x87654321)
|
if (Magic != 0x87654321)
|
||||||
{
|
{
|
||||||
|
@ -170,10 +170,10 @@ CStringTable* CStringLoader::LoadSTRG(IInputStream& rSTRG, CResourceEntry *pEntr
|
||||||
{
|
{
|
||||||
rSTRG.Seek(Magic, SEEK_SET);
|
rSTRG.Seek(Magic, SEEK_SET);
|
||||||
if ((rSTRG.EoF()) || (rSTRG.ReadShort() == 0xFFFF))
|
if ((rSTRG.EoF()) || (rSTRG.ReadShort() == 0xFFFF))
|
||||||
Version = ePrimeDemo;
|
Version = EGame::PrimeDemo;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Version != ePrimeDemo)
|
if (Version != EGame::PrimeDemo)
|
||||||
{
|
{
|
||||||
Log::FileError(rSTRG.GetSourceString(), "Invalid STRG magic: " + TString::HexString(Magic));
|
Log::FileError(rSTRG.GetSourceString(), "Invalid STRG magic: " + TString::HexString(Magic));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -185,7 +185,7 @@ CStringTable* CStringLoader::LoadSTRG(IInputStream& rSTRG, CResourceEntry *pEntr
|
||||||
u32 FileVersion = rSTRG.ReadLong();
|
u32 FileVersion = rSTRG.ReadLong();
|
||||||
Version = GetFormatVersion(FileVersion);
|
Version = GetFormatVersion(FileVersion);
|
||||||
|
|
||||||
if (FileVersion == eUnknownGame)
|
if (Version == EGame::Invalid)
|
||||||
{
|
{
|
||||||
Log::FileError(rSTRG.GetSourceString(), "Unsupported STRG version: " + TString::HexString(FileVersion, 0));
|
Log::FileError(rSTRG.GetSourceString(), "Unsupported STRG version: " + TString::HexString(FileVersion, 0));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -197,8 +197,8 @@ CStringTable* CStringLoader::LoadSTRG(IInputStream& rSTRG, CResourceEntry *pEntr
|
||||||
Loader.mpStringTable = new CStringTable(pEntry);
|
Loader.mpStringTable = new CStringTable(pEntry);
|
||||||
Loader.mVersion = Version;
|
Loader.mVersion = Version;
|
||||||
|
|
||||||
if (Version == ePrimeDemo) Loader.LoadPrimeDemoSTRG(rSTRG);
|
if (Version == EGame::PrimeDemo) Loader.LoadPrimeDemoSTRG(rSTRG);
|
||||||
else if (Version < eCorruption) Loader.LoadPrimeSTRG(rSTRG);
|
else if (Version < EGame::Corruption) Loader.LoadPrimeSTRG(rSTRG);
|
||||||
else Loader.LoadCorruptionSTRG(rSTRG);
|
else Loader.LoadCorruptionSTRG(rSTRG);
|
||||||
|
|
||||||
return Loader.mpStringTable;
|
return Loader.mpStringTable;
|
||||||
|
@ -208,9 +208,9 @@ EGame CStringLoader::GetFormatVersion(u32 Version)
|
||||||
{
|
{
|
||||||
switch (Version)
|
switch (Version)
|
||||||
{
|
{
|
||||||
case 0x0: return ePrime;
|
case 0x0: return EGame::Prime;
|
||||||
case 0x1: return eEchoes;
|
case 0x1: return EGame::Echoes;
|
||||||
case 0x3: return eCorruption;
|
case 0x3: return EGame::Corruption;
|
||||||
default: return eUnknownGame;
|
default: return EGame::Invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#include "CTemplateLoader.h"
|
#include "CTemplateLoader.h"
|
||||||
|
|
||||||
|
#if USE_LEGACY_TEMPLATE_LOADER
|
||||||
#include "CAreaLoader.h"
|
#include "CAreaLoader.h"
|
||||||
#include "Core/Resource/Script/Property/Properties.h"
|
#include "Core/Resource/Script/Property/Properties.h"
|
||||||
#include <Common/FileUtil.h>
|
#include <Common/FileUtil.h>
|
||||||
|
@ -149,7 +151,7 @@ IProperty* CTemplateLoader::LoadProperty(XMLElement* pElem, CScriptTemplate* pSc
|
||||||
|
|
||||||
if (!NameAttr.IsEmpty())
|
if (!NameAttr.IsEmpty())
|
||||||
Name = NameAttr;
|
Name = NameAttr;
|
||||||
else if (mGame >= eEchoesDemo)
|
else if (mGame >= EGame::EchoesDemo)
|
||||||
Name = CGameTemplate::PropertyName(ID);
|
Name = CGameTemplate::PropertyName(ID);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1402,3 +1404,5 @@ void CTemplateLoader::SaveGameList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
#ifndef CTEMPLATELOADER_H
|
#ifndef CTEMPLATELOADER_H
|
||||||
#define CTEMPLATELOADER_H
|
#define CTEMPLATELOADER_H
|
||||||
|
|
||||||
|
// Old code! This is being kept around for now in case there is a reason to need to load the old templates.
|
||||||
|
// Template loading is handled by the serializer now. This code should only be used if there is a reason that
|
||||||
|
// the new templates need to be regenerated (i.e. if any data from the old templates is missing on the new ones).
|
||||||
|
#define USE_LEGACY_TEMPLATE_LOADER 0
|
||||||
|
|
||||||
|
#if USE_LEGACY_TEMPLATE_LOADER
|
||||||
#include "Core/Resource/Script/CGameTemplate.h"
|
#include "Core/Resource/Script/CGameTemplate.h"
|
||||||
#include "Core/Resource/Script/CScriptTemplate.h"
|
#include "Core/Resource/Script/CScriptTemplate.h"
|
||||||
#include "Core/Resource/Script/Property/IProperty.h"
|
#include "Core/Resource/Script/Property/IProperty.h"
|
||||||
|
@ -53,5 +59,6 @@ public:
|
||||||
|
|
||||||
static void SaveGameList();
|
static void SaveGameList();
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // CTEMPLATELOADER_H
|
#endif // CTEMPLATELOADER_H
|
||||||
|
|
|
@ -9,12 +9,12 @@ void CUnsupportedFormatLoader::PerformCheating(IInputStream& rFile, EGame Game,
|
||||||
std::vector<u8> Data(rFile.Size() - rFile.Tell());
|
std::vector<u8> Data(rFile.Size() - rFile.Tell());
|
||||||
rFile.ReadBytes(Data.data(), Data.size());
|
rFile.ReadBytes(Data.data(), Data.size());
|
||||||
|
|
||||||
u32 MaxIndex = (Game <= eEchoes ? Data.size() - 3 : Data.size() - 7);
|
u32 MaxIndex = (Game <= EGame::Echoes ? Data.size() - 3 : Data.size() - 7);
|
||||||
CAssetID ID;
|
CAssetID ID;
|
||||||
|
|
||||||
for (u32 iByte = 0; iByte < MaxIndex; iByte++)
|
for (u32 iByte = 0; iByte < MaxIndex; iByte++)
|
||||||
{
|
{
|
||||||
if (Game <= eEchoes)
|
if (Game <= EGame::Echoes)
|
||||||
{
|
{
|
||||||
ID = ( (Data[iByte+0] << 24) |
|
ID = ( (Data[iByte+0] << 24) |
|
||||||
(Data[iByte+1] << 16) |
|
(Data[iByte+1] << 16) |
|
||||||
|
@ -44,17 +44,17 @@ CAudioMacro* CUnsupportedFormatLoader::LoadCAUD(IInputStream& rCAUD, CResourceEn
|
||||||
ASSERT(Magic == FOURCC('CAUD'));
|
ASSERT(Magic == FOURCC('CAUD'));
|
||||||
|
|
||||||
u32 Version = rCAUD.ReadLong();
|
u32 Version = rCAUD.ReadLong();
|
||||||
EGame Game = (Version == 0x2 ? eCorruptionProto :
|
EGame Game = (Version == 0x2 ? EGame::CorruptionProto :
|
||||||
Version == 0x9 ? eCorruption :
|
Version == 0x9 ? EGame::Corruption :
|
||||||
Version == 0xE ? eReturns :
|
Version == 0xE ? EGame::DKCReturns :
|
||||||
eUnknownGame);
|
EGame::Invalid);
|
||||||
ASSERT(Game != eUnknownGame && Game == pEntry->Game());
|
ASSERT(Game != EGame::Invalid && Game == pEntry->Game());
|
||||||
|
|
||||||
CAudioMacro *pMacro = new CAudioMacro(pEntry);
|
CAudioMacro *pMacro = new CAudioMacro(pEntry);
|
||||||
pMacro->mMacroName = rCAUD.ReadString();
|
pMacro->mMacroName = rCAUD.ReadString();
|
||||||
|
|
||||||
// DKCR is missing the sample data size value, and the bulk of the format isn't well understood, unfortunately
|
// DKCR is missing the sample data size value, and the bulk of the format isn't well understood, unfortunately
|
||||||
if (Game == eReturns)
|
if (Game == EGame::DKCReturns)
|
||||||
{
|
{
|
||||||
std::list<CAssetID> AssetList;
|
std::list<CAssetID> AssetList;
|
||||||
PerformCheating(rCAUD, pEntry->Game(), AssetList);
|
PerformCheating(rCAUD, pEntry->Game(), AssetList);
|
||||||
|
@ -71,7 +71,7 @@ CAudioMacro* CUnsupportedFormatLoader::LoadCAUD(IInputStream& rCAUD, CResourceEn
|
||||||
for (u32 iVol = 0; iVol < NumVolGroups; iVol++)
|
for (u32 iVol = 0; iVol < NumVolGroups; iVol++)
|
||||||
rCAUD.ReadString();
|
rCAUD.ReadString();
|
||||||
|
|
||||||
u32 SkipAmt = (Game == eCorruptionProto ? 0x10 : 0x14);
|
u32 SkipAmt = (Game == EGame::CorruptionProto ? 0x10 : 0x14);
|
||||||
rCAUD.Seek(SkipAmt, SEEK_CUR);
|
rCAUD.Seek(SkipAmt, SEEK_CUR);
|
||||||
u32 NumSamples = rCAUD.ReadLong();
|
u32 NumSamples = rCAUD.ReadLong();
|
||||||
|
|
||||||
|
@ -237,9 +237,9 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadFRME(IInputStream& rFRME, CResou
|
||||||
else if (Version == 4 || Version == 5 || Version == 0xD || Version == 0xE || Version == 0x10)
|
else if (Version == 4 || Version == 5 || Version == 0xD || Version == 0xE || Version == 0x10)
|
||||||
{
|
{
|
||||||
EGame Game;
|
EGame Game;
|
||||||
if (Version == 4) Game = eEchoes;
|
if (Version == 4) Game = EGame::Echoes;
|
||||||
else if (Version == 0x10) Game = eReturns;
|
else if (Version == 0x10) Game = EGame::DKCReturns;
|
||||||
else Game = eCorruption;
|
else Game = EGame::Corruption;
|
||||||
|
|
||||||
u32 NumDependencies = rFRME.ReadLong();
|
u32 NumDependencies = rFRME.ReadLong();
|
||||||
|
|
||||||
|
@ -359,7 +359,7 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadHIER(IInputStream& rHIER, CResou
|
||||||
|
|
||||||
// Note: For some reason this file still exists in MP3 and it's identical to MP2, including with 32-bit asset IDs.
|
// Note: For some reason this file still exists in MP3 and it's identical to MP2, including with 32-bit asset IDs.
|
||||||
// Obviously we can't read 32-bit asset IDs in MP3, so this file should just be ignored.
|
// Obviously we can't read 32-bit asset IDs in MP3, so this file should just be ignored.
|
||||||
if (pEntry->Game() > eEchoes)
|
if (pEntry->Game() > EGame::Echoes)
|
||||||
return pOut;
|
return pOut;
|
||||||
|
|
||||||
for (u32 iNode = 0; iNode < NumNodes; iNode++)
|
for (u32 iNode = 0; iNode < NumNodes; iNode++)
|
||||||
|
@ -382,8 +382,8 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadHINT(IInputStream& rHINT, CResou
|
||||||
u32 Version = rHINT.ReadLong();
|
u32 Version = rHINT.ReadLong();
|
||||||
EGame Game;
|
EGame Game;
|
||||||
|
|
||||||
if (Version == 0x1) Game = ePrime;
|
if (Version == 0x1) Game = EGame::Prime;
|
||||||
else if (Version == 0x3) Game = eCorruption;
|
else if (Version == 0x3) Game = EGame::Corruption;
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -402,7 +402,7 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadHINT(IInputStream& rHINT, CResou
|
||||||
pGroup->AddDependency( CAssetID(rHINT, Game) ); // Pop-up STRG
|
pGroup->AddDependency( CAssetID(rHINT, Game) ); // Pop-up STRG
|
||||||
rHINT.Seek(0x4, SEEK_CUR); // Skip unknowns
|
rHINT.Seek(0x4, SEEK_CUR); // Skip unknowns
|
||||||
|
|
||||||
if (Game <= eEchoes)
|
if (Game <= EGame::Echoes)
|
||||||
{
|
{
|
||||||
rHINT.Seek(0x4, SEEK_CUR);
|
rHINT.Seek(0x4, SEEK_CUR);
|
||||||
pGroup->AddDependency( CAssetID(rHINT, Game) ); // Target MLVL
|
pGroup->AddDependency( CAssetID(rHINT, Game) ); // Target MLVL
|
||||||
|
|
|
@ -1226,7 +1226,7 @@ void CUnsupportedParticleLoader::ParseFloatFunction(IInputStream& rFile)
|
||||||
|
|
||||||
case FOURCC('CEXT'):
|
case FOURCC('CEXT'):
|
||||||
ParseIntFunction(rFile);
|
ParseIntFunction(rFile);
|
||||||
if (mpGroup->Game() >= eReturns) ParseFloatFunction(rFile);
|
if (mpGroup->Game() >= EGame::DKCReturns) ParseFloatFunction(rFile);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1791,7 +1791,7 @@ CDependencyGroup* CUnsupportedParticleLoader::LoadParticle(IInputStream& rFile,
|
||||||
Loader.mpGroup = new CDependencyGroup(pEntry);
|
Loader.mpGroup = new CDependencyGroup(pEntry);
|
||||||
|
|
||||||
// Validate DKCR asset header
|
// Validate DKCR asset header
|
||||||
if (pEntry->Game() == eReturns)
|
if (pEntry->Game() == EGame::DKCReturns)
|
||||||
{
|
{
|
||||||
u32 AssetHeader = rFile.ReadLong();
|
u32 AssetHeader = rFile.ReadLong();
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,12 @@ void CWorldLoader::LoadPrimeMLVL(IInputStream& rMLVL)
|
||||||
* We start immediately after the "version" value (0x8 in the file)
|
* We start immediately after the "version" value (0x8 in the file)
|
||||||
*/
|
*/
|
||||||
// Header
|
// Header
|
||||||
if (mVersion < eCorruptionProto)
|
if (mVersion < EGame::CorruptionProto)
|
||||||
{
|
{
|
||||||
mpWorld->mpWorldName = gpResourceStore->LoadResource(rMLVL.ReadLong(), eStringTable);
|
mpWorld->mpWorldName = gpResourceStore->LoadResource(rMLVL.ReadLong(), eStringTable);
|
||||||
if (mVersion == eEchoes) mpWorld->mpDarkWorldName = gpResourceStore->LoadResource(rMLVL.ReadLong(), eStringTable);
|
if (mVersion == EGame::Echoes) mpWorld->mpDarkWorldName = gpResourceStore->LoadResource(rMLVL.ReadLong(), eStringTable);
|
||||||
if (mVersion >= eEchoes) mpWorld->mTempleKeyWorldIndex = rMLVL.ReadLong();
|
if (mVersion >= EGame::Echoes) mpWorld->mTempleKeyWorldIndex = rMLVL.ReadLong();
|
||||||
if (mVersion >= ePrime) mpWorld->mpSaveWorld = gpResourceStore->LoadResource(rMLVL.ReadLong(), eSaveWorld);
|
if (mVersion >= EGame::Prime) mpWorld->mpSaveWorld = gpResourceStore->LoadResource(rMLVL.ReadLong(), eSaveWorld);
|
||||||
mpWorld->mpDefaultSkybox = gpResourceStore->LoadResource(rMLVL.ReadLong(), eModel);
|
mpWorld->mpDefaultSkybox = gpResourceStore->LoadResource(rMLVL.ReadLong(), eModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ void CWorldLoader::LoadPrimeMLVL(IInputStream& rMLVL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Memory relays - only in MP1
|
// Memory relays - only in MP1
|
||||||
if (mVersion == ePrime)
|
if (mVersion == EGame::Prime)
|
||||||
{
|
{
|
||||||
u32 NumMemoryRelays = rMLVL.ReadLong();
|
u32 NumMemoryRelays = rMLVL.ReadLong();
|
||||||
mpWorld->mMemoryRelays.reserve(NumMemoryRelays);
|
mpWorld->mMemoryRelays.reserve(NumMemoryRelays);
|
||||||
|
@ -50,7 +50,7 @@ void CWorldLoader::LoadPrimeMLVL(IInputStream& rMLVL)
|
||||||
|
|
||||||
// Areas - here's the real meat of the file
|
// Areas - here's the real meat of the file
|
||||||
u32 NumAreas = rMLVL.ReadLong();
|
u32 NumAreas = rMLVL.ReadLong();
|
||||||
if (mVersion == ePrime) rMLVL.Seek(0x4, SEEK_CUR);
|
if (mVersion == EGame::Prime) rMLVL.Seek(0x4, SEEK_CUR);
|
||||||
mpWorld->mAreas.resize(NumAreas);
|
mpWorld->mAreas.resize(NumAreas);
|
||||||
|
|
||||||
for (u32 iArea = 0; iArea < NumAreas; iArea++)
|
for (u32 iArea = 0; iArea < NumAreas; iArea++)
|
||||||
|
@ -70,7 +70,7 @@ void CWorldLoader::LoadPrimeMLVL(IInputStream& rMLVL)
|
||||||
pArea->AttachedAreaIDs.push_back( rMLVL.ReadShort() );
|
pArea->AttachedAreaIDs.push_back( rMLVL.ReadShort() );
|
||||||
|
|
||||||
// Skip dependency list - this is very fast to regenerate so there's no use in caching it
|
// Skip dependency list - this is very fast to regenerate so there's no use in caching it
|
||||||
if (mVersion < eCorruptionProto)
|
if (mVersion < EGame::CorruptionProto)
|
||||||
{
|
{
|
||||||
rMLVL.Seek(0x4, SEEK_CUR);
|
rMLVL.Seek(0x4, SEEK_CUR);
|
||||||
u32 NumDependencies = rMLVL.ReadLong();
|
u32 NumDependencies = rMLVL.ReadLong();
|
||||||
|
@ -108,7 +108,7 @@ void CWorldLoader::LoadPrimeMLVL(IInputStream& rMLVL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rels
|
// Rels
|
||||||
if ( (mVersion == eEchoesDemo) || (mVersion == eEchoes) )
|
if ( (mVersion == EGame::EchoesDemo) || (mVersion == EGame::Echoes) )
|
||||||
{
|
{
|
||||||
u32 NumRels = rMLVL.ReadLong();
|
u32 NumRels = rMLVL.ReadLong();
|
||||||
pArea->RelFilenames.resize(NumRels);
|
pArea->RelFilenames.resize(NumRels);
|
||||||
|
@ -116,7 +116,7 @@ void CWorldLoader::LoadPrimeMLVL(IInputStream& rMLVL)
|
||||||
for (u32 iRel = 0; iRel < NumRels; iRel++)
|
for (u32 iRel = 0; iRel < NumRels; iRel++)
|
||||||
pArea->RelFilenames[iRel] = rMLVL.ReadString();
|
pArea->RelFilenames[iRel] = rMLVL.ReadString();
|
||||||
|
|
||||||
if (mVersion == eEchoes)
|
if (mVersion == EGame::Echoes)
|
||||||
{
|
{
|
||||||
u32 NumRelOffsets = rMLVL.ReadLong(); // Don't know what these offsets correspond to
|
u32 NumRelOffsets = rMLVL.ReadLong(); // Don't know what these offsets correspond to
|
||||||
pArea->RelOffsets.resize(NumRelOffsets);
|
pArea->RelOffsets.resize(NumRelOffsets);
|
||||||
|
@ -127,7 +127,7 @@ void CWorldLoader::LoadPrimeMLVL(IInputStream& rMLVL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal name - MP1 doesn't have this, we'll get it from the GameInfo file later
|
// Internal name - MP1 doesn't have this, we'll get it from the GameInfo file later
|
||||||
if (mVersion >= eEchoesDemo)
|
if (mVersion >= EGame::EchoesDemo)
|
||||||
pArea->InternalName = rMLVL.ReadString();
|
pArea->InternalName = rMLVL.ReadString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ void CWorldLoader::LoadPrimeMLVL(IInputStream& rMLVL)
|
||||||
rMLVL.Seek(0x5, SEEK_CUR); // Unknown values which are always 0
|
rMLVL.Seek(0x5, SEEK_CUR); // Unknown values which are always 0
|
||||||
|
|
||||||
// Audio Groups - we don't need this info as we regenerate it on cook
|
// Audio Groups - we don't need this info as we regenerate it on cook
|
||||||
if (mVersion == ePrime)
|
if (mVersion == EGame::Prime)
|
||||||
{
|
{
|
||||||
u32 NumAudioGrps = rMLVL.ReadLong();
|
u32 NumAudioGrps = rMLVL.ReadLong();
|
||||||
rMLVL.Seek(0x8 * NumAudioGrps, SEEK_CUR);
|
rMLVL.Seek(0x8 * NumAudioGrps, SEEK_CUR);
|
||||||
|
@ -168,7 +168,7 @@ void CWorldLoader::LoadPrimeMLVL(IInputStream& rMLVL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layer state IDs
|
// Layer state IDs
|
||||||
if (mVersion >= eCorruption)
|
if (mVersion >= EGame::Corruption)
|
||||||
{
|
{
|
||||||
rMLVL.Seek(0x4, SEEK_CUR); // Skipping redundant layer count
|
rMLVL.Seek(0x4, SEEK_CUR); // Skipping redundant layer count
|
||||||
for (u32 iArea = 0; iArea < NumAreas; iArea++)
|
for (u32 iArea = 0; iArea < NumAreas; iArea++)
|
||||||
|
@ -265,7 +265,7 @@ void CWorldLoader::GenerateEditorData()
|
||||||
{
|
{
|
||||||
CGameInfo *pGameInfo = mpWorld->Entry()->ResourceStore()->Project()->GameInfo();
|
CGameInfo *pGameInfo = mpWorld->Entry()->ResourceStore()->Project()->GameInfo();
|
||||||
|
|
||||||
if (mVersion <= ePrime)
|
if (mVersion <= EGame::Prime)
|
||||||
{
|
{
|
||||||
for (u32 iArea = 0; iArea < mpWorld->NumAreas(); iArea++)
|
for (u32 iArea = 0; iArea < mpWorld->NumAreas(); iArea++)
|
||||||
{
|
{
|
||||||
|
@ -289,7 +289,7 @@ CWorld* CWorldLoader::LoadMLVL(IInputStream& rMLVL, CResourceEntry *pEntry)
|
||||||
|
|
||||||
u32 FileVersion = rMLVL.ReadLong();
|
u32 FileVersion = rMLVL.ReadLong();
|
||||||
EGame Version = GetFormatVersion(FileVersion);
|
EGame Version = GetFormatVersion(FileVersion);
|
||||||
if (Version == eUnknownGame)
|
if (Version == EGame::Invalid)
|
||||||
{
|
{
|
||||||
Log::FileError(rMLVL.GetSourceString(), "Unsupported MLVL version: " + TString::HexString(FileVersion, 2));
|
Log::FileError(rMLVL.GetSourceString(), "Unsupported MLVL version: " + TString::HexString(FileVersion, 2));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -300,7 +300,7 @@ CWorld* CWorldLoader::LoadMLVL(IInputStream& rMLVL, CResourceEntry *pEntry)
|
||||||
Loader.mpWorld = new CWorld(pEntry);
|
Loader.mpWorld = new CWorld(pEntry);
|
||||||
Loader.mVersion = Version;
|
Loader.mVersion = Version;
|
||||||
|
|
||||||
if (Version != eReturns)
|
if (Version != EGame::DKCReturns)
|
||||||
Loader.LoadPrimeMLVL(rMLVL);
|
Loader.LoadPrimeMLVL(rMLVL);
|
||||||
else
|
else
|
||||||
Loader.LoadReturnsMLVL(rMLVL);
|
Loader.LoadReturnsMLVL(rMLVL);
|
||||||
|
@ -313,12 +313,12 @@ EGame CWorldLoader::GetFormatVersion(u32 Version)
|
||||||
{
|
{
|
||||||
switch (Version)
|
switch (Version)
|
||||||
{
|
{
|
||||||
case 0xD: return ePrimeDemo;
|
case 0xD: return EGame::PrimeDemo;
|
||||||
case 0x11: return ePrime;
|
case 0x11: return EGame::Prime;
|
||||||
case 0x14: return eEchoesDemo;
|
case 0x14: return EGame::EchoesDemo;
|
||||||
case 0x17: return eEchoes;
|
case 0x17: return EGame::Echoes;
|
||||||
case 0x19: return eCorruption;
|
case 0x19: return EGame::Corruption;
|
||||||
case 0x1B: return eReturns;
|
case 0x1B: return EGame::DKCReturns;
|
||||||
default: return eUnknownGame;
|
default: return EGame::Invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#include "CGameTemplate.h"
|
#include "CGameTemplate.h"
|
||||||
|
#include "NPropertyMap.h"
|
||||||
#include "Core/Resource/Factory/CWorldLoader.h"
|
#include "Core/Resource/Factory/CWorldLoader.h"
|
||||||
#include <Common/Log.h>
|
#include <Common/Log.h>
|
||||||
|
|
||||||
CGameTemplate::CGameTemplate()
|
CGameTemplate::CGameTemplate()
|
||||||
: mFullyLoaded(false)
|
: mFullyLoaded(false)
|
||||||
|
, mDirty(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,35 +17,57 @@ void CGameTemplate::Serialize(IArchive& Arc)
|
||||||
<< SerialParameter("Messages", mMessages);
|
<< SerialParameter("Messages", mMessages);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameTemplate::LoadSubTemplates()
|
void CGameTemplate::Load(const TString& kFilePath)
|
||||||
{
|
{
|
||||||
for (auto Iter = mScriptTemplates.begin(); Iter != mScriptTemplates.end(); Iter++)
|
CXMLReader Reader(kFilePath);
|
||||||
Internal_LoadScriptTemplate( Iter->second );
|
|
||||||
|
|
||||||
for (auto Iter = mPropertyTemplates.begin(); Iter != mPropertyTemplates.end(); Iter++)
|
|
||||||
Internal_LoadPropertyTemplate( Iter->second );
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGameTemplate::Internal_LoadScriptTemplate(SScriptTemplatePath& Path)
|
|
||||||
{
|
|
||||||
ASSERT(Path.pTemplate == nullptr); // make sure it hasn't been loaded yet
|
|
||||||
|
|
||||||
const TString kGameDir = GetGameDirectory(true);
|
|
||||||
const TString kTemplateFilePath = kGameDir + Path.Path;
|
|
||||||
CXMLReader Reader(kTemplateFilePath);
|
|
||||||
ASSERT(Reader.IsValid());
|
ASSERT(Reader.IsValid());
|
||||||
|
|
||||||
Path.pTemplate = std::make_shared<CScriptTemplate>(this, Path.ID.ID, Path.Path);
|
mGame = Reader.Game();
|
||||||
Path.pTemplate->Serialize(Reader);
|
Serialize(Reader);
|
||||||
Path.pTemplate->PostLoad();
|
|
||||||
|
mSourceFile = kFilePath;
|
||||||
|
mFullyLoaded = true;
|
||||||
|
|
||||||
|
// Load all sub-templates
|
||||||
|
const TString gkGameRoot = GetGameDirectory();
|
||||||
|
|
||||||
|
for (auto Iter = mScriptTemplates.begin(); Iter != mScriptTemplates.end(); Iter++)
|
||||||
|
{
|
||||||
|
SScriptTemplatePath& ScriptPath = Iter->second;
|
||||||
|
TString AbsPath = gkGameRoot + ScriptPath.Path;
|
||||||
|
ScriptPath.pTemplate = std::make_shared<CScriptTemplate>(this, ScriptPath.ID, AbsPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto Iter = mPropertyTemplates.begin(); Iter != mPropertyTemplates.end(); Iter++)
|
||||||
|
{
|
||||||
|
// For properties, remember that property archetypes can reference other archetypes which
|
||||||
|
// may not be loaded yet.. so if this happens, the referenced property will be loaded,
|
||||||
|
// meaning property templates can be loaded out of order, so we need to make sure
|
||||||
|
// that we don't load any template more than once.
|
||||||
|
SPropertyTemplatePath& PropertyPath = Iter->second;
|
||||||
|
|
||||||
|
if (!PropertyPath.pTemplate)
|
||||||
|
{
|
||||||
|
Internal_LoadPropertyTemplate(Iter->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGameTemplate::Save()
|
||||||
|
{
|
||||||
|
CXMLWriter Writer(mSourceFile, "Game", 0, mGame);
|
||||||
|
ASSERT(Writer.IsValid());
|
||||||
|
Serialize(Writer);
|
||||||
|
mDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Internal function for loading a property template from a file. */
|
||||||
void CGameTemplate::Internal_LoadPropertyTemplate(SPropertyTemplatePath& Path)
|
void CGameTemplate::Internal_LoadPropertyTemplate(SPropertyTemplatePath& Path)
|
||||||
{
|
{
|
||||||
if (Path.pTemplate != nullptr) // don't load twice
|
if (Path.pTemplate != nullptr) // don't load twice
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const TString kGameDir = GetGameDirectory(true);
|
const TString kGameDir = GetGameDirectory();
|
||||||
const TString kTemplateFilePath = kGameDir + Path.Path;
|
const TString kTemplateFilePath = kGameDir + Path.Path;
|
||||||
CXMLReader Reader(kTemplateFilePath);
|
CXMLReader Reader(kTemplateFilePath);
|
||||||
ASSERT(Reader.IsValid());
|
ASSERT(Reader.IsValid());
|
||||||
|
@ -51,44 +75,49 @@ void CGameTemplate::Internal_LoadPropertyTemplate(SPropertyTemplatePath& Path)
|
||||||
Reader << SerialParameter("PropertyArchetype", Path.pTemplate);
|
Reader << SerialParameter("PropertyArchetype", Path.pTemplate);
|
||||||
ASSERT(Path.pTemplate != nullptr);
|
ASSERT(Path.pTemplate != nullptr);
|
||||||
|
|
||||||
Path.pTemplate->SetPropertyFlags( EPropertyFlag::IsArchetype );
|
|
||||||
Path.pTemplate->Initialize(nullptr, nullptr, 0);
|
Path.pTemplate->Initialize(nullptr, nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameTemplate::SaveSubTemplates()
|
void CGameTemplate::SaveGameTemplates(bool ForceAll /*= false*/)
|
||||||
{
|
{
|
||||||
const TString kGameDir = GetGameDirectory(true);
|
const TString kGameDir = GetGameDirectory();
|
||||||
|
|
||||||
|
if (mDirty || ForceAll)
|
||||||
|
{
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
for (auto Iter = mScriptTemplates.begin(); Iter != mScriptTemplates.end(); Iter++)
|
for (auto Iter = mScriptTemplates.begin(); Iter != mScriptTemplates.end(); Iter++)
|
||||||
{
|
{
|
||||||
SScriptTemplatePath& Path = Iter->second;
|
SScriptTemplatePath& Path = Iter->second;
|
||||||
TString OutPath = kGameDir + Path.Path;
|
|
||||||
|
|
||||||
FileUtil::MakeDirectory( OutPath.GetFileDirectory() );
|
if( Path.pTemplate )
|
||||||
CXMLWriter Writer(OutPath, "ScriptObject", 0, Game());
|
{
|
||||||
Path.pTemplate->Serialize(Writer);
|
Path.pTemplate->Save(ForceAll);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto Iter = mPropertyTemplates.begin(); Iter != mPropertyTemplates.end(); Iter++)
|
for (auto Iter = mPropertyTemplates.begin(); Iter != mPropertyTemplates.end(); Iter++)
|
||||||
{
|
{
|
||||||
SPropertyTemplatePath& Path = Iter->second;
|
SPropertyTemplatePath& Path = Iter->second;
|
||||||
TString OutPath = kGameDir + Path.Path;
|
|
||||||
|
|
||||||
FileUtil::MakeDirectory( OutPath.GetFileDirectory() );
|
if( Path.pTemplate )
|
||||||
CXMLWriter Writer(OutPath, "PropertyTemplate", 0, Game());
|
{
|
||||||
Writer << SerialParameter("PropertyArchetype", Path.pTemplate);
|
if( ForceAll || Path.pTemplate->IsDirty() )
|
||||||
|
{
|
||||||
|
const TString kOutPath = kGameDir + Path.Path;
|
||||||
|
FileUtil::MakeDirectory( kOutPath.GetFileDirectory() );
|
||||||
|
|
||||||
|
CXMLWriter Writer(kOutPath, "PropertyTemplate", 0, Game());
|
||||||
|
ASSERT(Writer.IsValid());
|
||||||
|
|
||||||
|
Writer << SerialParameter("PropertyArchetype", Path.pTemplate);
|
||||||
|
Path.pTemplate->ClearDirtyFlag();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameTemplate::SaveScriptTemplate(CScriptTemplate* pTemplate)
|
|
||||||
{
|
|
||||||
ASSERT( pTemplate->GameTemplate() == this );
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGameTemplate::SavePropertyTemplate(IProperty* pProperty)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CGameTemplate::GameVersion(TString VersionName)
|
u32 CGameTemplate::GameVersion(TString VersionName)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -162,9 +191,8 @@ SMessage CGameTemplate::MessageByIndex(u32 Index)
|
||||||
IProperty* CGameTemplate::FindPropertyArchetype(const TString& kTypeName)
|
IProperty* CGameTemplate::FindPropertyArchetype(const TString& kTypeName)
|
||||||
{
|
{
|
||||||
auto Iter = mPropertyTemplates.find(kTypeName);
|
auto Iter = mPropertyTemplates.find(kTypeName);
|
||||||
|
ASSERT(Iter != mPropertyTemplates.end()); // Requested archetype property does not exist; missing or malformed template
|
||||||
|
|
||||||
// Should require Iter to be valid in the future. For now, this is possible for some of the transition template loader code.
|
|
||||||
// ASSERT(Iter != mPropertyTemplates.end()); // Requested archetype property does not exist; missing or malformed template
|
|
||||||
if (Iter == mPropertyTemplates.end())
|
if (Iter == mPropertyTemplates.end())
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -183,200 +211,14 @@ IProperty* CGameTemplate::FindPropertyArchetype(const TString& kTypeName)
|
||||||
return Path.pTemplate.get();
|
return Path.pTemplate.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
TString CGameTemplate::GetGameDirectory(bool Absolute) const
|
TString CGameTemplate::GetPropertyArchetypeFilePath(const TString& kTypeName)
|
||||||
{
|
{
|
||||||
TString Out = mSourceFile.GetFileDirectory();
|
auto Iter = mPropertyTemplates.find(kTypeName);
|
||||||
return Absolute ? "../templates_new/" + Out : Out;
|
ASSERT(Iter != mPropertyTemplates.end());
|
||||||
|
return GetGameDirectory() + Iter->second.Path;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ STATIC ************
|
TString CGameTemplate::GetGameDirectory() const
|
||||||
CGameTemplate* CGameTemplate::GetGameTemplate(EGame Game)
|
|
||||||
{
|
{
|
||||||
auto it = smGameMap.find(Game);
|
return mSourceFile.GetFileDirectory();
|
||||||
|
|
||||||
if (it != smGameMap.end())
|
|
||||||
return it->second;
|
|
||||||
else
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<CGameTemplate*> CGameTemplate::GameTemplateList()
|
|
||||||
{
|
|
||||||
std::list<CGameTemplate*> list;
|
|
||||||
|
|
||||||
for (auto it = smGameMap.begin(); it != smGameMap.end(); it++)
|
|
||||||
list.push_back(it->second);
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString CGameTemplate::FindGameName(EGame Game)
|
|
||||||
{
|
|
||||||
CGameTemplate *pGame = GetGameTemplate(Game);
|
|
||||||
return pGame ? pGame->GameName() : "Unknown Game";
|
|
||||||
}
|
|
||||||
|
|
||||||
EGame CGameTemplate::FindGameForName(const TString& rkName)
|
|
||||||
{
|
|
||||||
std::list<CGameTemplate*> Games = GameTemplateList();
|
|
||||||
|
|
||||||
for (auto It = Games.begin(); It != Games.end(); It++)
|
|
||||||
{
|
|
||||||
CGameTemplate *pGame = *It;
|
|
||||||
if (pGame->GameName() == rkName)
|
|
||||||
return pGame->Game();
|
|
||||||
}
|
|
||||||
|
|
||||||
return eUnknownGame;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString CGameTemplate::PropertyName(u32 PropertyID)
|
|
||||||
{
|
|
||||||
auto it = smPropertyNames.find(PropertyID);
|
|
||||||
|
|
||||||
if (it != smPropertyNames.end())
|
|
||||||
return it->second;
|
|
||||||
else
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removing these functions for now. I'm not sure of the best way to go about implementing them under the new system yet.
|
|
||||||
u32 CGameTemplate::CreatePropertyID(IProperty* pProp)
|
|
||||||
{
|
|
||||||
// MP1 properties don't have IDs so we can use this function to create one to track instances of a particular property.
|
|
||||||
// To ensure the IDs are unique we'll create a hash using two things: the struct source file and the ID string (relative to the struct).
|
|
||||||
//
|
|
||||||
// Note for properties that have accurate names we can apply a CRC32 to the name to generate a hash equivalent to what the hash would
|
|
||||||
// have been if this were an MP2/3 property. In an ideal world where every property was named, this would be great. However, we have a
|
|
||||||
// lot of properties that have generic names like "Unknown", and they should be tracked separately as they are in all likelihood
|
|
||||||
// different properties. So for this reason, we only want to track sub-instances of one property under one ID.
|
|
||||||
TString IDString = pProp->Archetype()->IDString(true);
|
|
||||||
TString TemplateFile = pProp->GetTemplateFileName();
|
|
||||||
|
|
||||||
CCRC32 Hash;
|
|
||||||
Hash.Hash(*IDString);
|
|
||||||
Hash.Hash(*TemplateFile);
|
|
||||||
return Hash.Digest();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGameTemplate::AddProperty(IProperty* pProp, const TString& rkTemplateName /*= ""*/)
|
|
||||||
{
|
|
||||||
u32 ID;
|
|
||||||
|
|
||||||
if (pProp->Game() >= eEchoesDemo)
|
|
||||||
ID = pProp->ID();
|
|
||||||
|
|
||||||
// Use a different ID for MP1
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// For MP1 we only really need to track properties that come from struct templates.
|
|
||||||
IProperty* pArchetype = pProp->Archetype();
|
|
||||||
|
|
||||||
if (!pArchetype ||
|
|
||||||
pArchetype->ScriptTemplate() != nullptr ||
|
|
||||||
pArchetype->RootParent()->Type() != EPropertyType::Struct)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ID = CreatePropertyID(pProp);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto it = smIDMap.find(ID);
|
|
||||||
|
|
||||||
// Add this property/template to existing ID info
|
|
||||||
if (it != smIDMap.end())
|
|
||||||
{
|
|
||||||
SPropIDInfo& rInfo = it->second;
|
|
||||||
rInfo.PropertyList.push_back(pProp);
|
|
||||||
|
|
||||||
if (!rkTemplateName.IsEmpty())
|
|
||||||
{
|
|
||||||
bool NewTemplate = true;
|
|
||||||
|
|
||||||
for (u32 iTemp = 0; iTemp < rInfo.XMLList.size(); iTemp++)
|
|
||||||
{
|
|
||||||
if (rInfo.XMLList[iTemp] == rkTemplateName)
|
|
||||||
{
|
|
||||||
NewTemplate = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NewTemplate)
|
|
||||||
rInfo.XMLList.push_back(rkTemplateName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create new ID info
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SPropIDInfo Info;
|
|
||||||
if (!rkTemplateName.IsEmpty()) Info.XMLList.push_back(rkTemplateName);
|
|
||||||
Info.PropertyList.push_back(pProp);
|
|
||||||
smIDMap[ID] = Info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGameTemplate::RenameProperty(IProperty* pProp, const TString& rkNewName)
|
|
||||||
{
|
|
||||||
u32 ID = pProp->ID();
|
|
||||||
if (ID <= 0xFF) ID = CreatePropertyID(pProp);
|
|
||||||
RenameProperty(ID, rkNewName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGameTemplate::RenameProperty(u32 ID, const TString& rkNewName)
|
|
||||||
{
|
|
||||||
// Game name list
|
|
||||||
auto NameIt = smPropertyNames.find(ID);
|
|
||||||
TString Original;
|
|
||||||
|
|
||||||
if (NameIt != smPropertyNames.end())
|
|
||||||
{
|
|
||||||
Original = NameIt->second;
|
|
||||||
smPropertyNames[ID] = rkNewName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Properties
|
|
||||||
auto InfoIt = smIDMap.find(ID);
|
|
||||||
|
|
||||||
if (InfoIt != smIDMap.end())
|
|
||||||
{
|
|
||||||
const SPropIDInfo& rkInfo = InfoIt->second;
|
|
||||||
|
|
||||||
for (u32 PropertyIdx = 0; PropertyIdx < rkInfo.PropertyList.size(); PropertyIdx++)
|
|
||||||
{
|
|
||||||
if (Original.IsEmpty() || rkInfo.PropertyList[PropertyIdx]->Name() == Original)
|
|
||||||
rkInfo.PropertyList[PropertyIdx]->SetName(rkNewName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGameTemplate::XMLsUsingID(u32 ID, std::vector<TString>& rOutList)
|
|
||||||
{
|
|
||||||
auto InfoIt = smIDMap.find(ID);
|
|
||||||
|
|
||||||
if (InfoIt != smIDMap.end())
|
|
||||||
{
|
|
||||||
const SPropIDInfo& rkInfo = InfoIt->second;
|
|
||||||
rOutList = rkInfo.XMLList;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<IProperty*>* CGameTemplate::TemplatesWithMatchingID(IProperty* pProp)
|
|
||||||
{
|
|
||||||
u32 ID = pProp->ID();
|
|
||||||
if (ID <= 0xFF) ID = CreatePropertyID(pProp);
|
|
||||||
|
|
||||||
auto InfoIt = smIDMap.find(ID);
|
|
||||||
|
|
||||||
if (InfoIt != smIDMap.end())
|
|
||||||
{
|
|
||||||
const SPropIDInfo& rkInfo = InfoIt->second;
|
|
||||||
return &rkInfo.PropertyList;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<u32, CGameTemplate::SPropIDInfo> CGameTemplate::smIDMap;
|
|
||||||
std::map<EGame, CGameTemplate*> CGameTemplate::smGameMap;
|
|
||||||
std::map<u32, TString> CGameTemplate::smPropertyNames;
|
|
||||||
u32 CGameTemplate::smGameListVersion;
|
|
||||||
|
|
|
@ -28,84 +28,85 @@ struct SObjId
|
||||||
|
|
||||||
void Serialize(IArchive& Arc)
|
void Serialize(IArchive& Arc)
|
||||||
{
|
{
|
||||||
if (Arc.Game() <= ePrime)
|
if (Arc.Game() <= EGame::Prime)
|
||||||
Arc.SerializePrimitive(ID, SH_HexDisplay);
|
Arc.SerializePrimitive(ID, SH_HexDisplay);
|
||||||
else
|
else
|
||||||
Arc.SerializePrimitive(ID_4CC, 0);
|
Arc.SerializePrimitive(ID_4CC, 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Struct holding a reference to a script object template */
|
||||||
|
struct SScriptTemplatePath
|
||||||
|
{
|
||||||
|
/** Script object ID */
|
||||||
|
SObjId ID;
|
||||||
|
|
||||||
|
/** File path to the template file, relative to the game directory */
|
||||||
|
TString Path;
|
||||||
|
|
||||||
|
/** Template in memory */
|
||||||
|
std::shared_ptr<CScriptTemplate> pTemplate;
|
||||||
|
|
||||||
|
/** Constructor */
|
||||||
|
SScriptTemplatePath()
|
||||||
|
: ID(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
SScriptTemplatePath(u32 InID, const TString& kInPath, CScriptTemplate* pInTemplate)
|
||||||
|
: ID(InID)
|
||||||
|
, Path(kInPath)
|
||||||
|
, pTemplate( std::shared_ptr<CScriptTemplate>(pInTemplate) )
|
||||||
|
{}
|
||||||
|
|
||||||
|
SScriptTemplatePath(const CFourCC& kInID, const TString& kInPath, CScriptTemplate* pInTemplate)
|
||||||
|
: ID(kInID)
|
||||||
|
, Path(kInPath)
|
||||||
|
, pTemplate( std::shared_ptr<CScriptTemplate>(pInTemplate) )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/** Serializer */
|
||||||
|
void Serialize(IArchive& Arc)
|
||||||
|
{
|
||||||
|
Arc << SerialParameter("ID", ID, SH_Attribute)
|
||||||
|
<< SerialParameter("Path", Path, SH_Attribute);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Struct holding a reference to a property template */
|
||||||
|
struct SPropertyTemplatePath
|
||||||
|
{
|
||||||
|
/** File path to the template file, relative to the game directory */
|
||||||
|
TString Path;
|
||||||
|
|
||||||
|
/** Template in memory */
|
||||||
|
std::shared_ptr<IProperty> pTemplate;
|
||||||
|
|
||||||
|
/** Constructor */
|
||||||
|
SPropertyTemplatePath()
|
||||||
|
{}
|
||||||
|
|
||||||
|
SPropertyTemplatePath(const TString& kInPath, IProperty* pInTemplate)
|
||||||
|
: Path(kInPath)
|
||||||
|
, pTemplate( std::shared_ptr<IProperty>(pInTemplate) )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/** Serializer */
|
||||||
|
void Serialize(IArchive& Arc)
|
||||||
|
{
|
||||||
|
Arc << SerialParameter("Path", Path, SH_Attribute);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** CGameTemplate - Per-game template data */
|
||||||
class CGameTemplate
|
class CGameTemplate
|
||||||
{
|
{
|
||||||
friend class CTemplateLoader;
|
friend class CTemplateLoader;
|
||||||
friend class CTemplateWriter;
|
friend class CTemplateWriter;
|
||||||
|
|
||||||
/** Struct holding a reference to a script object template */
|
|
||||||
struct SScriptTemplatePath
|
|
||||||
{
|
|
||||||
/** Script object ID */
|
|
||||||
SObjId ID;
|
|
||||||
|
|
||||||
/** File path to the template file, relative to the game directory */
|
|
||||||
TString Path;
|
|
||||||
|
|
||||||
/** Template in memory */
|
|
||||||
std::shared_ptr<CScriptTemplate> pTemplate;
|
|
||||||
|
|
||||||
/** Constructor */
|
|
||||||
SScriptTemplatePath()
|
|
||||||
: ID(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
SScriptTemplatePath(u32 InID, const TString& kInPath, CScriptTemplate* pInTemplate)
|
|
||||||
: ID(InID)
|
|
||||||
, Path(kInPath)
|
|
||||||
, pTemplate( std::shared_ptr<CScriptTemplate>(pInTemplate) )
|
|
||||||
{}
|
|
||||||
|
|
||||||
SScriptTemplatePath(const CFourCC& kInID, const TString& kInPath, CScriptTemplate* pInTemplate)
|
|
||||||
: ID(kInID)
|
|
||||||
, Path(kInPath)
|
|
||||||
, pTemplate( std::shared_ptr<CScriptTemplate>(pInTemplate) )
|
|
||||||
{}
|
|
||||||
|
|
||||||
/** Serializer */
|
|
||||||
void Serialize(IArchive& Arc)
|
|
||||||
{
|
|
||||||
Arc << SerialParameter("ID", ID, SH_Attribute)
|
|
||||||
<< SerialParameter("Path", Path, SH_Attribute);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Struct holding a reference to a property template */
|
|
||||||
struct SPropertyTemplatePath
|
|
||||||
{
|
|
||||||
/** File path to the template file, relative to the game directory */
|
|
||||||
TString Path;
|
|
||||||
|
|
||||||
/** Template in memory */
|
|
||||||
std::shared_ptr<IProperty> pTemplate;
|
|
||||||
|
|
||||||
/** Constructor */
|
|
||||||
SPropertyTemplatePath()
|
|
||||||
{}
|
|
||||||
|
|
||||||
SPropertyTemplatePath(const TString& kInPath, IProperty* pInTemplate)
|
|
||||||
: Path(kInPath)
|
|
||||||
, pTemplate( std::shared_ptr<IProperty>(pInTemplate) )
|
|
||||||
{}
|
|
||||||
|
|
||||||
/** Serializer */
|
|
||||||
void Serialize(IArchive& Arc)
|
|
||||||
{
|
|
||||||
Arc << SerialParameter("Path", Path, SH_Attribute);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
EGame mGame;
|
EGame mGame;
|
||||||
TString mGameName;
|
|
||||||
TString mSourceFile;
|
TString mSourceFile;
|
||||||
bool mFullyLoaded;
|
bool mFullyLoaded;
|
||||||
|
bool mDirty;
|
||||||
|
|
||||||
/** Template arrays */
|
/** Template arrays */
|
||||||
std::map<SObjId, SScriptTemplatePath> mScriptTemplates;
|
std::map<SObjId, SScriptTemplatePath> mScriptTemplates;
|
||||||
|
@ -114,26 +115,16 @@ class CGameTemplate
|
||||||
std::map<SObjId, TString> mStates;
|
std::map<SObjId, TString> mStates;
|
||||||
std::map<SObjId, TString> mMessages;
|
std::map<SObjId, TString> mMessages;
|
||||||
|
|
||||||
struct SPropIDInfo
|
/** Internal function for loading a property template from a file. */
|
||||||
{
|
|
||||||
std::vector<TString> XMLList; // List of script/struct templates that use this ID
|
|
||||||
std::vector<IProperty*> PropertyList; // List of all properties that use this ID
|
|
||||||
};
|
|
||||||
static std::map<u32, SPropIDInfo> smIDMap;
|
|
||||||
static std::map<EGame, CGameTemplate*> smGameMap;
|
|
||||||
static std::map<u32, TString> smPropertyNames;
|
|
||||||
static u32 smGameListVersion;
|
|
||||||
|
|
||||||
void Internal_LoadScriptTemplate(SScriptTemplatePath& Path);
|
|
||||||
void Internal_LoadPropertyTemplate(SPropertyTemplatePath& Path);
|
void Internal_LoadPropertyTemplate(SPropertyTemplatePath& Path);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CGameTemplate();
|
CGameTemplate();
|
||||||
void Serialize(IArchive& Arc);
|
void Serialize(IArchive& Arc);
|
||||||
void LoadSubTemplates();
|
void Load(const TString& kFilePath);
|
||||||
void SaveSubTemplates();
|
void Save();
|
||||||
void SaveScriptTemplate(CScriptTemplate* pTemplate);
|
void SaveGameTemplates(bool ForceAll = false);
|
||||||
void SavePropertyTemplate(IProperty* pProperty);
|
|
||||||
u32 GameVersion(TString VersionName);
|
u32 GameVersion(TString VersionName);
|
||||||
CScriptTemplate* TemplateByID(u32 ObjectID);
|
CScriptTemplate* TemplateByID(u32 ObjectID);
|
||||||
CScriptTemplate* TemplateByID(const CFourCC& ObjectID);
|
CScriptTemplate* TemplateByID(const CFourCC& ObjectID);
|
||||||
|
@ -145,28 +136,15 @@ public:
|
||||||
SMessage MessageByID(const CFourCC& MessageID);
|
SMessage MessageByID(const CFourCC& MessageID);
|
||||||
SMessage MessageByIndex(u32 Index);
|
SMessage MessageByIndex(u32 Index);
|
||||||
IProperty* FindPropertyArchetype(const TString& kTypeName);
|
IProperty* FindPropertyArchetype(const TString& kTypeName);
|
||||||
TString GetGameDirectory(bool Absolute = false) const;
|
TString GetPropertyArchetypeFilePath(const TString& kTypeName);
|
||||||
|
TString GetGameDirectory() const;
|
||||||
|
|
||||||
// Inline Accessors
|
// Inline Accessors
|
||||||
inline EGame Game() const { return mGame; }
|
inline EGame Game() const { return mGame; }
|
||||||
inline TString GameName() const { return mGameName; }
|
|
||||||
inline u32 NumScriptTemplates() const { return mScriptTemplates.size(); }
|
inline u32 NumScriptTemplates() const { return mScriptTemplates.size(); }
|
||||||
inline u32 NumStates() const { return mStates.size(); }
|
inline u32 NumStates() const { return mStates.size(); }
|
||||||
inline u32 NumMessages() const { return mMessages.size(); }
|
inline u32 NumMessages() const { return mMessages.size(); }
|
||||||
inline bool IsLoadedSuccessfully() { return mFullyLoaded; }
|
inline bool IsLoadedSuccessfully() { return mFullyLoaded; }
|
||||||
|
|
||||||
// Static
|
|
||||||
static CGameTemplate* GetGameTemplate(EGame Game);
|
|
||||||
static std::list<CGameTemplate*> GameTemplateList();
|
|
||||||
static TString FindGameName(EGame Game);
|
|
||||||
static EGame FindGameForName(const TString& rkName);
|
|
||||||
static TString PropertyName(u32 PropertyID);
|
|
||||||
static u32 CreatePropertyID(IProperty *pTemp);
|
|
||||||
static void AddProperty(IProperty *pTemp, const TString& rkTemplateName = "");
|
|
||||||
static void RenameProperty(IProperty *pTemp, const TString& rkNewName);
|
|
||||||
static void RenameProperty(u32 ID, const TString& rkNewName);
|
|
||||||
static void XMLsUsingID(u32 ID, std::vector<TString>& rOutList);
|
|
||||||
static const std::vector<IProperty*>* TemplatesWithMatchingID(IProperty *pTemp);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CGAMETEMPLATE_H
|
#endif // CGAMETEMPLATE_H
|
||||||
|
|
|
@ -24,7 +24,7 @@ struct SState
|
||||||
|
|
||||||
void Serialize(IArchive& Arc)
|
void Serialize(IArchive& Arc)
|
||||||
{
|
{
|
||||||
if (Arc.Game() <= ePrime)
|
if (Arc.Game() <= EGame::Prime)
|
||||||
Arc << SerialParameter("ID", ID, SH_Attribute | SH_HexDisplay);
|
Arc << SerialParameter("ID", ID, SH_Attribute | SH_HexDisplay);
|
||||||
else
|
else
|
||||||
Arc << SerialParameter("ID", ID_4CC, SH_Attribute);
|
Arc << SerialParameter("ID", ID_4CC, SH_Attribute);
|
||||||
|
@ -51,7 +51,7 @@ struct SMessage
|
||||||
|
|
||||||
void Serialize(IArchive& Arc)
|
void Serialize(IArchive& Arc)
|
||||||
{
|
{
|
||||||
if (Arc.Game() <= ePrime)
|
if (Arc.Game() <= EGame::Prime)
|
||||||
Arc << SerialParameter("ID", ID, SH_Attribute | SH_HexDisplay);
|
Arc << SerialParameter("ID", ID, SH_Attribute | SH_HexDisplay);
|
||||||
else
|
else
|
||||||
Arc << SerialParameter("ID", ID_4CC, SH_Attribute);
|
Arc << SerialParameter("ID", ID_4CC, SH_Attribute);
|
||||||
|
|
|
@ -13,6 +13,7 @@ CScriptTemplate::CScriptTemplate(CGameTemplate *pGame)
|
||||||
: mpGame(pGame)
|
: mpGame(pGame)
|
||||||
, mpProperties(nullptr)
|
, mpProperties(nullptr)
|
||||||
, mVisible(true)
|
, mVisible(true)
|
||||||
|
, mDirty(false)
|
||||||
, mpNameProperty(nullptr)
|
, mpNameProperty(nullptr)
|
||||||
, mpPositionProperty(nullptr)
|
, mpPositionProperty(nullptr)
|
||||||
, mpRotationProperty(nullptr)
|
, mpRotationProperty(nullptr)
|
||||||
|
@ -42,7 +43,23 @@ CScriptTemplate::CScriptTemplate(CGameTemplate* pInGame, u32 InObjectID, const T
|
||||||
, mpActiveProperty(nullptr)
|
, mpActiveProperty(nullptr)
|
||||||
, mpLightParametersProperty(nullptr)
|
, mpLightParametersProperty(nullptr)
|
||||||
, mVisible(true)
|
, mVisible(true)
|
||||||
|
, mDirty(false)
|
||||||
{
|
{
|
||||||
|
// Load
|
||||||
|
CXMLReader Reader(kInFilePath);
|
||||||
|
ASSERT(Reader.IsValid());
|
||||||
|
Serialize(Reader);
|
||||||
|
|
||||||
|
// Post load initialization
|
||||||
|
mSourceFile = kInFilePath;
|
||||||
|
mpProperties->Initialize(nullptr, this, 0);
|
||||||
|
|
||||||
|
if (!mNameIDString.IsEmpty()) mpNameProperty = TPropCast<CStringProperty>( mpProperties->ChildByIDString(mNameIDString) );
|
||||||
|
if (!mPositionIDString.IsEmpty()) mpPositionProperty = TPropCast<CVectorProperty>( mpProperties->ChildByIDString(mPositionIDString) );
|
||||||
|
if (!mRotationIDString.IsEmpty()) mpRotationProperty = TPropCast<CVectorProperty>( mpProperties->ChildByIDString(mRotationIDString) );
|
||||||
|
if (!mScaleIDString.IsEmpty()) mpScaleProperty = TPropCast<CVectorProperty>( mpProperties->ChildByIDString(mScaleIDString) );
|
||||||
|
if (!mActiveIDString.IsEmpty()) mpActiveProperty = TPropCast<CBoolProperty>( mpProperties->ChildByIDString(mActiveIDString) );
|
||||||
|
if (!mLightParametersIDString.IsEmpty()) mpLightParametersProperty = TPropCast<CStructProperty>( mpProperties->ChildByIDString(mLightParametersIDString) );
|
||||||
}
|
}
|
||||||
|
|
||||||
CScriptTemplate::~CScriptTemplate()
|
CScriptTemplate::~CScriptTemplate()
|
||||||
|
@ -77,16 +94,15 @@ void CScriptTemplate::Serialize(IArchive& Arc)
|
||||||
<< SerialParameter("VolumeConditions", mVolumeConditions, SH_Optional);
|
<< SerialParameter("VolumeConditions", mVolumeConditions, SH_Optional);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScriptTemplate::PostLoad()
|
void CScriptTemplate::Save(bool Force)
|
||||||
{
|
{
|
||||||
mpProperties->Initialize(nullptr, this, 0);
|
if (mDirty || Force)
|
||||||
|
{
|
||||||
if (!mNameIDString.IsEmpty()) mpNameProperty = TPropCast<CStringProperty>( mpProperties->ChildByIDString(mNameIDString) );
|
CXMLWriter Writer(mSourceFile, "ScriptObject", 0, mpGame->Game());
|
||||||
if (!mPositionIDString.IsEmpty()) mpPositionProperty = TPropCast<CVectorProperty>( mpProperties->ChildByIDString(mPositionIDString) );
|
ASSERT(Writer.IsValid());
|
||||||
if (!mRotationIDString.IsEmpty()) mpRotationProperty = TPropCast<CVectorProperty>( mpProperties->ChildByIDString(mRotationIDString) );
|
Serialize(Writer);
|
||||||
if (!mScaleIDString.IsEmpty()) mpScaleProperty = TPropCast<CVectorProperty>( mpProperties->ChildByIDString(mScaleIDString) );
|
mDirty = false;
|
||||||
if (!mActiveIDString.IsEmpty()) mpActiveProperty = TPropCast<CBoolProperty>( mpProperties->ChildByIDString(mActiveIDString) );
|
}
|
||||||
if (!mLightParametersIDString.IsEmpty()) mpLightParametersProperty = TPropCast<CStructProperty>( mpProperties->ChildByIDString(mLightParametersIDString) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EGame CScriptTemplate::Game() const
|
EGame CScriptTemplate::Game() const
|
||||||
|
|
|
@ -127,6 +127,7 @@ private:
|
||||||
};
|
};
|
||||||
std::vector<SVolumeCondition> mVolumeConditions;
|
std::vector<SVolumeCondition> mVolumeConditions;
|
||||||
bool mVisible;
|
bool mVisible;
|
||||||
|
bool mDirty;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Default constructor. Don't use. This is only here so the serializer doesn't complain
|
// Default constructor. Don't use. This is only here so the serializer doesn't complain
|
||||||
|
@ -137,7 +138,7 @@ public:
|
||||||
CScriptTemplate(CGameTemplate* pGame, u32 ObjectID, const TString& kFilePath);
|
CScriptTemplate(CGameTemplate* pGame, u32 ObjectID, const TString& kFilePath);
|
||||||
~CScriptTemplate();
|
~CScriptTemplate();
|
||||||
void Serialize(IArchive& rArc);
|
void Serialize(IArchive& rArc);
|
||||||
void PostLoad();
|
void Save(bool Force = false);
|
||||||
EGame Game() const;
|
EGame Game() const;
|
||||||
|
|
||||||
// Property Fetching
|
// Property Fetching
|
||||||
|
@ -168,6 +169,8 @@ public:
|
||||||
inline CStructProperty* LightParametersProperty() const { return mpLightParametersProperty; }
|
inline CStructProperty* LightParametersProperty() const { return mpLightParametersProperty; }
|
||||||
|
|
||||||
inline void SetVisible(bool Visible) { mVisible = Visible; }
|
inline void SetVisible(bool Visible) { mVisible = Visible; }
|
||||||
|
inline void MarkDirty() { mDirty = true; }
|
||||||
|
inline bool IsDirty() const { return mDirty; }
|
||||||
|
|
||||||
// Object Tracking
|
// Object Tracking
|
||||||
u32 NumObjects() const;
|
u32 NumObjects() const;
|
||||||
|
|
|
@ -22,7 +22,7 @@ public:
|
||||||
|
|
||||||
virtual const char* HashableTypeName() const
|
virtual const char* HashableTypeName() const
|
||||||
{
|
{
|
||||||
return (Game() <= eEchoes ? "AnimationSet" : "CharacterAnimationSet");
|
return (Game() <= EGame::Echoes ? "AnimationSet" : "CharacterAnimationSet");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual CAnimationParameters GetSerializationDefaultValue()
|
virtual CAnimationParameters GetSerializationDefaultValue()
|
||||||
|
|
|
@ -109,11 +109,6 @@ public:
|
||||||
{
|
{
|
||||||
TTypedProperty::Serialize(rArc);
|
TTypedProperty::Serialize(rArc);
|
||||||
rArc << SerialParameter("ItemArchetype", mpItemArchetype);
|
rArc << SerialParameter("ItemArchetype", mpItemArchetype);
|
||||||
|
|
||||||
if (rArc.IsReader())
|
|
||||||
{
|
|
||||||
mpItemArchetype->SetPropertyFlags( EPropertyFlag::IsArrayArchetype );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||||
|
|
|
@ -42,9 +42,6 @@ class TEnumPropertyBase : public TSerializeableTypedProperty<s32, TypeEnum>
|
||||||
};
|
};
|
||||||
std::vector<SEnumValue> mValues;
|
std::vector<SEnumValue> mValues;
|
||||||
|
|
||||||
/** XML template file that this enum originated from; for archetypes */
|
|
||||||
TString mSourceFile;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
TEnumPropertyBase(EGame Game)
|
TEnumPropertyBase(EGame Game)
|
||||||
|
@ -66,7 +63,7 @@ public:
|
||||||
TTypedProperty::Serialize(rArc);
|
TTypedProperty::Serialize(rArc);
|
||||||
|
|
||||||
TEnumPropertyBase* pArchetype = static_cast<TEnumPropertyBase*>(mpArchetype);
|
TEnumPropertyBase* pArchetype = static_cast<TEnumPropertyBase*>(mpArchetype);
|
||||||
u32 DefaultValueFlags = SH_HexDisplay | (pArchetype || Game() <= ePrime ? SH_Optional : 0);
|
u32 DefaultValueFlags = SH_HexDisplay | (pArchetype || Game() <= EGame::Prime ? SH_Optional : 0);
|
||||||
rArc << SerialParameter("DefaultValue", mDefaultValue, DefaultValueFlags, pArchetype ? pArchetype->mDefaultValue : 0);
|
rArc << SerialParameter("DefaultValue", mDefaultValue, DefaultValueFlags, pArchetype ? pArchetype->mDefaultValue : 0);
|
||||||
|
|
||||||
if (!pArchetype || !rArc.CanSkipParameters() || mValues != pArchetype->mValues)
|
if (!pArchetype || !rArc.CanSkipParameters() || mValues != pArchetype->mValues)
|
||||||
|
@ -87,12 +84,6 @@ public:
|
||||||
mValues = pOtherEnum->mValues;
|
mValues = pOtherEnum->mValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual TString GetTemplateFileName()
|
|
||||||
{
|
|
||||||
ASSERT(IsArchetype() || mpArchetype);
|
|
||||||
return IsArchetype() ? mSourceFile : mpArchetype->GetTemplateFileName();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddValue(TString ValueName, u32 ValueID)
|
void AddValue(TString ValueName, u32 ValueID)
|
||||||
{
|
{
|
||||||
mValues.push_back( SEnumValue(ValueName, ValueID) );
|
mValues.push_back( SEnumValue(ValueName, ValueID) );
|
||||||
|
|
|
@ -37,12 +37,6 @@ void CFlagsProperty::InitFromArchetype(IProperty* pOther)
|
||||||
mAllFlags = pOtherFlags->mAllFlags;
|
mAllFlags = pOtherFlags->mAllFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
TString CFlagsProperty::GetTemplateFileName()
|
|
||||||
{
|
|
||||||
ASSERT(IsArchetype() || mpArchetype);
|
|
||||||
return IsArchetype() ? mSourceFile : mpArchetype->GetTemplateFileName();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether there are any unrecognized bits toggled on in the property value.
|
* Checks whether there are any unrecognized bits toggled on in the property value.
|
||||||
* Returns the mask of any invalid bits. If all bits are valid, returns 0.
|
* Returns the mask of any invalid bits. If all bits are valid, returns 0.
|
||||||
|
|
|
@ -35,9 +35,6 @@ class CFlagsProperty : public TSerializeableTypedProperty<u32, EPropertyType::Fl
|
||||||
std::vector<SBitFlag> mBitFlags;
|
std::vector<SBitFlag> mBitFlags;
|
||||||
u32 mAllFlags;
|
u32 mAllFlags;
|
||||||
|
|
||||||
/** XML template file that this enum originated from; for archetypes */
|
|
||||||
TString mSourceFile;
|
|
||||||
|
|
||||||
CFlagsProperty(EGame Game)
|
CFlagsProperty(EGame Game)
|
||||||
: TSerializeableTypedProperty(Game)
|
: TSerializeableTypedProperty(Game)
|
||||||
, mAllFlags(0)
|
, mAllFlags(0)
|
||||||
|
@ -65,7 +62,6 @@ public:
|
||||||
virtual void PostInitialize();
|
virtual void PostInitialize();
|
||||||
virtual void SerializeValue(void* pData, IArchive& rArc) const;
|
virtual void SerializeValue(void* pData, IArchive& rArc) const;
|
||||||
virtual void InitFromArchetype(IProperty* pOther);
|
virtual void InitFromArchetype(IProperty* pOther);
|
||||||
virtual TString GetTemplateFileName();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether there are any unrecognized bits toggled on in the property value.
|
* Checks whether there are any unrecognized bits toggled on in the property value.
|
||||||
|
|
|
@ -149,6 +149,8 @@ void CPropertyNameGenerator::Generate(const SPropertyNameGenerationParameters& r
|
||||||
FullHash.Hash( *rkParams.TypeNames[TypeIdx] );
|
FullHash.Hash( *rkParams.TypeNames[TypeIdx] );
|
||||||
u32 PropertyID = FullHash.Digest();
|
u32 PropertyID = FullHash.Digest();
|
||||||
|
|
||||||
|
//@FIXME
|
||||||
|
#if 0
|
||||||
// Check if this hash is a property ID - it's valid if there are any XMLs using this ID
|
// Check if this hash is a property ID - it's valid if there are any XMLs using this ID
|
||||||
SGeneratedPropertyName PropertyName;
|
SGeneratedPropertyName PropertyName;
|
||||||
CGameTemplate::XMLsUsingID(PropertyID, PropertyName.XmlList);
|
CGameTemplate::XMLsUsingID(PropertyID, PropertyName.XmlList);
|
||||||
|
@ -202,6 +204,7 @@ void CPropertyNameGenerator::Generate(const SPropertyNameGenerationParameters& r
|
||||||
Log::Write(LogMsg);
|
Log::Write(LogMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Every 250 tests, check with the progress notifier. Update the progress
|
// Every 250 tests, check with the progress notifier. Update the progress
|
||||||
|
|
|
@ -6,6 +6,14 @@ EPropertyType CStructProperty::Type() const
|
||||||
return EPropertyType::Struct;
|
return EPropertyType::Struct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CStructProperty::PostInitialize()
|
||||||
|
{
|
||||||
|
IProperty::PostInitialize();
|
||||||
|
|
||||||
|
// All structs should have an archetype.
|
||||||
|
ASSERT( IsRootParent() || mpArchetype != nullptr );
|
||||||
|
}
|
||||||
|
|
||||||
u32 CStructProperty::DataSize() const
|
u32 CStructProperty::DataSize() const
|
||||||
{
|
{
|
||||||
if (!mChildren.empty())
|
if (!mChildren.empty())
|
||||||
|
@ -74,12 +82,9 @@ void CStructProperty::Serialize(IArchive& rArc)
|
||||||
bool Atomic = IsAtomic();
|
bool Atomic = IsAtomic();
|
||||||
rArc << SerialParameter("Atomic", Atomic, SH_Optional, false);
|
rArc << SerialParameter("Atomic", Atomic, SH_Optional, false);
|
||||||
|
|
||||||
if (rArc.IsReader())
|
if (rArc.IsReader() && Atomic)
|
||||||
{
|
{
|
||||||
if (Atomic)
|
mFlags.SetFlag(EPropertyFlag::IsAtomic);
|
||||||
mFlags.SetFlag(EPropertyFlag::IsAtomic);
|
|
||||||
else
|
|
||||||
mFlags.ClearFlag(EPropertyFlag::IsAtomic);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serialize archetype
|
// Serialize archetype
|
||||||
|
@ -187,9 +192,3 @@ bool CStructProperty::ShouldSerialize() const
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TString CStructProperty::GetTemplateFileName()
|
|
||||||
{
|
|
||||||
ASSERT(IsArchetype() || mpArchetype);
|
|
||||||
return IsArchetype() ? mTemplateFileName : mpArchetype->GetTemplateFileName();
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,15 +13,13 @@ public:
|
||||||
typedef void* ValueType;
|
typedef void* ValueType;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** For archetypes, the filename of the template XML file. */
|
|
||||||
TString mTemplateFileName;
|
|
||||||
|
|
||||||
CStructProperty(EGame Game)
|
CStructProperty(EGame Game)
|
||||||
: IProperty(Game)
|
: IProperty(Game)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual EPropertyType Type() const;
|
virtual EPropertyType Type() const;
|
||||||
|
virtual void PostInitialize();
|
||||||
virtual u32 DataSize() const;
|
virtual u32 DataSize() const;
|
||||||
virtual u32 DataAlignment() const;
|
virtual u32 DataAlignment() const;
|
||||||
virtual void Construct(void* pData) const;
|
virtual void Construct(void* pData) const;
|
||||||
|
@ -33,7 +31,6 @@ public:
|
||||||
virtual void SerializeValue(void* pData, IArchive& Arc) const;
|
virtual void SerializeValue(void* pData, IArchive& Arc) const;
|
||||||
virtual void InitFromArchetype(IProperty* pOther);
|
virtual void InitFromArchetype(IProperty* pOther);
|
||||||
virtual bool ShouldSerialize() const;
|
virtual bool ShouldSerialize() const;
|
||||||
virtual TString GetTemplateFileName();
|
|
||||||
|
|
||||||
inline static EPropertyType StaticType() { return EPropertyType::Struct; }
|
inline static EPropertyType StaticType() { return EPropertyType::Struct; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
#include "Core/Resource/Script/CGameTemplate.h"
|
#include "Core/Resource/Script/CGameTemplate.h"
|
||||||
#include "Core/Resource/Script/CScriptTemplate.h"
|
#include "Core/Resource/Script/CScriptTemplate.h"
|
||||||
|
#include "Core/Resource/Script/NGameList.h"
|
||||||
|
#include "Core/Resource/Script/NPropertyMap.h"
|
||||||
|
|
||||||
/** IProperty */
|
/** IProperty */
|
||||||
IProperty::IProperty(EGame Game)
|
IProperty::IProperty(EGame Game)
|
||||||
|
@ -25,7 +27,15 @@ IProperty::IProperty(EGame Game)
|
||||||
void IProperty::_ClearChildren()
|
void IProperty::_ClearChildren()
|
||||||
{
|
{
|
||||||
for (int ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
|
for (int ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
|
||||||
|
{
|
||||||
|
// Unregister children from the name map. This has to be done before actually deleting them.
|
||||||
|
if (mChildren[ChildIdx]->UsesNameMap())
|
||||||
|
{
|
||||||
|
NPropertyMap::UnregisterProperty(mChildren[ChildIdx]);
|
||||||
|
}
|
||||||
|
|
||||||
delete mChildren[ChildIdx];
|
delete mChildren[ChildIdx];
|
||||||
|
}
|
||||||
|
|
||||||
mChildren.clear();
|
mChildren.clear();
|
||||||
}
|
}
|
||||||
|
@ -35,13 +45,17 @@ IProperty::~IProperty()
|
||||||
// Remove from archetype
|
// Remove from archetype
|
||||||
if( mpArchetype != nullptr )
|
if( mpArchetype != nullptr )
|
||||||
{
|
{
|
||||||
|
// If you crash here, it most likely means this property was not added to the archetype's sub-instances list.
|
||||||
NBasics::VectorRemoveOne(mpArchetype->mSubInstances, this);
|
NBasics::VectorRemoveOne(mpArchetype->mSubInstances, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is an archetype, all our sub-instances should have destructed first.
|
// If this is an archetype, make sure no sub-instances have a reference to us.
|
||||||
if( IsArchetype() )
|
if( IsArchetype() )
|
||||||
{
|
{
|
||||||
ASSERT(mSubInstances.empty());
|
for( int SubIdx = 0; SubIdx < mSubInstances.size(); SubIdx++ )
|
||||||
|
{
|
||||||
|
mSubInstances[SubIdx]->mpArchetype = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete children
|
// Delete children
|
||||||
|
@ -72,7 +86,7 @@ void IProperty::Serialize(IArchive& rArc)
|
||||||
|
|
||||||
if (rArc.IsReader() && !ArchetypeName.IsEmpty())
|
if (rArc.IsReader() && !ArchetypeName.IsEmpty())
|
||||||
{
|
{
|
||||||
CGameTemplate* pGame = CGameTemplate::GetGameTemplate( Game() );
|
CGameTemplate* pGame = NGameList::GetGameTemplate( Game() );
|
||||||
IProperty* pArchetype = pGame->FindPropertyArchetype(ArchetypeName);
|
IProperty* pArchetype = pGame->FindPropertyArchetype(ArchetypeName);
|
||||||
|
|
||||||
// The archetype must exist, or else the template file is malformed.
|
// The archetype must exist, or else the template file is malformed.
|
||||||
|
@ -89,7 +103,7 @@ void IProperty::Serialize(IArchive& rArc)
|
||||||
//
|
//
|
||||||
// We can't currently tell if this property is atomic, as the flag hasn't been serialized and the parent
|
// We can't currently tell if this property is atomic, as the flag hasn't been serialized and the parent
|
||||||
// hasn't been set, but atomic sub-properties don't use hash IDs, so we can do a pseudo-check against the ID.
|
// hasn't been set, but atomic sub-properties don't use hash IDs, so we can do a pseudo-check against the ID.
|
||||||
if (rArc.Game() <= ePrime || IsRootParent() || IsArrayArchetype() || mID <= 0xFF)
|
if (rArc.Game() <= EGame::Prime || IsRootParent() || IsArrayArchetype() || mID <= 0xFF)
|
||||||
{
|
{
|
||||||
rArc << SerialParameter("Name", mName, mpArchetype ? SH_Optional : 0, mpArchetype ? mpArchetype->mName : "");
|
rArc << SerialParameter("Name", mName, mpArchetype ? SH_Optional : 0, mpArchetype ? mpArchetype->mName : "");
|
||||||
}
|
}
|
||||||
|
@ -107,6 +121,8 @@ void IProperty::InitFromArchetype(IProperty* pOther)
|
||||||
{
|
{
|
||||||
//@todo maybe somehow use Serialize for this instead?
|
//@todo maybe somehow use Serialize for this instead?
|
||||||
mpArchetype = pOther;
|
mpArchetype = pOther;
|
||||||
|
mpArchetype->mSubInstances.push_back(this);
|
||||||
|
|
||||||
mFlags = pOther->mFlags & EPropertyFlag::ArchetypeCopyFlags;
|
mFlags = pOther->mFlags & EPropertyFlag::ArchetypeCopyFlags;
|
||||||
mName = pOther->mName;
|
mName = pOther->mName;
|
||||||
mDescription = pOther->mDescription;
|
mDescription = pOther->mDescription;
|
||||||
|
@ -133,24 +149,6 @@ bool IProperty::ShouldSerialize() const
|
||||||
mMaxVersion != mpArchetype->mMaxVersion;
|
mMaxVersion != mpArchetype->mMaxVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
TString IProperty::GetTemplateFileName()
|
|
||||||
{
|
|
||||||
if (mpScriptTemplate)
|
|
||||||
{
|
|
||||||
return mpScriptTemplate->SourceFile();
|
|
||||||
}
|
|
||||||
else if (IsArchetype())
|
|
||||||
{
|
|
||||||
IProperty* pRootParent = RootParent();
|
|
||||||
ASSERT(pRootParent != this);
|
|
||||||
return pRootParent->GetTemplateFileName();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return mpArchetype->GetTemplateFileName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void IProperty::Initialize(IProperty* pInParent, CScriptTemplate* pInTemplate, u32 InOffset)
|
void IProperty::Initialize(IProperty* pInParent, CScriptTemplate* pInTemplate, u32 InOffset)
|
||||||
{
|
{
|
||||||
// Make sure we only get initialized once.
|
// Make sure we only get initialized once.
|
||||||
|
@ -161,12 +159,6 @@ void IProperty::Initialize(IProperty* pInParent, CScriptTemplate* pInTemplate, u
|
||||||
mOffset = InOffset;
|
mOffset = InOffset;
|
||||||
mpScriptTemplate = pInTemplate;
|
mpScriptTemplate = pInTemplate;
|
||||||
|
|
||||||
// Look up property name if needed.
|
|
||||||
if (Game() >= eEchoesDemo && !IsRootParent() && !IsIntrinsic() && !mpParent->IsAtomic() && !IsArrayArchetype())
|
|
||||||
{
|
|
||||||
mName = CGameTemplate::PropertyName(mID);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set any fields dependent on the parent...
|
// Set any fields dependent on the parent...
|
||||||
if (mpParent)
|
if (mpParent)
|
||||||
{
|
{
|
||||||
|
@ -180,6 +172,21 @@ void IProperty::Initialize(IProperty* pInParent, CScriptTemplate* pInTemplate, u
|
||||||
{
|
{
|
||||||
mpPointerParent = mpParent->mpPointerParent;
|
mpPointerParent = mpParent->mpPointerParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mpParent->Type() == EPropertyType::Array)
|
||||||
|
{
|
||||||
|
mFlags |= EPropertyFlag::IsArrayArchetype;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!mpScriptTemplate)
|
||||||
|
{
|
||||||
|
mFlags |= EPropertyFlag::IsArchetype;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register the property if needed.
|
||||||
|
if (UsesNameMap())
|
||||||
|
{
|
||||||
|
NPropertyMap::RegisterProperty(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow subclasses to handle any initialization tasks
|
// Allow subclasses to handle any initialization tasks
|
||||||
|
@ -259,7 +266,21 @@ IProperty* IProperty::ChildByIDString(const TIDString& rkIdString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IProperty::ShouldCook(void*pPropertyData) const
|
TString IProperty::GetTemplateFileName()
|
||||||
|
{
|
||||||
|
if (mpScriptTemplate)
|
||||||
|
{
|
||||||
|
return mpScriptTemplate->SourceFile();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CGameTemplate* pGameTemplate = NGameList::GetGameTemplate(Game());
|
||||||
|
IProperty* pTemplateRoot = (IsArchetype() ? RootParent() : mpArchetype);
|
||||||
|
return pGameTemplate->GetPropertyArchetypeFilePath( pTemplateRoot->Name() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IProperty::ShouldCook(void* pPropertyData) const
|
||||||
{
|
{
|
||||||
switch (mCookPreference)
|
switch (mCookPreference)
|
||||||
{
|
{
|
||||||
|
@ -270,7 +291,7 @@ bool IProperty::ShouldCook(void*pPropertyData) const
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (Game() < eReturns ? true : !MatchesDefault(pPropertyData));
|
return (Game() < EGame::DKCReturns ? true : !MatchesDefault(pPropertyData));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,28 +299,67 @@ void IProperty::SetName(const TString& rkNewName)
|
||||||
{
|
{
|
||||||
mName = rkNewName;
|
mName = rkNewName;
|
||||||
mFlags.ClearFlag(EPropertyFlag::HasCachedNameCheck);
|
mFlags.ClearFlag(EPropertyFlag::HasCachedNameCheck);
|
||||||
|
|
||||||
|
// in Echoes and on, since property names are referenced by ID, renaming a property
|
||||||
|
// doesn't directly affect the serialized data, so it doesn't need to be flagged dirty
|
||||||
|
if (mGame <= EGame::Prime)
|
||||||
|
{
|
||||||
|
MarkDirty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IProperty::SetDescription(const TString& rkNewDescription)
|
void IProperty::SetDescription(const TString& rkNewDescription)
|
||||||
{
|
{
|
||||||
mDescription = rkNewDescription;
|
mDescription = rkNewDescription;
|
||||||
|
MarkDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IProperty::SetSuffix(const TString& rkNewSuffix)
|
void IProperty::SetSuffix(const TString& rkNewSuffix)
|
||||||
{
|
{
|
||||||
mSuffix = rkNewSuffix;
|
mSuffix = rkNewSuffix;
|
||||||
|
MarkDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IProperty::SetPropertyFlags(FPropertyFlags FlagsToSet)
|
void IProperty::MarkDirty()
|
||||||
{
|
{
|
||||||
mFlags |= FlagsToSet;
|
// This property is either part of a script template, or a property archetype.
|
||||||
|
// Figure out which one, set the dirty flag as needed
|
||||||
|
if (mpScriptTemplate)
|
||||||
|
{
|
||||||
|
mpScriptTemplate->MarkDirty();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RootParent()->mFlags |= EPropertyFlag::IsDirty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IProperty::ClearDirtyFlag()
|
||||||
|
{
|
||||||
|
if (!mpScriptTemplate)
|
||||||
|
{
|
||||||
|
RootParent()->mFlags &= ~EPropertyFlag::IsDirty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IProperty::UsesNameMap()
|
||||||
|
{
|
||||||
|
return Game() >= EGame::EchoesDemo &&
|
||||||
|
!IsRootParent() &&
|
||||||
|
!IsIntrinsic() &&
|
||||||
|
!mpParent->IsAtomic() && // Atomic properties can use the name map, but their children shouldn't
|
||||||
|
!IsArrayArchetype();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IProperty::HasAccurateName()
|
bool IProperty::HasAccurateName()
|
||||||
{
|
{
|
||||||
// Exceptions for the three hardcoded 4CC property IDs
|
// Exceptions for the three hardcoded 4CC property IDs
|
||||||
if (mID == FOURCC('XFRM') || mID == FOURCC('INAM') || mID == FOURCC('ACTV'))
|
if (mID == FOURCC('XFRM') ||
|
||||||
|
mID == FOURCC('INAM') ||
|
||||||
|
mID == FOURCC('ACTV'))
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Children of atomic properties defer to parents. Intrinsic properties and array archetypes also defer to parents.
|
// Children of atomic properties defer to parents. Intrinsic properties and array archetypes also defer to parents.
|
||||||
if ( (mpParent && mpParent->IsAtomic()) || IsIntrinsic() || IsArrayArchetype() )
|
if ( (mpParent && mpParent->IsAtomic()) || IsIntrinsic() || IsArrayArchetype() )
|
||||||
|
@ -374,7 +434,6 @@ IProperty* IProperty::CreateCopy(IProperty* pArchetype)
|
||||||
{
|
{
|
||||||
IProperty* pOut = Create(pArchetype->Type(), pArchetype->mGame);
|
IProperty* pOut = Create(pArchetype->Type(), pArchetype->mGame);
|
||||||
pOut->InitFromArchetype(pArchetype);
|
pOut->InitFromArchetype(pArchetype);
|
||||||
pArchetype->mSubInstances.push_back(pOut);
|
|
||||||
return pOut;
|
return pOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ enum class EPropertyFlag : u32
|
||||||
IsAtomic = 0x8,
|
IsAtomic = 0x8,
|
||||||
/** This is a property of a C++ class, not a script object */
|
/** This is a property of a C++ class, not a script object */
|
||||||
IsIntrinsic = 0x10,
|
IsIntrinsic = 0x10,
|
||||||
|
/** Property has been modified, and needs to be resaved. Only valid on archetypes */
|
||||||
|
IsDirty = 0x20,
|
||||||
/** We have cached whether the property name is correct */
|
/** We have cached whether the property name is correct */
|
||||||
HasCachedNameCheck = 0x40000000,
|
HasCachedNameCheck = 0x40000000,
|
||||||
/** The name of the property is a match for the property ID hash */
|
/** The name of the property is a match for the property ID hash */
|
||||||
|
@ -185,18 +187,20 @@ public:
|
||||||
virtual void Serialize(IArchive& rArc);
|
virtual void Serialize(IArchive& rArc);
|
||||||
virtual void InitFromArchetype(IProperty* pOther);
|
virtual void InitFromArchetype(IProperty* pOther);
|
||||||
virtual bool ShouldSerialize() const;
|
virtual bool ShouldSerialize() const;
|
||||||
virtual TString GetTemplateFileName();
|
|
||||||
|
|
||||||
/** Utility methods */
|
/** Utility methods */
|
||||||
void Initialize(IProperty* pInParent, CScriptTemplate* pInTemplate, u32 InOffset);
|
void Initialize(IProperty* pInParent, CScriptTemplate* pInTemplate, u32 InOffset);
|
||||||
void* RawValuePtr(void* pData) const;
|
void* RawValuePtr(void* pData) const;
|
||||||
IProperty* ChildByID(u32 ID) const;
|
IProperty* ChildByID(u32 ID) const;
|
||||||
IProperty* ChildByIDString(const TIDString& rkIdString);
|
IProperty* ChildByIDString(const TIDString& rkIdString);
|
||||||
|
TString GetTemplateFileName();
|
||||||
bool ShouldCook(void* pPropertyData) const;
|
bool ShouldCook(void* pPropertyData) const;
|
||||||
void SetName(const TString& rkNewName);
|
void SetName(const TString& rkNewName);
|
||||||
void SetDescription(const TString& rkNewDescription);
|
void SetDescription(const TString& rkNewDescription);
|
||||||
void SetSuffix(const TString& rkNewSuffix);
|
void SetSuffix(const TString& rkNewSuffix);
|
||||||
void SetPropertyFlags(FPropertyFlags FlagsToSet);
|
void MarkDirty();
|
||||||
|
void ClearDirtyFlag();
|
||||||
|
bool UsesNameMap();
|
||||||
bool HasAccurateName();
|
bool HasAccurateName();
|
||||||
|
|
||||||
/** Accessors */
|
/** Accessors */
|
||||||
|
@ -219,6 +223,7 @@ public:
|
||||||
inline bool IsArrayArchetype() const { return mFlags.HasFlag(EPropertyFlag::IsArrayArchetype); }
|
inline bool IsArrayArchetype() const { return mFlags.HasFlag(EPropertyFlag::IsArrayArchetype); }
|
||||||
inline bool IsAtomic() const { return mFlags.HasFlag(EPropertyFlag::IsAtomic); }
|
inline bool IsAtomic() const { return mFlags.HasFlag(EPropertyFlag::IsAtomic); }
|
||||||
inline bool IsIntrinsic() const { return mFlags.HasFlag(EPropertyFlag::IsIntrinsic); }
|
inline bool IsIntrinsic() const { return mFlags.HasFlag(EPropertyFlag::IsIntrinsic); }
|
||||||
|
inline bool IsDirty() const { return mFlags.HasFlag(EPropertyFlag::IsDirty); }
|
||||||
inline bool IsRootParent() const { return mpParent == nullptr; }
|
inline bool IsRootParent() const { return mpParent == nullptr; }
|
||||||
|
|
||||||
/** Create */
|
/** Create */
|
||||||
|
@ -337,7 +342,7 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual EPropertyType Type() const { return PropEnum; }
|
virtual EPropertyType Type() const { return PropEnum; }
|
||||||
virtual u32 DataSize() const { return sizeof(PropType); }
|
virtual u32 DataSize() const { return sizeof(PropType); }
|
||||||
virtual u32 DataAlignment() const { return alignof(PropType); }
|
virtual u32 DataAlignment() const { return alignof(PropType); }
|
||||||
virtual void Construct(void* pData) const { new(ValuePtr(pData)) PropType(mDefaultValue); }
|
virtual void Construct(void* pData) const { new(ValuePtr(pData)) PropType(mDefaultValue); }
|
||||||
|
@ -400,7 +405,7 @@ public:
|
||||||
// on property types that don't have default values in the game executable.
|
// on property types that don't have default values in the game executable.
|
||||||
bool MakeOptional = false;
|
bool MakeOptional = false;
|
||||||
|
|
||||||
if (Game() <= ePrime || pArchetype != nullptr)
|
if (Game() <= EGame::Prime || pArchetype != nullptr)
|
||||||
{
|
{
|
||||||
MakeOptional = true;
|
MakeOptional = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER
|
||||||
|
|
||||||
// Turn off backface culling
|
// Turn off backface culling
|
||||||
EGame Game = mpScene->ActiveArea()->Game();
|
EGame Game = mpScene->ActiveArea()->Game();
|
||||||
bool ForceDisableBackfaceCull = (rkViewInfo.CollisionSettings.DrawBackfaces || Game == eReturns) && glIsEnabled(GL_CULL_FACE);
|
bool ForceDisableBackfaceCull = (rkViewInfo.CollisionSettings.DrawBackfaces || Game == EGame::DKCReturns) && glIsEnabled(GL_CULL_FACE);
|
||||||
|
|
||||||
if (ForceDisableBackfaceCull)
|
if (ForceDisableBackfaceCull)
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
|
@ -66,11 +66,11 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER
|
||||||
if (rkViewInfo.CollisionSettings.HighlightMask != 0 && (rMat.RawFlags() & rkViewInfo.CollisionSettings.HighlightMask) == rkViewInfo.CollisionSettings.HighlightMask)
|
if (rkViewInfo.CollisionSettings.HighlightMask != 0 && (rMat.RawFlags() & rkViewInfo.CollisionSettings.HighlightMask) == rkViewInfo.CollisionSettings.HighlightMask)
|
||||||
Tint *= CColor::skRed;
|
Tint *= CColor::skRed;
|
||||||
|
|
||||||
else if (Game != eReturns && rkViewInfo.CollisionSettings.TintWithSurfaceColor)
|
else if (Game != EGame::DKCReturns && rkViewInfo.CollisionSettings.TintWithSurfaceColor)
|
||||||
Tint *= rMat.SurfaceColor(Game);
|
Tint *= rMat.SurfaceColor(Game);
|
||||||
|
|
||||||
bool IsFloor = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.IsFloor() : true) || Game == eReturns;
|
bool IsFloor = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.IsFloor() : true) || Game == EGame::DKCReturns;
|
||||||
bool IsUnstandable = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.IsUnstandable(Game) : false) && Game != eReturns;
|
bool IsUnstandable = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.IsUnstandable(Game) : false) && Game != EGame::DKCReturns;
|
||||||
CDrawUtil::UseCollisionShader(IsFloor, IsUnstandable, Tint);
|
CDrawUtil::UseCollisionShader(IsFloor, IsUnstandable, Tint);
|
||||||
pMesh->DrawMaterial(iMat, false);
|
pMesh->DrawMaterial(iMat, false);
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER
|
||||||
// Draw collision bounds for area collision
|
// Draw collision bounds for area collision
|
||||||
// note: right now checking parent is the best way to check whether this node is area collision instead of actor collision
|
// note: right now checking parent is the best way to check whether this node is area collision instead of actor collision
|
||||||
// actor collision will have a script node parent whereas area collision will have a root node parent
|
// actor collision will have a script node parent whereas area collision will have a root node parent
|
||||||
if (rkViewInfo.CollisionSettings.DrawAreaCollisionBounds && Parent()->NodeType() == eRootNode && Game != eReturns)
|
if (rkViewInfo.CollisionSettings.DrawAreaCollisionBounds && Parent()->NodeType() == eRootNode && Game != EGame::DKCReturns)
|
||||||
CDrawUtil::DrawWireCube( mpCollision->MeshByIndex(0)->BoundingBox(), CColor::skRed );
|
CDrawUtil::DrawWireCube( mpCollision->MeshByIndex(0)->BoundingBox(), CColor::skRed );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -188,7 +188,7 @@ void CScriptNode::Draw(FRenderOptions Options, int /*ComponentIndex*/, ERenderCo
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// DKCR doesn't support world lighting yet, so light nodes that don't have ingame models with default lighting
|
// DKCR doesn't support world lighting yet, so light nodes that don't have ingame models with default lighting
|
||||||
if (Template()->Game() == eReturns && !mpInstance->HasInGameModel() && CGraphics::sLightMode == CGraphics::eWorldLighting)
|
if (Template()->Game() == EGame::DKCReturns && !mpInstance->HasInGameModel() && CGraphics::sLightMode == CGraphics::eWorldLighting)
|
||||||
{
|
{
|
||||||
CGraphics::SetDefaultLighting();
|
CGraphics::SetDefaultLighting();
|
||||||
CGraphics::sVertexBlock.COLOR0_Amb = CGraphics::skDefaultAmbientColor;
|
CGraphics::sVertexBlock.COLOR0_Amb = CGraphics::skDefaultAmbientColor;
|
||||||
|
@ -624,7 +624,7 @@ void CScriptNode::GeneratePosition()
|
||||||
void CScriptNode::TestGameModeVisibility()
|
void CScriptNode::TestGameModeVisibility()
|
||||||
{
|
{
|
||||||
// Don't render if we don't have an ingame model, or if this is the Prime series and the instance is not active.
|
// Don't render if we don't have an ingame model, or if this is the Prime series and the instance is not active.
|
||||||
if ((Template()->Game() < eReturns && !mpInstance->IsActive()) || !mpInstance->HasInGameModel())
|
if ((Template()->Game() < EGame::DKCReturns && !mpInstance->IsActive()) || !mpInstance->HasInGameModel())
|
||||||
mGameModeVisibility = eNotVisible;
|
mGameModeVisibility = eNotVisible;
|
||||||
|
|
||||||
// If this is Returns, only render if the instance is active OR if it has a near visible activation.
|
// If this is Returns, only render if the instance is active OR if it has a near visible activation.
|
||||||
|
|
|
@ -9,7 +9,7 @@ CDoorExtra::CDoorExtra(CScriptObject* pInstance, CScene* pScene, CScriptNode* pP
|
||||||
mShieldModelProp = CAssetRef(pInstance->PropertyData(), pProperties->ChildByID(0xB20CC271));
|
mShieldModelProp = CAssetRef(pInstance->PropertyData(), pProperties->ChildByID(0xB20CC271));
|
||||||
if (mShieldModelProp.IsValid()) PropertyModified(mShieldModelProp.Property());
|
if (mShieldModelProp.IsValid()) PropertyModified(mShieldModelProp.Property());
|
||||||
|
|
||||||
if (mGame >= eEchoes)
|
if (mGame >= EGame::Echoes)
|
||||||
{
|
{
|
||||||
mShieldColorProp = CColorRef(pInstance->PropertyData(), pProperties->ChildByID(0x47B4E863));
|
mShieldColorProp = CColorRef(pInstance->PropertyData(), pProperties->ChildByID(0x47B4E863));
|
||||||
if (mShieldColorProp.IsValid()) PropertyModified(mShieldColorProp.Property());
|
if (mShieldColorProp.IsValid()) PropertyModified(mShieldColorProp.Property());
|
||||||
|
|
|
@ -10,8 +10,8 @@ CPointOfInterestExtra::CPointOfInterestExtra(CScriptObject *pInstance, CScene *p
|
||||||
// Fetch scan data property
|
// Fetch scan data property
|
||||||
CStructProperty* pProperties = pInstance->Template()->Properties();
|
CStructProperty* pProperties = pInstance->Template()->Properties();
|
||||||
|
|
||||||
if (mGame <= ePrime) mScanProperty = CAssetRef(pInstance->PropertyData(), pProperties->ChildByIDString("0x04:0x00"));
|
if (mGame <= EGame::Prime) mScanProperty = CAssetRef(pInstance->PropertyData(), pProperties->ChildByIDString("0x04:0x00"));
|
||||||
else mScanProperty = CAssetRef(pInstance->PropertyData(), pProperties->ChildByIDString("0xBDBEC295:0xB94E9BE7"));
|
else mScanProperty = CAssetRef(pInstance->PropertyData(), pProperties->ChildByIDString("0xBDBEC295:0xB94E9BE7"));
|
||||||
|
|
||||||
PropertyModified(mScanProperty.Property());
|
PropertyModified(mScanProperty.Property());
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ CScriptExtra* CScriptExtra::CreateExtra(CScriptNode *pNode)
|
||||||
case 0x53505041: // "SPPA" SplinePath (DKCR)
|
case 0x53505041: // "SPPA" SplinePath (DKCR)
|
||||||
case 0x5043544C: // "PCTL" PathControl (DKCR)
|
case 0x5043544C: // "PCTL" PathControl (DKCR)
|
||||||
case 0x434C5043: // "CLPC" ClingPathControl (DKCR)
|
case 0x434C5043: // "CLPC" ClingPathControl (DKCR)
|
||||||
if (pNode->Instance()->Area()->Game() == eReturns)
|
if (pNode->Instance()->Area()->Game() == EGame::DKCReturns)
|
||||||
pExtra = new CSplinePathExtra(pObj, pNode->Scene(), pNode);
|
pExtra = new CSplinePathExtra(pObj, pNode->Scene(), pNode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ void CSplinePathExtra::FindAttachedWaypoints(std::set<CWaypointExtra*>& rChecked
|
||||||
|
|
||||||
void CSplinePathExtra::AddWaypoints()
|
void CSplinePathExtra::AddWaypoints()
|
||||||
{
|
{
|
||||||
if (mGame != eReturns)
|
if (mGame != EGame::DKCReturns)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::set<CWaypointExtra*> CheckedWaypoints;
|
std::set<CWaypointExtra*> CheckedWaypoints;
|
||||||
|
|
|
@ -28,7 +28,7 @@ void CWaypointExtra::CheckColor()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch color from parent node's model (MP1/2/3)
|
// Fetch color from parent node's model (MP1/2/3)
|
||||||
else if (mGame < eReturns)
|
else if (mGame < EGame::DKCReturns)
|
||||||
{
|
{
|
||||||
CScriptNode *pScript = static_cast<CScriptNode*>(mpParent);
|
CScriptNode *pScript = static_cast<CScriptNode*>(mpParent);
|
||||||
CModel *pModel = pScript->ActiveModel();
|
CModel *pModel = pScript->ActiveModel();
|
||||||
|
@ -185,5 +185,5 @@ void CWaypointExtra::Draw(FRenderOptions /*Options*/, int ComponentIndex, ERende
|
||||||
|
|
||||||
CColor CWaypointExtra::TevColor()
|
CColor CWaypointExtra::TevColor()
|
||||||
{
|
{
|
||||||
return (mGame < eReturns ? CColor::skWhite : mColor);
|
return (mGame < EGame::DKCReturns ? CColor::skWhite : mColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
inline CGameProject* ActiveProject() const { return mpActiveProject; }
|
inline CGameProject* ActiveProject() const { return mpActiveProject; }
|
||||||
inline CWorldEditor* WorldEditor() const { return mpWorldEditor; }
|
inline CWorldEditor* WorldEditor() const { return mpWorldEditor; }
|
||||||
inline CProjectSettingsDialog* ProjectDialog() const { return mpProjectDialog; }
|
inline CProjectSettingsDialog* ProjectDialog() const { return mpProjectDialog; }
|
||||||
inline EGame CurrentGame() const { return mpActiveProject ? mpActiveProject->Game() : eUnknownGame; }
|
inline EGame CurrentGame() const { return mpActiveProject ? mpActiveProject->Game() : EGame::Invalid; }
|
||||||
|
|
||||||
inline void SetEditorTicksEnabled(bool Enabled) { Enabled ? mRefreshTimer.start(gkTickFrequencyMS) : mRefreshTimer.stop(); }
|
inline void SetEditorTicksEnabled(bool Enabled) { Enabled ? mRefreshTimer.start(gkTickFrequencyMS) : mRefreshTimer.stop(); }
|
||||||
inline bool AreEditorTicksEnabled() const { return mRefreshTimer.isActive(); }
|
inline bool AreEditorTicksEnabled() const { return mRefreshTimer.isActive(); }
|
||||||
|
|
|
@ -24,7 +24,7 @@ CExportGameDialog::CExportGameDialog(const QString& rkIsoPath, const QString& rk
|
||||||
, mpDisc(nullptr)
|
, mpDisc(nullptr)
|
||||||
, mpExporter(nullptr)
|
, mpExporter(nullptr)
|
||||||
, mDiscType(eDT_Normal)
|
, mDiscType(eDT_Normal)
|
||||||
, mGame(eUnknownGame)
|
, mGame(EGame::Invalid)
|
||||||
, mRegion(ERegion::Unknown)
|
, mRegion(ERegion::Unknown)
|
||||||
, mBuildVer(0.f)
|
, mBuildVer(0.f)
|
||||||
, mWiiFrontend(false)
|
, mWiiFrontend(false)
|
||||||
|
@ -85,7 +85,7 @@ void CExportGameDialog::InitUI(QString ExportDir)
|
||||||
mpUI->GameTitleLineEdit->setText( TO_QSTRING(mGameTitle) );
|
mpUI->GameTitleLineEdit->setText( TO_QSTRING(mGameTitle) );
|
||||||
mpUI->GameIdLineEdit->setText( TO_QSTRING(mGameID) );
|
mpUI->GameIdLineEdit->setText( TO_QSTRING(mGameID) );
|
||||||
mpUI->BuildVersionLineEdit->setText( QString("%1 (%2)").arg(mBuildVer).arg( TO_QSTRING(GameInfo.GetBuildName(mBuildVer, mRegion)) ));
|
mpUI->BuildVersionLineEdit->setText( QString("%1 (%2)").arg(mBuildVer).arg( TO_QSTRING(GameInfo.GetBuildName(mBuildVer, mRegion)) ));
|
||||||
mpUI->RegionLineEdit->setText( GetRegionName(mRegion) );
|
mpUI->RegionLineEdit->setText( TEnumReflection<ERegion>::ConvertValueToString(mRegion) );
|
||||||
|
|
||||||
// Disc tree widget
|
// Disc tree widget
|
||||||
nod::IPartition *pPartition = mpDisc->getDataPartition();
|
nod::IPartition *pPartition = mpDisc->getDataPartition();
|
||||||
|
@ -155,23 +155,23 @@ bool CExportGameDialog::ValidateGame()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mGame = ePrime;
|
mGame = EGame::Prime;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FOURCC('G2MX'):
|
case FOURCC('G2MX'):
|
||||||
// Echoes, but also appears in the MP3 proto
|
// Echoes, but also appears in the MP3 proto
|
||||||
if (mGameID[4] == 'A' && mGameID[5] == 'B')
|
if (mGameID[4] == 'A' && mGameID[5] == 'B')
|
||||||
mGame = eCorruptionProto;
|
mGame = EGame::CorruptionProto;
|
||||||
else
|
else
|
||||||
mGame = eEchoes;
|
mGame = EGame::Echoes;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FOURCC('RM3X'):
|
case FOURCC('RM3X'):
|
||||||
mGame = eCorruption;
|
mGame = EGame::Corruption;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FOURCC('SF8X'):
|
case FOURCC('SF8X'):
|
||||||
mGame = eReturns;
|
mGame = EGame::DKCReturns;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FOURCC('R3MX'):
|
case FOURCC('R3MX'):
|
||||||
|
@ -187,13 +187,13 @@ bool CExportGameDialog::ValidateGame()
|
||||||
|
|
||||||
case FOURCC('R3IX'):
|
case FOURCC('R3IX'):
|
||||||
// MP1 Wii de Asobu
|
// MP1 Wii de Asobu
|
||||||
mGame = ePrime;
|
mGame = EGame::Prime;
|
||||||
mDiscType = eDT_WiiDeAsobu;
|
mDiscType = eDT_WiiDeAsobu;
|
||||||
if (!RequestWiiPortGame()) return false;
|
if (!RequestWiiPortGame()) return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FOURCC('R32X'):
|
case FOURCC('R32X'):
|
||||||
mGame = eEchoes;
|
mGame = EGame::Echoes;
|
||||||
mDiscType = eDT_WiiDeAsobu;
|
mDiscType = eDT_WiiDeAsobu;
|
||||||
if (!RequestWiiPortGame()) return false;
|
if (!RequestWiiPortGame()) return false;
|
||||||
break;
|
break;
|
||||||
|
@ -211,9 +211,9 @@ bool CExportGameDialog::RequestWiiPortGame()
|
||||||
QDialog Dialog;
|
QDialog Dialog;
|
||||||
Dialog.setWindowTitle("Select Game");
|
Dialog.setWindowTitle("Select Game");
|
||||||
|
|
||||||
bool IsTrilogy = (mGame == eUnknownGame);
|
bool IsTrilogy = (mGame == EGame::Invalid);
|
||||||
bool HasMP1 = (IsTrilogy || mGame == ePrime);
|
bool HasMP1 = (IsTrilogy || mGame == EGame::Prime);
|
||||||
bool HasMP2 = (IsTrilogy || mGame == eEchoes);
|
bool HasMP2 = (IsTrilogy || mGame == EGame::Echoes);
|
||||||
bool HasMP3 = IsTrilogy;
|
bool HasMP3 = IsTrilogy;
|
||||||
|
|
||||||
QString GameName = (IsTrilogy ? "Metroid Prime: Trilogy" : "Wii de Asobu");
|
QString GameName = (IsTrilogy ? "Metroid Prime: Trilogy" : "Wii de Asobu");
|
||||||
|
@ -242,20 +242,20 @@ bool CExportGameDialog::RequestWiiPortGame()
|
||||||
switch (ComboBox.currentIndex())
|
switch (ComboBox.currentIndex())
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
mGame = eCorruption;
|
mGame = EGame::Corruption;
|
||||||
mWiiFrontend = true;
|
mWiiFrontend = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
mGame = (HasMP1 ? ePrime : eEchoes);
|
mGame = (HasMP1 ? EGame::Prime : EGame::Echoes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
mGame = eEchoes;
|
mGame = EGame::Echoes;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
mGame = eCorruption;
|
mGame = EGame::Corruption;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ float CExportGameDialog::FindBuildVersion()
|
||||||
ASSERT(mpDisc != nullptr);
|
ASSERT(mpDisc != nullptr);
|
||||||
|
|
||||||
// MP1 demo build doesn't have a build version
|
// MP1 demo build doesn't have a build version
|
||||||
if (mGame == ePrimeDemo) return 0.f;
|
if (mGame == EGame::PrimeDemo) return 0.f;
|
||||||
|
|
||||||
// Get DOL buffer
|
// Get DOL buffer
|
||||||
std::unique_ptr<uint8_t[]> pDolData = mpDisc->getDataPartition()->getDOLBuf();
|
std::unique_ptr<uint8_t[]> pDolData = mpDisc->getDataPartition()->getDOLBuf();
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
|
|
||||||
#include "Editor/Widgets/CCheckableTreeWidgetItem.h"
|
#include "Editor/Widgets/CCheckableTreeWidgetItem.h"
|
||||||
#include "UICommon.h"
|
#include "UICommon.h"
|
||||||
#include <Core/Resource/Factory/CTemplateLoader.h>
|
#include <Core/Resource/Script/NGameList.h>
|
||||||
|
#include <Core/Resource/Script/NPropertyMap.h>
|
||||||
#include <QtConcurrent/QtConcurrent>
|
#include <QtConcurrent/QtConcurrent>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
|
@ -85,7 +86,7 @@ void CGeneratePropertyNamesDialog::StartGeneration()
|
||||||
mpUI->OutputTreeWidget->clear();
|
mpUI->OutputTreeWidget->clear();
|
||||||
|
|
||||||
// Load all templates so we can match as many properties as possible
|
// Load all templates so we can match as many properties as possible
|
||||||
CTemplateLoader::LoadAllGames();
|
NGameList::LoadAllGameTemplates();
|
||||||
|
|
||||||
// Configure the generator
|
// Configure the generator
|
||||||
SPropertyNameGenerationParameters Params;
|
SPropertyNameGenerationParameters Params;
|
||||||
|
@ -225,13 +226,15 @@ void CGeneratePropertyNamesDialog::ApplyChanges()
|
||||||
QTreeWidgetItem* pItem = mCheckedItems[ItemIdx];
|
QTreeWidgetItem* pItem = mCheckedItems[ItemIdx];
|
||||||
u32 ID = TO_TSTRING( pItem->text(2) ).ToInt32();
|
u32 ID = TO_TSTRING( pItem->text(2) ).ToInt32();
|
||||||
|
|
||||||
|
//FIXME
|
||||||
|
#if 0
|
||||||
QString NewName = pItem->text(0);
|
QString NewName = pItem->text(0);
|
||||||
CGameTemplate::RenameProperty( ID, TO_TSTRING(NewName) );
|
NPropertyMap::SetPropertyName(::RenameProperty( ID, TO_TSTRING(NewName) );
|
||||||
pItem->setText(3, NewName);
|
pItem->setText(3, NewName);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME
|
NPropertyMap::SaveMap();
|
||||||
// CTemplateWriter::SavePropertyList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check progress on name generation task and display results on the UI */
|
/** Check progress on name generation task and display results on the UI */
|
||||||
|
@ -258,7 +261,7 @@ void CGeneratePropertyNamesDialog::CheckForNewResults()
|
||||||
ColumnText << TO_QSTRING( rkName.Name )
|
ColumnText << TO_QSTRING( rkName.Name )
|
||||||
<< TO_QSTRING( rkName.Type )
|
<< TO_QSTRING( rkName.Type )
|
||||||
<< TO_QSTRING( TString::HexString(rkName.ID) )
|
<< TO_QSTRING( TString::HexString(rkName.ID) )
|
||||||
<< TO_QSTRING( CGameTemplate::PropertyName(rkName.ID) );
|
<< TO_QSTRING( NPropertyMap::GetPropertyName(rkName.ID, *rkName.Type) );
|
||||||
|
|
||||||
QTreeWidgetItem* pItem = new CCheckableTreeWidgetItem(pTreeWidget, ColumnText);
|
QTreeWidgetItem* pItem = new CCheckableTreeWidgetItem(pTreeWidget, ColumnText);
|
||||||
pItem->setFlags(Qt::ItemIsEnabled |
|
pItem->setFlags(Qt::ItemIsEnabled |
|
||||||
|
|
|
@ -59,9 +59,10 @@ void CProjectSettingsDialog::ActiveProjectChanged(CGameProject *pProj)
|
||||||
|
|
||||||
float BuildVer = pProj->BuildVersion();
|
float BuildVer = pProj->BuildVersion();
|
||||||
ERegion Region = pProj->Region();
|
ERegion Region = pProj->Region();
|
||||||
|
TString RegionName = TEnumReflection<ERegion>::ConvertValueToString(Region);
|
||||||
TString BuildName = pProj->GameInfo()->GetBuildName(BuildVer, Region);
|
TString BuildName = pProj->GameInfo()->GetBuildName(BuildVer, Region);
|
||||||
mpUI->BuildLineEdit->setText( QString("%1 (%2)").arg(BuildVer).arg( TO_QSTRING(BuildName) ) );
|
mpUI->BuildLineEdit->setText( QString("%1 (%2)").arg(BuildVer).arg( TO_QSTRING(BuildName) ) );
|
||||||
mpUI->RegionLineEdit->setText( TO_QSTRING(GetRegionName(Region)) );
|
mpUI->RegionLineEdit->setText( TO_QSTRING(RegionName) );
|
||||||
|
|
||||||
// Banner info
|
// Banner info
|
||||||
COpeningBanner Banner(pProj);
|
COpeningBanner Banner(pProj);
|
||||||
|
|
|
@ -22,6 +22,16 @@ QValidator::State CPropertyNameValidator::validate(QString& rInput, int&) const
|
||||||
Hash.Hash( mpProperty->HashableTypeName() );
|
Hash.Hash( mpProperty->HashableTypeName() );
|
||||||
u32 PropertyID = Hash.Digest();
|
u32 PropertyID = Hash.Digest();
|
||||||
|
|
||||||
|
if (PropertyID != mpProperty->ID())
|
||||||
|
{
|
||||||
|
if (mpProperty->Type() == EPropertyType::Int)
|
||||||
|
{
|
||||||
|
CCRC32 Hash2;
|
||||||
|
Hash2.Hash( rInput.toStdString().c_str() );
|
||||||
|
Hash2.Hash( "choice" );
|
||||||
|
PropertyID = Hash2.Digest();
|
||||||
|
}
|
||||||
|
}
|
||||||
return ( PropertyID == mpProperty->ID() ? QValidator::Acceptable : QValidator::Invalid );
|
return ( PropertyID == mpProperty->ID() ? QValidator::Acceptable : QValidator::Invalid );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ CModelEditorWindow::CModelEditorWindow(CModel *pModel, QWidget *pParent)
|
||||||
, mIgnoreSignals(false)
|
, mIgnoreSignals(false)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->ActionSave->setEnabled( pModel->Game() == ePrime ); // we don't support saving games later than MP1
|
ui->ActionSave->setEnabled( pModel->Game() == EGame::Prime ); // we don't support saving games later than MP1
|
||||||
REPLACE_WINDOWTITLE_APPVARS;
|
REPLACE_WINDOWTITLE_APPVARS;
|
||||||
|
|
||||||
ui->Viewport->SetNode(mpCurrentModelNode);
|
ui->Viewport->SetNode(mpCurrentModelNode);
|
||||||
|
@ -740,7 +740,7 @@ void CModelEditorWindow::Import()
|
||||||
}
|
}
|
||||||
|
|
||||||
CModel *pModel = nullptr;
|
CModel *pModel = nullptr;
|
||||||
CMaterialSet *pSet = CMaterialLoader::ImportAssimpMaterials(pScene, ePrime);
|
CMaterialSet *pSet = CMaterialLoader::ImportAssimpMaterials(pScene, EGame::Prime);
|
||||||
pModel = CModelLoader::ImportAssimpNode(pScene->mRootNode, pScene, *pSet);
|
pModel = CModelLoader::ImportAssimpNode(pScene->mRootNode, pScene, *pSet);
|
||||||
|
|
||||||
SetActiveModel(pModel);
|
SetActiveModel(pModel);
|
||||||
|
|
|
@ -557,7 +557,7 @@ QWidget* CPropertyDelegate::CreateCharacterEditor(QWidget *pParent, const QModel
|
||||||
CResourceSelector* pSelector = new CResourceSelector(pParent);
|
CResourceSelector* pSelector = new CResourceSelector(pParent);
|
||||||
pSelector->SetFrameVisible(false);
|
pSelector->SetFrameVisible(false);
|
||||||
|
|
||||||
if (Params.Version() <= eEchoes)
|
if (Params.Version() <= EGame::Echoes)
|
||||||
pSelector->SetTypeFilter(mpEditor->CurrentGame(), "ANCS");
|
pSelector->SetTypeFilter(mpEditor->CurrentGame(), "ANCS");
|
||||||
else
|
else
|
||||||
pSelector->SetTypeFilter(mpEditor->CurrentGame(), "CHAR");
|
pSelector->SetTypeFilter(mpEditor->CurrentGame(), "CHAR");
|
||||||
|
@ -609,7 +609,7 @@ void CPropertyDelegate::SetCharacterEditorData(QWidget *pEditor, const QModelInd
|
||||||
|
|
||||||
else if (Type == EPropertyType::Int && !pEditor->hasFocus())
|
else if (Type == EPropertyType::Int && !pEditor->hasFocus())
|
||||||
{
|
{
|
||||||
int UnkIndex = (Params.Version() <= eEchoes ? rkIndex.row() - 2 : rkIndex.row() - 1);
|
int UnkIndex = (Params.Version() <= EGame::Echoes ? rkIndex.row() - 2 : rkIndex.row() - 1);
|
||||||
u32 Value = Params.Unknown(UnkIndex);
|
u32 Value = Params.Unknown(UnkIndex);
|
||||||
static_cast<WIntegralSpinBox*>(pEditor)->setValue(Value);
|
static_cast<WIntegralSpinBox*>(pEditor)->setValue(Value);
|
||||||
}
|
}
|
||||||
|
@ -634,7 +634,7 @@ void CPropertyDelegate::SetCharacterModelData(QWidget *pEditor, const QModelInde
|
||||||
|
|
||||||
else if (Type == EPropertyType::Int)
|
else if (Type == EPropertyType::Int)
|
||||||
{
|
{
|
||||||
int UnkIndex = (Params.Version() <= eEchoes ? rkIndex.row() - 2 : rkIndex.row() - 1);
|
int UnkIndex = (Params.Version() <= EGame::Echoes ? rkIndex.row() - 2 : rkIndex.row() - 1);
|
||||||
Params.SetUnknown(UnkIndex, static_cast<WIntegralSpinBox*>(pEditor)->value() );
|
Params.SetUnknown(UnkIndex, static_cast<WIntegralSpinBox*>(pEditor)->value() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,13 +651,13 @@ void CPropertyDelegate::SetCharacterModelData(QWidget *pEditor, const QModelInde
|
||||||
|
|
||||||
EPropertyType CPropertyDelegate::DetermineCharacterPropType(EGame Game, const QModelIndex& rkIndex) const
|
EPropertyType CPropertyDelegate::DetermineCharacterPropType(EGame Game, const QModelIndex& rkIndex) const
|
||||||
{
|
{
|
||||||
if (Game <= eEchoes)
|
if (Game <= EGame::Echoes)
|
||||||
{
|
{
|
||||||
if (rkIndex.row() == 0) return EPropertyType::Asset;
|
if (rkIndex.row() == 0) return EPropertyType::Asset;
|
||||||
else if (rkIndex.row() == 1) return EPropertyType::Choice;
|
else if (rkIndex.row() == 1) return EPropertyType::Choice;
|
||||||
else if (rkIndex.row() == 2) return EPropertyType::Int;
|
else if (rkIndex.row() == 2) return EPropertyType::Int;
|
||||||
}
|
}
|
||||||
else if (Game <= eCorruption)
|
else if (Game <= EGame::Corruption)
|
||||||
{
|
{
|
||||||
if (rkIndex.row() == 0) return EPropertyType::Asset;
|
if (rkIndex.row() == 0) return EPropertyType::Asset;
|
||||||
else if (rkIndex.row() == 1) return EPropertyType::Int;
|
else if (rkIndex.row() == 1) return EPropertyType::Int;
|
||||||
|
|
|
@ -201,8 +201,8 @@ int CPropertyModel::rowCount(const QModelIndex& rkParent) const
|
||||||
void* pData = DataPointerForIndex(rkParent);
|
void* pData = DataPointerForIndex(rkParent);
|
||||||
CAnimationParameters Params = TPropCast<CAnimationSetProperty>(pProp)->Value(pData);
|
CAnimationParameters Params = TPropCast<CAnimationSetProperty>(pProp)->Value(pData);
|
||||||
|
|
||||||
if (Params.Version() <= eEchoes) return 3;
|
if (Params.Version() <= EGame::Echoes) return 3;
|
||||||
if (Params.Version() <= eCorruption) return 2;
|
if (Params.Version() <= EGame::Corruption) return 2;
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
||||||
CAnimationParameters Params = pAnimSet->Value(pData);
|
CAnimationParameters Params = pAnimSet->Value(pData);
|
||||||
|
|
||||||
// There are three different layouts for this property - one for MP1/2, one for MP3, and one for DKCR
|
// There are three different layouts for this property - one for MP1/2, one for MP3, and one for DKCR
|
||||||
if (Params.Version() <= eEchoes)
|
if (Params.Version() <= EGame::Echoes)
|
||||||
{
|
{
|
||||||
if (rkIndex.column() == 0)
|
if (rkIndex.column() == 0)
|
||||||
{
|
{
|
||||||
|
@ -270,7 +270,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
||||||
return QString::number(Params.Unknown(0));
|
return QString::number(Params.Unknown(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Params.Version() <= eCorruption)
|
else if (Params.Version() <= EGame::Corruption)
|
||||||
{
|
{
|
||||||
if (rkIndex.column() == 0)
|
if (rkIndex.column() == 0)
|
||||||
{
|
{
|
||||||
|
@ -453,7 +453,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
||||||
|
|
||||||
if (Role == Qt::ForegroundRole)
|
if (Role == Qt::ForegroundRole)
|
||||||
{
|
{
|
||||||
if (mShowNameValidity && mpRootProperty->ScriptTemplate()->Game() >= eEchoesDemo)
|
if (mShowNameValidity && mpRootProperty->ScriptTemplate()->Game() >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
IProperty *pProp = PropertyForIndex(rkIndex, true);
|
IProperty *pProp = PropertyForIndex(rkIndex, true);
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ void CPropertyView::SetProperties(CStructRef InProperties)
|
||||||
void CPropertyView::SetInstance(CScriptObject *pObj)
|
void CPropertyView::SetInstance(CScriptObject *pObj)
|
||||||
{
|
{
|
||||||
mpObject = pObj;
|
mpObject = pObj;
|
||||||
mpModel->SetBoldModifiedProperties(mpEditor ? (mpEditor->CurrentGame() > ePrime) : true);
|
mpModel->SetBoldModifiedProperties(mpEditor ? (mpEditor->CurrentGame() > EGame::Prime) : true);
|
||||||
|
|
||||||
if (pObj)
|
if (pObj)
|
||||||
mpModel->ConfigureScript(pObj->Area()->Entry()->Project(), pObj->Template()->Properties(), pObj);
|
mpModel->ConfigureScript(pObj->Area()->Entry()->Project(), pObj->Template()->Properties(), pObj);
|
||||||
|
@ -133,7 +133,7 @@ void CPropertyView::UpdateEditorProperties(const QModelIndex& rkParent)
|
||||||
// As an optimization, in MP2+, we don't need to update unless this is an atomic struct or if
|
// As an optimization, in MP2+, we don't need to update unless this is an atomic struct or if
|
||||||
// it's EditorProperties, because other structs never have editor properties in them.
|
// it's EditorProperties, because other structs never have editor properties in them.
|
||||||
// In MP1 this isn't the case so we need to update every struct regardless
|
// In MP1 this isn't the case so we need to update every struct regardless
|
||||||
if ((Game <= ePrime) || (pStruct->IsAtomic() || pStruct->ID() == 0x255A4580))
|
if ((Game <= EGame::Prime) || (pStruct->IsAtomic() || pStruct->ID() == 0x255A4580))
|
||||||
UpdateEditorProperties(Index0);
|
UpdateEditorProperties(Index0);
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
@ -241,7 +241,7 @@ void CPropertyView::CreateContextMenu(const QPoint& rkPos)
|
||||||
Menu.addAction(mpEditTemplateAction);
|
Menu.addAction(mpEditTemplateAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mpEditor->CurrentGame() >= eEchoesDemo)
|
if (mpEditor->CurrentGame() >= EGame::EchoesDemo)
|
||||||
{
|
{
|
||||||
Menu.addAction(mpShowNameValidityAction);
|
Menu.addAction(mpShowNameValidityAction);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ void WScanPreviewPanel::SetResource(CResource *pRes)
|
||||||
ui->ScanTypeLabel->setText("<b><font color=\"red\">Important</font></b>");
|
ui->ScanTypeLabel->setText("<b><font color=\"red\">Important</font></b>");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (pScan->Game() <= ePrime)
|
if (pScan->Game() <= EGame::Prime)
|
||||||
ui->ScanTypeLabel->setText("<b><font color=\"#FF9030\">Normal</font></b>");
|
ui->ScanTypeLabel->setText("<b><font color=\"#FF9030\">Normal</font></b>");
|
||||||
else
|
else
|
||||||
ui->ScanTypeLabel->setText("<b><font color=\"#A0A0FF\">Normal</font></b>");
|
ui->ScanTypeLabel->setText("<b><font color=\"#A0A0FF\">Normal</font></b>");
|
||||||
|
@ -81,7 +81,7 @@ void WScanPreviewPanel::SetResource(CResource *pRes)
|
||||||
ui->ScanTextWidget->SetResource(pScan->ScanText());
|
ui->ScanTextWidget->SetResource(pScan->ScanText());
|
||||||
|
|
||||||
// Show logbook category? (Yes on MP1, no on MP2+)
|
// Show logbook category? (Yes on MP1, no on MP2+)
|
||||||
if (pScan->Game() <= ePrime)
|
if (pScan->Game() <= EGame::Prime)
|
||||||
{
|
{
|
||||||
ui->CategoryInfoLabel->show();
|
ui->CategoryInfoLabel->show();
|
||||||
ui->ScanCategoryLabel->show();
|
ui->ScanCategoryLabel->show();
|
||||||
|
|
|
@ -53,17 +53,17 @@ void CCollisionRenderSettingsDialog::SetupWidgets()
|
||||||
mpUi->HideAiBlockCheckBox->setChecked(rSettings.HideMaterial.HasFlag(eCF_AiBlock));
|
mpUi->HideAiBlockCheckBox->setChecked(rSettings.HideMaterial.HasFlag(eCF_AiBlock));
|
||||||
|
|
||||||
// Toggle visibility of game-exclusive widgets
|
// Toggle visibility of game-exclusive widgets
|
||||||
mpUi->SurfaceTypeCheckBox->setHidden( Game == eReturns );
|
mpUi->SurfaceTypeCheckBox->setHidden( Game == EGame::DKCReturns );
|
||||||
mpUi->StandableTrisCheckBox->setHidden( Game == eReturns );
|
mpUi->StandableTrisCheckBox->setHidden( Game == EGame::DKCReturns );
|
||||||
mpUi->AreaBoundsCheckBox->setHidden( Game == eReturns );
|
mpUi->AreaBoundsCheckBox->setHidden( Game == EGame::DKCReturns );
|
||||||
mpUi->BackfacesCheckBox->setHidden( Game == eReturns );
|
mpUi->BackfacesCheckBox->setHidden( Game == EGame::DKCReturns );
|
||||||
|
|
||||||
mpUi->VisibilityGroupBox->setHidden( Game == eReturns );
|
mpUi->VisibilityGroupBox->setHidden( Game == EGame::DKCReturns );
|
||||||
mpUi->HideShootThruCheckBox->setHidden( Game == eReturns );
|
mpUi->HideShootThruCheckBox->setHidden( Game == EGame::DKCReturns );
|
||||||
mpUi->HideCameraThruCheckBox->setHidden( Game == eReturns );
|
mpUi->HideCameraThruCheckBox->setHidden( Game == EGame::DKCReturns );
|
||||||
mpUi->HideScanThruCheckBox->setHidden( Game == eReturns );
|
mpUi->HideScanThruCheckBox->setHidden( Game == EGame::DKCReturns );
|
||||||
mpUi->HideAiWalkThruCheckBox->setHidden( Game == eReturns );
|
mpUi->HideAiWalkThruCheckBox->setHidden( Game == EGame::DKCReturns );
|
||||||
mpUi->HideAiBlockCheckBox->setHidden( Game < eEchoesDemo || Game == eReturns );
|
mpUi->HideAiBlockCheckBox->setHidden( Game < EGame::EchoesDemo || Game == EGame::DKCReturns );
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCollisionRenderSettingsDialog::OnHideMaskChanged(QString NewMask)
|
void CCollisionRenderSettingsDialog::OnHideMaskChanged(QString NewMask)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "CInstancesModel.h"
|
#include "CInstancesModel.h"
|
||||||
#include "Editor/UICommon.h"
|
#include "Editor/UICommon.h"
|
||||||
#include <Core/Resource/Script/CScriptLayer.h>
|
#include <Core/Resource/Script/CScriptLayer.h>
|
||||||
|
#include <Core/Resource/Script/NGameList.h>
|
||||||
#include <Core/Scene/CScriptNode.h>
|
#include <Core/Scene/CScriptNode.h>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
@ -364,10 +365,7 @@ void CInstancesModel::OnActiveProjectChanged(CGameProject *pProj)
|
||||||
if (mModelType == eTypes)
|
if (mModelType == eTypes)
|
||||||
{
|
{
|
||||||
if (pProj)
|
if (pProj)
|
||||||
{
|
mpCurrentGame = NGameList::GetGameTemplate( pProj->Game() );
|
||||||
EGame ProjGame = pProj->Game();
|
|
||||||
mpCurrentGame = CGameTemplate::GetGameTemplate(ProjGame);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
mpCurrentGame = nullptr;
|
mpCurrentGame = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <Core/Resource/CScan.h>
|
#include <Core/Resource/CScan.h>
|
||||||
#include <Core/Resource/Cooker/CPoiToWorldCooker.h>
|
#include <Core/Resource/Cooker/CPoiToWorldCooker.h>
|
||||||
#include <Core/Resource/Script/CGameTemplate.h>
|
#include <Core/Resource/Script/CGameTemplate.h>
|
||||||
|
#include <Core/Resource/Script/NGameList.h>
|
||||||
#include <Core/ScriptExtra/CPointOfInterestExtra.h>
|
#include <Core/ScriptExtra/CPointOfInterestExtra.h>
|
||||||
|
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
@ -339,7 +340,7 @@ void CPoiMapSidebar::StopPicking()
|
||||||
void CPoiMapSidebar::OnInstanceListButtonClicked()
|
void CPoiMapSidebar::OnInstanceListButtonClicked()
|
||||||
{
|
{
|
||||||
EGame Game = Editor()->CurrentGame();
|
EGame Game = Editor()->CurrentGame();
|
||||||
CScriptTemplate *pPoiTemplate = CGameTemplate::GetGameTemplate(Game)->TemplateByID("POIN");
|
CScriptTemplate *pPoiTemplate = NGameList::GetGameTemplate(Game)->TemplateByID("POIN");
|
||||||
|
|
||||||
CPoiListDialog Dialog(pPoiTemplate, &mSourceModel, Editor()->Scene(), this);
|
CPoiListDialog Dialog(pPoiTemplate, &mSourceModel, Editor()->Scene(), this);
|
||||||
Dialog.exec();
|
Dialog.exec();
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue