2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2026-03-07 05:23:02 +00:00

chore: refactor IW4 asset loaders

This commit is contained in:
Jan
2024-12-25 21:39:05 +01:00
parent f9456101e6
commit 7ef944ebd4
139 changed files with 2370 additions and 2965 deletions

View File

@@ -16,19 +16,17 @@
#include <cassert>
#include <cstring>
#include <format>
#include <sstream>
using namespace IW4;
using namespace menu;
namespace IW4
namespace
{
class MenuConverterImpl : public AbstractMenuConverter
class MenuConverter : public AbstractMenuConverter, public IMenuConverter
{
MenuConversionZoneState* m_conversion_zone_state;
MenuAssetZoneState* m_parsing_zone_state;
_NODISCARD static rectDef_s ConvertRectDef(const CommonRect& rect)
[[nodiscard]] static rectDef_s ConvertRectDef(const CommonRect& rect)
{
return rectDef_s{
static_cast<float>(rect.x),
@@ -40,7 +38,7 @@ namespace IW4
};
}
_NODISCARD static rectDef_s ConvertRectDefRelativeTo(const CommonRect& rect, const CommonRect& rectRelativeTo)
[[nodiscard]] static rectDef_s ConvertRectDefRelativeTo(const CommonRect& rect, const CommonRect& rectRelativeTo)
{
return rectDef_s{
static_cast<float>(rectRelativeTo.x + rect.x),
@@ -78,26 +76,26 @@ namespace IW4
return input;
}
_NODISCARD Material* ConvertMaterial(const std::string& materialName, const CommonMenuDef* menu, const CommonItemDef* item = nullptr) const
[[nodiscard]] Material* ConvertMaterial(const std::string& materialName, const CommonMenuDef* menu, const CommonItemDef* item = nullptr) const
{
if (materialName.empty())
return nullptr;
auto* materialDependency = m_manager->LoadDependency<AssetMaterial>(materialName);
auto* materialDependency = m_context.LoadDependency<AssetMaterial>(materialName);
if (!materialDependency)
throw MenuConversionException("Failed to load material \"" + materialName + "\"", menu, item);
throw MenuConversionException(std::format("Failed to load material \"{}\"", materialName), menu, item);
return materialDependency->Asset();
}
_NODISCARD snd_alias_list_t* ConvertSound(const std::string& soundName, const CommonMenuDef* menu, const CommonItemDef* item = nullptr) const
[[nodiscard]] snd_alias_list_t* ConvertSound(const std::string& soundName, const CommonMenuDef* menu, const CommonItemDef* item = nullptr) const
{
if (soundName.empty())
return nullptr;
auto* soundDependency = m_manager->LoadDependency<AssetSound>(soundName);
auto* soundDependency = m_context.LoadDependency<AssetSound>(soundName);
if (!soundDependency)
throw MenuConversionException("Failed to load sound \"" + soundName + "\"", menu, item);
throw MenuConversionException(std::format("Failed to load sound \"{}\"", soundName), menu, item);
return soundDependency->Asset();
}
@@ -416,7 +414,7 @@ namespace IW4
if (!expression)
return nullptr;
auto* statement = m_memory->Create<Statement_s>();
auto* statement = m_memory.Alloc<Statement_s>();
statement->lastResult = Operand{};
statement->lastExecuteTime = 0;
statement->supportingData = nullptr; // Supporting data is set upon using it
@@ -424,7 +422,7 @@ namespace IW4
std::vector<expressionEntry> expressionEntries;
ConvertExpressionEntry(statement, expressionEntries, expression, menu, item);
auto* outputExpressionEntries = m_memory->Alloc<expressionEntry>(expressionEntries.size());
auto* outputExpressionEntries = m_memory.Alloc<expressionEntry>(expressionEntries.size());
memcpy(outputExpressionEntries, expressionEntries.data(), sizeof(expressionEntry) * expressionEntries.size());
statement->entries = outputExpressionEntries;
@@ -481,7 +479,7 @@ namespace IW4
switch (value.m_type)
{
case SimpleExpressionValue::Type::STRING:
staticValue = m_memory->Dup(value.m_string_value->c_str());
staticValue = m_memory.Dup(value.m_string_value->c_str());
break;
case SimpleExpressionValue::Type::DOUBLE:
@@ -586,13 +584,13 @@ namespace IW4
if (!setLocalVar)
return;
auto* outputHandler = m_memory->Alloc<MenuEventHandler>();
auto* outputSetLocalVar = m_memory->Alloc<SetLocalVarData>();
auto* outputHandler = m_memory.Alloc<MenuEventHandler>();
auto* outputSetLocalVar = m_memory.Alloc<SetLocalVarData>();
outputHandler->eventType = SetLocalVarTypeToEventType(setLocalVar->m_type);
outputHandler->eventData.setLocalVarData = outputSetLocalVar;
outputSetLocalVar->localVarName = m_memory->Dup(setLocalVar->m_var_name.c_str());
outputSetLocalVar->localVarName = m_memory.Dup(setLocalVar->m_var_name.c_str());
outputSetLocalVar->expression = ConvertExpression(setLocalVar->m_value.get(), menu, item);
elements.push_back(outputHandler);
@@ -604,9 +602,9 @@ namespace IW4
if (!script)
return;
auto* outputHandler = m_memory->Create<MenuEventHandler>();
auto* outputHandler = m_memory.Alloc<MenuEventHandler>();
outputHandler->eventType = EVENT_UNCONDITIONAL;
outputHandler->eventData.unconditionalScript = m_memory->Dup(script->m_script.c_str());
outputHandler->eventData.unconditionalScript = m_memory.Dup(script->m_script.c_str());
elements.push_back(outputHandler);
}
@@ -631,8 +629,8 @@ namespace IW4
}
else
{
auto* outputHandler = m_memory->Alloc<MenuEventHandler>();
auto* outputCondition = m_memory->Alloc<ConditionalScript>();
auto* outputHandler = m_memory.Alloc<MenuEventHandler>();
auto* outputCondition = m_memory.Alloc<ConditionalScript>();
outputHandler->eventType = EVENT_IF;
outputHandler->eventData.conditionalScript = outputCondition;
@@ -644,7 +642,7 @@ namespace IW4
if (condition->m_else_elements)
{
auto* outputElseHandler = m_memory->Create<MenuEventHandler>();
auto* outputElseHandler = m_memory.Alloc<MenuEventHandler>();
outputElseHandler->eventType = EVENT_ELSE;
outputElseHandler->eventData.elseScript = ConvertEventHandlerSet(condition->m_else_elements.get(), menu, item);
@@ -699,8 +697,8 @@ namespace IW4
if (elements.empty())
return nullptr;
auto* outputSet = m_memory->Alloc<MenuEventHandlerSet>();
auto* outputElements = m_memory->Alloc<MenuEventHandler*>(elements.size());
auto* outputSet = m_memory.Alloc<MenuEventHandlerSet>();
auto* outputElements = m_memory.Alloc<MenuEventHandler*>(elements.size());
memcpy(outputElements, elements.data(), sizeof(void*) * elements.size());
outputSet->eventHandlerCount = static_cast<int>(elements.size());
@@ -717,7 +715,7 @@ namespace IW4
return nullptr;
const auto keyHandlerCount = keyHandlers.size();
auto* output = m_memory->Alloc<ItemKeyHandler>(keyHandlerCount);
auto* output = m_memory.Alloc<ItemKeyHandler>(keyHandlerCount);
auto currentKeyHandler = keyHandlers.cbegin();
for (auto i = 0u; i < keyHandlerCount; i++)
{
@@ -829,7 +827,7 @@ namespace IW4
if (floatExpressionCount <= 0)
return nullptr;
auto* floatExpressions = m_memory->Alloc<ItemFloatExpression>(floatExpressionCount);
auto* floatExpressions = m_memory.Alloc<ItemFloatExpression>(floatExpressionCount);
auto floatExpressionIndex = 0;
for (const auto& [expression, expressionIsStatic, target, staticValue, staticValueArraySize, dynamicFlagsToSet] : locations)
{
@@ -855,7 +853,7 @@ namespace IW4
ss << "\"" << element << "\" ";
}
return m_memory->Dup(ss.str().c_str());
return m_memory.Dup(ss.str().c_str());
}
_NODISCARD const char* ConvertEnableDvar(const CommonItemDef& commonItem, int& dvarFlags) const
@@ -903,7 +901,7 @@ namespace IW4
if (commonListBox == nullptr)
return nullptr;
auto* listBox = m_memory->Alloc<listBoxDef_s>();
auto* listBox = m_memory.Alloc<listBoxDef_s>();
listBox->notselectable = commonListBox->m_not_selectable ? 1 : 0;
listBox->noScrollBars = commonListBox->m_no_scrollbars ? 1 : 0;
listBox->usePaging = commonListBox->m_use_paging ? 1 : 0;
@@ -938,7 +936,7 @@ namespace IW4
if (commonEditField == nullptr)
return nullptr;
auto* editField = m_memory->Alloc<editFieldDef_s>();
auto* editField = m_memory.Alloc<editFieldDef_s>();
editField->defVal = static_cast<float>(commonEditField->m_def_val);
editField->minVal = static_cast<float>(commonEditField->m_min_val);
editField->maxVal = static_cast<float>(commonEditField->m_max_val);
@@ -958,7 +956,7 @@ namespace IW4
if (commonMultiValue == nullptr)
return nullptr;
auto* multiValue = m_memory->Alloc<multiDef_s>();
auto* multiValue = m_memory.Alloc<multiDef_s>();
multiValue->count = static_cast<int>(std::min(std::extent_v<decltype(multiDef_s::dvarList)>, commonMultiValue->m_step_names.size()));
multiValue->strDef = !commonMultiValue->m_string_values.empty() ? 1 : 0;
@@ -989,7 +987,7 @@ namespace IW4
if (commonNewsTicker == nullptr)
return nullptr;
auto* newsTicker = m_memory->Alloc<newsTickerDef_s>();
auto* newsTicker = m_memory.Alloc<newsTickerDef_s>();
newsTicker->spacing = commonNewsTicker->m_spacing;
newsTicker->speed = commonNewsTicker->m_speed;
newsTicker->feedId = commonNewsTicker->m_news_feed_id;
@@ -999,8 +997,7 @@ namespace IW4
_NODISCARD itemDef_s* ConvertItem(const CommonMenuDef& parentMenu, const CommonItemDef& commonItem) const
{
auto* item = m_memory->Create<itemDef_s>();
memset(item, 0, sizeof(itemDef_s));
auto* item = m_memory.Alloc<itemDef_s>();
item->window.name = ConvertString(commonItem.m_name);
item->text = ConvertString(commonItem.m_text);
@@ -1087,7 +1084,7 @@ namespace IW4
case CommonItemFeatureType::NONE:
default:
if (item->type == ITEM_TYPE_TEXT_SCROLL)
item->typeData.scroll = m_memory->Alloc<textScrollDef_s>();
item->typeData.scroll = m_memory.Alloc<textScrollDef_s>();
break;
}
@@ -1103,7 +1100,7 @@ namespace IW4
return nullptr;
}
auto* items = m_memory->Alloc<itemDef_s*>(commonMenu.m_items.size());
auto* items = m_memory.Alloc<itemDef_s*>(commonMenu.m_items.size());
for (auto i = 0u; i < commonMenu.m_items.size(); i++)
items[i] = ConvertItem(commonMenu, *commonMenu.m_items[i]);
@@ -1113,98 +1110,75 @@ namespace IW4
}
public:
MenuConverterImpl(const bool disableOptimizations, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager)
: AbstractMenuConverter(disableOptimizations, searchPath, memory, manager),
m_conversion_zone_state(manager->GetAssetLoadingContext()->GetZoneAssetLoaderState<MenuConversionZoneState>()),
m_parsing_zone_state(manager->GetAssetLoadingContext()->GetZoneAssetLoaderState<MenuAssetZoneState>())
MenuConverter(const bool disableOptimizations, ISearchPath& searchPath, MemoryManager& memory, AssetCreationContext& context)
: AbstractMenuConverter(disableOptimizations, searchPath, memory, context),
m_conversion_zone_state(context.GetZoneAssetLoaderState<MenuConversionZoneState>()),
m_parsing_zone_state(context.GetZoneAssetLoaderState<MenuAssetZoneState>())
{
assert(m_conversion_zone_state);
assert(m_parsing_zone_state);
}
_NODISCARD menuDef_t* ConvertMenu(const CommonMenuDef& commonMenu) const
void ConvertMenu(const menu::CommonMenuDef& commonMenu, menuDef_t& menu, AssetRegistration<AssetMenu>& registration) override
{
auto* menu = m_memory->Create<menuDef_t>();
memset(menu, 0, sizeof(menuDef_t));
menu->window.name = m_memory->Dup(commonMenu.m_name.c_str());
menu->fullScreen = commonMenu.m_full_screen;
ApplyFlag(menu->window.staticFlags, commonMenu.m_screen_space, WINDOW_FLAG_SCREEN_SPACE);
ApplyFlag(menu->window.staticFlags, commonMenu.m_decoration, WINDOW_FLAG_DECORATION);
menu->window.rect = ConvertRectDef(commonMenu.m_rect);
menu->window.style = commonMenu.m_style;
menu->window.border = commonMenu.m_border;
menu->window.borderSize = static_cast<float>(commonMenu.m_border_size);
ConvertColor(menu->window.backColor, commonMenu.m_back_color);
ConvertColor(menu->window.foreColor, commonMenu.m_fore_color);
ConvertColor(menu->window.borderColor, commonMenu.m_border_color);
ConvertColor(menu->focusColor, commonMenu.m_focus_color);
menu->window.background = ConvertMaterial(commonMenu.m_background, &commonMenu);
menu->window.ownerDraw = commonMenu.m_owner_draw;
menu->window.ownerDrawFlags = commonMenu.m_owner_draw_flags;
ApplyFlag(menu->window.staticFlags, commonMenu.m_out_of_bounds_click, WINDOW_FLAG_OUT_OF_BOUNDS_CLICK);
menu->soundName = ConvertString(commonMenu.m_sound_loop);
ApplyFlag(menu->window.staticFlags, commonMenu.m_popup, WINDOW_FLAG_POPUP);
menu->fadeClamp = static_cast<float>(commonMenu.m_fade_clamp);
menu->fadeCycle = commonMenu.m_fade_cycle;
menu->fadeAmount = static_cast<float>(commonMenu.m_fade_amount);
menu->fadeInAmount = static_cast<float>(commonMenu.m_fade_in_amount);
menu->blurRadius = static_cast<float>(commonMenu.m_blur_radius);
ApplyFlag(menu->window.staticFlags, commonMenu.m_legacy_split_screen_scale, WINDOW_FLAG_LEGACY_SPLIT_SCREEN_SCALE);
ApplyFlag(menu->window.staticFlags, commonMenu.m_hidden_during_scope, WINDOW_FLAG_HIDDEN_DURING_SCOPE);
ApplyFlag(menu->window.staticFlags, commonMenu.m_hidden_during_flashbang, WINDOW_FLAG_HIDDEN_DURING_FLASH_BANG);
ApplyFlag(menu->window.staticFlags, commonMenu.m_hidden_during_ui, WINDOW_FLAG_HIDDEN_DURING_UI);
menu->allowedBinding = ConvertString(commonMenu.m_allowed_binding);
ApplyFlag(menu->window.staticFlags, commonMenu.m_text_only_focus, WINDOW_FLAG_TEXT_ONLY_FOCUS);
menu->visibleExp = ConvertVisibleExpression(&menu->window, commonMenu.m_visible_expression.get(), &commonMenu);
menu->rectXExp = ConvertOrApplyStatement(menu->window.rect.x, commonMenu.m_rect_x_exp.get(), &commonMenu);
menu->rectYExp = ConvertOrApplyStatement(menu->window.rect.y, commonMenu.m_rect_y_exp.get(), &commonMenu);
menu->rectWExp = ConvertOrApplyStatement(menu->window.rect.w, commonMenu.m_rect_w_exp.get(), &commonMenu);
menu->rectHExp = ConvertOrApplyStatement(menu->window.rect.h, commonMenu.m_rect_h_exp.get(), &commonMenu);
menu->openSoundExp = ConvertExpression(commonMenu.m_open_sound_exp.get(), &commonMenu);
menu->closeSoundExp = ConvertExpression(commonMenu.m_close_sound_exp.get(), &commonMenu);
menu->onOpen = ConvertEventHandlerSet(commonMenu.m_on_open.get(), &commonMenu);
menu->onClose = ConvertEventHandlerSet(commonMenu.m_on_close.get(), &commonMenu);
menu->onCloseRequest = ConvertEventHandlerSet(commonMenu.m_on_request_close.get(), &commonMenu);
menu->onESC = ConvertEventHandlerSet(commonMenu.m_on_esc.get(), &commonMenu);
menu->onKey = ConvertKeyHandler(commonMenu.m_key_handlers, &commonMenu);
menu->items = ConvertMenuItems(commonMenu, menu->itemCount);
menu->expressionData = m_conversion_zone_state->m_supporting_data;
return menu;
try
{
menu.window.name = m_memory.Dup(commonMenu.m_name.c_str());
menu.fullScreen = commonMenu.m_full_screen;
ApplyFlag(menu.window.staticFlags, commonMenu.m_screen_space, WINDOW_FLAG_SCREEN_SPACE);
ApplyFlag(menu.window.staticFlags, commonMenu.m_decoration, WINDOW_FLAG_DECORATION);
menu.window.rect = ConvertRectDef(commonMenu.m_rect);
menu.window.style = commonMenu.m_style;
menu.window.border = commonMenu.m_border;
menu.window.borderSize = static_cast<float>(commonMenu.m_border_size);
ConvertColor(menu.window.backColor, commonMenu.m_back_color);
ConvertColor(menu.window.foreColor, commonMenu.m_fore_color);
ConvertColor(menu.window.borderColor, commonMenu.m_border_color);
ConvertColor(menu.focusColor, commonMenu.m_focus_color);
menu.window.background = ConvertMaterial(commonMenu.m_background, &commonMenu);
menu.window.ownerDraw = commonMenu.m_owner_draw;
menu.window.ownerDrawFlags = commonMenu.m_owner_draw_flags;
ApplyFlag(menu.window.staticFlags, commonMenu.m_out_of_bounds_click, WINDOW_FLAG_OUT_OF_BOUNDS_CLICK);
menu.soundName = ConvertString(commonMenu.m_sound_loop);
ApplyFlag(menu.window.staticFlags, commonMenu.m_popup, WINDOW_FLAG_POPUP);
menu.fadeClamp = static_cast<float>(commonMenu.m_fade_clamp);
menu.fadeCycle = commonMenu.m_fade_cycle;
menu.fadeAmount = static_cast<float>(commonMenu.m_fade_amount);
menu.fadeInAmount = static_cast<float>(commonMenu.m_fade_in_amount);
menu.blurRadius = static_cast<float>(commonMenu.m_blur_radius);
ApplyFlag(menu.window.staticFlags, commonMenu.m_legacy_split_screen_scale, WINDOW_FLAG_LEGACY_SPLIT_SCREEN_SCALE);
ApplyFlag(menu.window.staticFlags, commonMenu.m_hidden_during_scope, WINDOW_FLAG_HIDDEN_DURING_SCOPE);
ApplyFlag(menu.window.staticFlags, commonMenu.m_hidden_during_flashbang, WINDOW_FLAG_HIDDEN_DURING_FLASH_BANG);
ApplyFlag(menu.window.staticFlags, commonMenu.m_hidden_during_ui, WINDOW_FLAG_HIDDEN_DURING_UI);
menu.allowedBinding = ConvertString(commonMenu.m_allowed_binding);
ApplyFlag(menu.window.staticFlags, commonMenu.m_text_only_focus, WINDOW_FLAG_TEXT_ONLY_FOCUS);
menu.visibleExp = ConvertVisibleExpression(&menu.window, commonMenu.m_visible_expression.get(), &commonMenu);
menu.rectXExp = ConvertOrApplyStatement(menu.window.rect.x, commonMenu.m_rect_x_exp.get(), &commonMenu);
menu.rectYExp = ConvertOrApplyStatement(menu.window.rect.y, commonMenu.m_rect_y_exp.get(), &commonMenu);
menu.rectWExp = ConvertOrApplyStatement(menu.window.rect.w, commonMenu.m_rect_w_exp.get(), &commonMenu);
menu.rectHExp = ConvertOrApplyStatement(menu.window.rect.h, commonMenu.m_rect_h_exp.get(), &commonMenu);
menu.openSoundExp = ConvertExpression(commonMenu.m_open_sound_exp.get(), &commonMenu);
menu.closeSoundExp = ConvertExpression(commonMenu.m_close_sound_exp.get(), &commonMenu);
menu.onOpen = ConvertEventHandlerSet(commonMenu.m_on_open.get(), &commonMenu);
menu.onClose = ConvertEventHandlerSet(commonMenu.m_on_close.get(), &commonMenu);
menu.onCloseRequest = ConvertEventHandlerSet(commonMenu.m_on_request_close.get(), &commonMenu);
menu.onESC = ConvertEventHandlerSet(commonMenu.m_on_esc.get(), &commonMenu);
menu.onKey = ConvertKeyHandler(commonMenu.m_key_handlers, &commonMenu);
menu.items = ConvertMenuItems(commonMenu, menu.itemCount);
menu.expressionData = m_conversion_zone_state->m_supporting_data;
}
catch (const MenuConversionException& e)
{
PrintConversionExceptionDetails(e);
}
}
std::vector<XAssetInfoGeneric*> m_dependencies;
MenuConversionZoneState* m_conversion_zone_state;
MenuAssetZoneState* m_parsing_zone_state;
};
} // namespace IW4
} // namespace
MenuConverter::MenuConverter(const bool disableOptimizations, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager)
: m_disable_optimizations(disableOptimizations),
m_search_path(searchPath),
m_memory(memory),
m_manager(manager)
std::unique_ptr<IMenuConverter> IMenuConverter::Create(bool disableOptimizations, ISearchPath& searchPath, MemoryManager& memory, AssetCreationContext& context)
{
}
std::vector<XAssetInfoGeneric*>& MenuConverter::GetDependencies()
{
return m_dependencies;
}
menuDef_t* MenuConverter::ConvertMenu(const CommonMenuDef& commonMenu)
{
MenuConverterImpl impl(m_disable_optimizations, m_search_path, m_memory, m_manager);
try
{
auto* result = impl.ConvertMenu(commonMenu);
m_dependencies = std::move(impl.m_dependencies);
return result;
}
catch (const MenuConversionException& e)
{
MenuConverterImpl::PrintConversionExceptionDetails(e);
}
return nullptr;
return std::make_unique<MenuConverter>(disableOptimizations, searchPath, memory, context);
}