From 0827c05802a5716af4f315e1265de41c35f677e3 Mon Sep 17 00:00:00 2001 From: Aruki Date: Mon, 18 Feb 2019 03:54:58 -0700 Subject: [PATCH] Various crash fixes --- src/Core/Render/CRenderer.cpp | 1 + .../Collision/CCollisionRenderData.cpp | 4 +- src/Core/Resource/Cooker/CStringCooker.cpp | 15 +++--- src/Core/Resource/Factory/CStringLoader.cpp | 46 +++++++++++++------ .../Resource/StringTable/CStringTable.cpp | 3 +- src/Core/Tweaks/CTweakManager.cpp | 37 +++++++++++++-- src/Core/Tweaks/CTweakManager.h | 3 ++ .../ResourceBrowser/CResourceBrowser.cpp | 2 + src/Editor/WorldEditor/CWorldEditor.cpp | 2 + src/Editor/WorldEditor/CWorldEditor.ui | 3 ++ src/Editor/WorldEditor/WCreateTab.cpp | 13 ++++-- templates/PropertyMap.xml | 18 ++------ 12 files changed, 99 insertions(+), 48 deletions(-) diff --git a/src/Core/Render/CRenderer.cpp b/src/Core/Render/CRenderer.cpp index a3e3f19d..eaecf961 100644 --- a/src/Core/Render/CRenderer.cpp +++ b/src/Core/Render/CRenderer.cpp @@ -29,6 +29,7 @@ CRenderer::CRenderer() CRenderer::~CRenderer() { sNumRenderers--; + CGraphics::ReleaseContext(mContextIndex); if (sNumRenderers == 0) { diff --git a/src/Core/Resource/Collision/CCollisionRenderData.cpp b/src/Core/Resource/Collision/CCollisionRenderData.cpp index 3a1e1754..5cfd8f72 100644 --- a/src/Core/Resource/Collision/CCollisionRenderData.cpp +++ b/src/Core/Resource/Collision/CCollisionRenderData.cpp @@ -19,7 +19,9 @@ void CCollisionRenderData::BuildRenderData(const SCollisionIndexData& kIndexData mWireframeIndexBuffer.SetPrimitiveType(GL_LINES); // Build list of triangle indices sorted by material index - std::vector SortedTris(kIndexData.TriangleMaterialIndices.size(), 0); + // Apparently some collision meshes have more triangle indices than actual triangles + uint NumTris = Math::Min(kIndexData.TriangleIndices.size() / 3, kIndexData.TriangleMaterialIndices.size()); + std::vector SortedTris(NumTris, 0); for (uint16 i=0; i CookedLanguageData( mpStringTable->NumLanguages() ); + int EnglishIdx = -1; for (uint LanguageIdx = 0; LanguageIdx < mpStringTable->NumLanguages(); LanguageIdx++) { @@ -165,6 +166,11 @@ void CStringCooker::WriteCorruptionSTRG(IOutputStream& STRG) CookedData.Language = kLanguageData.Language; CookedData.StringOffsets.resize( mpStringTable->NumStrings() ); CookedData.TotalSize = 0; + + if (CookedData.Language == ELanguage::English) + { + EnglishIdx = (int) LanguageIdx; + } } // Language IDs @@ -185,9 +191,6 @@ void CStringCooker::WriteCorruptionSTRG(IOutputStream& STRG) STRG.WriteLong( 0 ); } - // Some of the following code assumes that language 0 is English. - ASSERT( mpStringTable->mLanguages[0].Language == ELanguage::English ); - // Strings uint StringsStart = STRG.Tell(); @@ -201,7 +204,7 @@ void CStringCooker::WriteCorruptionSTRG(IOutputStream& STRG) // If the "localized" flag is disabled, then we will not write this string. Instead, it will // reuse the offset for the English text. - if (LanguageIdx == 0 || kStringData.IsLocalized) + if (LanguageIdx == EnglishIdx || kStringData.IsLocalized) { CookedData.StringOffsets[StringIdx] = STRG.Tell() - StringsStart; CookedData.TotalSize += kStringData.String.Size() + 1; // +1 for terminating zero @@ -210,8 +213,8 @@ void CStringCooker::WriteCorruptionSTRG(IOutputStream& STRG) } else { - CookedData.StringOffsets[StringIdx] = CookedLanguageData[0].StringOffsets[StringIdx]; - CookedData.TotalSize += mpStringTable->mLanguages[0].Strings[StringIdx].String.Size() + 1; // +1 for terminating zero + CookedData.StringOffsets[StringIdx] = CookedLanguageData[EnglishIdx].StringOffsets[StringIdx]; + CookedData.TotalSize += mpStringTable->mLanguages[EnglishIdx].Strings[StringIdx].String.Size() + 1; // +1 for terminating zero } } } diff --git a/src/Core/Resource/Factory/CStringLoader.cpp b/src/Core/Resource/Factory/CStringLoader.cpp index f5a802ae..49aee91e 100644 --- a/src/Core/Resource/Factory/CStringLoader.cpp +++ b/src/Core/Resource/Factory/CStringLoader.cpp @@ -38,6 +38,7 @@ void CStringLoader::LoadPrimeSTRG(IInputStream& STRG) // Language definitions mpStringTable->mLanguages.resize(NumLanguages); std::vector LanguageOffsets(NumLanguages); + int EnglishIdx = -1; for (uint LanguageIdx = 0; LanguageIdx < NumLanguages; LanguageIdx++) { @@ -49,10 +50,13 @@ void CStringLoader::LoadPrimeSTRG(IInputStream& STRG) { STRG.Skip(4); } - } - // Some of the following code assumes that language 0 is English - ASSERT( mpStringTable->mLanguages[0].Language == ELanguage::English ); + if (mpStringTable->mLanguages[LanguageIdx].Language == ELanguage::English) + { + EnglishIdx = (int) LanguageIdx; + } + } + ASSERT(EnglishIdx != -1); // String names if (mVersion >= EGame::EchoesDemo) @@ -89,16 +93,24 @@ void CStringLoader::LoadPrimeSTRG(IInputStream& STRG) { STRG.GoTo( StringOffsets[StringIdx] ); TString String = STRG.Read16String().ToUTF8(); + Language.Strings[StringIdx].String = String; + } + } + // Set "localized" flags on strings + const CStringTable::SLanguageData& kEnglishData = mpStringTable->mLanguages[EnglishIdx]; + + for (uint LanguageIdx = 0; LanguageIdx < NumLanguages; LanguageIdx++) + { + CStringTable::SLanguageData& LanguageData = mpStringTable->mLanguages[LanguageIdx]; + + for (uint StringIdx = 0; StringIdx < NumStrings; StringIdx++) + { // Flag the string as localized if it is different than the English // version of the same string. - const TString& kEnglishString = (StringIdx == 0 ? String : - mpStringTable->mLanguages[0].Strings[StringIdx].String); - - bool IsLocalized = (LanguageIdx == 0 || String != kEnglishString); - - Language.Strings[StringIdx].String = String; - Language.Strings[StringIdx].IsLocalized = IsLocalized; + const TString& kLocalString = LanguageData.Strings[StringIdx].String; + const TString& kEnglishString = kEnglishData.Strings[StringIdx].String; + LanguageData.Strings[StringIdx].IsLocalized = (LanguageIdx == EnglishIdx || kLocalString != kEnglishString); } } } @@ -116,11 +128,18 @@ void CStringLoader::LoadCorruptionSTRG(IInputStream& STRG) // Language definitions mpStringTable->mLanguages.resize(NumLanguages); std::vector< std::vector > LanguageOffsets(NumLanguages); + int EnglishIdx = -1; for (uint LanguageIdx = 0; LanguageIdx < NumLanguages; LanguageIdx++) { mpStringTable->mLanguages[LanguageIdx].Language = (ELanguage) STRG.ReadFourCC(); + + if (mpStringTable->mLanguages[LanguageIdx].Language == ELanguage::English) + { + EnglishIdx = (int) LanguageIdx; + } } + ASSERT(EnglishIdx != -1); for (uint LanguageIdx = 0; LanguageIdx < NumLanguages; LanguageIdx++) { @@ -133,9 +152,6 @@ void CStringLoader::LoadCorruptionSTRG(IInputStream& STRG) } } - // Some of the following code assumes that language 0 is English - ASSERT( mpStringTable->mLanguages[0].Language == ELanguage::English ); - // Strings uint StringsStart = STRG.Tell(); @@ -151,8 +167,8 @@ void CStringLoader::LoadCorruptionSTRG(IInputStream& STRG) Language.Strings[StringIdx].String = STRG.ReadString(); // Flag the string as localized if it has a different offset than the English string - Language.Strings[StringIdx].IsLocalized = (LanguageIdx == 0 || - LanguageOffsets[LanguageIdx][StringIdx] != LanguageOffsets[0][StringIdx]); + Language.Strings[StringIdx].IsLocalized = (LanguageIdx == EnglishIdx || + LanguageOffsets[LanguageIdx][StringIdx] != LanguageOffsets[EnglishIdx][StringIdx]); } } } diff --git a/src/Core/Resource/StringTable/CStringTable.cpp b/src/Core/Resource/StringTable/CStringTable.cpp index d629a317..aae2fbfb 100644 --- a/src/Core/Resource/StringTable/CStringTable.cpp +++ b/src/Core/Resource/StringTable/CStringTable.cpp @@ -96,12 +96,13 @@ TString CStringTable::GetString(ELanguage Language, uint StringIndex) const void CStringTable::SetString(ELanguage Language, uint StringIndex, const TString& kNewString) { int LanguageIdx = FindLanguageIndex(this, Language); + int EnglishIdx = FindLanguageIndex(this, ELanguage::English); if (LanguageIdx >= 0 && mLanguages[LanguageIdx].Strings.size() > StringIndex) { mLanguages[LanguageIdx].Strings[StringIndex].String = kNewString; mLanguages[LanguageIdx].Strings[StringIndex].IsLocalized = - (LanguageIdx == 0 || kNewString != mLanguages[0].Strings[StringIndex].String); + (LanguageIdx == EnglishIdx || kNewString != mLanguages[EnglishIdx].Strings[StringIndex].String); } } diff --git a/src/Core/Tweaks/CTweakManager.cpp b/src/Core/Tweaks/CTweakManager.cpp index af5f2034..eedb7221 100644 --- a/src/Core/Tweaks/CTweakManager.cpp +++ b/src/Core/Tweaks/CTweakManager.cpp @@ -32,14 +32,42 @@ void CTweakManager::LoadTweaks() // MP2+ - Load tweaks from Standard.ntwk else { - TString FilePath = mpProject->DiscFilesystemRoot(false) + "Standard.ntwk"; - CFileInStream StandardNTWK(FilePath, EEndian::BigEndian); - CTweakLoader::LoadNTWK(StandardNTWK, mpProject->Game(), mTweakObjects); + if (!mpProject->IsWiiBuild()) + { + mStandardFilePath = mpProject->DiscFilesystemRoot(false) / "Standard.ntwk"; + } + else + { + // For Wii builds, there is another game-dependent subfolder. + EGame Game = mpProject->Game(); + TString GameName = (Game == EGame::Prime ? "MP1" : + Game == EGame::Echoes ? "MP2" : + "MP3"); + mStandardFilePath = mpProject->DiscFilesystemRoot(false) / GameName / "Standard.ntwk"; + + // MP3 might actually be FrontEnd + if (Game == EGame::Corruption && !FileUtil::Exists(mStandardFilePath)) + { + mStandardFilePath = mpProject->DiscFilesystemRoot(false) / "fe/Standard.ntwk"; + } + } + + if (FileUtil::Exists(mStandardFilePath)) + { + CFileInStream StandardNTWK(mStandardFilePath, EEndian::BigEndian); + CTweakLoader::LoadNTWK(StandardNTWK, mpProject->Game(), mTweakObjects); + } } } bool CTweakManager::SaveTweaks() { + // If we don't have any tweaks loaded, nothing to do + if (mTweakObjects.empty()) + { + return false; + } + // MP1 - Save all tweak assets if (mpProject->Game() <= EGame::Prime) { @@ -67,8 +95,7 @@ bool CTweakManager::SaveTweaks() // MP2+ - Save tweaks to Standard.ntwk else { - TString FilePath = mpProject->DiscFilesystemRoot(false) + "Standard.ntwk"; - CFileOutStream StandardNTWK(FilePath, EEndian::BigEndian); + CFileOutStream StandardNTWK(mStandardFilePath, EEndian::BigEndian); return CTweakCooker::CookNTWK(mTweakObjects, StandardNTWK); } } diff --git a/src/Core/Tweaks/CTweakManager.h b/src/Core/Tweaks/CTweakManager.h index cc5d9eb5..2ee24afb 100644 --- a/src/Core/Tweaks/CTweakManager.h +++ b/src/Core/Tweaks/CTweakManager.h @@ -12,6 +12,9 @@ class CTweakManager /** All tweak resources in the current game */ std::vector< CTweakData* > mTweakObjects; + /** For MP2+, the path to Standard.ntwk */ + TString mStandardFilePath; + public: CTweakManager(CGameProject* pInProject); ~CTweakManager(); diff --git a/src/Editor/ResourceBrowser/CResourceBrowser.cpp b/src/Editor/ResourceBrowser/CResourceBrowser.cpp index 68411585..e63bfde2 100644 --- a/src/Editor/ResourceBrowser/CResourceBrowser.cpp +++ b/src/Editor/ResourceBrowser/CResourceBrowser.cpp @@ -34,6 +34,7 @@ CResourceBrowser::CResourceBrowser(QWidget *pParent) , mpInspectedEntry(nullptr) { mpUI->setupUi(this); + setEnabled(false); // Hide sorting combo box for now. The size isn't displayed on the UI so this isn't really useful for the end user. mpUI->SortComboBox->hide(); @@ -896,6 +897,7 @@ void CResourceBrowser::UpdateStore() // Refresh project-specific UI CreateAddMenu(); CreateFilterCheckboxes(); + setEnabled(mpStore != nullptr); // Refresh directory tree mpDirectoryModel->SetRoot(mpStore ? mpStore->RootDirectory() : nullptr); diff --git a/src/Editor/WorldEditor/CWorldEditor.cpp b/src/Editor/WorldEditor/CWorldEditor.cpp index 23602bde..a4e21c71 100644 --- a/src/Editor/WorldEditor/CWorldEditor.cpp +++ b/src/Editor/WorldEditor/CWorldEditor.cpp @@ -229,6 +229,7 @@ bool CWorldEditor::CloseWorld() ui->ActionSave->setEnabled(false); ui->ActionSaveAndRepack->setEnabled(false); + ui->ActionEditLayers->setEnabled(false); emit MapChanged(mpWorld, mpArea); return true; } @@ -287,6 +288,7 @@ bool CWorldEditor::SetArea(CWorld *pWorld, int AreaIndex) // Update toolbar actions ui->ActionSave->setEnabled(true); ui->ActionSaveAndRepack->setEnabled(true); + ui->ActionEditLayers->setEnabled(true); // Emit signals emit MapChanged(mpWorld, mpArea); diff --git a/src/Editor/WorldEditor/CWorldEditor.ui b/src/Editor/WorldEditor/CWorldEditor.ui index 87c5a4a5..b7db3167 100644 --- a/src/Editor/WorldEditor/CWorldEditor.ui +++ b/src/Editor/WorldEditor/CWorldEditor.ui @@ -568,6 +568,9 @@ + + false + Edit Layers diff --git a/src/Editor/WorldEditor/WCreateTab.cpp b/src/Editor/WorldEditor/WCreateTab.cpp index a20cf289..739ab177 100644 --- a/src/Editor/WorldEditor/WCreateTab.cpp +++ b/src/Editor/WorldEditor/WCreateTab.cpp @@ -31,12 +31,15 @@ bool WCreateTab::eventFilter(QObject *pObj, QEvent *pEvent) { if (pEvent->type() == QEvent::DragEnter) { - QDragEnterEvent *pDragEvent = static_cast(pEvent); - - if (qobject_cast(pDragEvent->mimeData())) + if (mpEditor->ActiveArea() != nullptr) { - pDragEvent->acceptProposedAction(); - return true; + QDragEnterEvent *pDragEvent = static_cast(pEvent); + + if (qobject_cast(pDragEvent->mimeData())) + { + pDragEvent->acceptProposedAction(); + return true; + } } } diff --git a/templates/PropertyMap.xml b/templates/PropertyMap.xml index 42294c19..a8bf3f72 100644 --- a/templates/PropertyMap.xml +++ b/templates/PropertyMap.xml @@ -7927,7 +7927,7 @@ - + @@ -13561,10 +13561,6 @@ - - - - @@ -14913,10 +14909,6 @@ - - - - @@ -16003,7 +15995,7 @@ - + @@ -32865,10 +32857,6 @@ - - - - @@ -36643,7 +36631,7 @@ - +