From 29bf0234ec7c5151824dd109578b9227d5ad3cc0 Mon Sep 17 00:00:00 2001 From: parax0 Date: Sun, 10 Jan 2016 08:57:21 -0700 Subject: [PATCH] Loading SCLY file properties into a new class CResourceInfo instead of loading it as a CResource --- src/Core/CAreaAttributes.cpp | 4 +- src/Core/Core.pro | 3 +- src/Core/Resource/CResCache.cpp | 36 ++++++++++ src/Core/Resource/CResCache.h | 1 + src/Core/Resource/CResourceInfo.h | 70 +++++++++++++++++++ src/Core/Resource/Factory/CScriptLoader.cpp | 36 ++-------- src/Core/Resource/SResInfo.h | 3 + src/Core/Resource/Script/CScriptTemplate.cpp | 8 +-- src/Core/Resource/Script/IProperty.h | 2 +- src/Core/Resource/Script/IPropertyValue.h | 5 +- .../ScriptExtra/CDamageableTriggerExtra.cpp | 2 +- src/Core/ScriptExtra/CDoorExtra.cpp | 2 +- .../ScriptExtra/CPointOfInterestExtra.cpp | 2 +- src/Editor/Widgets/WResourceSelector.cpp | 51 +++++++------- src/Editor/Widgets/WResourceSelector.h | 11 +-- 15 files changed, 163 insertions(+), 73 deletions(-) create mode 100644 src/Core/Resource/CResourceInfo.h diff --git a/src/Core/CAreaAttributes.cpp b/src/Core/CAreaAttributes.cpp index ae6a74d1..ee9681d9 100644 --- a/src/Core/CAreaAttributes.cpp +++ b/src/Core/CAreaAttributes.cpp @@ -46,12 +46,12 @@ CModel* CAreaAttributes::SkyModel() const switch (mGame) { case ePrime: - return (CModel*) static_cast(pBaseStruct->PropertyByIndex(7))->Get().RawPointer(); + return (CModel*) static_cast(pBaseStruct->PropertyByIndex(7))->Get().Load(); case eEchoesDemo: case eEchoes: case eCorruptionProto: case eCorruption: - return (CModel*) static_cast(pBaseStruct->PropertyByID(0xD208C9FA))->Get().RawPointer(); + return (CModel*) static_cast(pBaseStruct->PropertyByID(0xD208C9FA))->Get().Load(); default: return nullptr; } diff --git a/src/Core/Core.pro b/src/Core/Core.pro index b785a66b..342a7e14 100644 --- a/src/Core/Core.pro +++ b/src/Core/Core.pro @@ -181,7 +181,8 @@ HEADERS += \ Render/FRenderOptions.h \ Scene/FShowFlags.h \ Scene/CScene.h \ - Scene/CSceneIterator.h + Scene/CSceneIterator.h \ + Resource/CResourceInfo.h # Source Files SOURCES += \ diff --git a/src/Core/Resource/CResCache.cpp b/src/Core/Resource/CResCache.cpp index 1cfb1651..e22338e8 100644 --- a/src/Core/Resource/CResCache.cpp +++ b/src/Core/Resource/CResCache.cpp @@ -13,6 +13,7 @@ #include #include #include +#include CResCache::CResCache() { @@ -208,6 +209,41 @@ CResource* CResCache::GetResource(const TString& ResPath) return Res; } +CFourCC CResCache::FindResourceType(CUniqueID ResID, const TStringList& rkPossibleTypes) +{ + // If we only have one type then there's only one possibility. + if (rkPossibleTypes.size() == 1) + return CFourCC(rkPossibleTypes.front()); + + // Determine extension from pak + if (mResSource.Source == SResSource::PakFile) + { + for (auto it = rkPossibleTypes.begin(); it != rkPossibleTypes.end(); it++) + { + SResInfo ResInfo = mpPak->getResourceInfo(ResID.ToLongLong(), CFourCC(*it)); + + if (ResInfo.resType != "NULL") + return CFourCC(*it); + } + } + + // Determine extension from filesystem - try every extension until we find one that works + else + { + TString PathBase = mResSource.Path + ResID.ToString() + "."; + + for (auto it = rkPossibleTypes.begin(); it != rkPossibleTypes.end(); it++) + { + TString NewPath = PathBase + *it; + + if (boost::filesystem::exists(NewPath.ToStdString())) + return CFourCC(*it); + } + } + + return "UNKN"; +} + void CResCache::CacheResource(CResource *pRes) { u64 ID = pRes->ResID().ToLongLong(); diff --git a/src/Core/Resource/CResCache.h b/src/Core/Resource/CResCache.h index 212fb299..6af0c8e6 100644 --- a/src/Core/Resource/CResCache.h +++ b/src/Core/Resource/CResCache.h @@ -32,6 +32,7 @@ public: TString GetSourcePath(); CResource* GetResource(CUniqueID ResID, CFourCC type); CResource* GetResource(const TString& ResPath); + CFourCC FindResourceType(CUniqueID ResID, const TStringList& rkPossibleTypes); void CacheResource(CResource *pRes); void DeleteResource(CUniqueID ResID); }; diff --git a/src/Core/Resource/CResourceInfo.h b/src/Core/Resource/CResourceInfo.h new file mode 100644 index 00000000..3441bc3e --- /dev/null +++ b/src/Core/Resource/CResourceInfo.h @@ -0,0 +1,70 @@ +#ifndef CRESOURCEINFO +#define CRESOURCEINFO + +#include "CResource.h" +#include "CResCache.h" +#include +#include +#include + +class CResourceInfo +{ + TString mPath; + bool mIsPath; + bool mIsValidPath; + +public: + CResourceInfo() + : mPath(""), mIsPath(false), mIsValidPath(false) {} + + CResourceInfo(const TString& rkPath) + : mPath(rkPath), mIsPath(true) + { + mIsValidPath = boost::filesystem::exists(rkPath.ToStdString()); + } + + CResourceInfo(const CUniqueID& rkID, CFourCC Type) + : mIsPath(false), mIsValidPath(false) + { + mPath = rkID.ToString() + "." + Type.ToString(); + } + + inline CUniqueID ID() const + { + if (!mIsPath) + return CUniqueID::FromString(mPath.GetFileName()); + else + return CUniqueID::skInvalidID64; + } + + inline CFourCC Type() const + { + return mPath.GetFileExtension(); + } + + inline TString ToString() const + { + return mPath; + } + + inline CResource* Load() const + { + if (!IsValid()) + return nullptr; + if (mIsPath) + return gResCache.GetResource(mPath); + else + return gResCache.GetResource(ID(), Type()); + } + + inline bool IsValid() const + { + if (!mIsPath) + return ID().IsValid(); + else + return mIsValidPath; + } +}; + +#endif // CRESOURCEINFO + diff --git a/src/Core/Resource/Factory/CScriptLoader.cpp b/src/Core/Resource/Factory/CScriptLoader.cpp index 24919aa2..14361dec 100644 --- a/src/Core/Resource/Factory/CScriptLoader.cpp +++ b/src/Core/Resource/Factory/CScriptLoader.cpp @@ -97,43 +97,17 @@ void CScriptLoader::ReadProperty(IProperty *pProp, u32 Size, IInputStream& SCLY) TFileProperty *pFileCast = static_cast(pProp); CUniqueID ResID = (mVersion < eCorruptionProto ? SCLY.ReadLong() : SCLY.ReadLongLong()); - const TStringList& Extensions = static_cast(pTemp)->Extensions(); + const TStringList& rkExtensions = static_cast(pTemp)->Extensions(); - CResource *pRes = nullptr; - - // Check for each extension individually until we find a match - // This could be done better with a function to fetch the extension given the resource ID - // and a "does resource exist" function, but this will do for now - bool hasIgnoredExt = false; + CResourceInfo Info(ResID, "UNKN"); if (ResID.IsValid()) { - for (auto it = Extensions.begin(); it != Extensions.end(); it++) - { - const TString& ext = *it; - - if ((ext != "MREA") && (ext != "MLVL")) { - pRes = gResCache.GetResource(ResID, ext); - if (pRes) break; - } - - else - hasIgnoredExt = true; - } + CFourCC Type = gResCache.FindResourceType(ResID, rkExtensions); + Info = CResourceInfo(ResID, Type); } - // Property may have an incorrect extension listed - print error - if ((!pRes) && (CUniqueID(ResID).IsValid()) && (!hasIgnoredExt)) - { - TString ExtList; - for (auto it = Extensions.begin(); it != Extensions.end(); it++) - { - if (it != Extensions.begin()) ExtList += "/"; - ExtList += *it; - } - } - - pFileCast->Set(pRes); + pFileCast->Set(Info); break; } diff --git a/src/Core/Resource/SResInfo.h b/src/Core/Resource/SResInfo.h index 518a27f4..63b9944b 100644 --- a/src/Core/Resource/SResInfo.h +++ b/src/Core/Resource/SResInfo.h @@ -11,6 +11,9 @@ struct SResInfo u64 resID; u32 offset; u32 size; + + SResInfo() + : compressed(false), resType("NULL"), resID(0), offset(0), size(0) {} }; #endif // SRESINFO_H diff --git a/src/Core/Resource/Script/CScriptTemplate.cpp b/src/Core/Resource/Script/CScriptTemplate.cpp index 2b37fc50..aeb2a68c 100644 --- a/src/Core/Resource/Script/CScriptTemplate.cpp +++ b/src/Core/Resource/Script/CScriptTemplate.cpp @@ -228,7 +228,7 @@ CModel* CScriptTemplate::FindDisplayModel(CPropertyStruct *pProperties) if (pProp->Type() == eFileProperty) { TFileProperty *pFile = static_cast(pProp); - pRes = pFile->Get(); + pRes = pFile->Get().Load(); } else if (pProp->Type() == eCharacterProperty) @@ -268,7 +268,7 @@ CTexture* CScriptTemplate::FindBillboardTexture(CPropertyStruct *pProperties) if (pProp->Type() == eFileProperty) { TFileProperty *pFile = static_cast(pProp); - pRes = pFile->Get(); + pRes = pFile->Get().Load(); } } @@ -302,7 +302,7 @@ CCollisionMeshGroup* CScriptTemplate::FindCollision(CPropertyStruct *pProperties if (pProp->Type() == eFileProperty) { TFileProperty *pFile = static_cast(pProp); - pRes = pFile->Get(); + pRes = pFile->Get().Load(); } } @@ -327,7 +327,7 @@ bool CScriptTemplate::HasInGameModel(CPropertyStruct *pProperties) if (pProp->Type() == eFileProperty) { TFileProperty *pFile = static_cast(pProp); - pRes = pFile->Get(); + pRes = pFile->Get().Load(); } else if (pProp->Type() == eCharacterProperty) diff --git a/src/Core/Resource/Script/IProperty.h b/src/Core/Resource/Script/IProperty.h index f671758e..208a5c2e 100644 --- a/src/Core/Resource/Script/IProperty.h +++ b/src/Core/Resource/Script/IProperty.h @@ -67,7 +67,7 @@ typedef TTypedProperty typedef TTypedProperty TStringProperty; typedef TTypedProperty TVector3Property; typedef TTypedProperty TColorProperty; -typedef TTypedProperty, eFileProperty, CFileValue> TFileProperty; +typedef TTypedProperty TFileProperty; typedef TTypedProperty TAnimParamsProperty; typedef TTypedProperty, eUnknownProperty, CUnknownValue> TUnknownProperty; diff --git a/src/Core/Resource/Script/IPropertyValue.h b/src/Core/Resource/Script/IPropertyValue.h index 3cab35bc..12be6c65 100644 --- a/src/Core/Resource/Script/IPropertyValue.h +++ b/src/Core/Resource/Script/IPropertyValue.h @@ -5,6 +5,7 @@ #include "Core/Log.h" #include "Core/Resource/CAnimationParameters.h" #include "Core/Resource/CResource.h" +#include "Core/Resource/CResourceInfo.h" #include "Core/Resource/TResPtr.h" #include @@ -253,11 +254,11 @@ public: void FromString(const TString&) { } }; -class CFileValue : public TTypedPropertyValue> +class CFileValue : public TTypedPropertyValue { public: CFileValue() {} - CFileValue(CResource *pRes) { mValue = pRes; } + CFileValue(const CResourceInfo& rkInfo) { mValue = rkInfo; } TString ToString() const { return ""; } void FromString(const TString&) { } diff --git a/src/Core/ScriptExtra/CDamageableTriggerExtra.cpp b/src/Core/ScriptExtra/CDamageableTriggerExtra.cpp index 8e7bd4bf..b9c131f2 100644 --- a/src/Core/ScriptExtra/CDamageableTriggerExtra.cpp +++ b/src/Core/ScriptExtra/CDamageableTriggerExtra.cpp @@ -167,7 +167,7 @@ void CDamageableTriggerExtra::PropertyModified(IProperty *pProperty) { if (pProperty == mpTextureProps[iTex]) { - mpTextures[iTex] = mpTextureProps[iTex]->Get(); + mpTextures[iTex] = mpTextureProps[iTex]->Get().Load(); if (mpTextures[iTex] && mpTextures[iTex]->Type() != eTexture) mpTextures[iTex] = nullptr; diff --git a/src/Core/ScriptExtra/CDoorExtra.cpp b/src/Core/ScriptExtra/CDoorExtra.cpp index 5fd070fa..47a965b3 100644 --- a/src/Core/ScriptExtra/CDoorExtra.cpp +++ b/src/Core/ScriptExtra/CDoorExtra.cpp @@ -41,7 +41,7 @@ void CDoorExtra::PropertyModified(IProperty *pProperty) { if (pProperty == mpShieldModelProp) { - mpShieldModel = mpShieldModelProp->Get(); + mpShieldModel = mpShieldModelProp->Get().Load(); if (mpShieldModel) mLocalAABox = mpShieldModel->AABox(); diff --git a/src/Core/ScriptExtra/CPointOfInterestExtra.cpp b/src/Core/ScriptExtra/CPointOfInterestExtra.cpp index a596ba16..d01e8c83 100644 --- a/src/Core/ScriptExtra/CPointOfInterestExtra.cpp +++ b/src/Core/ScriptExtra/CPointOfInterestExtra.cpp @@ -42,7 +42,7 @@ CPointOfInterestExtra::CPointOfInterestExtra(CScriptObject *pInstance, CScene *p void CPointOfInterestExtra::PropertyModified(IProperty* pProperty) { if (mpScanProperty == pProperty) - mpScanData = mpScanProperty->Get(); + mpScanData = mpScanProperty->Get().Load(); } void CPointOfInterestExtra::ModifyTintColor(CColor& Color) diff --git a/src/Editor/Widgets/WResourceSelector.cpp b/src/Editor/Widgets/WResourceSelector.cpp index 9936fdb1..65157716 100644 --- a/src/Editor/Widgets/WResourceSelector.cpp +++ b/src/Editor/Widgets/WResourceSelector.cpp @@ -24,7 +24,6 @@ WResourceSelector::WResourceSelector(QWidget *parent) : QWidget(parent) mAdjustPreviewToParent = false; // Initialize Resource Members - mpResource = nullptr; mResourceValid = false; // Create Widgets @@ -102,9 +101,9 @@ bool WResourceSelector::IsSupportedExtension(const QString& extension) return false; } -bool WResourceSelector::HasSupportedExtension(CResource* pRes) +bool WResourceSelector::HasSupportedExtension(const CResourceInfo& rkRes) { - return IsSupportedExtension(TO_QSTRING(pRes->FullSource().GetFileExtension())); + return IsSupportedExtension(TO_QSTRING(rkRes.Type().ToString())); } // ************ GETTERS ************ @@ -132,12 +131,20 @@ bool WResourceSelector::IsPreviewPanelEnabled() // ************ SETTERS ************ void WResourceSelector::SetResource(CResource *pRes) { - mpResource = pRes; - if (pRes) + SetResource(CResourceInfo(pRes->ResID(), CFourCC(pRes->Source().GetFileExtension()))); + else + SetResource(CResourceInfo()); +} + +void WResourceSelector::SetResource(const CResourceInfo& rkRes) +{ + mResource = rkRes; + + if (mResource.IsValid()) { - mResourceValid = HasSupportedExtension(pRes); - mUI.LineEdit->setText(TO_QSTRING(pRes->FullSource())); + mResourceValid = HasSupportedExtension(rkRes); + mUI.LineEdit->setText(TO_QSTRING(mResource.ToString())); } else @@ -248,31 +255,27 @@ void WResourceSelector::OnExportButtonClicked() // or delegate it entirely to the signals? void WResourceSelector::Edit() { - emit EditResource(mpResource); + emit EditResource(mResource); } void WResourceSelector::Export() { - emit ExportResource(mpResource); + emit ExportResource(mResource); } void WResourceSelector::LoadResource(const QString& ResPath) { - mpResource = nullptr; + mResource = CResourceInfo(); - TString pathStr = ResPath.toStdString(); - TString ext = pathStr.GetFileExtension(); + TString PathStr = ResPath.toStdString(); + TString Ext = PathStr.GetFileExtension(); - if (IsSupportedExtension(TO_QSTRING(ext))) + if (IsSupportedExtension(TO_QSTRING(Ext))) { - if ((ext != "MREA") && (ext != "MLVL")) - { - mpResource = gResCache.GetResource(pathStr); - mResourceValid = (mpResource != nullptr); + mResource = CResourceInfo(TO_TSTRING(ResPath)); + mResourceValid = mResource.IsValid(); - if (mPreviewPanelValid) mpPreviewPanel->SetResource(mpResource); - } - else mResourceValid = false; + if (mPreviewPanelValid) mpPreviewPanel->SetResource(mResource.Load()); } else mResourceValid = false; @@ -287,7 +290,7 @@ void WResourceSelector::CreatePreviewPanel() mpPreviewPanel = nullptr; if (mResourceValid) - mpPreviewPanel = IPreviewPanel::CreatePanel(mpResource->Type(), this); + mpPreviewPanel = IPreviewPanel::CreatePanel(CResource::ResTypeForExtension(mResource.Type()), this); if (!mpPreviewPanel) mPreviewPanelValid = false; @@ -295,7 +298,7 @@ void WResourceSelector::CreatePreviewPanel() { mPreviewPanelValid = true; mpPreviewPanel->setWindowFlags(Qt::ToolTip); - if (mpResource) mpPreviewPanel->SetResource(mpResource); + if (mResourceValid) mpPreviewPanel->SetResource(mResource.Load()); } } @@ -345,13 +348,13 @@ void WResourceSelector::SetButtonsBasedOnResType() { // Basically this function sets whether the "Export" and "Edit" // buttons are present based on the resource type. - if (!mpResource) + if (!mResource.IsValid()) { SetEditButtonEnabled(false); SetExportButtonEnabled(false); } - else switch (mpResource->Type()) + else switch (CResource::ResTypeForExtension(mResource.Type())) { // Export button should be enabled here because CTexture already has a DDS export function // However, need to figure out what sort of interface to create to do it. Disabling until then. diff --git a/src/Editor/Widgets/WResourceSelector.h b/src/Editor/Widgets/WResourceSelector.h index 4f1f9533..99f9a5d1 100644 --- a/src/Editor/Widgets/WResourceSelector.h +++ b/src/Editor/Widgets/WResourceSelector.h @@ -3,7 +3,7 @@ #include "IPreviewPanel.h" #include -#include +#include #include #include @@ -29,7 +29,7 @@ class WResourceSelector : public QWidget bool mAdjustPreviewToParent; // Resource - TResPtr mpResource; + CResourceInfo mResource; bool mResourceValid; // UI @@ -44,8 +44,8 @@ class WResourceSelector : public QWidget // Functions signals: void ResourceChanged(const QString& NewResPath); - void EditResource(CResource *pRes); - void ExportResource(CResource *pRes); + void EditResource(const CResourceInfo& rkRes); + void ExportResource(const CResourceInfo& rkRes); public: explicit WResourceSelector(QWidget *parent = 0); @@ -53,7 +53,7 @@ public: bool event(QEvent *); bool eventFilter(QObject *, QEvent *); bool IsSupportedExtension(const QString& extension); - bool HasSupportedExtension(CResource* pRes); + bool HasSupportedExtension(const CResourceInfo& rkRes); // Getters QString GetText(); @@ -63,6 +63,7 @@ public: // Setters void SetResource(CResource *pRes); + void SetResource(const CResourceInfo& rkRes); void SetAllowedExtensions(const QString& extension); void SetAllowedExtensions(const QStringList& extensions); void SetAllowedExtensions(const TStringList& extensions);