Fixed CHAR files failing to load
This commit is contained in:
parent
f967519a77
commit
2f2ec13ced
|
@ -96,7 +96,12 @@ CResource* CResourceEntry::Load()
|
|||
{
|
||||
// todo: load raw
|
||||
if (mpResource) return mpResource;
|
||||
if (!HasCookedVersion()) return nullptr;
|
||||
|
||||
if (!HasCookedVersion())
|
||||
{
|
||||
Log::Error("Couldn't locate resource: " + CookedAssetPath(true));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CFileInStream File(CookedAssetPath().ToStdString(), IOUtil::eBigEndian);
|
||||
if (!File.IsValid())
|
||||
|
@ -116,27 +121,20 @@ CResource* CResourceEntry::Load(IInputStream& rInput)
|
|||
|
||||
switch (mType)
|
||||
{
|
||||
case eAnimation: mpResource = CAnimationLoader::LoadANIM(rInput, this); break;
|
||||
case eArea: mpResource = CAreaLoader::LoadMREA(rInput, this); break;
|
||||
case eDynamicCollision: mpResource = CCollisionLoader::LoadDCLN(rInput, this); break;
|
||||
case eFont: mpResource = CFontLoader::LoadFONT(rInput, this); break;
|
||||
case eModel: mpResource = CModelLoader::LoadCMDL(rInput, this); break;
|
||||
case eScan: mpResource = CScanLoader::LoadSCAN(rInput, this); break;
|
||||
case eSkeleton: mpResource = CSkeletonLoader::LoadCINF(rInput, this); break;
|
||||
case eSkin: mpResource = CSkinLoader::LoadCSKR(rInput, this); break;
|
||||
case eStaticGeometryMap: mpResource = CPoiToWorldLoader::LoadEGMC(rInput, this); break;
|
||||
case eStringTable: mpResource = CStringLoader::LoadSTRG(rInput, this); break;
|
||||
case eTexture: mpResource = CTextureDecoder::LoadTXTR(rInput, this); break;
|
||||
case eWorld: mpResource = CWorldLoader::LoadMLVL(rInput, this); break;
|
||||
|
||||
case eAnimSet:
|
||||
if (mGame <= eEchoes)
|
||||
mpResource = CAnimSetLoader::LoadANCS(rInput, this);
|
||||
else
|
||||
mpResource = CAnimSetLoader::LoadCHAR(rInput, this);
|
||||
break;
|
||||
|
||||
default: mpResource = new CResource(this); break;
|
||||
case eAnimation: mpResource = CAnimationLoader::LoadANIM(rInput, this); break;
|
||||
case eAnimSet: mpResource = CAnimSetLoader::LoadANCSOrCHAR(rInput, this); break;
|
||||
case eArea: mpResource = CAreaLoader::LoadMREA(rInput, this); break;
|
||||
case eDynamicCollision: mpResource = CCollisionLoader::LoadDCLN(rInput, this); break;
|
||||
case eFont: mpResource = CFontLoader::LoadFONT(rInput, this); break;
|
||||
case eModel: mpResource = CModelLoader::LoadCMDL(rInput, this); break;
|
||||
case eScan: mpResource = CScanLoader::LoadSCAN(rInput, this); break;
|
||||
case eSkeleton: mpResource = CSkeletonLoader::LoadCINF(rInput, this); break;
|
||||
case eSkin: mpResource = CSkinLoader::LoadCSKR(rInput, this); break;
|
||||
case eStaticGeometryMap: mpResource = CPoiToWorldLoader::LoadEGMC(rInput, this); break;
|
||||
case eStringTable: mpResource = CStringLoader::LoadSTRG(rInput, this); break;
|
||||
case eTexture: mpResource = CTextureDecoder::LoadTXTR(rInput, this); break;
|
||||
case eWorld: mpResource = CWorldLoader::LoadMLVL(rInput, this); break;
|
||||
default: mpResource = new CResource(this); break;
|
||||
}
|
||||
|
||||
return mpResource;
|
||||
|
|
|
@ -232,14 +232,14 @@ bool CResourceStore::RegisterResource(const CUniqueID& rkID, EResType Type, cons
|
|||
}
|
||||
}
|
||||
|
||||
CResourceEntry* CResourceStore::CreateTransientEntry(EResType Type, const TWideString& rkDir /*= L""*/, const TWideString& rkFileName /*= L""*/)
|
||||
CResourceEntry* CResourceStore::RegisterTransientResource(EResType Type, const TWideString& rkDir /*= L""*/, const TWideString& rkFileName /*= L""*/)
|
||||
{
|
||||
CResourceEntry *pEntry = new CResourceEntry(this, CUniqueID::RandomID(), rkDir, rkFileName, Type, true);
|
||||
mResourceEntries[pEntry->ID()] = pEntry;
|
||||
return pEntry;
|
||||
}
|
||||
|
||||
CResourceEntry* CResourceStore::CreateTransientEntry(EResType Type, const CUniqueID& rkID, const TWideString& rkDir /*=L ""*/, const TWideString& rkFileName /*= L""*/)
|
||||
CResourceEntry* CResourceStore::RegisterTransientResource(EResType Type, const CUniqueID& rkID, const TWideString& rkDir /*=L ""*/, const TWideString& rkFileName /*= L""*/)
|
||||
{
|
||||
CResourceEntry *pEntry = new CResourceEntry(this, rkID, rkDir, rkFileName, Type, true);
|
||||
mResourceEntries[rkID] = pEntry;
|
||||
|
@ -264,7 +264,7 @@ CResource* CResourceStore::LoadResource(const CUniqueID& rkID, const CFourCC& rk
|
|||
|
||||
CMemoryInStream MemStream(DataBuffer.data(), DataBuffer.size(), IOUtil::eBigEndian);
|
||||
EResType Type = CResource::ResTypeForExtension(rkType);
|
||||
CResourceEntry *pEntry = CreateTransientEntry(Type, rkID);
|
||||
CResourceEntry *pEntry = RegisterTransientResource(Type, rkID);
|
||||
CResource *pRes = pEntry->Load(MemStream);
|
||||
if (pRes) mLoadedResources[rkID] = pEntry;
|
||||
return pRes;
|
||||
|
@ -282,9 +282,15 @@ CResource* CResourceStore::LoadResource(const CUniqueID& rkID, const CFourCC& rk
|
|||
|
||||
if (Type != eInvalidResType)
|
||||
{
|
||||
TWideString Name = rkID.ToString().ToUTF16();
|
||||
CResourceEntry *pEntry = CreateTransientEntry(Type, mTransientLoadDir, Name);
|
||||
CResource *pRes = pEntry->Load();
|
||||
// Note the entry may not be able to find the resource on its own (due to not knowing what game
|
||||
// it is) so we will attempt to open the file stream ourselves and pass it to the entry instead.
|
||||
TString Name = rkID.ToString();
|
||||
CResourceEntry *pEntry = RegisterTransientResource(Type, mTransientLoadDir, Name.ToUTF16());
|
||||
|
||||
TString Path = mTransientLoadDir.ToUTF8() + Name + "." + rkType.ToString();
|
||||
CFileInStream File(Path.ToStdString(), IOUtil::eBigEndian);
|
||||
CResource *pRes = pEntry->Load(File);
|
||||
|
||||
if (pRes) mLoadedResources[rkID] = pEntry;
|
||||
return pRes;
|
||||
}
|
||||
|
@ -318,10 +324,22 @@ CResource* CResourceStore::LoadResource(const TString& rkPath)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// Open file
|
||||
CFileInStream File(rkPath.ToStdString(), IOUtil::eBigEndian);
|
||||
|
||||
if (!File.IsValid())
|
||||
{
|
||||
Log::Error("Unable to load resource; couldn't open file: " + rkPath);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Load resource
|
||||
TString OldTransientDir = mTransientLoadDir;
|
||||
mTransientLoadDir = Dir;
|
||||
CResourceEntry *pEntry = CreateTransientEntry(Type, ID, Dir, Name);
|
||||
CResource *pRes = pEntry->Load();
|
||||
|
||||
CResourceEntry *pEntry = RegisterTransientResource(Type, ID, Dir, Name);
|
||||
CResource *pRes = pEntry->Load(File);
|
||||
|
||||
if (pRes) mLoadedResources[ID] = pEntry;
|
||||
mTransientLoadDir = OldTransientDir;
|
||||
|
||||
|
@ -375,6 +393,7 @@ void CResourceStore::DestroyUnreferencedResources()
|
|||
{
|
||||
It = mLoadedResources.erase(It);
|
||||
NumDeleted++;
|
||||
if (It == mLoadedResources.end()) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,8 +47,8 @@ public:
|
|||
|
||||
bool RegisterResource(const CUniqueID& rkID, EResType Type, const TWideString& rkDir, const TWideString& rkFileName);
|
||||
CResourceEntry* FindEntry(const CUniqueID& rkID) const;
|
||||
CResourceEntry* CreateTransientEntry(EResType Type, const TWideString& rkDir = L"", const TWideString& rkFileName = L"");
|
||||
CResourceEntry* CreateTransientEntry(EResType Type, const CUniqueID& rkID, const TWideString& rkDir = L"", const TWideString& rkFileName = L"");
|
||||
CResourceEntry* RegisterTransientResource(EResType Type, const TWideString& rkDir = L"", const TWideString& rkFileName = L"");
|
||||
CResourceEntry* RegisterTransientResource(EResType Type, const CUniqueID& rkID, const TWideString& rkDir = L"", const TWideString& rkFileName = L"");
|
||||
|
||||
CResource* LoadResource(const CUniqueID& rkID, const CFourCC& rkType);
|
||||
CResource* LoadResource(const TString& rkPath);
|
||||
|
|
|
@ -165,7 +165,7 @@ REGISTER_RESOURCE_TYPE(ATBL, eAudioLookupTable, ePrimeDemo, eCorruption)
|
|||
REGISTER_RESOURCE_TYPE(BFRC, eBurstFireData, eCorruptionProto, eCorruption)
|
||||
REGISTER_RESOURCE_TYPE(CAAD, eUnknown_CAAD, eCorruption, eCorruption)
|
||||
REGISTER_RESOURCE_TYPE(CAUD, eAudioMacro, eCorruptionProto, eReturns)
|
||||
REGISTER_RESOURCE_TYPE(CHAR, eCharacter, eCorruptionProto, eReturns)
|
||||
REGISTER_RESOURCE_TYPE(CHAR, eAnimSet, eCorruptionProto, eReturns)
|
||||
REGISTER_RESOURCE_TYPE(CINF, eSkeleton, ePrimeDemo, eReturns)
|
||||
REGISTER_RESOURCE_TYPE(CMDL, eModel, ePrimeDemo, eReturns)
|
||||
REGISTER_RESOURCE_TYPE(CRSC, eParticleCollisionResponse, ePrimeDemo, eCorruption)
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
CResource(CResourceEntry *pEntry = 0)
|
||||
: mpEntry(pEntry), mRefCount(0)
|
||||
{
|
||||
if (!mpEntry) mpEntry = gResourceStore.CreateTransientEntry(Type());
|
||||
if (!mpEntry) mpEntry = gResourceStore.RegisterTransientResource(Type());
|
||||
}
|
||||
|
||||
virtual ~CResource() {}
|
||||
|
|
|
@ -194,6 +194,20 @@ void CAnimSetLoader::LoadHalfTransition(IInputStream& rANCS)
|
|||
}
|
||||
|
||||
// ************ STATIC ************
|
||||
CAnimSet* CAnimSetLoader::LoadANCSOrCHAR(IInputStream& rFile, CResourceEntry *pEntry)
|
||||
{
|
||||
if (!rFile.IsValid()) return nullptr;
|
||||
u8 Test = rFile.PeekByte();
|
||||
|
||||
if (Test == 0x3 || Test == 0x5 || Test == 0x59)
|
||||
return LoadCHAR(rFile, pEntry);
|
||||
else if (Test == 0x0)
|
||||
return LoadANCS(rFile, pEntry);
|
||||
|
||||
Log::Error("Failed to determine animset format for " + rFile.GetSourceString() + "; first byte is " + TString::HexString(Test, 2));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
||||
{
|
||||
if (!rANCS.IsValid()) return nullptr;
|
||||
|
|
|
@ -42,6 +42,7 @@ class CAnimSetLoader
|
|||
void LoadHalfTransition(IInputStream& rANCS);
|
||||
|
||||
public:
|
||||
static CAnimSet* LoadANCSOrCHAR(IInputStream& rFile, CResourceEntry *pEntry);
|
||||
static CAnimSet* LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry);
|
||||
static CAnimSet* LoadCHAR(IInputStream& rCHAR, CResourceEntry *pEntry);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue