Add half-baked menu caching writer

This commit is contained in:
Jan 2024-01-13 22:56:41 +01:00
parent 48d320c99d
commit ecfcf940a4
No known key found for this signature in database
GPG Key ID: 44B581F78FF5C57C
5 changed files with 356 additions and 0 deletions

View File

@ -0,0 +1,42 @@
#include "AbstractCacheWriter.h"
using namespace cache;
AbstractCacheWriter::AbstractCacheWriter(std::ostream& stream)
: m_stream(stream)
{
}
void AbstractCacheWriter::Write(const void* data, const size_t dataSize) const
{
m_stream.write(static_cast<const char*>(data), dataSize);
}
void AbstractCacheWriter::WriteString(const char* str) const
{
if (!str)
return;
const auto len = strnlen(str, 0xFFFF);
Write(&len, sizeof(len));
Write(str, len);
}
void AbstractCacheWriter::WriteBool(const bool value) const
{
m_stream << (value ? '\x01' : '\x00');
}
void AbstractCacheWriter::WriteFalse() const
{
WriteBool(false);
}
void AbstractCacheWriter::WriteTrue() const
{
WriteBool(true);
}
void AbstractCacheWriter::WriteFileDependency(const std::string& dependencyName, uint64_t timestamp) const {}
void AbstractCacheWriter::WriteGdtDependency(const std::string& dependencyName, uint32_t crc32) const {}

View File

@ -0,0 +1,25 @@
#pragma once
#include <ostream>
#include <string>
namespace cache
{
class AbstractCacheWriter
{
protected:
explicit AbstractCacheWriter(std::ostream& stream);
void WriteFileDependency(const std::string& dependencyName, uint64_t timestamp) const;
void WriteGdtDependency(const std::string& dependencyName, uint32_t crc32) const;
void Write(const void* data, size_t dataSize) const;
void WriteString(const char* str) const;
void WriteBool(bool value) const;
void WriteTrue() const;
void WriteFalse() const;
std::ostream& m_stream;
};
} // namespace cache

View File

@ -0,0 +1,263 @@
#include "MenuCacheWriter.h"
using namespace IW4;
MenuCacheWriter::MenuCacheWriter(std::ostream& stream)
: AbstractCacheWriter(stream)
{
}
void MenuCacheWriter::WriteItemKeyHandler(const ItemKeyHandler& itemKeyHandler) const
{
Write(&itemKeyHandler, sizeof(ItemKeyHandler));
if (itemKeyHandler.action)
WriteMenuEventHandlerSet(*itemKeyHandler.action);
if (itemKeyHandler.next)
WriteItemKeyHandler(*itemKeyHandler.next);
}
void MenuCacheWriter::WriteStatement(const Statement_s& statement) const
{
Write(&statement, sizeof(Statement_s));
if (statement.entries && statement.numEntries > 0)
{
Write(statement.entries, sizeof(expressionEntry) * statement.numEntries);
for (auto i = 0; i < statement.numEntries; i++)
{
const auto& entry = statement.entries[i];
if (entry.type == EET_OPERAND)
{
if (entry.data.operand.dataType == VAL_STRING)
{
WriteString(entry.data.operand.internals.stringVal.string);
}
else if (entry.data.operand.dataType == VAL_FUNCTION)
{
if (entry.data.operand.internals.function)
WriteStatement(*entry.data.operand.internals.function);
}
}
}
}
// supportingData
}
void MenuCacheWriter::WriteMenuEventHandler(const MenuEventHandler& menuEventHandler) const
{
Write(&menuEventHandler, sizeof(MenuEventHandler));
switch (menuEventHandler.eventType)
{
case EVENT_UNCONDITIONAL:
WriteString(menuEventHandler.eventData.unconditionalScript);
break;
case EVENT_IF:
if (menuEventHandler.eventData.conditionalScript)
{
if (menuEventHandler.eventData.conditionalScript->eventHandlerSet)
{
WriteTrue();
WriteMenuEventHandlerSet(*menuEventHandler.eventData.conditionalScript->eventHandlerSet);
}
else
WriteFalse();
if (menuEventHandler.eventData.conditionalScript->eventExpression)
{
WriteTrue();
WriteStatement(*menuEventHandler.eventData.conditionalScript->eventExpression);
}
else
WriteFalse();
}
break;
case EVENT_ELSE:
if (menuEventHandler.eventData.elseScript)
WriteMenuEventHandlerSet(*menuEventHandler.eventData.elseScript);
break;
case EVENT_SET_LOCAL_VAR_BOOL:
case EVENT_SET_LOCAL_VAR_FLOAT:
case EVENT_SET_LOCAL_VAR_INT:
case EVENT_SET_LOCAL_VAR_STRING:
if (menuEventHandler.eventData.setLocalVarData)
{
WriteBool(menuEventHandler.eventData.setLocalVarData->localVarName != nullptr);
WriteString(menuEventHandler.eventData.setLocalVarData->localVarName);
if (menuEventHandler.eventData.setLocalVarData->expression)
{
WriteTrue();
WriteStatement(*menuEventHandler.eventData.setLocalVarData->expression);
}
else
WriteFalse();
}
break;
default:
break;
}
}
void MenuCacheWriter::WriteMenuEventHandlerSet(const MenuEventHandlerSet& menuEventHandlerSet) const
{
Write(&menuEventHandlerSet, sizeof(MenuEventHandlerSet));
if (menuEventHandlerSet.eventHandlers)
{
for (auto i = 0; i < menuEventHandlerSet.eventHandlerCount; i++)
{
if (menuEventHandlerSet.eventHandlers[i])
{
WriteTrue();
WriteMenuEventHandler(*menuEventHandlerSet.eventHandlers[i]);
}
else
WriteFalse();
}
}
}
void MenuCacheWriter::WriteWindowDef(const windowDef_t& windowDef) const
{
WriteString(windowDef.name);
WriteString(windowDef.group);
// background
}
void MenuCacheWriter::WriteItem(const itemDef_s& item) const
{
Write(&item, sizeof(item));
WriteWindowDef(item.window);
WriteString(item.text);
if (item.mouseEnterText)
WriteMenuEventHandlerSet(*item.mouseEnterText);
if (item.mouseExitText)
WriteMenuEventHandlerSet(*item.mouseExitText);
if (item.mouseEnter)
WriteMenuEventHandlerSet(*item.mouseEnter);
if (item.mouseExit)
WriteMenuEventHandlerSet(*item.mouseExit);
if (item.action)
WriteMenuEventHandlerSet(*item.action);
if (item.accept)
WriteMenuEventHandlerSet(*item.accept);
if (item.onFocus)
WriteMenuEventHandlerSet(*item.onFocus);
if (item.leaveFocus)
WriteMenuEventHandlerSet(*item.leaveFocus);
WriteString(item.dvar);
WriteString(item.dvarTest);
if (item.onKey)
WriteItemKeyHandler(*item.onKey);
WriteString(item.enableDvar);
WriteString(item.localVar);
// focusSound
// itemDefData
// floatExpressions
if (item.visibleExp)
WriteStatement(*item.visibleExp);
if (item.disabledExp)
WriteStatement(*item.disabledExp);
if (item.textExp)
WriteStatement(*item.textExp);
if (item.materialExp)
WriteStatement(*item.materialExp);
}
void MenuCacheWriter::WriteMenu(const menuDef_t& menu) const
{
Write(&menu, sizeof(menu));
// expressionData
WriteWindowDef(menu.window);
WriteString(menu.font);
if (menu.onOpen)
WriteMenuEventHandlerSet(*menu.onOpen);
if (menu.onClose)
WriteMenuEventHandlerSet(*menu.onClose);
if (menu.onCloseRequest)
WriteMenuEventHandlerSet(*menu.onCloseRequest);
if (menu.onESC)
WriteMenuEventHandlerSet(*menu.onESC);
if (menu.onKey)
WriteItemKeyHandler(*menu.onKey);
if (menu.visibleExp)
WriteStatement(*menu.visibleExp);
WriteString(menu.allowedBinding);
WriteString(menu.soundName);
if (menu.rectXExp)
WriteStatement(*menu.rectXExp);
if (menu.rectYExp)
WriteStatement(*menu.rectYExp);
if (menu.rectWExp)
WriteStatement(*menu.rectWExp);
if (menu.rectHExp)
WriteStatement(*menu.rectHExp);
if (menu.openSoundExp)
WriteStatement(*menu.openSoundExp);
if (menu.closeSoundExp)
WriteStatement(*menu.closeSoundExp);
if (menu.items)
{
for (auto i = 0; i < menu.itemCount; i++)
{
if (menu.items[i])
{
WriteTrue();
WriteItem(*menu.items[i]);
}
else
WriteFalse();
}
}
}

View File

@ -0,0 +1,25 @@
#pragma once
#include "Cache/AbstractCacheWriter.h"
#include "Game/IW4/IW4.h"
#include <ostream>
namespace IW4
{
class MenuCacheWriter : public cache::AbstractCacheWriter
{
public:
explicit MenuCacheWriter(std::ostream& stream);
void WriteStatement(const Statement_s& statement) const;
void WriteItemKeyHandler(const ItemKeyHandler& itemKeyHandler) const;
void WriteMenuEventHandler(const MenuEventHandler& menuEventHandler) const;
void WriteMenuEventHandlerSet(const MenuEventHandlerSet& menuEventHandlerSet) const;
void WriteWindowDef(const windowDef_t& windowDef) const;
void WriteItem(const itemDef_s& item) const;
void WriteMenu(const menuDef_t& menu) const;
};
} // namespace IW4

View File

@ -39,6 +39,7 @@
#include "Loading/Exception/UnsupportedAssetTypeException.h"
#include <cassert>
#include <iostream>
using namespace IW4;