Fixed a couple things related to attempting to create projects for demo builds

This commit is contained in:
Aruki 2019-01-12 09:28:06 -08:00
parent 4714c6ccf5
commit 32b12ff650
5 changed files with 52 additions and 17 deletions

View File

@ -103,7 +103,7 @@ public:
inline TString DirectoryPath() const { return mpDirectory->FullPath(); } inline TString DirectoryPath() const { return mpDirectory->FullPath(); }
inline TString Name() const { return mName; } inline TString Name() const { return mName; }
inline const TString& UppercaseName() const { return mCachedUppercaseName; } inline const TString& UppercaseName() const { return mCachedUppercaseName; }
inline EResourceType ResourceType() const { return mpTypeInfo->Type(); } inline EResourceType ResourceType() const { return mpTypeInfo->Type(); }
protected: protected:
CResource* InternalLoad(IInputStream& rInput); CResource* InternalLoad(IInputStream& rInput);

View File

@ -113,6 +113,7 @@ void CCharacterUsageMap::DebugPrintContents()
// ************ PROTECTED ************ // ************ PROTECTED ************
void CCharacterUsageMap::ParseDependencyNode(IDependencyNode *pNode) void CCharacterUsageMap::ParseDependencyNode(IDependencyNode *pNode)
{ {
if (!pNode) return;
EDependencyNodeType Type = pNode->Type(); EDependencyNodeType Type = pNode->Type();
if (Type == EDependencyNodeType::CharacterProperty) if (Type == EDependencyNodeType::CharacterProperty)
@ -271,6 +272,7 @@ void CPackageDependencyListBuilder::AddDependency(CResourceEntry *pCurEntry, con
void CPackageDependencyListBuilder::EvaluateDependencyNode(CResourceEntry *pCurEntry, IDependencyNode *pNode, std::list<CAssetID>& rOut) void CPackageDependencyListBuilder::EvaluateDependencyNode(CResourceEntry *pCurEntry, IDependencyNode *pNode, std::list<CAssetID>& rOut)
{ {
if (!pNode) return;
EDependencyNodeType Type = pNode->Type(); EDependencyNodeType Type = pNode->Type();
bool ParseChildren = false; bool ParseChildren = false;
@ -513,6 +515,7 @@ void CAreaDependencyListBuilder::AddDependency(const CAssetID& rkID, std::list<C
void CAreaDependencyListBuilder::EvaluateDependencyNode(CResourceEntry *pCurEntry, IDependencyNode *pNode, std::list<CAssetID>& rOut, std::set<CAssetID> *pAudioGroupsOut) void CAreaDependencyListBuilder::EvaluateDependencyNode(CResourceEntry *pCurEntry, IDependencyNode *pNode, std::list<CAssetID>& rOut, std::set<CAssetID> *pAudioGroupsOut)
{ {
if (!pNode) return;
EDependencyNodeType Type = pNode->Type(); EDependencyNodeType Type = pNode->Type();
bool ParseChildren = false; bool ParseChildren = false;

View File

@ -195,7 +195,7 @@ void CResTypeInfo::CResTypeInfoFactory::InitTypes()
} }
{ {
CResTypeInfo *pType = new CResTypeInfo(EResourceType::AudioGroup, "Audio Group", "agsc"); CResTypeInfo *pType = new CResTypeInfo(EResourceType::AudioGroup, "Audio Group", "agsc");
AddExtension(pType, "AGSC", EGame::PrimeDemo, EGame::Echoes); AddExtension(pType, "AGSC", EGame::PrimeDemo, EGame::CorruptionProto);
pType->mCanHaveDependencies = false; pType->mCanHaveDependencies = false;
} }
{ {
@ -386,6 +386,7 @@ void CResTypeInfo::CResTypeInfoFactory::InitTypes()
CResTypeInfo *pType = new CResTypeInfo(EResourceType::Texture, "Texture", "txtr"); CResTypeInfo *pType = new CResTypeInfo(EResourceType::Texture, "Texture", "txtr");
AddExtension(pType, "TXTR", EGame::PrimeDemo, EGame::DKCReturns); AddExtension(pType, "TXTR", EGame::PrimeDemo, EGame::DKCReturns);
pType->mCanHaveDependencies = false; pType->mCanHaveDependencies = false;
pType->mCanBeSerialized = true;
} }
{ {
CResTypeInfo *pType = new CResTypeInfo(EResourceType::Tweaks, "Tweak Data", "ctwk"); CResTypeInfo *pType = new CResTypeInfo(EResourceType::Tweaks, "Tweak Data", "ctwk");

View File

@ -81,7 +81,7 @@ void CAnimationLoader::ReadUncompressedANIM()
// Echoes only - rotation channel indices // Echoes only - rotation channel indices
std::vector<uint8> RotationIndices; std::vector<uint8> RotationIndices;
if (mGame == EGame::Echoes) if (mGame >= EGame::EchoesDemo)
{ {
uint32 NumRotationIndices = mpInput->ReadLong(); uint32 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<uint8> ScaleIndices; std::vector<uint8> ScaleIndices;
if (mGame == EGame::Echoes) if (mGame >= EGame::EchoesDemo)
{ {
uint32 NumScaleIndices = mpInput->ReadLong(); uint32 NumScaleIndices = mpInput->ReadLong();
ScaleIndices.resize(NumScaleIndices); ScaleIndices.resize(NumScaleIndices);
@ -161,7 +161,7 @@ void CAnimationLoader::ReadUncompressedANIM()
} }
// Read bone transforms // Read bone transforms
if (mGame == EGame::Echoes) if (mGame >= EGame::EchoesDemo)
{ {
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);
@ -208,23 +208,24 @@ void CAnimationLoader::ReadCompressedANIM()
// Header // Header
mpInput->Seek(0x4, SEEK_CUR); // Skip alloc size mpInput->Seek(0x4, SEEK_CUR); // Skip alloc size
if (mGame == EGame::Invalid) // Version check
mGame = (mpInput->PeekShort() == 0x0101 ? EGame::Echoes : EGame::Prime); mGame = (mpInput->PeekShort() == 0x0101 ? EGame::Echoes : EGame::Prime);
if (mGame == EGame::Prime) // Check the ANIM resource's game instead of the version check we just determined.
// The Echoes demo has some ANIMs that use MP1's format, but don't have the EVNT reference.
if (mpAnim->Game() <= EGame::Prime)
{ {
mpAnim->mpEventData = gpResourceStore->LoadResource<CAnimEventData>(mpInput->ReadLong()); mpAnim->mpEventData = gpResourceStore->LoadResource<CAnimEventData>(mpInput->ReadLong());
mpInput->Seek(0x4, SEEK_CUR); // Skip unknown
} }
else mpInput->Seek(0x2, SEEK_CUR); // Skip unknowns
mpInput->Seek(mGame <= EGame::Prime ? 4 : 2, SEEK_CUR); // Skip unknowns
mpAnim->mDuration = mpInput->ReadFloat(); mpAnim->mDuration = mpInput->ReadFloat();
mpAnim->mTickInterval = mpInput->ReadFloat(); mpAnim->mTickInterval = mpInput->ReadFloat();
mpInput->Seek(0x8, SEEK_CUR); // Skip two unknown values mpInput->Seek(0x8, SEEK_CUR); // Skip two unknown values
mRotationDivisor = mpInput->ReadLong(); mRotationDivisor = mpInput->ReadLong();
mTranslationMultiplier = mpInput->ReadFloat(); mTranslationMultiplier = mpInput->ReadFloat();
if (mGame == EGame::Echoes) mScaleMultiplier = mpInput->ReadFloat(); if (mGame >= EGame::EchoesDemo) mScaleMultiplier = mpInput->ReadFloat();
uint32 NumBoneChannels = mpInput->ReadLong(); uint32 NumBoneChannels = mpInput->ReadLong();
mpInput->Seek(0x4, SEEK_CUR); // Skip unknown value mpInput->Seek(0x4, SEEK_CUR); // Skip unknown value
@ -284,7 +285,7 @@ void CAnimationLoader::ReadCompressedANIM()
// Read scale parameters // Read scale parameters
uint8 ScaleIdx = 0xFF; uint8 ScaleIdx = 0xFF;
if (mGame == EGame::Echoes) if (mGame >= EGame::EchoesDemo)
{ {
rChan.NumScaleKeys = mpInput->ReadShort(); rChan.NumScaleKeys = mpInput->ReadShort();

View File

@ -150,12 +150,32 @@ bool CExportGameDialog::ValidateGame()
// This ID is normally MP1, but it's used by the MP1 NTSC demo and the MP2 bonus disc demo as well // This ID is normally MP1, but it's used by the MP1 NTSC demo and the MP2 bonus disc demo as well
if (strcmp(rkHeader.m_gameTitle, "Long Game Name") == 0) if (strcmp(rkHeader.m_gameTitle, "Long Game Name") == 0)
{ {
// todo - not handling demos yet // Calculate the CRC of the apploader to figure out which game this is.
return false; std::unique_ptr<uint8_t[]> pApploaderData = mpDisc->getDataPartition()->getApploaderBuf();
} uint ApploaderSize = (uint) mpDisc->getDataPartition()->getApploaderSize();
uint ApploaderHash = CCRC32::StaticHashData(pApploaderData.get(), ApploaderSize);
mGame = EGame::Prime; if (ApploaderHash == 0x21B7AFF5)
break; {
// This is the hash for the NTSC MP1 demo.
mGame = EGame::PrimeDemo;
}
else
{
// Hash is different, so this is most likely an Echoes demo build
mGame = EGame::EchoesDemo;
}
break;
}
else
{
// This could be either Metroid Prime, or the PAL demo of it...
// In either case, the PAL demo is based on a later build of the game than the NTSC demo
// So the PAL demo should be configured the same way as the release build of the game anyway
mGame = EGame::Prime;
break;
}
case FOURCC('G2MX'): case FOURCC('G2MX'):
// Echoes, but also appears in the MP3 proto // Echoes, but also appears in the MP3 proto
@ -202,6 +222,16 @@ bool CExportGameDialog::ValidateGame()
return false; return false;
} }
// The demo builds are not supported. The MP1 demo does not have script templates currently.
// Additionally, a lot of file format loaders currently don't support the demo variants of the
// file formats, meaning that attempting to export results in crashes.
if (mGame == EGame::PrimeDemo || mGame == EGame::EchoesDemo || mGame == EGame::CorruptionProto)
{
// we cannot parent the error message box to ourselves because this window hasn't been shown
UICommon::ErrorMsg(parentWidget(), "The demo builds are currently not supported.");
return false;
}
return true; return true;
} }