Write all menu function definitions on top of every menu list item

This commit is contained in:
Jan 2021-10-24 16:22:36 +02:00
parent 70c31143f4
commit c1fd5b80a4
4 changed files with 104 additions and 19 deletions

View File

@ -1,8 +1,11 @@
#include "AssetDumperMenuList.h" #include "AssetDumperMenuList.h"
#include <cassert>
#include <filesystem> #include <filesystem>
#include <sstream> #include <sstream>
#include <set>
#include "ObjWriting.h"
#include "Game/IW4/Menu/MenuDumperIW4.h" #include "Game/IW4/Menu/MenuDumperIW4.h"
#include "Menu/AbstractMenuDumper.h" #include "Menu/AbstractMenuDumper.h"
@ -10,6 +13,87 @@ namespace fs = std::filesystem;
using namespace IW4; using namespace IW4;
std::vector<const ExpressionSupportingData*> AssetDumperMenuList::GetAllUniqueExpressionSupportingData(const MenuList* menuList)
{
std::vector<const ExpressionSupportingData*> result;
std::set<const ExpressionSupportingData*> 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<MenuList>* asset) bool AssetDumperMenuList::ShouldDump(XAssetInfo<MenuList>* asset)
{ {
return true; return true;
@ -19,34 +103,18 @@ void AssetDumperMenuList::DumpAsset(AssetDumpingContext& context, XAssetInfo<Men
{ {
const auto* menuList = asset->Asset(); const auto* menuList = asset->Asset();
const auto assetFile = context.OpenAssetFile(asset->m_name); const auto assetFile = context.OpenAssetFile(asset->m_name);
const fs::path p(asset->Asset()->name);
if (!assetFile) if (!assetFile)
return; return;
std::string parentPath;
if(p.has_parent_path())
parentPath = p.parent_path().string() + "/";
MenuDumper menuDumper(*assetFile); MenuDumper menuDumper(*assetFile);
menuDumper.Start(); menuDumper.Start();
for(auto menuNum = 0; menuNum < menuList->menuCount; menuNum++) if(!ObjWriting::Configuration.MenuLegacyMode)
{ DumpFunctions(menuDumper, menuList);
const auto* menu = menuList->menus[menuNum];
std::ostringstream ss; DumpMenus(menuDumper, menuList);
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());
}
menuDumper.End(); menuDumper.End();
} }

View File

@ -2,11 +2,17 @@
#include "Dumping/AbstractAssetDumper.h" #include "Dumping/AbstractAssetDumper.h"
#include "Game/IW4/IW4.h" #include "Game/IW4/IW4.h"
#include "Game/IW4/Menu/MenuDumperIW4.h"
namespace IW4 namespace IW4
{ {
class AssetDumperMenuList final : public AbstractAssetDumper<MenuList> class AssetDumperMenuList final : public AbstractAssetDumper<MenuList>
{ {
static std::vector<const ExpressionSupportingData*> GetAllUniqueExpressionSupportingData(const MenuList* menuList);
static void DumpFunctions(MenuDumper& menuDumper, const MenuList* menuList);
static void DumpMenus(MenuDumper& menuDumper, const MenuList* menuList);
protected: protected:
bool ShouldDump(XAssetInfo<MenuList>* asset) override; bool ShouldDump(XAssetInfo<MenuList>* asset) override;
void DumpAsset(AssetDumpingContext& context, XAssetInfo<MenuList>* asset) override; void DumpAsset(AssetDumpingContext& context, XAssetInfo<MenuList>* asset) override;

View File

@ -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) void MenuDumper::WriteMenu(const menuDef_t* menu)
{ {
StartMenuDefScope(); StartMenuDefScope();

View File

@ -48,6 +48,7 @@ namespace IW4
public: public:
explicit MenuDumper(std::ostream& stream); explicit MenuDumper(std::ostream& stream);
void WriteFunctionDef(const std::string& functionName, const Statement_s* statement);
void WriteMenu(const menuDef_t* menu); void WriteMenu(const menuDef_t* menu);
}; };
} }