diff --git a/resources/gameinfo/GameInfoDKCR.xml b/resources/gameinfo/GameInfoDKCR.xml index db57cb98..6b9e366d 100644 --- a/resources/gameinfo/GameInfoDKCR.xml +++ b/resources/gameinfo/GameInfoDKCR.xml @@ -1,6 +1,11 @@ + + 74844 + NTSC + Wii NTSC 0A-0 + 74887 PAL diff --git a/src/Common/CAssetID.cpp b/src/Common/CAssetID.cpp index c71acbbe..3af213a9 100644 --- a/src/Common/CAssetID.cpp +++ b/src/Common/CAssetID.cpp @@ -63,7 +63,7 @@ TString CAssetID::ToString() const if (mLength == e32Bit) return TString::HexString(ToLong(), 8, false, true); else - return TString::FromInt64(ToLongLong(), 8, 16).ToUpper(); + return TString::FromInt64(ToLongLong(), 16, 16).ToUpper(); } bool CAssetID::IsValid() const diff --git a/src/Core/Core.pro b/src/Core/Core.pro index 2ced1c33..0d79c617 100644 --- a/src/Core/Core.pro +++ b/src/Core/Core.pro @@ -227,7 +227,8 @@ HEADERS += \ GameProject/AssetNameGeneration.h \ GameProject/CGameInfo.h \ Resource/CResTypeInfo.h \ - Resource/Cooker/CResourceCooker.h + Resource/Cooker/CResourceCooker.h \ + Resource/CAudioMacro.h # Source Files SOURCES += \ diff --git a/src/Core/GameProject/AssetNameGeneration.cpp b/src/Core/GameProject/AssetNameGeneration.cpp index 88ca4820..86cc88e8 100644 --- a/src/Core/GameProject/AssetNameGeneration.cpp +++ b/src/Core/GameProject/AssetNameGeneration.cpp @@ -41,6 +41,7 @@ void ApplyGeneratedName(CResourceEntry *pEntry, const TWideString& rkDir, const TWideString MakeWorldName(EGame Game, TWideString RawName) { + // The raw world names are basically formatted differently in every single game... // MP1 demo - Remove ! from the beginning if (Game == ePrimeDemo) { @@ -75,18 +76,8 @@ TWideString MakeWorldName(EGame Game, TWideString RawName) RawName = RawName.SubString(UnderscoreA + 1, UnderscoreB - UnderscoreA - 1); } - // MP3 proto - Remove ! from the beginning and all text after last underscore - else if (Game == eCorruptionProto) - { - if (RawName.StartsWith(L'!')) - RawName = RawName.ChopFront(1); - - u32 LastUnderscore = RawName.LastIndexOf(L"_"); - RawName = RawName.ChopBack(RawName.Size() - LastUnderscore); - } - - // MP2/3 - Remove text before first underscore and after last underscore, strip remaining underscores (except multiplayer maps, which have one underscore) - else if (Game == eEchoes || Game == eCorruption) + // MP2 - Remove text before first underscore and after last underscore, strip remaining underscores (except multiplayer maps, which have one underscore) + else if (Game == eEchoes) { u32 FirstUnderscore = RawName.IndexOf(L'_'); u32 LastUnderscore = RawName.LastIndexOf(L"_"); @@ -99,6 +90,23 @@ TWideString MakeWorldName(EGame Game, TWideString RawName) } } + // MP3 proto - Remove ! from the beginning and all text after last underscore + else if (Game == eCorruptionProto) + { + if (RawName.StartsWith(L'!')) + RawName = RawName.ChopFront(1); + + u32 LastUnderscore = RawName.LastIndexOf(L"_"); + RawName = RawName.ChopBack(RawName.Size() - LastUnderscore); + } + + // MP3 - Remove text after last underscore + else if (Game == eCorruption) + { + u32 LastUnderscore = RawName.LastIndexOf(L"_"); + RawName = RawName.ChopBack(RawName.Size() - LastUnderscore); + } + // DKCR - Remove text after second-to-last underscore else if (Game == eReturns) { diff --git a/src/Core/GameProject/CGameProject.cpp b/src/Core/GameProject/CGameProject.cpp index 7f918b1e..0f9169ec 100644 --- a/src/Core/GameProject/CGameProject.cpp +++ b/src/Core/GameProject/CGameProject.cpp @@ -100,12 +100,27 @@ void CGameProject::GetWorldList(std::list& rOut) const { CPackage *pPkg = mPackages[iPkg]; + // Little workaround to fix some of Retro's paks having worlds listed in the wrong order... + // Construct a sorted list of worlds in this package + std::list PackageWorlds; + for (u32 iRes = 0; iRes < pPkg->NumNamedResources(); iRes++) { const SNamedResource& rkRes = pPkg->NamedResourceByIndex(iRes); if (rkRes.Type == "MLVL" && !rkRes.Name.EndsWith("NODEPEND")) - rOut.push_back(rkRes.ID); + PackageWorlds.push_back(&rkRes); + } + + PackageWorlds.sort([](const SNamedResource *pkLeft, const SNamedResource *pkRight) -> bool { + return pkLeft->Name.ToUpper() < pkRight->Name.ToUpper(); + }); + + // Add sorted worlds to the output world list + for (auto Iter = PackageWorlds.begin(); Iter != PackageWorlds.end(); Iter++) + { + const SNamedResource *pkRes = *Iter; + rOut.push_back(pkRes->ID); } } } diff --git a/src/Core/GameProject/CResourceEntry.cpp b/src/Core/GameProject/CResourceEntry.cpp index e6d6cec1..b6f3c27c 100644 --- a/src/Core/GameProject/CResourceEntry.cpp +++ b/src/Core/GameProject/CResourceEntry.cpp @@ -29,7 +29,6 @@ CResourceEntry::CResourceEntry(CResourceStore *pStore, const CAssetID& rkID, mpDirectory = mpStore->GetVirtualDirectory(rkDir, Transient, true); if (mpDirectory) mpDirectory->AddChild(L"", this); - mGame = ((Transient || !mpStore) ? eUnknownGame : mpStore->Game()); } CResourceEntry::~CResourceEntry() @@ -74,6 +73,7 @@ void CResourceEntry::UpdateDependencies() if (!mpResource) { Log::Error("Unable to update cached dependencies; failed to load resource"); + mpDependencies = new CDependencyTree(ID()); return; } @@ -117,7 +117,7 @@ TString CResourceEntry::CookedAssetPath(bool Relative) const CFourCC CResourceEntry::CookedExtension() const { - return mpTypeInfo->CookedExtension(mGame); + return mpTypeInfo->CookedExtension(Game()); } bool CResourceEntry::IsInDirectory(CVirtualDirectory *pDir) const @@ -157,17 +157,6 @@ bool CResourceEntry::NeedsRecook() const return (FileUtil::LastModifiedTime(CookedAssetPath()) < FileUtil::LastModifiedTime(RawAssetPath())); } -void CResourceEntry::SetGame(EGame NewGame) -{ - if (mGame != NewGame) - { - // todo: implement checks here. This needs work because we should trigger a recook and if the extension changes - // we should delete the old file. Also a lot of resources can't evaluate this correctly due to file version - // numbers being shared between games. - mGame = NewGame; - } -} - bool CResourceEntry::Save(bool SkipCacheSave /*= false*/) { // SkipCacheSave argument tells us not to save the resource cache file. This is generally not advised because we don't @@ -196,7 +185,7 @@ bool CResourceEntry::Save(bool SkipCacheSave /*= false*/) TString SerialName = mpTypeInfo->TypeName(); SerialName.RemoveWhitespace(); - CXMLWriter Writer(Path, SerialName, 0, mGame); + CXMLWriter Writer(Path, SerialName, 0, Game()); mpResource->Serialize(Writer); if (!Writer.Save()) @@ -501,5 +490,10 @@ void CResourceEntry::RemoveFromProject() CGameProject* CResourceEntry::Project() const { - return mpStore->Project(); + return mpStore ? mpStore->Project() : nullptr; +} + +EGame CResourceEntry::Game() const +{ + return mpStore ? mpStore->Game() : eUnknownGame; } diff --git a/src/Core/GameProject/CResourceEntry.h b/src/Core/GameProject/CResourceEntry.h index 58f1e69f..8a9bd7db 100644 --- a/src/Core/GameProject/CResourceEntry.h +++ b/src/Core/GameProject/CResourceEntry.h @@ -33,7 +33,6 @@ class CResourceEntry CResourceStore *mpStore; CDependencyTree *mpDependencies; CAssetID mID; - EGame mGame; CVirtualDirectory *mpDirectory; TWideString mName; FResEntryFlags mFlags; @@ -59,7 +58,6 @@ public: bool IsInDirectory(CVirtualDirectory *pDir) const; u64 Size() const; bool NeedsRecook() const; - void SetGame(EGame NewGame); bool Save(bool SkipCacheSave = false); bool Cook(); CResource* Load(); @@ -70,6 +68,7 @@ public: void AddToProject(const TWideString& rkDir, const TWideString& rkName); void RemoveFromProject(); CGameProject* Project() const; + EGame Game() const; // Accessors void SetDirty() { mFlags.SetFlag(eREF_NeedsRecook); } @@ -83,7 +82,6 @@ public: inline CResourceStore* ResourceStore() const { return mpStore; } inline CDependencyTree* Dependencies() const { return mpDependencies; } inline CAssetID ID() const { return mID; } - inline EGame Game() const { return mGame; } inline CVirtualDirectory* Directory() const { return mpDirectory; } inline TWideString DirectoryPath() const { return mpDirectory->FullPath(); } inline TWideString Name() const { return mName; } diff --git a/src/Core/Resource/CResource.h b/src/Core/Resource/CResource.h index 1643e2d6..959b6b06 100644 --- a/src/Core/Resource/CResource.h +++ b/src/Core/Resource/CResource.h @@ -52,7 +52,6 @@ public: inline CAssetID ID() const { return mpEntry ? mpEntry->ID() : CAssetID::skInvalidID64; } inline EGame Game() const { return mpEntry ? mpEntry->Game() : eUnknownGame; } inline bool IsReferenced() const { return mRefCount > 0; } - inline void SetGame(EGame Game) { if (mpEntry) mpEntry->SetGame(Game); } inline void Lock() { mRefCount++; } inline void Release() { mRefCount--; } }; diff --git a/src/Core/Resource/CStringTable.h b/src/Core/Resource/CStringTable.h index 4fcb2d8b..52bcfbfa 100644 --- a/src/Core/Resource/CStringTable.h +++ b/src/Core/Resource/CStringTable.h @@ -76,6 +76,12 @@ public: // Font if (TagName == L"font") { + if (Game() >= eCorruptionProto) + { + ASSERT(ParamString.StartsWith(L"0x")); + ParamString = ParamString.ChopFront(2); + } + ASSERT(ParamString.Size() == IDLength * 2); pTree->AddDependency( CAssetID::FromString(ParamString) ); } @@ -115,6 +121,13 @@ public: if (iParam >= TexturesStart) { TWideString Param = *Iter; + + if (Game() >= eCorruptionProto) + { + ASSERT(Param.StartsWith(L"0x")); + Param = Param.ChopFront(2); + } + ASSERT(Param.Size() == IDLength * 2); pTree->AddDependency( CAssetID::FromString(Param) ); } diff --git a/src/Core/Resource/Factory/CAnimSetLoader.cpp b/src/Core/Resource/Factory/CAnimSetLoader.cpp index 89c63f4b..007d8da7 100644 --- a/src/Core/Resource/Factory/CAnimSetLoader.cpp +++ b/src/Core/Resource/Factory/CAnimSetLoader.cpp @@ -301,7 +301,6 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry) if (iNode == 0 && Loader.mVersion == eUnknownGame) { Loader.mVersion = (Unknown1 == 0xA) ? eEchoes : ePrime; // Best version indicator we know of unfortunately - Loader.pSet->SetGame(Loader.mVersion); } pChar->Name = rANCS.ReadString(); pChar->pModel = gpResourceStore->LoadResource(rANCS.ReadLong(), "CMDL"); @@ -419,7 +418,6 @@ CAnimSet* CAnimSetLoader::LoadCHAR(IInputStream& rCHAR, CResourceEntry *pEntry) { Loader.mVersion = eCorruption; Loader.pSet = new CAnimSet(pEntry); - Loader.pSet->SetGame(eCorruption); return Loader.LoadCorruptionCHAR(rCHAR); } @@ -427,7 +425,6 @@ CAnimSet* CAnimSetLoader::LoadCHAR(IInputStream& rCHAR, CResourceEntry *pEntry) { Loader.mVersion = eReturns; Loader.pSet = new CAnimSet(pEntry); - Loader.pSet->SetGame(eReturns); return Loader.LoadReturnsCHAR(rCHAR); } diff --git a/src/Core/Resource/Factory/CAnimationLoader.cpp b/src/Core/Resource/Factory/CAnimationLoader.cpp index 3720c231..afa673eb 100644 --- a/src/Core/Resource/Factory/CAnimationLoader.cpp +++ b/src/Core/Resource/Factory/CAnimationLoader.cpp @@ -76,10 +76,7 @@ void CAnimationLoader::ReadUncompressedANIM() } if (mGame == eUnknownGame) - { mGame = UncompressedCheckVersion(); - mpAnim->SetGame(mGame); - } // Echoes only - rotation channel indices std::vector RotationIndices; @@ -212,10 +209,7 @@ void CAnimationLoader::ReadCompressedANIM() mpInput->Seek(0x4, SEEK_CUR); // Skip alloc size if (mGame == eUnknownGame) - { mGame = (mpInput->PeekShort() == 0x0101 ? eEchoes : ePrime); - mpAnim->SetGame(mGame); - } if (mGame == ePrime) { @@ -470,6 +464,10 @@ CQuaternion CAnimationLoader::DequantizeRotation(bool Sign, s16 X, s16 Y, s16 Z) // ************ STATIC ************ CAnimation* CAnimationLoader::LoadANIM(IInputStream& rANIM, CResourceEntry *pEntry) { + // MP3/DKCR unsupported + if (pEntry->Game() > eEchoes) + return nullptr; + u32 CompressionType = rANIM.ReadLong(); if (CompressionType != 0 && CompressionType != 2) diff --git a/src/Core/Resource/Factory/CAreaLoader.cpp b/src/Core/Resource/Factory/CAreaLoader.cpp index 9f2b66fb..ba1b45a6 100644 --- a/src/Core/Resource/Factory/CAreaLoader.cpp +++ b/src/Core/Resource/Factory/CAreaLoader.cpp @@ -686,7 +686,6 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry) Loader.mpArea = new CGameArea(pEntry); u32 Version = MREA.ReadLong(); Loader.mVersion = GetFormatVersion(Version); - Loader.mpArea->SetGame(Loader.mVersion); Loader.mpMREA = &MREA; switch (Loader.mVersion) diff --git a/src/Core/Resource/Factory/CCollisionLoader.cpp b/src/Core/Resource/Factory/CCollisionLoader.cpp index ff4ae5e4..20bf5952 100644 --- a/src/Core/Resource/Factory/CCollisionLoader.cpp +++ b/src/Core/Resource/Factory/CCollisionLoader.cpp @@ -235,7 +235,6 @@ CCollisionMeshGroup* CCollisionLoader::LoadDCLN(IInputStream& rDCLN, CResourceEn Loader.mpMesh = new CCollisionMesh; Loader.mpMesh->mOctreeLoaded = false; - Loader.mpGroup->SetGame(Loader.mVersion); if (Loader.mVersion == eReturns) Loader.mpMesh->mAABox = CAABox(rDCLN); diff --git a/src/Core/Resource/Factory/CDependencyGroupLoader.cpp b/src/Core/Resource/Factory/CDependencyGroupLoader.cpp index c8e79c74..236ae9a1 100644 --- a/src/Core/Resource/Factory/CDependencyGroupLoader.cpp +++ b/src/Core/Resource/Factory/CDependencyGroupLoader.cpp @@ -8,20 +8,24 @@ EGame CDependencyGroupLoader::VersionTest(IInputStream& rDGRP, u32 DepCount) rDGRP.Seek(DepCount * 8, SEEK_CUR); u32 Remaining = rDGRP.Size() - rDGRP.Tell(); - EGame Game = ePrimeDemo; + EGame Game = eCorruptionProto; if (Remaining < 32) { + bool IsEOF = true; + for (u32 iRem = 0; iRem < Remaining; iRem++) { u8 Byte = rDGRP.ReadByte(); if (Byte != 0xFF) { - Game = eCorruptionProto; + IsEOF = false; break; } } + + if (IsEOF) Game = ePrimeDemo; } rDGRP.Seek(Start, SEEK_SET); @@ -36,7 +40,6 @@ CDependencyGroup* CDependencyGroupLoader::LoadDGRP(IInputStream& rDGRP, CResourc EGame Game = VersionTest(rDGRP, NumDependencies); CDependencyGroup *pGroup = new CDependencyGroup(pEntry); - pGroup->SetGame(Game); for (u32 iDep = 0; iDep < NumDependencies; iDep++) { diff --git a/src/Core/Resource/Factory/CFontLoader.cpp b/src/Core/Resource/Factory/CFontLoader.cpp index e448f145..19043aab 100644 --- a/src/Core/Resource/Factory/CFontLoader.cpp +++ b/src/Core/Resource/Factory/CFontLoader.cpp @@ -100,7 +100,6 @@ CFont* CFontLoader::LoadFONT(IInputStream& rFONT, CResourceEntry *pEntry) CFontLoader Loader; Loader.mpFont = new CFont(pEntry); - Loader.mpFont->SetGame(Version); Loader.mVersion = Version; return Loader.LoadFont(rFONT); } diff --git a/src/Core/Resource/Factory/CMaterialLoader.cpp b/src/Core/Resource/Factory/CMaterialLoader.cpp index db2abc3f..0cdde2b3 100644 --- a/src/Core/Resource/Factory/CMaterialLoader.cpp +++ b/src/Core/Resource/Factory/CMaterialLoader.cpp @@ -396,6 +396,8 @@ CMaterial* CMaterialLoader::ReadCorruptionMaterial() case 6: // Model Matrix case 10: // Yet-to-be-named break; + case 8: // Unknown/unsupported animation type + break; default: Log::FileError(mpFile->GetSourceString(), mpFile->Tell() - 8, "Unsupported animation mode encountered: " + TString::HexString((u32) pPass->mAnimMode)); break; diff --git a/src/Core/Resource/Factory/CModelLoader.cpp b/src/Core/Resource/Factory/CModelLoader.cpp index b4e81508..b2246be2 100644 --- a/src/Core/Resource/Factory/CModelLoader.cpp +++ b/src/Core/Resource/Factory/CModelLoader.cpp @@ -453,7 +453,6 @@ CModel* CModelLoader::LoadCMDL(IInputStream& rCMDL, CResourceEntry *pEntry) } CModel *pModel = new CModel(pEntry); - pModel->SetGame(Loader.mVersion); Loader.mpModel = pModel; Loader.mpSectionMgr = new CSectionMgrIn(BlockCount, &rCMDL); rCMDL.SeekToBoundary(32); diff --git a/src/Core/Resource/Factory/CResourceFactory.h b/src/Core/Resource/Factory/CResourceFactory.h index c4d07f30..77e7afb8 100644 --- a/src/Core/Resource/Factory/CResourceFactory.h +++ b/src/Core/Resource/Factory/CResourceFactory.h @@ -40,6 +40,7 @@ public: case eArea: return new CGameArea(pEntry); case eAudioGroup: return new CAudioGroup(pEntry); case eAudioLookupTable: return new CAudioLookupTable(pEntry); + case eCharacter: return new CAnimSet(pEntry); case eDynamicCollision: return new CCollisionMeshGroup(pEntry); case eDependencyGroup: return new CDependencyGroup(pEntry); case eFont: return new CFont(pEntry); @@ -66,11 +67,12 @@ public: { case eAnimation: pRes = CAnimationLoader::LoadANIM(rInput, pEntry); break; case eAnimEventData: pRes = CAnimEventLoader::LoadEVNT(rInput, pEntry); break; - case eAnimSet: pRes = CAnimSetLoader::LoadANCSOrCHAR(rInput, pEntry); break; + case eAnimSet: pRes = CAnimSetLoader::LoadANCS(rInput, pEntry); break; case eArea: pRes = CAreaLoader::LoadMREA(rInput, pEntry); break; case eAudioGroup: pRes = CAudioGroupLoader::LoadAGSC(rInput, pEntry); break; case eAudioLookupTable: pRes = CAudioGroupLoader::LoadATBL(rInput, pEntry); break; case eBinaryData: pRes = CUnsupportedFormatLoader::LoadDUMB(rInput, pEntry); break; + case eCharacter: pRes = CAnimSetLoader::LoadCHAR(rInput, pEntry); break; case eDependencyGroup: pRes = CDependencyGroupLoader::LoadDGRP(rInput, pEntry); break; case eDynamicCollision: pRes = CCollisionLoader::LoadDCLN(rInput, pEntry); break; case eFont: pRes = CFontLoader::LoadFONT(rInput, pEntry); break; diff --git a/src/Core/Resource/Factory/CScanLoader.cpp b/src/Core/Resource/Factory/CScanLoader.cpp index fa4478fd..e25bb736 100644 --- a/src/Core/Resource/Factory/CScanLoader.cpp +++ b/src/Core/Resource/Factory/CScanLoader.cpp @@ -21,7 +21,6 @@ CScan* CScanLoader::LoadScanMP1(IInputStream& rSCAN) rSCAN.Seek(0x18, SEEK_CUR); } - mpScan->SetGame(ePrime); return mpScan; } @@ -66,13 +65,11 @@ CScan* CScanLoader::LoadScanMP2(IInputStream& rSCAN) case 0x14: case 0xB: mpScan = new CScan(mpEntry); - mpScan->SetGame(eEchoes); LoadParamsMP2(rSCAN, NumProperties); break; case 0x12: case 0x16: mpScan = new CScan(mpEntry); - mpScan->SetGame(eCorruption); LoadParamsMP3(rSCAN, NumProperties); break; default: @@ -80,7 +77,6 @@ CScan* CScanLoader::LoadScanMP2(IInputStream& rSCAN) return nullptr; } - mpScan->SetGame(eEchoes); return mpScan; } @@ -283,7 +279,6 @@ CScan* CScanLoader::LoadSCAN(IInputStream& rSCAN, CResourceEntry *pEntry) CScanLoader Loader; Loader.mVersion = ePrime; Loader.mpScan = new CScan(pEntry); - Loader.mpScan->SetGame(ePrime); Loader.mpEntry = pEntry; return Loader.LoadScanMP1(rSCAN); } diff --git a/src/Core/Resource/Factory/CSkeletonLoader.cpp b/src/Core/Resource/Factory/CSkeletonLoader.cpp index 3d2e5f42..80cf0374 100644 --- a/src/Core/Resource/Factory/CSkeletonLoader.cpp +++ b/src/Core/Resource/Factory/CSkeletonLoader.cpp @@ -60,7 +60,6 @@ CSkeleton* CSkeletonLoader::LoadCINF(IInputStream& rCINF, CResourceEntry *pEntry { u32 Check = rCINF.PeekLong(); Game = ((Check > 100 || Check == 0) ? eEchoes : ePrime); - Loader.mpSkeleton->SetGame(Game); } if (Game == eEchoes) { diff --git a/src/Core/Resource/Factory/CStringLoader.cpp b/src/Core/Resource/Factory/CStringLoader.cpp index b51ac961..65e4e49f 100644 --- a/src/Core/Resource/Factory/CStringLoader.cpp +++ b/src/Core/Resource/Factory/CStringLoader.cpp @@ -195,7 +195,6 @@ CStringTable* CStringLoader::LoadSTRG(IInputStream& rSTRG, CResourceEntry *pEntr // Valid; now we create the loader and call the function that reads the rest of the file CStringLoader Loader; Loader.mpStringTable = new CStringTable(pEntry); - Loader.mpStringTable->SetGame(Version); Loader.mVersion = Version; if (Version == ePrimeDemo) Loader.LoadPrimeDemoSTRG(rSTRG); diff --git a/src/Core/Resource/Factory/CUnsupportedFormatLoader.cpp b/src/Core/Resource/Factory/CUnsupportedFormatLoader.cpp index ae736edc..e1665750 100644 --- a/src/Core/Resource/Factory/CUnsupportedFormatLoader.cpp +++ b/src/Core/Resource/Factory/CUnsupportedFormatLoader.cpp @@ -272,6 +272,11 @@ CDependencyGroup* CUnsupportedFormatLoader::LoadHIER(IInputStream& rHIER, CResou u32 NumNodes = rHIER.ReadLong(); CDependencyGroup *pOut = new CDependencyGroup(pEntry); + // 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. + if (pEntry->Game() > eEchoes) + return pOut; + for (u32 iNode = 0; iNode < NumNodes; iNode++) { // NOTE: The SCAN ID isn't considered a real dependency! diff --git a/src/Core/Resource/Factory/CUnsupportedParticleLoader.cpp b/src/Core/Resource/Factory/CUnsupportedParticleLoader.cpp index 6ca86406..f3a30469 100644 --- a/src/Core/Resource/Factory/CUnsupportedParticleLoader.cpp +++ b/src/Core/Resource/Factory/CUnsupportedParticleLoader.cpp @@ -1389,20 +1389,23 @@ CDependencyGroup* CUnsupportedParticleLoader::LoadParticle(IInputStream& rFile, CUnsupportedParticleLoader Loader; Loader.mpGroup = new CDependencyGroup(pEntry); + if (pEntry->Game() >= eCorruptionProto) + return Loader.mpGroup; + while (true) { bool ShouldContinue = false; switch (Magic.ToLong()) { - case kGPSM: ShouldContinue = Loader.ParseParticleParameter(rFile); break; - case kELSM: ShouldContinue = Loader.ParseElectricParameter(rFile); break; - case kSRSM: ShouldContinue = Loader.ParseSortedParameter(rFile); break; - case kSPSM: ShouldContinue = Loader.ParseSpawnParameter(rFile); break; - case kSWSH: ShouldContinue = Loader.ParseSwooshParameter(rFile); break; - case kDPSM: ShouldContinue = Loader.ParseDecalParameter(rFile); break; - case kWPSM: ShouldContinue = Loader.ParseWeaponParameter(rFile); break; - case kCRSM: ShouldContinue = Loader.ParseCollisionResponseParameter(rFile); break; + case FOURCC('GPSM'): ShouldContinue = Loader.ParseParticleParameter(rFile); break; + case FOURCC('ELSM'): ShouldContinue = Loader.ParseElectricParameter(rFile); break; + case FOURCC('SRSM'): ShouldContinue = Loader.ParseSortedParameter(rFile); break; + case FOURCC('SPSM'): ShouldContinue = Loader.ParseSpawnParameter(rFile); break; + case FOURCC('SWSH'): ShouldContinue = Loader.ParseSwooshParameter(rFile); break; + case FOURCC('DPSM'): ShouldContinue = Loader.ParseDecalParameter(rFile); break; + case FOURCC('WPSM'): ShouldContinue = Loader.ParseWeaponParameter(rFile); break; + case FOURCC('CRSM'): ShouldContinue = Loader.ParseCollisionResponseParameter(rFile); break; default: Log::Error("Unrecognized particle system magic: " + Magic.ToString()); diff --git a/src/Core/Resource/Factory/CWorldLoader.cpp b/src/Core/Resource/Factory/CWorldLoader.cpp index 6adbb034..e78f1eb0 100644 --- a/src/Core/Resource/Factory/CWorldLoader.cpp +++ b/src/Core/Resource/Factory/CWorldLoader.cpp @@ -270,7 +270,6 @@ CWorld* CWorldLoader::LoadMLVL(IInputStream& rMLVL, CResourceEntry *pEntry) // Filestream is valid, magic+version are valid; everything seems good! CWorldLoader Loader; Loader.mpWorld = new CWorld(pEntry); - Loader.mpWorld->SetGame(Version); Loader.mVersion = Version; if (Version != eReturns) diff --git a/templates/mp3/Script/GragnolFlyer.xml b/templates/mp3/Script/GragnolFlyer.xml index b5fbc01c..20fddc2f 100644 --- a/templates/mp3/Script/GragnolFlyer.xml +++ b/templates/mp3/Script/GragnolFlyer.xml @@ -70,8 +70,8 @@ - - + + -1.0 diff --git a/templates/mp3/Script/PhazonPuddle.xml b/templates/mp3/Script/PhazonPuddle.xml index 5f2a8fa5..57245ed6 100644 --- a/templates/mp3/Script/PhazonPuddle.xml +++ b/templates/mp3/Script/PhazonPuddle.xml @@ -9,7 +9,7 @@ - + diff --git a/templates/mp3/Script/ReptilicusHunter.xml b/templates/mp3/Script/ReptilicusHunter.xml index 18ad7eb2..789d1d80 100644 --- a/templates/mp3/Script/ReptilicusHunter.xml +++ b/templates/mp3/Script/ReptilicusHunter.xml @@ -97,7 +97,7 @@ 5.0 - + 1.0 @@ -148,7 +148,7 @@ 0.5 - + 1.0 diff --git a/templates/mp3/Script/SeedBoss1.xml b/templates/mp3/Script/SeedBoss1.xml index 2f0a9f7d..e41ce786 100644 --- a/templates/mp3/Script/SeedBoss1.xml +++ b/templates/mp3/Script/SeedBoss1.xml @@ -167,7 +167,7 @@ - + diff --git a/templates/mp3proto/Script/PhazonPuddle.xml b/templates/mp3proto/Script/PhazonPuddle.xml index f4423109..79f2ba99 100644 --- a/templates/mp3proto/Script/PhazonPuddle.xml +++ b/templates/mp3proto/Script/PhazonPuddle.xml @@ -6,7 +6,7 @@ - + diff --git a/templates/mp3proto/Script/SeedBoss1.xml b/templates/mp3proto/Script/SeedBoss1.xml index 098dc4ee..b11081ed 100644 --- a/templates/mp3proto/Script/SeedBoss1.xml +++ b/templates/mp3proto/Script/SeedBoss1.xml @@ -52,7 +52,7 @@ - +