From c1fd5b80a467a9630e53e7824c7a846f3f338212 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 24 Oct 2021 16:22:36 +0200 Subject: [PATCH] Write all menu function definitions on top of every menu list item --- .../IW4/AssetDumpers/AssetDumperMenuList.cpp | 106 ++++++++++++++---- .../IW4/AssetDumpers/AssetDumperMenuList.h | 6 + .../Game/IW4/Menu/MenuDumperIW4.cpp | 10 ++ src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.h | 1 + 4 files changed, 104 insertions(+), 19 deletions(-) diff --git a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMenuList.cpp b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMenuList.cpp index 9cc4f0f2..217f63a7 100644 --- a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMenuList.cpp +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMenuList.cpp @@ -1,8 +1,11 @@ #include "AssetDumperMenuList.h" +#include #include #include +#include +#include "ObjWriting.h" #include "Game/IW4/Menu/MenuDumperIW4.h" #include "Menu/AbstractMenuDumper.h" @@ -10,6 +13,87 @@ namespace fs = std::filesystem; using namespace IW4; +std::vector AssetDumperMenuList::GetAllUniqueExpressionSupportingData(const MenuList* menuList) +{ + std::vector result; + std::set alreadyAddedSupportingData; + + if (menuList->menus == nullptr) + return result; + + for(auto i = 0; i < menuList->menuCount; i++) + { + if(menuList->menus[i] == nullptr) + continue; + + const auto* menu = menuList->menus[i]; + + if(menu->expressionData == nullptr) + continue; + + if(alreadyAddedSupportingData.find(menu->expressionData) == alreadyAddedSupportingData.end()) + { + result.push_back(menu->expressionData); + alreadyAddedSupportingData.emplace(menu->expressionData); + } + } + + return result; +} + +void AssetDumperMenuList::DumpFunctions(MenuDumper& menuDumper, const MenuList* menuList) +{ + const auto allSupportingData = GetAllUniqueExpressionSupportingData(menuList); + auto functionIndex = 0u; + + assert(allSupportingData.size() <= 1); + + for (const auto* supportingData : allSupportingData) + { + if (supportingData->uifunctions.functions == nullptr) + continue; + + for(auto i = 0; i < supportingData->uifunctions.totalFunctions; i++) + { + const auto* function = supportingData->uifunctions.functions[i]; + if(function == nullptr) + continue; + + std::stringstream ss; + ss << "FUNC_" << functionIndex; + + menuDumper.WriteFunctionDef(ss.str(), function); + + functionIndex++; + } + } +} + +void AssetDumperMenuList::DumpMenus(MenuDumper& menuDumper, const MenuList* menuList) +{ + const fs::path p(menuList->name); + + std::string parentPath; + if (p.has_parent_path()) + parentPath = p.parent_path().string() + "/"; + + for (auto menuNum = 0; menuNum < menuList->menuCount; menuNum++) + { + const auto* menu = menuList->menus[menuNum]; + + std::ostringstream ss; + ss << parentPath << menu->window.name << ".menu"; + + const auto menuName = ss.str(); + + // If the menu was embedded directly as menu list write its data in the menu list file + if (menuName == menuList->name) + menuDumper.WriteMenu(menu); + else + menuDumper.IncludeMenu(ss.str()); + } +} + bool AssetDumperMenuList::ShouldDump(XAssetInfo* asset) { return true; @@ -19,34 +103,18 @@ void AssetDumperMenuList::DumpAsset(AssetDumpingContext& context, XAssetInfoAsset(); const auto assetFile = context.OpenAssetFile(asset->m_name); - const fs::path p(asset->Asset()->name); if (!assetFile) return; - std::string parentPath; - if(p.has_parent_path()) - parentPath = p.parent_path().string() + "/"; - MenuDumper menuDumper(*assetFile); menuDumper.Start(); - for(auto menuNum = 0; menuNum < menuList->menuCount; menuNum++) - { - const auto* menu = menuList->menus[menuNum]; + if(!ObjWriting::Configuration.MenuLegacyMode) + DumpFunctions(menuDumper, menuList); - std::ostringstream ss; - ss << parentPath << menu->window.name << ".menu"; - - const auto menuName = ss.str(); - - // If the menu was embedded directly as menu list write its data in the menu list file - if(menuName == menuList->name) - menuDumper.WriteMenu(menu); - else - menuDumper.IncludeMenu(ss.str()); - } + DumpMenus(menuDumper, menuList); menuDumper.End(); } diff --git a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMenuList.h b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMenuList.h index a1632aa8..043a3fd8 100644 --- a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMenuList.h +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperMenuList.h @@ -2,11 +2,17 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW4/IW4.h" +#include "Game/IW4/Menu/MenuDumperIW4.h" namespace IW4 { class AssetDumperMenuList final : public AbstractAssetDumper { + static std::vector GetAllUniqueExpressionSupportingData(const MenuList* menuList); + + static void DumpFunctions(MenuDumper& menuDumper, const MenuList* menuList); + static void DumpMenus(MenuDumper& menuDumper, const MenuList* menuList); + protected: bool ShouldDump(XAssetInfo* asset) override; void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; diff --git a/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.cpp b/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.cpp index 891fc662..8762f62f 100644 --- a/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.cpp @@ -776,6 +776,16 @@ MenuDumper::MenuDumper(std::ostream& stream) { } +void MenuDumper::WriteFunctionDef(const std::string& functionName, const Statement_s* statement) +{ + StartFunctionDefScope(); + + WriteStringProperty("name", functionName); + WriteStatementProperty("value", statement, false); + + EndScope(); +} + void MenuDumper::WriteMenu(const menuDef_t* menu) { StartMenuDefScope(); diff --git a/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.h b/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.h index ff0ac99d..5c914b79 100644 --- a/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.h +++ b/src/ObjWriting/Game/IW4/Menu/MenuDumperIW4.h @@ -48,6 +48,7 @@ namespace IW4 public: explicit MenuDumper(std::ostream& stream); + void WriteFunctionDef(const std::string& functionName, const Statement_s* statement); void WriteMenu(const menuDef_t* menu); }; }