IW5 support initial commit

This commit is contained in:
Jan 2021-07-23 01:12:36 +02:00
parent c6ea52018a
commit f201dfafd8
102 changed files with 8835 additions and 0 deletions

View File

View File

@ -0,0 +1,5 @@
#pragma once
namespace IW5
{
}

View File

@ -0,0 +1,43 @@
#include "GameIW5.h"
#include <algorithm>
#include "IW5.h"
using namespace IW5;
GameIW5 g_GameIW5;
std::string GameIW5::GetFullName()
{
return "Call Of Duty: Modern Warfare 3";
}
std::string GameIW5::GetShortName()
{
return "IW5";
}
void GameIW5::AddZone(Zone* zone)
{
m_zones.push_back(zone);
}
void GameIW5::RemoveZone(Zone* zone)
{
const auto foundEntry = std::find(m_zones.begin(), m_zones.end(), zone);
if (foundEntry != m_zones.end())
m_zones.erase(foundEntry);
}
std::vector<Zone*> GameIW5::GetZones()
{
return m_zones;
}
std::vector<GameLanguagePrefix> GameIW5::GetLanguagePrefixes()
{
std::vector<GameLanguagePrefix> prefixes;
return prefixes;
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "Game/IGame.h"
class GameIW5 : public IGame
{
std::vector<Zone*> m_zones;
public:
std::string GetFullName() override;
std::string GetShortName() override;
void AddZone(Zone* zone) override;
void RemoveZone(Zone* zone) override;
std::vector<Zone*> GetZones() override;
std::vector<GameLanguagePrefix> GetLanguagePrefixes() override;
};
extern GameIW5 g_GameIW5;

82
src/Common/Game/IW5/IW5.h Normal file
View File

@ -0,0 +1,82 @@
#pragma once
//#include <d3d11.h>
#include "Image/Texture.h"
#include "IW5_Assets.h"
namespace IW5
{
struct DB_AuthHash
{
char bytes[32];
};
struct DB_AuthSignature
{
char bytes[256];
};
struct DB_AuthSubHeader
{
char fastfileName[32];
unsigned int reserved;
DB_AuthHash masterBlockHashes[244];
};
struct DB_AuthHeader
{
char magic[8]; // + 0
unsigned int reserved; // + 8
DB_AuthHash subheaderHash; // + 12
DB_AuthSignature signedSubheaderHash; // + 44
DB_AuthSubHeader subheader; // + 300
};
struct ScriptStringList
{
int count;
const char** strings;
};
struct XAsset
{
XAssetType type;
XAssetHeader header;
};
struct XAssetList
{
ScriptStringList stringList;
int assetCount;
XAsset* assets;
};
struct cspField_t
{
const char* szName;
int iOffset;
int iFieldType;
};
enum csParseFieldType_t
{
CSPFT_STRING = 0,
CSPFT_STRING_MAX_STRING_CHARS,
CSPFT_STRING_MAX_QPATH,
CSPFT_STRING_MAX_OSPATH,
CSPFT_INT,
CSPFT_QBOOLEAN,
CSPFT_BOOL,
CSPFT_FLOAT,
CSPFT_MPH_TO_INCHES_PER_SEC,
CSPFT_MILLISECONDS,
CSPFT_FX,
CSPFT_XMODEL,
CSPFT_MATERIAL,
CSPFT_SOUND,
CSPFT_TRACER,
CSPFT_NUM_BASE_FIELD_TYPES,
};
}

File diff suppressed because it is too large Load Diff

View File

@ -20,6 +20,12 @@
#define memb_align(x) alignas(x)
#define gcc_align(x)
#else
#ifdef __ida
#define type_align(x) __declspec(align(x))
#define tdef_align(x) __declspec(align(x))
#define memb_align(x) __declspec(align(x))
#define gcc_align(x)
#else
#ifdef _MSVC_LANG
#define type_align(x) __declspec(align(x))
#define tdef_align(x) __declspec(align(x))
@ -31,4 +37,5 @@
#define memb_align(x) __attribute__((__aligned__(x)))
#define gcc_align(x) __attribute__((__aligned__(x)))
#endif
#endif
#endif

View File

@ -0,0 +1,95 @@
#include "ZoneCreatorIW5.h"
#include <iostream>
#include "ObjLoading.h"
#include "Game/IW5/GameIW5.h"
#include "Game/IW5/GameAssetPoolIW5.h"
using namespace IW5;
ZoneCreator::ZoneCreator()
{
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
{
AddAssetTypeName(assetType, GameAssetPoolIW5::AssetTypeNameByType(assetType));
}
}
void ZoneCreator::AddAssetTypeName(asset_type_t assetType, std::string name)
{
m_asset_types_by_name.emplace(std::make_pair(std::move(name), assetType));
}
std::vector<Gdt*> ZoneCreator::CreateGdtList(ZoneCreationContext& context)
{
std::vector<Gdt*> gdtList;
gdtList.reserve(context.m_gdt_files.size());
for (const auto& gdt : context.m_gdt_files)
gdtList.push_back(gdt.get());
return gdtList;
}
bool ZoneCreator::CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map<std::string, asset_type_t>& ignoredAssetMap) const
{
for (const auto& ignoreEntry : context.m_ignored_assets)
{
const auto foundAssetTypeEntry = m_asset_types_by_name.find(ignoreEntry.m_type);
if (foundAssetTypeEntry == m_asset_types_by_name.end())
{
std::cout << "Unknown asset type \"" << ignoreEntry.m_type << "\" for ignore \"" << ignoreEntry.m_name << "\"" << std::endl;
return false;
}
ignoredAssetMap[ignoreEntry.m_name] = foundAssetTypeEntry->second;
}
return true;
}
void ZoneCreator::CreateZoneAssetPools(Zone* zone) const
{
zone->m_pools = std::make_unique<GameAssetPoolIW5>(zone, zone->m_priority);
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
zone->m_pools->InitPoolDynamic(assetType);
}
bool ZoneCreator::SupportsGame(const std::string& gameName) const
{
return gameName == g_GameIW5.GetShortName();
}
std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const
{
auto zone = std::make_unique<Zone>(context.m_zone_name, 0, &g_GameIW5);
CreateZoneAssetPools(zone.get());
for (const auto& assetEntry : context.m_definition->m_assets)
{
if (!assetEntry.m_is_reference)
continue;
context.m_ignored_assets.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name);
}
const auto assetLoadingContext = std::make_unique<AssetLoadingContext>(zone.get(), context.m_asset_search_path, CreateGdtList(context));
if (!CreateIgnoredAssetMap(context, assetLoadingContext->m_ignored_asset_map))
return nullptr;
for (const auto& assetEntry : context.m_definition->m_assets)
{
const auto foundAssetTypeEntry = m_asset_types_by_name.find(assetEntry.m_asset_type);
if (foundAssetTypeEntry == m_asset_types_by_name.end())
{
std::cout << "Unknown asset type \"" << assetEntry.m_asset_type << "\"" << std::endl;
return nullptr;
}
if (!ObjLoading::LoadAssetForZone(assetLoadingContext.get(), foundAssetTypeEntry->second, assetEntry.m_asset_name))
return nullptr;
}
return zone;
}

View File

@ -0,0 +1,25 @@
#pragma once
#include <unordered_map>
#include <string>
#include "Zone/ZoneTypes.h"
#include "ZoneCreation/IZoneCreator.h"
namespace IW5
{
class ZoneCreator final : public IZoneCreator
{
std::unordered_map<std::string, asset_type_t> m_asset_types_by_name;
void AddAssetTypeName(asset_type_t assetType, std::string name);
static std::vector<Gdt*> CreateGdtList(ZoneCreationContext& context);
bool CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map<std::string, asset_type_t>& ignoredAssetMap) const;
void CreateZoneAssetPools(Zone* zone) const;
public:
ZoneCreator();
_NODISCARD bool SupportsGame(const std::string& gameName) const override;
_NODISCARD std::unique_ptr<Zone> CreateZoneForDefinition(ZoneCreationContext& context) const override;
};
}

View File

@ -20,6 +20,7 @@
#include "ZoneCreation/ZoneCreationContext.h"
#include "ZoneCreation/IZoneCreator.h"
#include "Game/IW4/ZoneCreatorIW4.h"
#include "Game/IW5/ZoneCreatorIW5.h"
#include "Game/T5/ZoneCreatorT5.h"
#include "Game/T6/ZoneCreatorT6.h"
@ -34,6 +35,7 @@ const IZoneCreator* const ZONE_CREATORS[]
{
new IW3::ZoneCreator(),
new IW4::ZoneCreator(),
new IW5::ZoneCreator(),
new T5::ZoneCreator(),
new T6::ZoneCreator()
};

View File

@ -0,0 +1,51 @@
#include "AssetLoaderLocalizeEntry.h"
#include <sstream>
#include "Localize/LocalizeCommon.h"
#include "Parsing/LocalizeFile/LocalizeFileReader.h"
using namespace IW5;
XAssetInfoGeneric* AssetLoaderLocalizeEntry::LoadFromGlobalAssetPools(const std::string& assetName) const
{
return nullptr;
}
void* AssetLoaderLocalizeEntry::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
{
return nullptr;
}
bool AssetLoaderLocalizeEntry::CanLoadFromRaw() const
{
return true;
}
bool AssetLoaderLocalizeEntry::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
{
std::string fileName;
{
std::ostringstream str;
str << LocalizeCommon::GetNameOfLanguage(zone->m_language) << "/localizedstrings/" << assetName << ".str";
fileName = str.str();
}
const auto file = searchPath->Open(fileName);
if (!file.IsOpen())
return false;
LocalizeFileReader reader(*file.m_stream, assetName, zone->m_language);
const auto localizeEntries = reader.ReadLocalizeFile();
for (const auto& entry : localizeEntries)
{
auto* localizeEntry = memory->Create<LocalizeEntry>();
localizeEntry->name = memory->Dup(entry.m_key.c_str());
localizeEntry->value = memory->Dup(entry.m_value.c_str());
manager->AddAsset(ASSET_TYPE_LOCALIZE_ENTRY, entry.m_key, localizeEntry);
}
return true;
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "Game/IW5/IW5.h"
#include "AssetLoading/BasicAssetLoader.h"
#include "AssetLoading/IAssetLoadingManager.h"
#include "SearchPath/ISearchPath.h"
namespace IW5
{
class AssetLoaderLocalizeEntry final : public BasicAssetLoader<ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry>
{
public:
_NODISCARD XAssetInfoGeneric* LoadFromGlobalAssetPools(const std::string& assetName) const override;
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
_NODISCARD bool CanLoadFromRaw() const override;
bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
};
}

View File

@ -0,0 +1,43 @@
#include "AssetLoaderRawFile.h"
#include <cstring>
#include "Game/IW5/IW5.h"
#include "Pool/GlobalAssetPool.h"
using namespace IW5;
void* AssetLoaderRawFile::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
{
auto* rawFile = memory->Create<RawFile>();
memset(rawFile, 0, sizeof(RawFile));
rawFile->name = memory->Dup(assetName.c_str());
return rawFile;
}
bool AssetLoaderRawFile::CanLoadFromRaw() const
{
return true;
}
bool AssetLoaderRawFile::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
{
const auto file = searchPath->Open(assetName);
if (!file.IsOpen())
return false;
auto* rawFile = memory->Create<RawFile>();
rawFile->name = memory->Dup(assetName.c_str());
rawFile->len = static_cast<int>(file.m_length);
auto* fileBuffer = static_cast<char*>(memory->Alloc(static_cast<size_t>(file.m_length + 1)));
file.m_stream->read(fileBuffer, file.m_length);
if (file.m_stream->gcount() != file.m_length)
return false;
fileBuffer[rawFile->len] = '\0';
rawFile->data.buffer = fileBuffer;
manager->AddAsset(ASSET_TYPE_RAWFILE, assetName, rawFile);
return true;
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "Game/IW5/IW5.h"
#include "AssetLoading/BasicAssetLoader.h"
#include "AssetLoading/IAssetLoadingManager.h"
#include "SearchPath/ISearchPath.h"
namespace IW5
{
class AssetLoaderRawFile final : public BasicAssetLoader<ASSET_TYPE_RAWFILE, RawFile>
{
public:
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
_NODISCARD bool CanLoadFromRaw() const override;
bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
};
}

View File

@ -0,0 +1,4 @@
#include "InfoStringToStructConverter.h"
using namespace IW5;

View File

@ -0,0 +1,25 @@
#pragma once
#include "AssetLoading/IAssetLoadingManager.h"
#include "InfoString/InfoStringToStructConverterBase.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class InfoStringToStructConverter : public InfoStringToStructConverterBase
{
protected:
IAssetLoadingManager* m_loading_manager;
const cspField_t* m_fields;
size_t m_field_count;
static bool GetHashValue(const std::string& value, unsigned int& hash);
virtual bool ConvertExtensionField(const cspField_t& field, const std::string& value) = 0;
bool ConvertBaseField(const cspField_t& field, const std::string& value);
public:
InfoStringToStructConverter(const InfoString& infoString, void* structure, ZoneScriptStrings& zoneScriptStrings, MemoryManager* memory, IAssetLoadingManager* manager, const cspField_t* fields,
size_t fieldCount);
bool Convert() override;
};
}

View File

@ -0,0 +1,193 @@
#include "ObjLoaderIW5.h"
#include "Game/IW5/GameIW5.h"
#include "Game/IW5/GameAssetPoolIW5.h"
#include "ObjContainer/IPak/IPak.h"
#include "ObjLoading.h"
#include "AssetLoaders/AssetLoaderLocalizeEntry.h"
#include "AssetLoaders/AssetLoaderRawFile.h"
#include "AssetLoading/AssetLoadingManager.h"
#include "Image/Dx9TextureLoader.h"
#include "Image/Texture.h"
#include "Image/IwiLoader.h"
#include "Image/IwiTypes.h"
using namespace IW5;
ObjLoader::ObjLoader()
{
#define REGISTER_ASSET_LOADER(t) {auto l = std::make_unique<t>(); m_asset_loaders_by_type[l->GetHandlingAssetType()] = std::move(l);}
#define BASIC_LOADER(assetType, assetClass) BasicAssetLoader<assetType, assetClass>
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_PHYSPRESET, PhysPreset))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_PHYSCOLLMAP, PhysCollmap))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_XANIMPARTS, XAnimParts))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_XMODEL_SURFS, XModelSurfs))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_XMODEL, XModel))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MATERIAL, Material))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_PIXELSHADER, MaterialPixelShader))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_VERTEXSHADER, MaterialVertexShader))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_VERTEXDECL, MaterialVertexDeclaration))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_IMAGE, GfxImage))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SOUND, snd_alias_list_t))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SOUND_CURVE, SndCurve))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LOADED_SOUND, LoadedSound))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_CLIPMAP, clipMap_t))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_COMWORLD, ComWorld))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_GLASSWORLD, GlassWorld))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_PATHDATA, PathData))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_VEHICLE_TRACK, VehicleTrack))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MAP_ENTS, MapEnts))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FXWORLD, FxWorld))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_GFXWORLD, GfxWorld))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LIGHT_DEF, GfxLightDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FONT, Font_s))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MENULIST, MenuList))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MENU, menuDef_t))
REGISTER_ASSET_LOADER(AssetLoaderLocalizeEntry)
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_ATTACHMENT, WeaponAttachment))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_WEAPON, WeaponCompleteDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FX, FxEffectDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_IMPACT_FX, FxImpactTable))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SURFACE_FX, SurfaceFxTable))
REGISTER_ASSET_LOADER(AssetLoaderRawFile)
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SCRIPTFILE, ScriptFile))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_STRINGTABLE, StringTable))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LEADERBOARD, LeaderboardDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_STRUCTURED_DATA_DEF, StructuredDataDefSet))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_TRACER, TracerDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_VEHICLE, VehicleDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_ADDON_MAP_ENTS, AddonMapEnts))
#undef BASIC_LOADER
#undef REGISTER_ASSET_LOADER
}
bool ObjLoader::SupportsZone(Zone* zone) const
{
return zone->m_game == &g_GameIW5;
}
bool ObjLoader::IsMpZone(Zone* zone)
{
return zone->m_name.compare(0, 3, "mp_") == 0
|| zone->m_name.compare(zone->m_name.length() - 3, 3, "_mp") == 0;
}
bool ObjLoader::IsZmZone(Zone* zone)
{
return zone->m_name.compare(0, 3, "zm_") == 0
|| zone->m_name.compare(zone->m_name.length() - 3, 3, "_zm") == 0;
}
void ObjLoader::LoadReferencedContainersForZone(ISearchPath* searchPath, Zone* zone) const
{
}
void ObjLoader::UnloadContainersOfZone(Zone* zone) const
{
}
void ObjLoader::LoadImageFromLoadDef(GfxImage* image, Zone* zone)
{
const auto* loadDef = image->texture.loadDef;
Dx9TextureLoader textureLoader(zone->GetMemory());
textureLoader.Width(image->width).Height(image->height).Depth(image->depth);
if ((loadDef->flags & iwi8::IMG_FLAG_MAPTYPE_MASK) == iwi8::IMG_FLAG_MAPTYPE_3D)
textureLoader.Type(TextureType::T_3D);
else if ((loadDef->flags & iwi8::IMG_FLAG_MAPTYPE_MASK) == iwi8::IMG_FLAG_MAPTYPE_CUBE)
textureLoader.Type(TextureType::T_CUBE);
else
textureLoader.Type(TextureType::T_2D);
textureLoader.Format(static_cast<D3DFORMAT>(loadDef->format));
textureLoader.HasMipMaps(!(loadDef->flags & iwi8::IMG_FLAG_NOMIPMAPS));
Texture* loadedTexture = textureLoader.LoadTexture(image->texture.loadDef->data);
if (loadedTexture != nullptr)
{
image->texture.texture = loadedTexture;
image->cardMemory.platform[0] = 0;
const auto textureMipCount = loadedTexture->GetMipMapCount();
for (auto mipLevel = 0; mipLevel < textureMipCount; mipLevel++)
image->cardMemory.platform[0] += static_cast<int>(loadedTexture->GetSizeOfMipLevel(mipLevel) * loadedTexture->GetFaceCount());
}
}
void ObjLoader::LoadImageFromIwi(GfxImage* image, ISearchPath* searchPath, Zone* zone)
{
Texture* loadedTexture = nullptr;
IwiLoader loader(zone->GetMemory());
const auto imageFileName = "images/" + std::string(image->name) + ".iwi";
{
const auto filePathImage = searchPath->Open(imageFileName);
if (filePathImage.IsOpen())
{
loadedTexture = loader.LoadIwi(*filePathImage.m_stream);
}
}
if (loadedTexture != nullptr)
{
image->texture.texture = loadedTexture;
image->cardMemory.platform[0] = 0;
const auto textureMipCount = loadedTexture->GetMipMapCount();
for (auto mipLevel = 0; mipLevel < textureMipCount; mipLevel++)
image->cardMemory.platform[0] += static_cast<int>(loadedTexture->GetSizeOfMipLevel(mipLevel) * loadedTexture->GetFaceCount());
}
else
{
printf("Could not find data for image \"%s\"\n", image->name);
}
}
void ObjLoader::LoadImageData(ISearchPath* searchPath, Zone* zone)
{
auto* assetPool = dynamic_cast<GameAssetPoolIW5*>(zone->m_pools.get());
if (assetPool && assetPool->m_image != nullptr)
{
for (auto* imageEntry : *assetPool->m_image)
{
auto* image = imageEntry->Asset();
if (image->cardMemory.platform[0] > 0)
{
continue;
}
// Do not load linked assets
if (image->name && image->name[0] == ',')
{
continue;
}
if (image->texture.loadDef && image->texture.loadDef->resourceSize > 0)
{
LoadImageFromLoadDef(image, zone);
}
else
{
LoadImageFromIwi(image, searchPath, zone);
}
}
}
}
void ObjLoader::LoadObjDataForZone(ISearchPath* searchPath, Zone* zone) const
{
LoadImageData(searchPath, zone);
}
bool ObjLoader::LoadAssetForZone(AssetLoadingContext* context, asset_type_t assetType, const std::string& assetName) const
{
AssetLoadingManager assetLoadingManager(m_asset_loaders_by_type, *context);
return assetLoadingManager.LoadAssetFromLoader(assetType, assetName);
}

View File

@ -0,0 +1,36 @@
#pragma once
#include <unordered_map>
#include <memory>
#include "IObjLoader.h"
#include "AssetLoading/IAssetLoader.h"
#include "SearchPath/ISearchPath.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class ObjLoader final : public IObjLoader
{
std::unordered_map<asset_type_t, std::unique_ptr<IAssetLoader>> m_asset_loaders_by_type;
static void LoadImageFromIwi(GfxImage* image, ISearchPath* searchPath, Zone* zone);
static void LoadImageFromLoadDef(GfxImage* image, Zone* zone);
static void LoadImageData(ISearchPath* searchPath, Zone* zone);
static bool IsMpZone(Zone* zone);
static bool IsZmZone(Zone* zone);
public:
ObjLoader();
bool SupportsZone(Zone* zone) const override;
void LoadReferencedContainersForZone(ISearchPath* searchPath, Zone* zone) const override;
void UnloadContainersOfZone(Zone* zone) const override;
void LoadObjDataForZone(ISearchPath* searchPath, Zone* zone) const override;
bool LoadAssetForZone(AssetLoadingContext* context, asset_type_t assetType, const std::string& assetName) const override;
};
}

View File

@ -5,6 +5,7 @@
#include "IObjLoader.h"
#include "Game/IW3/ObjLoaderIW3.h"
#include "Game/IW4/ObjLoaderIW4.h"
#include "Game/IW5/ObjLoaderIW5.h"
#include "Game/T5/ObjLoaderT5.h"
#include "Game/T6/ObjLoaderT6.h"
#include "ObjContainer/IWD/IWD.h"
@ -17,6 +18,7 @@ const IObjLoader* const OBJ_LOADERS[]
{
new IW3::ObjLoader(),
new IW4::ObjLoader(),
new IW5::ObjLoader(),
new T5::ObjLoader(),
new T6::ObjLoader()
};

View File

@ -0,0 +1,27 @@
#define NOMINMAX
#include "AssetDumperAddonMapEnts.h"
#include <algorithm>
using namespace IW5;
bool AssetDumperAddonMapEnts::ShouldDump(XAssetInfo<AddonMapEnts>* asset)
{
return true;
}
bool AssetDumperAddonMapEnts::CanDumpAsRaw()
{
return true;
}
std::string AssetDumperAddonMapEnts::GetFileNameForAsset(Zone* zone, XAssetInfo<AddonMapEnts>* asset)
{
return asset->m_name;
}
void AssetDumperAddonMapEnts::DumpRaw(AssetDumpingContext& context, XAssetInfo<AddonMapEnts>* asset, std::ostream& stream)
{
const auto* addonMapEnts = asset->Asset();
stream.write(addonMapEnts->entityString, std::max(addonMapEnts->numEntityChars - 1, 0));
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class AssetDumperAddonMapEnts final : public AbstractAssetDumper<AddonMapEnts>
{
protected:
bool ShouldDump(XAssetInfo<AddonMapEnts>* asset) override;
bool CanDumpAsRaw() override;
std::string GetFileNameForAsset(Zone* zone, XAssetInfo<AddonMapEnts>* asset) override;
void DumpRaw(AssetDumpingContext& context, XAssetInfo<AddonMapEnts>* asset, std::ostream& stream) override;
};
}

View File

@ -0,0 +1,62 @@
#include "AssetDumperGfxImage.h"
#include <cassert>
#include "ObjWriting.h"
#include "Image/IwiWriter8.h"
#include "Image/DdsWriter.h"
using namespace IW5;
AssetDumperGfxImage::AssetDumperGfxImage()
{
switch (ObjWriting::Configuration.ImageOutputFormat)
{
case ObjWriting::Configuration_t::ImageOutputFormat_e::DDS:
m_writer = std::make_unique<DdsWriter>();
break;
case ObjWriting::Configuration_t::ImageOutputFormat_e::IWI:
m_writer = std::make_unique<iwi8::IwiWriter>();
break;
default:
assert(false);
m_writer = nullptr;
break;
}
}
bool AssetDumperGfxImage::ShouldDump(XAssetInfo<GfxImage>* asset)
{
const auto* image = asset->Asset();
return image->cardMemory.platform[0] > 0;
}
bool AssetDumperGfxImage::CanDumpAsRaw()
{
return true;
}
std::string AssetDumperGfxImage::GetFileNameForAsset(Zone* zone, XAssetInfo<GfxImage>* asset)
{
std::string cleanAssetName = asset->m_name;
for (auto& c : cleanAssetName)
{
switch (c)
{
case '*':
c = '_';
break;
default:
break;
}
}
return "images/" + cleanAssetName + m_writer->GetFileExtension();
}
void AssetDumperGfxImage::DumpRaw(AssetDumpingContext& context, XAssetInfo<GfxImage>* asset, std::ostream& stream)
{
const auto* image = asset->Asset();
m_writer->DumpImage(stream, image->texture.texture);
}

View File

@ -0,0 +1,24 @@
#pragma once
#include <memory>
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
#include "Image/IImageWriter.h"
namespace IW5
{
class AssetDumperGfxImage final : public AbstractAssetDumper<GfxImage>
{
std::unique_ptr<IImageWriter> m_writer;
protected:
bool ShouldDump(XAssetInfo<GfxImage>* asset) override;
bool CanDumpAsRaw() override;
std::string GetFileNameForAsset(Zone* zone, XAssetInfo<GfxImage>* asset) override;
void DumpRaw(AssetDumpingContext& context, XAssetInfo<GfxImage>* asset, std::ostream& stream) override;
public:
AssetDumperGfxImage();
};
}

View File

@ -0,0 +1,76 @@
#include "AssetDumperLoadedSound.h"
#include "Sound/WavTypes.h"
using namespace IW5;
bool AssetDumperLoadedSound::ShouldDump(XAssetInfo<LoadedSound>* asset)
{
return true;
}
bool AssetDumperLoadedSound::CanDumpAsRaw()
{
return true;
}
std::string AssetDumperLoadedSound::GetFileNameForAsset(Zone* zone, XAssetInfo<LoadedSound>* asset)
{
return "sound/" + asset->m_name;
}
void AssetDumperLoadedSound::DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream)
{
const auto riffMasterChunkSize = sizeof(WAV_CHUNK_ID_RIFF)
+ sizeof(uint32_t)
+ sizeof(WAV_WAVE_ID)
+ sizeof(WavChunkHeader)
+ sizeof(WavFormatChunkPcm)
+ sizeof(WavChunkHeader)
+ sizeof(asset->sound.info.data_len);
stream.write(reinterpret_cast<const char*>(&WAV_CHUNK_ID_RIFF), sizeof(WAV_CHUNK_ID_RIFF));
stream.write(reinterpret_cast<const char*>(&riffMasterChunkSize), sizeof(riffMasterChunkSize));
stream.write(reinterpret_cast<const char*>(&WAV_WAVE_ID), sizeof(WAV_WAVE_ID));
const WavChunkHeader formatChunkHeader
{
WAV_CHUNK_ID_FMT,
sizeof(WavFormatChunkPcm)
};
stream.write(reinterpret_cast<const char*>(&formatChunkHeader), sizeof(formatChunkHeader));
WavFormatChunkPcm formatChunk
{
WavFormat::PCM,
static_cast<uint16_t>(asset->sound.info.channels),
asset->sound.info.rate,
asset->sound.info.rate * asset->sound.info.channels * asset->sound.info.bits / 8,
static_cast<uint16_t>(asset->sound.info.block_size),
static_cast<uint16_t>(asset->sound.info.bits)
};
stream.write(reinterpret_cast<const char*>(&formatChunk), sizeof(formatChunk));
const WavChunkHeader dataChunkHeader
{
WAV_CHUNK_ID_DATA,
asset->sound.info.data_len
};
stream.write(reinterpret_cast<const char*>(&dataChunkHeader), sizeof(dataChunkHeader));
stream.write(asset->sound.data, asset->sound.info.data_len);
}
void AssetDumperLoadedSound::DumpRaw(AssetDumpingContext& context, XAssetInfo<LoadedSound>* asset, std::ostream& stream)
{
const auto* loadedSound = asset->Asset();
switch (static_cast<WavFormat>(loadedSound->sound.info.format))
{
case WavFormat::PCM:
DumpWavPcm(context, loadedSound, stream);
break;
default:
printf("Unknown format %i for loaded sound: %s\n", loadedSound->sound.info.format, loadedSound->name);
break;
}
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class AssetDumperLoadedSound final : public AbstractAssetDumper<LoadedSound>
{
static void DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream);
protected:
bool ShouldDump(XAssetInfo<LoadedSound>* asset) override;
bool CanDumpAsRaw() override;
std::string GetFileNameForAsset(Zone* zone, XAssetInfo<LoadedSound>* asset) override;
void DumpRaw(AssetDumpingContext& context, XAssetInfo<LoadedSound>* asset, std::ostream& stream) override;
};
}

View File

@ -0,0 +1,53 @@
#include "AssetDumperLocalizeEntry.h"
#include <fstream>
#include <filesystem>
#include "Localize/LocalizeCommon.h"
#include "Dumping/Localize/StringFileDumper.h"
using namespace IW5;
namespace fs = std::filesystem;
void AssetDumperLocalizeEntry::DumpPool(AssetDumpingContext& context, AssetPool<LocalizeEntry>* pool)
{
if (pool->m_asset_lookup.empty())
return;
const auto language = LocalizeCommon::GetNameOfLanguage(context.m_zone->m_language);
fs::path stringsPath(context.m_base_path);
stringsPath.append(language);
stringsPath.append("localizedstrings");
create_directories(stringsPath);
auto stringFilePath(stringsPath);
stringFilePath.append(context.m_zone->m_name + ".str");
std::ofstream stringFile(stringFilePath, std::fstream::out | std::ofstream::binary);
if (stringFile.is_open())
{
StringFileDumper stringFileDumper(context.m_zone, stringFile);
stringFileDumper.SetLanguageName(language);
// Magic string. Original string files do have this config file. The purpose of the config file is unknown though.
stringFileDumper.SetConfigFile(R"(C:\trees\cod3\cod3\bin\StringEd.cfg)");
stringFileDumper.SetNotes("");
for (auto* localizeEntry : *pool)
{
stringFileDumper.WriteLocalizeEntry(localizeEntry->m_name, localizeEntry->Asset()->value);
}
stringFileDumper.Finalize();
stringFile.close();
}
else
{
printf("Could not create string file for dumping localized strings of zone '%s'\n", context.m_zone->m_name.c_str());
}
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class AssetDumperLocalizeEntry final : public IAssetDumper<LocalizeEntry>
{
public:
void DumpPool(AssetDumpingContext& context, AssetPool<LocalizeEntry>* pool) override;
};
}

View File

@ -0,0 +1,70 @@
#include "AssetDumperRawFile.h"
#include <zlib.h>
#include <stdexcept>
using namespace IW5;
bool AssetDumperRawFile::ShouldDump(XAssetInfo<RawFile>* asset)
{
return true;
}
bool AssetDumperRawFile::CanDumpAsRaw()
{
return true;
}
std::string AssetDumperRawFile::GetFileNameForAsset(Zone* zone, XAssetInfo<RawFile>* asset)
{
return asset->m_name;
}
void AssetDumperRawFile::DumpRaw(AssetDumpingContext& context, XAssetInfo<RawFile>* asset, std::ostream& stream)
{
const auto* rawFile = asset->Asset();
if (rawFile->compressedLen > 0)
{
z_stream_s zs{};
zs.zalloc = Z_NULL;
zs.zfree = Z_NULL;
zs.opaque = Z_NULL;
zs.avail_in = 0;
zs.next_in = Z_NULL;
int ret = inflateInit(&zs);
if (ret != Z_OK)
{
throw std::runtime_error("Initializing inflate failed");
}
zs.next_in = reinterpret_cast<const Bytef*>(rawFile->data.compressedBuffer);
zs.avail_in = rawFile->compressedLen;
Bytef buffer[0x1000];
while (zs.avail_in > 0)
{
zs.next_out = buffer;
zs.avail_out = sizeof buffer;
ret = inflate(&zs, Z_SYNC_FLUSH);
if (ret < 0)
{
printf("Inflate failed for dumping rawfile '%s'\n", rawFile->name);
inflateEnd(&zs);
return;
}
stream.write(reinterpret_cast<char*>(buffer), sizeof buffer - zs.avail_out);
}
inflateEnd(&zs);
}
else if (rawFile->len > 0)
{
stream.write(rawFile->data.buffer, rawFile->len);
}
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class AssetDumperRawFile final : public AbstractAssetDumper<RawFile>
{
protected:
bool ShouldDump(XAssetInfo<RawFile>* asset) override;
bool CanDumpAsRaw() override;
std::string GetFileNameForAsset(Zone* zone, XAssetInfo<RawFile>* asset) override;
void DumpRaw(AssetDumpingContext& context, XAssetInfo<RawFile>* asset, std::ostream& stream) override;
};
}

View File

@ -0,0 +1,37 @@
#include "AssetDumperStringTable.h"
#include "Csv/CsvStream.h"
using namespace IW5;
bool AssetDumperStringTable::ShouldDump(XAssetInfo<StringTable>* asset)
{
return true;
}
bool AssetDumperStringTable::CanDumpAsRaw()
{
return true;
}
std::string AssetDumperStringTable::GetFileNameForAsset(Zone* zone, XAssetInfo<StringTable>* asset)
{
return asset->m_name;
}
void AssetDumperStringTable::DumpRaw(AssetDumpingContext& context, XAssetInfo<StringTable>* asset, std::ostream& stream)
{
const auto* stringTable = asset->Asset();
CsvOutputStream csv(stream);
for (auto row = 0; row < stringTable->rowCount; row++)
{
for (auto column = 0; column < stringTable->columnCount; column++)
{
const auto* cell = &stringTable->values[column + row * stringTable->columnCount];
csv.WriteColumn(cell->string);
}
csv.NextRow();
}
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class AssetDumperStringTable final : public AbstractAssetDumper<StringTable>
{
protected:
bool ShouldDump(XAssetInfo<StringTable>* asset) override;
bool CanDumpAsRaw() override;
std::string GetFileNameForAsset(Zone* zone, XAssetInfo<StringTable>* asset) override;
void DumpRaw(AssetDumpingContext& context, XAssetInfo<StringTable>* asset, std::ostream& stream) override;
};
}

View File

@ -0,0 +1,159 @@
#include "InfoStringFromStructConverter.h"
#include <cassert>
using namespace IW5;
void InfoStringFromStructConverter::FillFromBaseField(const cspField_t& field)
{
switch (static_cast<csParseFieldType_t>(field.iFieldType))
{
case CSPFT_STRING:
FillFromString(std::string(field.szName), field.iOffset);
break;
case CSPFT_STRING_MAX_STRING_CHARS:
FillFromStringBuffer(std::string(field.szName), field.iOffset, 1024);
break;
case CSPFT_STRING_MAX_QPATH:
FillFromStringBuffer(std::string(field.szName), field.iOffset, 64);
break;
case CSPFT_STRING_MAX_OSPATH:
FillFromStringBuffer(std::string(field.szName), field.iOffset, 256);
break;
case CSPFT_INT:
FillFromInt(std::string(field.szName), field.iOffset);
break;
case CSPFT_QBOOLEAN:
FillFromQBoolean(std::string(field.szName), field.iOffset);
break;
case CSPFT_BOOL:
FillFromBool(std::string(field.szName), field.iOffset);
break;
case CSPFT_FLOAT:
FillFromFloat(std::string(field.szName), field.iOffset);
break;
case CSPFT_MPH_TO_INCHES_PER_SEC:
{
const auto* num = reinterpret_cast<float*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
m_info_string.SetValueForKey(std::string(field.szName), std::to_string(*num / 17.6f));
break;
}
case CSPFT_MILLISECONDS:
FillFromMilliseconds(std::string(field.szName), field.iOffset);
break;
case CSPFT_FX:
{
const auto* fx = *reinterpret_cast<FxEffectDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
if (fx)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(fx->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_XMODEL:
{
const auto* model = *reinterpret_cast<XModel**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
if (model)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(model->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_MATERIAL:
{
const auto* material = *reinterpret_cast<Material**>(reinterpret_cast<uintptr_t>(m_structure) + field.
iOffset);
if (material)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(material->info.name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_PHYS_COLLMAP:
{
const auto* physCollMap = *reinterpret_cast<PhysCollmap**>(reinterpret_cast<uintptr_t>(m_structure) + field.
iOffset);
if (physCollMap)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(physCollMap->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_SOUND:
{
const auto* sndAlias = reinterpret_cast<SndAliasCustom*>(reinterpret_cast<uintptr_t>(m_structure) + field.
iOffset);
if (sndAlias->name)
m_info_string.SetValueForKey(std::string(field.szName), std::string(sndAlias->name->soundName));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_TRACER:
{
const auto* tracer = *reinterpret_cast<TracerDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.
iOffset);
if (tracer)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(tracer->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_NUM_BASE_FIELD_TYPES:
default:
assert(false);
break;
}
}
void InfoStringFromStructConverter::FillInfoString()
{
for (auto fieldIndex = 0u; fieldIndex < m_field_count; fieldIndex++)
{
const auto& field = m_fields[fieldIndex];
assert(field.iFieldType >= 0);
if (field.iFieldType < CSPFT_NUM_BASE_FIELD_TYPES)
FillFromBaseField(field);
else
FillFromExtensionField(field);
}
}
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields,
const size_t fieldCount)
: InfoStringFromStructConverterBase(structure),
m_fields(fields),
m_field_count(fieldCount)
{
}
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields, const size_t fieldCount,
std::function<std::string(scr_string_t)> scriptStringValueCallback)
: InfoStringFromStructConverterBase(structure, std::move(scriptStringValueCallback)),
m_fields(fields),
m_field_count(fieldCount)
{
}

View File

@ -0,0 +1,21 @@
#pragma once
#include "InfoString/InfoStringFromStructConverterBase.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class InfoStringFromStructConverter : public InfoStringFromStructConverterBase
{
protected:
const cspField_t* m_fields;
size_t m_field_count;
virtual void FillFromExtensionField(const cspField_t& field) = 0;
void FillFromBaseField(const cspField_t& field);
void FillInfoString() override;
public:
InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount);
InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount, std::function<std::string(scr_string_t)> scriptStringValueCallback);
};
}

View File

@ -0,0 +1,74 @@
#include "ZoneDumperIW5.h"
#include "Game/IW5/GameIW5.h"
#include "Game/IW5/GameAssetPoolIW5.h"
#include "AssetDumpers/AssetDumperAddonMapEnts.h"
#include "AssetDumpers/AssetDumperGfxImage.h"
#include "AssetDumpers/AssetDumperLoadedSound.h"
#include "AssetDumpers/AssetDumperLocalizeEntry.h"
#include "AssetDumpers/AssetDumperRawFile.h"
#include "AssetDumpers/AssetDumperStringTable.h"
using namespace IW5;
bool ZoneDumper::CanHandleZone(AssetDumpingContext& context) const
{
return context.m_zone->m_game == &g_GameIW5;
}
bool ZoneDumper::DumpZone(AssetDumpingContext& context) const
{
#define DUMP_ASSET_POOL(dumperType, poolName) \
if(assetPools->poolName) \
{ \
dumperType dumper; \
dumper.DumpPool(context, assetPools->poolName.get()); \
}
const auto* assetPools = dynamic_cast<GameAssetPoolIW5*>(context.m_zone->m_pools.get());
// DUMP_ASSET_POOL(AssetDumperPhysPreset, m_phys_preset)
// DUMP_ASSET_POOL(AssetDumperPhysCollmap, m_phys_collmap)
// DUMP_ASSET_POOL(AssetDumperXAnimParts, m_xanim_parts)
// DUMP_ASSET_POOL(AssetDumperXModelSurfs, m_xmodel_surfs)
// DUMP_ASSET_POOL(AssetDumperXModel, m_xmodel)
// DUMP_ASSET_POOL(AssetDumperMaterial, m_material)
// DUMP_ASSET_POOL(AssetDumperMaterialPixelShader, m_material_pixel_shader)
// DUMP_ASSET_POOL(AssetDumperMaterialVertexShader, m_material_vertex_shader)
// DUMP_ASSET_POOL(AssetDumperMaterialVertexDeclaration, m_material_vertex_decl)
// DUMP_ASSET_POOL(AssetDumperMaterialTechniqueSet, m_technique_set)
DUMP_ASSET_POOL(AssetDumperGfxImage, m_image)
// DUMP_ASSET_POOL(AssetDumpersnd_alias_list_t, m_sound)
// DUMP_ASSET_POOL(AssetDumperSndCurve, m_sound_curve)
DUMP_ASSET_POOL(AssetDumperLoadedSound, m_loaded_sound)
// DUMP_ASSET_POOL(AssetDumperclipMap_t, m_clip_map)
// DUMP_ASSET_POOL(AssetDumperComWorld, m_com_world)
// DUMP_ASSET_POOL(AssetDumperGlassWorld, m_glass_world)
// DUMP_ASSET_POOL(AssetDumperPathData, m_path_data)
// DUMP_ASSET_POOL(AssetDumperVehicleTrack, m_vehicle_track)
// DUMP_ASSET_POOL(AssetDumperMapEnts, m_map_ents)
// DUMP_ASSET_POOL(AssetDumperFxWorld, m_fx_world)
// DUMP_ASSET_POOL(AssetDumperGfxWorld, m_gfx_world)
// DUMP_ASSET_POOL(AssetDumperGfxLightDef, m_gfx_light_def)
// DUMP_ASSET_POOL(AssetDumperFont_s, m_font)
// DUMP_ASSET_POOL(AssetDumperMenuList, m_menu_list)
// DUMP_ASSET_POOL(AssetDumpermenuDef_t, m_menu_def)
DUMP_ASSET_POOL(AssetDumperLocalizeEntry, m_localize)
// DUMP_ASSET_POOL(AssetDumperWeaponAttachment, m_attachment)
// DUMP_ASSET_POOL(AssetDumperWeaponCompleteDef, m_weapon)
// DUMP_ASSET_POOL(AssetDumperFxEffectDef, m_fx)
// DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table)
// DUMP_ASSET_POOL(AssetDumperSurfaceFxTable, m_surface_fx_table)
DUMP_ASSET_POOL(AssetDumperRawFile, m_raw_file)
// DUMP_ASSET_POOL(AssetDumperScriptFile, m_script_file)
DUMP_ASSET_POOL(AssetDumperStringTable, m_string_table)
// DUMP_ASSET_POOL(AssetDumperLeaderboardDef, m_leaderboard)
// DUMP_ASSET_POOL(AssetDumperStructuredDataDefSet, m_structed_data_def_set)
// DUMP_ASSET_POOL(AssetDumperTracerDef, m_tracer)
// DUMP_ASSET_POOL(AssetDumperVehicleDef, m_vehicle)
DUMP_ASSET_POOL(AssetDumperAddonMapEnts, m_addon_map_ents)
return true;
#undef DUMP_ASSET_POOL
}

View File

@ -0,0 +1,12 @@
#pragma once
#include "Dumping/IZoneDumper.h"
namespace IW5
{
class ZoneDumper final : public IZoneDumper
{
public:
bool CanHandleZone(AssetDumpingContext& context) const override;
bool DumpZone(AssetDumpingContext& context) const override;
};
}

View File

@ -2,6 +2,7 @@
#include "Dumping/IZoneDumper.h"
#include "Game/IW3/ZoneDumperIW3.h"
#include "Game/IW4/ZoneDumperIW4.h"
#include "Game/IW5/ZoneDumperIW5.h"
#include "Game/T5/ZoneDumperT5.h"
#include "Game/T6/ZoneDumperT6.h"
@ -11,6 +12,7 @@ const IZoneDumper* const ZONE_DUMPER[]
{
new IW3::ZoneDumper(),
new IW4::ZoneDumper(),
new IW5::ZoneDumper(),
new T5::ZoneDumper(),
new T6::ZoneDumper()
};

View File

@ -0,0 +1,45 @@
#include "ZoneDefWriterIW5.h"
#include <cassert>
#include "Game/IW5/GameIW5.h"
#include "Game/IW5/GameAssetPoolIW5.h"
using namespace IW5;
bool ZoneDefWriter::CanHandleZone(Zone* zone) const
{
return zone->m_game == &g_GameIW5;
}
void ZoneDefWriter::WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const
{
}
void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const
{
const auto* pools = dynamic_cast<GameAssetPoolIW5*>(zone->m_pools.get());
assert(pools);
if (!pools)
return;
// Localized strings are all collected in one string file. So only add this to the zone file.
if (!pools->m_localize->m_asset_lookup.empty())
{
stream.WriteEntry(pools->GetAssetTypeName(ASSET_TYPE_LOCALIZE_ENTRY), zone->m_name);
}
for (const auto& asset : *pools)
{
switch (asset->m_type)
{
case ASSET_TYPE_LOCALIZE_ENTRY:
break;
default:
stream.WriteEntry(pools->GetAssetTypeName(asset->m_type), asset->m_name);
break;
}
}
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "ContentLister/ZoneDefWriter.h"
namespace IW5
{
class ZoneDefWriter final : public AbstractZoneDefWriter
{
protected:
void WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const override;
void WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const override;
public:
bool CanHandleZone(Zone* zone) const override;
};
}

View File

@ -18,6 +18,7 @@
#include "UnlinkerArgs.h"
#include "Game/IW3/ZoneDefWriterIW3.h"
#include "Game/IW4/ZoneDefWriterIW4.h"
#include "Game/IW5/ZoneDefWriterIW5.h"
#include "Game/T5/ZoneDefWriterT5.h"
#include "Game/T6/ZoneDefWriterT6.h"
#include "Utils/ObjFileStream.h"
@ -28,6 +29,7 @@ const IZoneDefWriter* const ZONE_DEF_WRITERS[]
{
new IW3::ZoneDefWriter(),
new IW4::ZoneDefWriter(),
new IW5::ZoneDefWriter(),
new T5::ZoneDefWriter(),
new T6::ZoneDefWriter()
};

View File

@ -67,6 +67,49 @@ ZoneCode.Assets = {
"AddonMapEnts"
},
IW5 = {
"PhysPreset",
"PhysCollmap",
"XAnimParts",
"XModelSurfs",
"XModel",
"Material",
"MaterialPixelShader",
"MaterialVertexShader",
"MaterialVertexDeclaration",
"MaterialTechniqueSet",
"GfxImage",
"snd_alias_list_t",
"SndCurve",
"LoadedSound",
"clipMap_t",
"ComWorld",
"GlassWorld",
"PathData",
"VehicleTrack",
"MapEnts",
"FxWorld",
"GfxWorld",
"GfxLightDef",
"Font_s",
"MenuList",
"menuDef_t",
"LocalizeEntry",
"WeaponAttachment",
"WeaponCompleteDef",
"FxEffectDef",
"FxImpactTable",
"SurfaceFxTable",
"RawFile",
"ScriptFile",
"StringTable",
"LeaderboardDef",
"StructuredDataDefSet",
"TracerDef",
"VehicleDef",
"AddonMapEnts",
},
T5 = {
"PhysPreset",
"PhysConstraints",
@ -278,6 +321,10 @@ function ZoneCode:project()
self:outputForAssets(self.Assets.IW4)
filter {}
filter "files:**/IW5.gen"
self:outputForAssets(self.Assets.IW5)
filter {}
filter "files:**/T5.gen"
self:outputForAssets(self.Assets.T5)
filter {}

View File

@ -0,0 +1 @@
# This file exists for automatically generating zone loading code.

View File

@ -0,0 +1,8 @@
#pragma once
// Entry point for IW5 code generation
#include "../Common.h"
#include "../../../Common/Game/IW5/IW5_Assets.h"
// EOF

View File

@ -0,0 +1,97 @@
// Game: Modern Warfare 3 (IW5)
game IW5;
architecture x86;
// Game Assets
asset PhysPreset ASSET_TYPE_PHYSPRESET;
asset PhysCollmap ASSET_TYPE_PHYSCOLLMAP;
asset XAnimParts ASSET_TYPE_XANIMPARTS;
asset XModelSurfs ASSET_TYPE_XMODEL_SURFS;
asset XModel ASSET_TYPE_XMODEL;
asset Material ASSET_TYPE_MATERIAL;
asset MaterialPixelShader ASSET_TYPE_PIXELSHADER;
asset MaterialVertexShader ASSET_TYPE_VERTEXSHADER;
asset MaterialVertexDeclaration ASSET_TYPE_VERTEXDECL;
asset MaterialTechniqueSet ASSET_TYPE_TECHNIQUE_SET;
asset GfxImage ASSET_TYPE_IMAGE;
asset snd_alias_list_t ASSET_TYPE_SOUND;
asset SndCurve ASSET_TYPE_SOUND_CURVE;
asset LoadedSound ASSET_TYPE_LOADED_SOUND;
asset clipMap_t ASSET_TYPE_CLIPMAP;
asset ComWorld ASSET_TYPE_COMWORLD;
asset GlassWorld ASSET_TYPE_GLASSWORLD;
asset PathData ASSET_TYPE_PATHDATA;
asset VehicleTrack ASSET_TYPE_VEHICLE_TRACK;
asset MapEnts ASSET_TYPE_MAP_ENTS;
asset FxWorld ASSET_TYPE_FXWORLD;
asset GfxWorld ASSET_TYPE_GFXWORLD;
asset GfxLightDef ASSET_TYPE_LIGHT_DEF;
asset Font_s ASSET_TYPE_FONT;
asset MenuList ASSET_TYPE_MENULIST;
asset menuDef_t ASSET_TYPE_MENU;
asset LocalizeEntry ASSET_TYPE_LOCALIZE_ENTRY;
asset WeaponAttachment ASSET_TYPE_ATTACHMENT;
asset WeaponCompleteDef ASSET_TYPE_WEAPON;
asset FxEffectDef ASSET_TYPE_FX;
asset FxImpactTable ASSET_TYPE_IMPACT_FX;
asset SurfaceFxTable ASSET_TYPE_SURFACE_FX;
asset RawFile ASSET_TYPE_RAWFILE;
asset ScriptFile ASSET_TYPE_SCRIPTFILE;
asset StringTable ASSET_TYPE_STRINGTABLE;
asset LeaderboardDef ASSET_TYPE_LEADERBOARD;
asset StructuredDataDefSet ASSET_TYPE_STRUCTURED_DATA_DEF;
asset TracerDef ASSET_TYPE_TRACER;
asset VehicleDef ASSET_TYPE_VEHICLE;
asset AddonMapEnts ASSET_TYPE_ADDON_MAP_ENTS;
// Setup blocks
block temp XFILE_BLOCK_TEMP default;
block normal XFILE_BLOCK_PHYSICAL;
block runtime XFILE_BLOCK_RUNTIME default;
block normal XFILE_BLOCK_VIRTUAL default;
block normal XFILE_BLOCK_LARGE;
block normal XFILE_BLOCK_CALLBACK;
block normal XFILE_BLOCK_SCRIPT;
#include "XAssets/PhysPreset.txt"
#include "XAssets/PhysCollmap.txt"
#include "XAssets/XAnimParts.txt"
#include "XAssets/XModelSurfs.txt"
#include "XAssets/XModel.txt"
#include "XAssets/Material.txt"
#include "XAssets/MaterialPixelShader.txt"
#include "XAssets/MaterialVertexShader.txt"
#include "XAssets/MaterialVertexDeclaration.txt"
#include "XAssets/MaterialTechniqueSet.txt"
#include "XAssets/GfxImage.txt"
#include "XAssets/snd_alias_list_t.txt"
#include "XAssets/SndCurve.txt"
#include "XAssets/LoadedSound.txt"
#include "XAssets/clipMap_t.txt"
#include "XAssets/ComWorld.txt"
#include "XAssets/GlassWorld.txt"
#include "XAssets/PathData.txt"
#include "XAssets/VehicleTrack.txt"
#include "XAssets/MapEnts.txt"
#include "XAssets/FxWorld.txt"
#include "XAssets/GfxWorld.txt"
#include "XAssets/GfxLightDef.txt"
#include "XAssets/Font_s.txt"
#include "XAssets/MenuList.txt"
#include "XAssets/menuDef_t.txt"
#include "XAssets/LocalizeEntry.txt"
#include "XAssets/WeaponAttachment.txt"
#include "XAssets/WeaponCompleteDef.txt"
#include "XAssets/FxEffectDef.txt"
#include "XAssets/FxImpactTable.txt"
#include "XAssets/SurfaceFxTable.txt"
#include "XAssets/RawFile.txt"
#include "XAssets/ScriptFile.txt"
#include "XAssets/StringTable.txt"
#include "XAssets/LeaderboardDef.txt"
#include "XAssets/StructuredDataDefSet.txt"
#include "XAssets/TracerDef.txt"
#include "XAssets/VehicleDef.txt"
#include "XAssets/AddonMapEnts.txt"
// EOF

View File

@ -0,0 +1,8 @@
// =========================================
// AddonMapEnts
// =========================================
use AddonMapEnts;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set count entityString numEntityChars;

View File

@ -0,0 +1,11 @@
// =========================================
// ComWorld
// =========================================
use ComWorld;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set count primaryLights primaryLightCount;
// ComPrimaryLight
set string ComPrimaryLight::defName;

View File

@ -0,0 +1,9 @@
// =========================================
// Font_s
// =========================================
use Font_s;
set block XFILE_BLOCK_TEMP;
set string fontName;
set name fontName;
set reusable glyphs;
set count glyphs glyphCount;

View File

@ -0,0 +1,50 @@
// =========================================
// FxEffectDef
// =========================================
use FxEffectDef;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set count elemDefs elemDefCountEmission + elemDefCountLooping + elemDefCountOneShot;
// FxElemDef
use FxElemDef;
set count velSamples velIntervalCount + 1;
set count visSamples visStateIntervalCount + 1;
// FxElemDefVisuals
use FxElemDefVisuals;
set condition markArray FxElemDef::elemType == FX_ELEM_TYPE_DECAL;
set count markArray FxElemDef::visualCount;
set condition array FxElemDef::visualCount > 1;
set count array FxElemDef::visualCount;
// FxElemVisuals
use FxElemVisuals;
set condition anonymous never;
set condition model FxElemDef::elemType == FX_ELEM_TYPE_MODEL;
set condition effectDef FxElemDef::elemType == FX_ELEM_TYPE_RUNNER;
set condition soundName FxElemDef::elemType == FX_ELEM_TYPE_SOUND;
set string soundName;
set condition material FxElemDef::elemType == FX_ELEM_TYPE_SPRITE_BILLBOARD
|| FxElemDef::elemType == FX_ELEM_TYPE_SPRITE_ORIENTED
|| FxElemDef::elemType == FX_ELEM_TYPE_TAIL
|| FxElemDef::elemType == FX_ELEM_TYPE_TRAIL
|| FxElemDef::elemType == FX_ELEM_TYPE_CLOUD
|| FxElemDef::elemType == FX_ELEM_TYPE_SPARK_CLOUD
|| FxElemDef::elemType == FX_ELEM_TYPE_SPARK_FOUNTAIN;
// FxEffectDefRef
use FxEffectDefRef;
set condition handle never;
set string name;
// FxElemExtendedDefPtr
use FxElemExtendedDefPtr;
set condition trailDef FxElemDef::elemType == FX_ELEM_TYPE_TRAIL;
set condition sparkFountainDef FxElemDef::elemType == FX_ELEM_TYPE_SPARK_FOUNTAIN;
// FxTrailDef
use FxTrailDef;
set count verts vertCount;
set count inds indCount;

View File

@ -0,0 +1,8 @@
// =========================================
// FxImpactTable
// =========================================
use FxImpactTable;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set count table 15;

View File

@ -0,0 +1,38 @@
// =========================================
// FxWorld
// =========================================
use FxWorld;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
// FxGlassSystem
use FxGlassSystem;
set count defs defCount;
set block piecePlaces XFILE_BLOCK_RUNTIME;
set count piecePlaces pieceLimit;
set block pieceStates XFILE_BLOCK_RUNTIME;
set count pieceStates pieceLimit;
set block pieceDynamics XFILE_BLOCK_RUNTIME;
set count pieceDynamics pieceLimit;
set block geoData XFILE_BLOCK_RUNTIME;
set count geoData geoDataLimit;
set block isInUse XFILE_BLOCK_RUNTIME;
set count isInUse pieceWordCount;
set block cellBits XFILE_BLOCK_RUNTIME;
set count cellBits pieceWordCount * cellCount;
set block visData XFILE_BLOCK_RUNTIME;
set count visData (pieceLimit + 15) / 16 * 16;
set block linkOrg XFILE_BLOCK_RUNTIME;
set count linkOrg pieceLimit;
set block halfThickness XFILE_BLOCK_RUNTIME;
set count halfThickness (pieceLimit + 3) / 4 * 4;
set count lightingHandles initPieceCount;
set count initPieceStates initPieceCount;
set count initGeoData initGeoDataCount;
// FxGlassDef
reorder FxGlassDef:
physPreset
material
materialShattered;

View File

@ -0,0 +1,22 @@
// =========================================
// GfxImage
// =========================================
use GfxImage;
set block XFILE_BLOCK_TEMP;
set action OnImageLoaded(GfxImage);
set string name;
set name name;
reorder:
name
texture;
// GfxTexture
use GfxTexture;
set reusable loadDef;
set block loadDef XFILE_BLOCK_TEMP;
set condition texture never;
// GfxImageLoadDef
use GfxImageLoadDef;
set action LoadImageData(GfxImageLoadDef, GfxImage);
set arraysize data resourceSize;

View File

@ -0,0 +1,7 @@
// =========================================
// GfxLightDef
// =========================================
use GfxLightDef;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;

View File

@ -0,0 +1,128 @@
// =========================================
// GfxWorld
// =========================================
use GfxWorld;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set string baseName;
set count skies skyCount;
set count aabbTreeCounts dpvsPlanes::cellCount;
set count aabbTrees dpvsPlanes::cellCount;
set count cells dpvsPlanes::cellCount;
set count models modelCount;
set count materialMemory materialMemoryCount;
set block cellCasterBits XFILE_BLOCK_RUNTIME;
set count cellCasterBits dpvsPlanes::cellCount * ((dpvsPlanes::cellCount + 31) / 32);
set block cellHasSunLitSurfsBits XFILE_BLOCK_RUNTIME;
set count cellHasSunLitSurfsBits (dpvsPlanes::cellCount + 31) / 32;
set block sceneDynModel XFILE_BLOCK_RUNTIME;
set count sceneDynModel dpvsDyn::dynEntClientCount[0];
set block sceneDynBrush XFILE_BLOCK_RUNTIME;
set count sceneDynBrush dpvsDyn::dynEntClientCount[1];
set block primaryLightEntityShadowVis XFILE_BLOCK_RUNTIME;
set count primaryLightEntityShadowVis (primaryLightCount - lastSunPrimaryLightIndex - 1) * 0x2000;
set block primaryLightDynEntShadowVis XFILE_BLOCK_RUNTIME;
set count primaryLightDynEntShadowVis[0] dpvsDyn::dynEntClientCount[0] * (primaryLightCount - lastSunPrimaryLightIndex - 1);
set count primaryLightDynEntShadowVis[1] dpvsDyn::dynEntClientCount[1] * (primaryLightCount - lastSunPrimaryLightIndex - 1);
set block nonSunPrimaryLightForModelDynEnt XFILE_BLOCK_RUNTIME;
set count nonSunPrimaryLightForModelDynEnt dpvsDyn::dynEntClientCount[0];
set count shadowGeom primaryLightCount;
set count lightRegion primaryLightCount;
set count heroOnlyLights heroOnlyLightCount;
// GfxSky
set count GfxSky::skyStartSurfs skySurfCount;
// GfxWorldDpvsPlanes
use GfxWorldDpvsPlanes;
set reusable planes;
set count planes GfxWorld::planeCount;
set count nodes GfxWorld::nodeCount;
set block sceneEntCellBits XFILE_BLOCK_RUNTIME;
set count sceneEntCellBits cellCount * 0x200;
// GfxCellTree
// Extremly dirty hack caused by IW doing an extremly dirty hack in their code as well.
// No idea why they decided to separate the count from the pointer that uses the count.
// Thank you Treyarch for doing better in your games at least.
set count GfxCellTree::aabbTree GfxWorld::aabbTreeCounts[GfxCellTree - GfxWorld::aabbTrees];
// GfxAabbTree
use GfxAabbTree;
set reusable smodelIndexes;
set count smodelIndexes smodelIndexCount;
// GfxCell
use GfxCell;
set count portals portalCount;
set count reflectionProbes reflectionProbeCount;
// GfxPortal
use GfxPortal;
set condition writable never;
set count vertices vertexCount;
// GfxWorldDraw
use GfxWorldDraw;
set count reflectionProbes reflectionProbeCount;
set count reflectionProbeOrigins reflectionProbeCount;
set block reflectionProbeTextures XFILE_BLOCK_RUNTIME;
set count reflectionProbeTextures reflectionProbeCount;
set count lightmaps lightmapCount;
set block lightmapPrimaryTextures XFILE_BLOCK_RUNTIME;
set count lightmapPrimaryTextures lightmapCount;
set block lightmapSecondaryTextures XFILE_BLOCK_RUNTIME;
set count lightmapSecondaryTextures lightmapCount;
set count vd::vertices vertexCount;
set condition vd::worldVb never;
set count vld::data vertexLayerDataSize;
set condition vld::layerVb never;
set count indices indexCount;
// GfxLightGrid
use GfxLightGrid;
set count rowDataStart maxs[rowAxis] - mins[rowAxis] + 1;
set count rawRowData rawRowDataSize;
set count entries entryCount;
set count colors colorCount;
// GfxShadowGeometry
use GfxShadowGeometry;
set count sortedSurfIndex surfaceCount;
set count smodelIndex smodelCount;
// GfxLightRegion
set count GfxLightRegion::hulls hullCount;
// GfxLightRegionHull
set count GfxLightRegionHull::axis axisCount;
// GfxWorldDpvsStatic
use GfxWorldDpvsStatic;
set block smodelVisData XFILE_BLOCK_RUNTIME;
set count smodelVisData smodelCount;
set block surfaceVisData XFILE_BLOCK_RUNTIME;
set count surfaceVisData staticSurfaceCount;
set count sortedSurfIndex staticSurfaceCount + staticSurfaceCountNoDecal;
set count smodelInsts smodelCount;
set count surfaces GfxWorld::surfaceCount;
set count surfacesBounds GfxWorld::surfaceCount;
set count smodelDrawInsts smodelCount;
set block surfaceMaterials XFILE_BLOCK_RUNTIME;
set count surfaceMaterials GfxWorld::surfaceCount;
set block surfaceCastsSunShadow XFILE_BLOCK_RUNTIME;
set count surfaceCastsSunShadow surfaceVisDataCount;
// GfxWorldDpvsDynamic
use GfxWorldDpvsDynamic;
set block dynEntCellBits XFILE_BLOCK_RUNTIME;
set count dynEntCellBits[0] dynEntClientWordCount[0] * GfxWorld::dpvsPlanes::cellCount;
set count dynEntCellBits[1] dynEntClientWordCount[1] * GfxWorld::dpvsPlanes::cellCount;
set block dynEntVisData XFILE_BLOCK_RUNTIME;
set count dynEntVisData[0][0] 32 * dynEntClientWordCount[0];
set count dynEntVisData[1][0] 32 * dynEntClientWordCount[1];
set count dynEntVisData[0][1] 32 * dynEntClientWordCount[0];
set count dynEntVisData[1][1] 32 * dynEntClientWordCount[1];
set count dynEntVisData[0][2] 32 * dynEntClientWordCount[0];
set count dynEntVisData[1][2] 32 * dynEntClientWordCount[1];

View File

@ -0,0 +1,7 @@
// =========================================
// GlassWorld
// =========================================
use GlassWorld;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;

View File

@ -0,0 +1,13 @@
// =========================================
// LeaderboardDef
// =========================================
use LeaderboardDef;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set count columns columnCount;
// LbColumnDef
use LbColumnDef;
set string name;
set string statName;

View File

@ -0,0 +1,16 @@
// =========================================
// LoadedSound
// =========================================
use LoadedSound;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
// MssSound
use MssSound;
set block data XFILE_BLOCK_TEMP;
set reusable data;
set count data info::data_len;
set condition info::data_ptr never;
set condition info::initial_ptr never;
set action SetSoundData(MssSound);

View File

@ -0,0 +1,8 @@
// =========================================
// LocalizeEntry
// =========================================
use LocalizeEntry;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set string value;

View File

@ -0,0 +1,18 @@
// =========================================
// MapEnts
// =========================================
use MapEnts;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set count entityString numEntityChars;
set count stages stageCount;
// MapTriggers
use MapTriggers;
set count models count;
set count hulls hullCount;
set count slabs slabCount;
// Stage
set string Stage::name;

View File

@ -0,0 +1,23 @@
// =========================================
// Material
// =========================================
use Material;
set block XFILE_BLOCK_TEMP;
set string info::name;
set name info::name;
set reusable textureTable;
set count textureTable textureCount;
set reusable constantTable;
set count constantTable constantCount;
set reusable stateBitsTable;
set count stateBitsTable stateBitsCount;
// MaterialTextureDef
use MaterialTextureDef;
set condition u::water semantic == TS_WATER_MAP;
set reusable u::water;
// water_t
use water_t;
set count H0 N * M;
set count wTerm N * M;

View File

@ -0,0 +1,13 @@
// =========================================
// MaterialPixelShader
// =========================================
use MaterialPixelShader;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
// GfxPixelShaderLoadDef
set count GfxPixelShaderLoadDef::program programSize;
// MaterialPixelShaderProgram
set condition MaterialPixelShaderProgram::ps never;

View File

@ -0,0 +1,27 @@
// =========================================
// MaterialTechniqueSet
// =========================================
use MaterialTechniqueSet;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set condition remappedTechniqueSet never;
set reusable techniques;
// MaterialTechnique
use MaterialTechnique;
set string name;
set arraysize passArray passCount;
reorder:
passArray
name;
// MaterialPass
use MaterialPass;
set count args perPrimArgCount + perObjArgCount + stableArgCount;
// MaterialShaderArgument
use MaterialShaderArgument;
set condition u::literalConst type == MTL_ARG_LITERAL_VERTEX_CONST
|| type == MTL_ARG_LITERAL_PIXEL_CONST;
set reusable u::literalConst;

View File

@ -0,0 +1,10 @@
// =========================================
// MaterialVertexDeclaration
// =========================================
use MaterialVertexDeclaration;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
// MaterialVertexStreamRouting
set condition MaterialVertexStreamRouting::decl never;

View File

@ -0,0 +1,13 @@
// =========================================
// MaterialVertexShader
// =========================================
use MaterialVertexShader;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
// GfxVertexShaderLoadDef
set count GfxVertexShaderLoadDef::program programSize;
// MaterialVertexShaderProgram
set condition MaterialVertexShaderProgram::vs never;

View File

@ -0,0 +1,8 @@
// =========================================
// MenuList
// =========================================
use MenuList;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set count menus menuCount;

View File

@ -0,0 +1,7 @@
// =========================================
// PathData
// =========================================
use PathData;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;

View File

@ -0,0 +1,27 @@
// =========================================
// PhysCollmap
// =========================================
use PhysCollmap;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set count geoms count;
// PhysGeomInfo
use PhysGeomInfo;
set count brushWrapper 1;
// BrushWrapper
use BrushWrapper;
set reusable planes;
set count planes brush::numsides;
// cbrushWrapper_t
use cbrushWrapper_t;
set count sides numsides;
set count baseAdjacentSide BrushWrapper::totalEdgeCount;
// cbrushside_t
use cbrushside_t;
set reusable plane;
set count plane 1;

View File

@ -0,0 +1,8 @@
// =========================================
// PhysPreset
// =========================================
use PhysPreset;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set string sndAliasPrefix;

View File

@ -0,0 +1,10 @@
// =========================================
// RawFile
// =========================================
use RawFile;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set condition data::compressedBuffer compressedLen > 0;
set count data::compressedBuffer compressedLen;
set count data::buffer len + 1;

View File

@ -0,0 +1,7 @@
// =========================================
// ScriptFile
// =========================================
use ScriptFile;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;

View File

@ -0,0 +1,7 @@
// =========================================
// SndCurve
// =========================================
use SndCurve;
set block XFILE_BLOCK_TEMP;
set string filename;
set name filename;

View File

@ -0,0 +1,11 @@
// =========================================
// StringTable
// =========================================
use StringTable;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set count values columnCount * rowCount;
// StringTableCell
set string StringTableCell::string;

View File

@ -0,0 +1,27 @@
// =========================================
// StructuredDataDefSet
// =========================================
use StructuredDataDefSet;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set count defs defCount;
// StructuredDataDef
use StructuredDataDef;
set count enums enumCount;
set count structs structCount;
set count indexedArrays indexedArrayCount;
set count enumedArrays enumedArrayCount;
// StructuredDataEnum
set count StructuredDataEnum::entries entryCount;
// StructuredDataEnumEntry
set string StructuredDataEnumEntry::string;
// StructuredDataStruct
set count StructuredDataStruct::properties propertyCount;
// StructuredDataStructProperty
set string StructuredDataStructProperty::name;

View File

@ -0,0 +1,7 @@
// =========================================
// SurfaceFxTable
// =========================================
use SurfaceFxTable;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;

View File

@ -0,0 +1,7 @@
// =========================================
// TracerDef
// =========================================
use TracerDef;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;

View File

@ -0,0 +1,16 @@
// =========================================
// VehicleDef
// =========================================
use VehicleDef;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set string useHintString;
set string turretWeaponName;
set scriptstring trophyTags;
set string surfaceSndPrefix;
// VehiclePhysDef
use VehiclePhysDef;
set string physPresetName;
set string accelGraphName;

View File

@ -0,0 +1,7 @@
// =========================================
// VehicleTrack
// =========================================
use VehicleTrack;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;

View File

@ -0,0 +1,7 @@
// =========================================
// WeaponAttachment
// =========================================
use WeaponAttachment;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;

View File

@ -0,0 +1,84 @@
// =========================================
// WeaponCompleteDef
// =========================================
use WeaponCompleteDef;
set block XFILE_BLOCK_TEMP;
set string szInternalName;
set name szInternalName;
set reusable weapDef;
set string szDisplayName;
set reusable hideTags;
set scriptstring hideTags;
set count hideTags 32;
set string szXAnims;
set reusable szXAnims;
set count szXAnims 37;
set string szAltWeaponName;
set reusable accuracyGraphKnots;
set count accuracyGraphKnots[0] accuracyGraphKnotCount[0];
set count accuracyGraphKnots[1] accuracyGraphKnotCount[1];
// WeaponDef
use WeaponDef;
set string szOverlayName;
set reusable gunXModel;
set count gunXModel 16;
set reusable szXAnimsRightHanded;
set string szXAnimsRightHanded;
set count szXAnimsRightHanded 37;
set reusable szXAnimsLeftHanded;
set string szXAnimsLeftHanded;
set count szXAnimsLeftHanded 37;
set string szModeName;
set reusable notetrackSoundMapKeys;
set scriptstring notetrackSoundMapKeys;
set count notetrackSoundMapKeys 16;
set reusable notetrackSoundMapValues;
set scriptstring notetrackSoundMapValues;
set count notetrackSoundMapValues 16;
set reusable notetrackRumbleMapKeys;
set scriptstring notetrackRumbleMapKeys;
set count notetrackRumbleMapKeys 16;
set reusable notetrackRumbleMapValues;
set scriptstring notetrackRumbleMapValues;
set count notetrackRumbleMapValues 16;
set reusable bounceSound;
set count bounceSound 31;
set reusable worldModel;
set count worldModel 16;
set string szAmmoName;
set string szClipName;
set string szSharedAmmoCapName;
set reusable parallelBounce;
set count parallelBounce 31;
set reusable perpendicularBounce;
set count perpendicularBounce 31;
set string accuracyGraphName0;
set string accuracyGraphName1;
set reusable originalAccuracyGraphKnots0;
set reusable originalAccuracyGraphKnots1;
set count originalAccuracyGraphKnots0 WeaponCompleteDef::accuracyGraphKnotCount[0];
set count originalAccuracyGraphKnots1 WeaponCompleteDef::accuracyGraphKnotCount[1];
set string szUseHintString;
set string dropHintString;
set string szScript;
set reusable locationDamageMultipliers;
set count locationDamageMultipliers 20;
set string fireRumble;
set string meleeImpactRumble;
set string turretBarrelSpinRumble;
reorder:
...
accuracyGraphName0
originalAccuracyGraphKnots0
accuracyGraphName1
originalAccuracyGraphKnots1;
// SndAliasCustom
use SndAliasCustom;
set count name 1;
set reusable name;
set condition sound never;
// snd_alias_list_name
set string snd_alias_list_name::soundName;

View File

@ -0,0 +1,83 @@
// =========================================
// XAnimParts
// =========================================
use XAnimParts;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set scriptstring names;
set count names boneCount[9];
set count notify notifyCount;
set count deltaPart 1;
set count dataByte dataByteCount;
set count dataShort dataShortCount;
set count dataInt dataIntCount;
set count randomDataShort randomDataShortCount;
set count randomDataByte randomDataByteCount;
set count randomDataInt randomDataIntCount;
set count indices::_1 indexCount;
set count indices::_2 indexCount;
set condition indices::_1 numframes < 256;
set condition indices::data never;
reorder:
name
names
notify
deltaPart
dataByte
dataShort
dataInt
randomDataShort
randomDataByte
randomDataInt
indices;
// XAnimNotifyInfo
set scriptstring XAnimNotifyInfo::name;
// XAnimDeltaPart
use XAnimDeltaPart;
set count trans 1;
set count quat2 1;
set count quat 1;
// XAnimPartTrans
use XAnimPartTrans;
set condition u::frames size > 0;
set condition u::frames::indices::_1 XAnimParts::numframes < 256;
set arraysize u::frames::indices::_1 size + 1;
set arraysize u::frames::indices::_2 size + 1;
set condition u::frames::frames::_1 smallTrans;
set count u::frames::frames::_1 size + 1;
set count u::frames::frames::_2 size + 1;
// XAnimPartTransFrames
reorder XAnimPartTransFrames:
indices
frames;
// XAnimDeltaPartQuat2
use XAnimDeltaPartQuat2;
set condition u::frames size > 0;
set condition u::frames::indices::_1 XAnimParts::numframes < 256;
set arraysize u::frames::indices::_1 size + 1;
set arraysize u::frames::indices::_2 size + 1;
set count u::frames::frames size + 1;
// XAnimDeltaPartQuatDataFrames2
reorder XAnimDeltaPartQuatDataFrames2:
indices
frames;
// XAnimDeltaPartQuat
use XAnimDeltaPartQuat;
set condition u::frames size > 0;
set condition u::frames::indices::_1 XAnimParts::numframes < 256;
set arraysize u::frames::indices::_1 size + 1;
set arraysize u::frames::indices::_2 size + 1;
set count u::frames::frames size + 1;
// XAnimDeltaPartQuatDataFrames
reorder XAnimDeltaPartQuatDataFrames:
indices
frames;

View File

@ -0,0 +1,72 @@
// =========================================
// XModel
// =========================================
use XModel;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set scriptstring boneNames;
set reusable boneNames;
set count boneNames numBones;
set reusable parentList;
set count parentList numBones - numRootBones;
set reusable quats;
set count quats numBones - numRootBones;
set reusable trans;
set count trans numBones - numRootBones;
set reusable partClassification;
set count partClassification numBones;
set reusable baseMat;
set count baseMat numBones;
set count materialHandles numsurfs;
set count collSurfs numCollSurfs;
set count boneInfo numBones;
// XModelLodInfo
use XModelLodInfo;
set block modelSurfs XFILE_BLOCK_TEMP;
set action modelSurfs SetModelSurfs(XModelLodInfo, XModelSurfs);
set reusable modelSurfs;
set condition surfs never;
// XModelSurfs
use XModelSurfs;
set block XFILE_BLOCK_VIRTUAL;
set string name;
set count surfs XModelLodInfo::numsurfs; // No this is not a mistake. This is how the game does it.
// XSurface
use XSurface;
set reusable verts0;
set block verts0 XFILE_BLOCK_VERTEX;
set count verts0 vertCount;
set reusable vertList;
set count vertList vertListCount;
set reusable triIndices;
set block triIndices XFILE_BLOCK_INDEX;
set count triIndices triCount;
reorder:
zoneHandle
vertInfo
verts0
vertList
triIndices;
// XSurfaceVertexInfo
use XSurfaceVertexInfo;
set reusable vertsBlend;
set count vertsBlend vertCount[0]
+ 3 * vertCount[1]
+ 5 * vertCount[2]
+ 7 * vertCount[3];
// XRigidVertList
set reusable XRigidVertList::collisionTree;
// XSurfaceCollisionTree
use XSurfaceCollisionTree;
set count nodes nodeCount;
set count leafs leafCount;
// XModelCollSurf_s
set count XModelCollSurf_s::collTris numCollTris;

View File

@ -0,0 +1,7 @@
// =========================================
// XModelSurfs
// =========================================
use XModelSurfs;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;

View File

@ -0,0 +1,71 @@
// =========================================
// clipMap_t
// =========================================
use clipMap_t;
set block XFILE_BLOCK_TEMP;
set string name;
set name name;
set reusable planes;
set count planes planeCount;
set count staticModelList numStaticModels;
set count materials numMaterials;
set count brushsides numBrushSides;
set count brushEdges numBrushEdges;
set count nodes numNodes;
set count leafs numLeafs;
set count leafbrushNodes leafbrushNodesCount;
set count leafbrushes numLeafBrushes;
set count leafsurfaces numLeafSurfaces;
set count verts vertCount;
set count triIndices 3 * triCount;
set count triEdgeIsWalkable ((3 * triCount + 31) / 32) * 4;
set count borders borderCount;
set count partitions partitionCount;
set count aabbTrees aabbTreeCount;
set count cmodels numSubModels;
set count brushes numBrushes;
set count brushBounds numBrushes;
set count brushContents numBrushes;
set count smodelNodes smodelNodeCount;
set count dynEntDefList[0] dynEntCount[0];
set count dynEntDefList[1] dynEntCount[1];
set block dynEntPoseList XFILE_BLOCK_RUNTIME;
set count dynEntPoseList[0] dynEntCount[0];
set count dynEntPoseList[1] dynEntCount[1];
set block dynEntClientList XFILE_BLOCK_RUNTIME;
set count dynEntClientList[0] dynEntCount[0];
set count dynEntClientList[1] dynEntCount[1];
set block dynEntCollList XFILE_BLOCK_RUNTIME;
set count dynEntCollList[0] dynEntCount[0];
set count dynEntCollList[1] dynEntCount[1];
reorder:
...
leafs
leafbrushes
leafbrushNodes;
reorder:
...
brushContents
smodelNodes
mapEnts;
// ClipMaterial
set string ClipMaterial::name;
// cNode_t
set reusable cNode_t::plane;
// cLeafBrushNode_s
use cLeafBrushNode_s;
set condition data::leaf leafBrushCount > 0;
set reusable data::leaf::brushes;
set count data::leaf::brushes leafBrushCount;
// CollisionPartition
use CollisionPartition;
set reusable borders;
// cbrush_t
use cbrush_t;
set reusable sides;
set reusable baseAdjacentSide;

View File

@ -0,0 +1,150 @@
// =========================================
// menuDef_t
// =========================================
use menuDef_t;
set block XFILE_BLOCK_TEMP;
set string window::name;
set name window::name;
set string font;
set reusable visibleExp;
set string allowedBinding;
set string soundName;
set reusable rectXExp;
set reusable rectYExp;
set reusable rectWExp;
set reusable rectHExp;
set reusable openSoundExp;
set reusable closeSoundExp;
set count items itemCount;
set reusable expressionData;
reorder:
expressionData
window
font
onOpen
onClose
onCloseRequest
onESC
onKey
visibleExp
allowedBinding
soundName
rectXExp
rectYExp
rectWExp
rectHExp
openSoundExp
closeSoundExp
items;
// windowDef_t
use windowDef_t;
set string name;
set string group;
// MenuEventHandlerSet
set count MenuEventHandlerSet::eventHandlers eventHandlerCount;
// MenuEventHandler
use MenuEventHandler;
set string eventData::unconditionalScript;
set condition eventData::unconditionalScript eventType == EVENT_UNCONDITIONAL;
set condition eventData::conditionalScript eventType == EVENT_IF;
set condition eventData::elseScript eventType == EVENT_ELSE;
set condition eventData::setLocalVarData eventType == EVENT_SET_LOCAL_VAR_BOOL
|| eventType == EVENT_SET_LOCAL_VAR_INT
|| eventType == EVENT_SET_LOCAL_VAR_FLOAT
|| eventType == EVENT_SET_LOCAL_VAR_STRING;
// ConditionalScript
use ConditionalScript;
set reusable eventExpression;
reorder:
eventExpression
eventHandlerSet;
// SetLocalVarData
use SetLocalVarData;
set string localVarName;
set reusable expression;
// Statement_s
use Statement_s;
set count entries numEntries;
set reusable supportingData;
set condition lastResult never;
// expressionEntry
set condition expressionEntry::data::operand type == EET_OPERAND;
// Operand
use Operand;
set reusable internals::function;
set condition internals::intVal dataType == VAL_INT;
set condition internals::floatVal dataType == VAL_FLOAT;
set condition internals::stringVal dataType == VAL_STRING;
set condition internals::function dataType == VAL_FUNCTION;
// ExpressionString
set string ExpressionString::string;
// itemDef_s
use itemDef_s;
set string text;
set condition parent never;
set string dvar;
set string dvarTest;
set string enableDvar;
set string localVar;
set count floatExpressions floatExpressionCount;
set reusable visibleExp;
set reusable disabledExp;
set reusable textExp;
set reusable materialExp;
// itemDefData_t
use itemDefData_t;
set string enumDvarName;
set condition data never;
set condition listBox itemDef_s::type == 6;
set condition editField itemDef_s::type == 0
|| itemDef_s::type == 4
|| itemDef_s::type == 9
|| itemDef_s::type == 10
|| itemDef_s::type == 11
|| itemDef_s::type == 14
|| itemDef_s::type == 16
|| itemDef_s::type == 17
|| itemDef_s::type == 18
|| itemDef_s::type == 22
|| itemDef_s::type == 23;
set condition multi itemDef_s::type == 12;
set condition enumDvarName itemDef_s::type == 13;
set condition ticker itemDef_s::type == 20;
set condition scroll itemDef_s::type == 21;
// multiDef_s
use multiDef_s;
set string dvarList;
set string dvarStr;
// ItemFloatExpression
set reusable ItemFloatExpression::expression;
// UIFunctionList
use UIFunctionList;
set count functions totalFunctions;
set reusable functions; // This statement makes both the array of pointers and the pointers in the array reusable. only the second one is correct however this shouldn't be a problem with vanilla fastfiles.
// StaticDvarList
set count StaticDvarList::staticDvars numStaticDvars;
// StaticDvar
use StaticDvar;
set condition dvar never;
set string dvarName;
// StringList
use StringList;
set count strings totalStrings;
set string strings;

View File

@ -0,0 +1,30 @@
// =========================================
// snd_alias_list_t
// =========================================
use snd_alias_list_t;
set block XFILE_BLOCK_TEMP;
set string aliasName;
set name aliasName;
set reusable head;
set count head count;
// snd_alias_t
use snd_alias_t;
set string aliasName;
set string subtitle;
set string secondaryAliasName;
set string chainAliasName;
set string mixerGroup;
set reusable soundFile;
set reusable speakerMap;
// SoundFile
set condition SoundFile::u::loadSnd type == SAT_LOADED;
// SpeakerMap
set string SpeakerMap::name;
// StreamedSound
use StreamedSound;
set string dir;
set string name;

View File

@ -0,0 +1,422 @@
#include "GameAssetPoolIW5.h"
#include <cassert>
#include <type_traits>
#include "Pool/AssetPoolStatic.h"
#include "Pool/AssetPoolDynamic.h"
using namespace IW5;
const char* GameAssetPoolIW5::ASSET_TYPE_NAMES[]
{
"physpreset",
"physcollmap",
"xanim",
"xmodelsurfs",
"xmodel",
"material",
"pixelshader",
"vertexshader",
"vertexdecl",
"techniqueset",
"image",
"sound",
"soundcurve",
"loadedsound",
"clipmap",
"comworld",
"glassworld",
"pathdata",
"vehicletrack",
"mapents",
"fxworld",
"gfxworld",
"lightdef",
"uimap",
"font",
"menulist",
"menu",
"localize",
"attachment",
"weapon",
"fx",
"impactfx",
"surfacefx",
"aitype",
"mptype",
"character",
"xmodelalias",
"rawfile",
"scriptfile",
"stringtable",
"leaderboard",
"structureddatadef",
"tracer",
"vehicle",
"addonmapents"
};
/*
Asset Pool Table
Useful for macro generation via regex-replace for example
#assetType, #typeName, #unionEntry, #poolName
ASSET_TYPE_PHYSPRESET, PhysPreset, physPreset, m_phys_preset
ASSET_TYPE_PHYSCOLLMAP, PhysCollmap, physCollmap, m_phys_collmap
ASSET_TYPE_XANIMPARTS, XAnimParts, parts, m_xanim_parts
ASSET_TYPE_XMODEL_SURFS, XModelSurfs, modelSurfs, m_xmodel_surfs
ASSET_TYPE_XMODEL, XModel, model, m_xmodel
ASSET_TYPE_MATERIAL, Material, material, m_material
ASSET_TYPE_PIXELSHADER, MaterialPixelShader, pixelShader, m_material_pixel_shader
ASSET_TYPE_VERTEXSHADER, MaterialVertexShader, vertexShader, m_material_vertex_shader
ASSET_TYPE_VERTEXDECL, MaterialVertexDeclaration, vertexDecl, m_material_vertex_decl
ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet, techniqueSet, m_technique_set
ASSET_TYPE_IMAGE, GfxImage, image, m_image
ASSET_TYPE_SOUND, snd_alias_list_t, sound, m_sound
ASSET_TYPE_SOUND_CURVE, SndCurve, sndCurve, m_sound_curve
ASSET_TYPE_LOADED_SOUND, LoadedSound, loadSnd, m_loaded_sound
ASSET_TYPE_CLIPMAP, clipMap_t, clipMap, m_clip_map
ASSET_TYPE_COMWORLD, ComWorld, comWorld, m_com_world
ASSET_TYPE_GLASSWORLD, GlassWorld, glassWorld, m_glass_world
ASSET_TYPE_PATHDATA, PathData, pathData, m_path_data
ASSET_TYPE_VEHICLE_TRACK, VehicleTrack, vehicleTrack, m_vehicle_track
ASSET_TYPE_MAP_ENTS, MapEnts, mapEnts, m_map_ents
ASSET_TYPE_FXWORLD, FxWorld, fxWorld, m_fx_world
ASSET_TYPE_GFXWORLD, GfxWorld, gfxWorld, m_gfx_world
ASSET_TYPE_LIGHT_DEF, GfxLightDef, lightDef, m_gfx_light_def
ASSET_TYPE_FONT, Font_s, font, m_font
ASSET_TYPE_MENULIST, MenuList, menuList, m_menu_list
ASSET_TYPE_MENU, menuDef_t, menu, m_menu_def
ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry, localize, m_localize
ASSET_TYPE_ATTACHMENT, WeaponAttachment, attachment, m_attachment
ASSET_TYPE_WEAPON, WeaponCompleteDef, weapon, m_weapon
ASSET_TYPE_FX, FxEffectDef, fx, m_fx
ASSET_TYPE_IMPACT_FX, FxImpactTable, impactFx, m_fx_impact_table
ASSET_TYPE_SURFACE_FX, SurfaceFxTable, surfaceFx, m_surface_fx_table
ASSET_TYPE_RAWFILE, RawFile, rawfile, m_raw_file
ASSET_TYPE_SCRIPTFILE, ScriptFile, scriptfile, m_script_file
ASSET_TYPE_STRINGTABLE, StringTable, stringTable, m_string_table
ASSET_TYPE_LEADERBOARD, LeaderboardDef, leaderboardDef, m_leaderboard
ASSET_TYPE_STRUCTURED_DATA_DEF, StructuredDataDefSet, structuredDataDefSet, m_structed_data_def_set
ASSET_TYPE_TRACER, TracerDef, tracerDef, m_tracer
ASSET_TYPE_VEHICLE, VehicleDef, vehDef, m_vehicle
ASSET_TYPE_ADDON_MAP_ENTS, AddonMapEnts, addonMapEnts, m_addon_map_ents
*/
GameAssetPoolIW5::GameAssetPoolIW5(Zone* zone, const int priority)
: ZoneAssetPools(zone),
m_priority(priority)
{
assert(std::extent<decltype(ASSET_TYPE_NAMES)>::value == ASSET_TYPE_COUNT);
m_phys_preset = nullptr;
m_phys_collmap = nullptr;
m_xanim_parts = nullptr;
m_xmodel_surfs = nullptr;
m_xmodel = nullptr;
m_material = nullptr;
m_material_pixel_shader = nullptr;
m_material_vertex_shader = nullptr;
m_material_vertex_decl = nullptr;
m_technique_set = nullptr;
m_image = nullptr;
m_sound = nullptr;
m_sound_curve = nullptr;
m_loaded_sound = nullptr;
m_clip_map = nullptr;
m_com_world = nullptr;
m_glass_world = nullptr;
m_path_data = nullptr;
m_vehicle_track = nullptr;
m_map_ents = nullptr;
m_fx_world = nullptr;
m_gfx_world = nullptr;
m_gfx_light_def = nullptr;
m_font = nullptr;
m_menu_list = nullptr;
m_menu_def = nullptr;
m_localize = nullptr;
m_attachment = nullptr;
m_weapon = nullptr;
m_fx = nullptr;
m_fx_impact_table = nullptr;
m_surface_fx_table = nullptr;
m_raw_file = nullptr;
m_script_file = nullptr;
m_string_table = nullptr;
m_leaderboard = nullptr;
m_structed_data_def_set = nullptr;
m_tracer = nullptr;
m_vehicle = nullptr;
m_addon_map_ents = nullptr;
}
void GameAssetPoolIW5::InitPoolStatic(const asset_type_t type, const size_t capacity)
{
#define CASE_INIT_POOL_STATIC(assetType, poolName, poolType) \
case assetType: \
{ \
if((poolName) == nullptr && capacity > 0) \
{ \
(poolName) = std::make_unique<AssetPoolStatic<poolType>>(capacity, m_priority, (assetType)); \
} \
break; \
}
switch (type)
{
CASE_INIT_POOL_STATIC(ASSET_TYPE_PHYSPRESET, m_phys_preset, PhysPreset);
CASE_INIT_POOL_STATIC(ASSET_TYPE_PHYSCOLLMAP, m_phys_collmap, PhysCollmap);
CASE_INIT_POOL_STATIC(ASSET_TYPE_XANIMPARTS, m_xanim_parts, XAnimParts);
CASE_INIT_POOL_STATIC(ASSET_TYPE_XMODEL_SURFS, m_xmodel_surfs, XModelSurfs);
CASE_INIT_POOL_STATIC(ASSET_TYPE_XMODEL, m_xmodel, XModel);
CASE_INIT_POOL_STATIC(ASSET_TYPE_MATERIAL, m_material, Material);
CASE_INIT_POOL_STATIC(ASSET_TYPE_PIXELSHADER, m_material_pixel_shader, MaterialPixelShader);
CASE_INIT_POOL_STATIC(ASSET_TYPE_VERTEXSHADER, m_material_vertex_shader, MaterialVertexShader);
CASE_INIT_POOL_STATIC(ASSET_TYPE_VERTEXDECL, m_material_vertex_decl, MaterialVertexDeclaration);
CASE_INIT_POOL_STATIC(ASSET_TYPE_TECHNIQUE_SET, m_technique_set, MaterialTechniqueSet);
CASE_INIT_POOL_STATIC(ASSET_TYPE_IMAGE, m_image, GfxImage);
CASE_INIT_POOL_STATIC(ASSET_TYPE_SOUND, m_sound, snd_alias_list_t);
CASE_INIT_POOL_STATIC(ASSET_TYPE_SOUND_CURVE, m_sound_curve, SndCurve);
CASE_INIT_POOL_STATIC(ASSET_TYPE_LOADED_SOUND, m_loaded_sound, LoadedSound);
CASE_INIT_POOL_STATIC(ASSET_TYPE_CLIPMAP, m_clip_map, clipMap_t);
CASE_INIT_POOL_STATIC(ASSET_TYPE_COMWORLD, m_com_world, ComWorld);
CASE_INIT_POOL_STATIC(ASSET_TYPE_GLASSWORLD, m_glass_world, GlassWorld);
CASE_INIT_POOL_STATIC(ASSET_TYPE_PATHDATA, m_path_data, PathData);
CASE_INIT_POOL_STATIC(ASSET_TYPE_VEHICLE_TRACK, m_vehicle_track, VehicleTrack);
CASE_INIT_POOL_STATIC(ASSET_TYPE_MAP_ENTS, m_map_ents, MapEnts);
CASE_INIT_POOL_STATIC(ASSET_TYPE_FXWORLD, m_fx_world, FxWorld);
CASE_INIT_POOL_STATIC(ASSET_TYPE_GFXWORLD, m_gfx_world, GfxWorld);
CASE_INIT_POOL_STATIC(ASSET_TYPE_LIGHT_DEF, m_gfx_light_def, GfxLightDef);
CASE_INIT_POOL_STATIC(ASSET_TYPE_FONT, m_font, Font_s);
CASE_INIT_POOL_STATIC(ASSET_TYPE_MENULIST, m_menu_list, MenuList);
CASE_INIT_POOL_STATIC(ASSET_TYPE_MENU, m_menu_def, menuDef_t);
CASE_INIT_POOL_STATIC(ASSET_TYPE_LOCALIZE_ENTRY, m_localize, LocalizeEntry);
CASE_INIT_POOL_STATIC(ASSET_TYPE_ATTACHMENT, m_attachment, WeaponAttachment);
CASE_INIT_POOL_STATIC(ASSET_TYPE_WEAPON, m_weapon, WeaponCompleteDef);
CASE_INIT_POOL_STATIC(ASSET_TYPE_FX, m_fx, FxEffectDef);
CASE_INIT_POOL_STATIC(ASSET_TYPE_IMPACT_FX, m_fx_impact_table, FxImpactTable);
CASE_INIT_POOL_STATIC(ASSET_TYPE_SURFACE_FX, m_surface_fx_table, SurfaceFxTable);
CASE_INIT_POOL_STATIC(ASSET_TYPE_RAWFILE, m_raw_file, RawFile);
CASE_INIT_POOL_STATIC(ASSET_TYPE_SCRIPTFILE, m_script_file, ScriptFile);
CASE_INIT_POOL_STATIC(ASSET_TYPE_STRINGTABLE, m_string_table, StringTable);
CASE_INIT_POOL_STATIC(ASSET_TYPE_LEADERBOARD, m_leaderboard, LeaderboardDef);
CASE_INIT_POOL_STATIC(ASSET_TYPE_STRUCTURED_DATA_DEF, m_structed_data_def_set, StructuredDataDefSet);
CASE_INIT_POOL_STATIC(ASSET_TYPE_TRACER, m_tracer, TracerDef);
CASE_INIT_POOL_STATIC(ASSET_TYPE_VEHICLE, m_vehicle, VehicleDef);
CASE_INIT_POOL_STATIC(ASSET_TYPE_ADDON_MAP_ENTS, m_addon_map_ents, AddonMapEnts);
default:
assert(type >= 0 && type < ASSET_TYPE_COUNT);
break;
}
#undef CASE_INIT_POOL_STATIC
}
void GameAssetPoolIW5::InitPoolDynamic(const asset_type_t type)
{
#define CASE_INIT_POOL_DYNAMIC(assetType, poolName, poolType) \
case assetType: \
{ \
if((poolName) == nullptr) \
{ \
(poolName) = std::make_unique<AssetPoolDynamic<poolType>>(m_priority, (assetType)); \
} \
break; \
}
switch (type)
{
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_PHYSPRESET, m_phys_preset, PhysPreset);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_PHYSCOLLMAP, m_phys_collmap, PhysCollmap);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_XANIMPARTS, m_xanim_parts, XAnimParts);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_XMODEL_SURFS, m_xmodel_surfs, XModelSurfs);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_XMODEL, m_xmodel, XModel);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_MATERIAL, m_material, Material);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_PIXELSHADER, m_material_pixel_shader, MaterialPixelShader);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_VERTEXSHADER, m_material_vertex_shader, MaterialVertexShader);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_VERTEXDECL, m_material_vertex_decl, MaterialVertexDeclaration);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_TECHNIQUE_SET, m_technique_set, MaterialTechniqueSet);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_IMAGE, m_image, GfxImage);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_SOUND, m_sound, snd_alias_list_t);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_SOUND_CURVE, m_sound_curve, SndCurve);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_LOADED_SOUND, m_loaded_sound, LoadedSound);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_CLIPMAP, m_clip_map, clipMap_t);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_COMWORLD, m_com_world, ComWorld);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_GLASSWORLD, m_glass_world, GlassWorld);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_PATHDATA, m_path_data, PathData);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_VEHICLE_TRACK, m_vehicle_track, VehicleTrack);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_MAP_ENTS, m_map_ents, MapEnts);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_FXWORLD, m_fx_world, FxWorld);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_GFXWORLD, m_gfx_world, GfxWorld);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_LIGHT_DEF, m_gfx_light_def, GfxLightDef);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_FONT, m_font, Font_s);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_MENULIST, m_menu_list, MenuList);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_MENU, m_menu_def, menuDef_t);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_LOCALIZE_ENTRY, m_localize, LocalizeEntry);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_ATTACHMENT, m_attachment, WeaponAttachment);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_WEAPON, m_weapon, WeaponCompleteDef);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_FX, m_fx, FxEffectDef);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_IMPACT_FX, m_fx_impact_table, FxImpactTable);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_SURFACE_FX, m_surface_fx_table, SurfaceFxTable);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_RAWFILE, m_raw_file, RawFile);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_SCRIPTFILE, m_script_file, ScriptFile);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_STRINGTABLE, m_string_table, StringTable);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_LEADERBOARD, m_leaderboard, LeaderboardDef);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_STRUCTURED_DATA_DEF, m_structed_data_def_set, StructuredDataDefSet);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_TRACER, m_tracer, TracerDef);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_VEHICLE, m_vehicle, VehicleDef);
CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_ADDON_MAP_ENTS, m_addon_map_ents, AddonMapEnts);
default:
assert(type >= 0 && type < ASSET_TYPE_COUNT);
break;
}
#undef CASE_INIT_POOL_STATIC
}
XAssetInfoGeneric* GameAssetPoolIW5::AddAssetToPool(asset_type_t type, std::string name, void* asset, std::vector<XAssetInfoGeneric*> dependencies, std::vector<scr_string_t> usedScriptStrings, Zone* zone)
{
XAsset xAsset{};
xAsset.type = static_cast<XAssetType>(type);
xAsset.header.data = asset;
#define CASE_ADD_TO_POOL(assetType, poolName, headerName) \
case assetType: \
{ \
assert((poolName) != nullptr); \
return (poolName)->AddAsset(std::move(name), xAsset.header.headerName, zone, std::move(dependencies), std::move(usedScriptStrings)); \
}
switch (xAsset.type)
{
CASE_ADD_TO_POOL(ASSET_TYPE_PHYSPRESET, m_phys_preset, physPreset);
CASE_ADD_TO_POOL(ASSET_TYPE_PHYSCOLLMAP, m_phys_collmap, physCollmap);
CASE_ADD_TO_POOL(ASSET_TYPE_XANIMPARTS, m_xanim_parts, parts);
CASE_ADD_TO_POOL(ASSET_TYPE_XMODEL_SURFS, m_xmodel_surfs, modelSurfs);
CASE_ADD_TO_POOL(ASSET_TYPE_XMODEL, m_xmodel, model);
CASE_ADD_TO_POOL(ASSET_TYPE_MATERIAL, m_material, material);
CASE_ADD_TO_POOL(ASSET_TYPE_PIXELSHADER, m_material_pixel_shader, pixelShader);
CASE_ADD_TO_POOL(ASSET_TYPE_VERTEXSHADER, m_material_vertex_shader, vertexShader);
CASE_ADD_TO_POOL(ASSET_TYPE_VERTEXDECL, m_material_vertex_decl, vertexDecl);
CASE_ADD_TO_POOL(ASSET_TYPE_TECHNIQUE_SET, m_technique_set, techniqueSet);
CASE_ADD_TO_POOL(ASSET_TYPE_IMAGE, m_image, image);
CASE_ADD_TO_POOL(ASSET_TYPE_SOUND, m_sound, sound);
CASE_ADD_TO_POOL(ASSET_TYPE_SOUND_CURVE, m_sound_curve, sndCurve);
CASE_ADD_TO_POOL(ASSET_TYPE_LOADED_SOUND, m_loaded_sound, loadSnd);
CASE_ADD_TO_POOL(ASSET_TYPE_CLIPMAP, m_clip_map, clipMap);
CASE_ADD_TO_POOL(ASSET_TYPE_COMWORLD, m_com_world, comWorld);
CASE_ADD_TO_POOL(ASSET_TYPE_GLASSWORLD, m_glass_world, glassWorld);
CASE_ADD_TO_POOL(ASSET_TYPE_PATHDATA, m_path_data, pathData);
CASE_ADD_TO_POOL(ASSET_TYPE_VEHICLE_TRACK, m_vehicle_track, vehicleTrack);
CASE_ADD_TO_POOL(ASSET_TYPE_MAP_ENTS, m_map_ents, mapEnts);
CASE_ADD_TO_POOL(ASSET_TYPE_FXWORLD, m_fx_world, fxWorld);
CASE_ADD_TO_POOL(ASSET_TYPE_GFXWORLD, m_gfx_world, gfxWorld);
CASE_ADD_TO_POOL(ASSET_TYPE_LIGHT_DEF, m_gfx_light_def, lightDef);
CASE_ADD_TO_POOL(ASSET_TYPE_FONT, m_font, font);
CASE_ADD_TO_POOL(ASSET_TYPE_MENULIST, m_menu_list, menuList);
CASE_ADD_TO_POOL(ASSET_TYPE_MENU, m_menu_def, menu);
CASE_ADD_TO_POOL(ASSET_TYPE_LOCALIZE_ENTRY, m_localize, localize);
CASE_ADD_TO_POOL(ASSET_TYPE_ATTACHMENT, m_attachment, attachment);
CASE_ADD_TO_POOL(ASSET_TYPE_WEAPON, m_weapon, weapon);
CASE_ADD_TO_POOL(ASSET_TYPE_FX, m_fx, fx);
CASE_ADD_TO_POOL(ASSET_TYPE_IMPACT_FX, m_fx_impact_table, impactFx);
CASE_ADD_TO_POOL(ASSET_TYPE_SURFACE_FX, m_surface_fx_table, surfaceFx);
CASE_ADD_TO_POOL(ASSET_TYPE_RAWFILE, m_raw_file, rawfile);
CASE_ADD_TO_POOL(ASSET_TYPE_SCRIPTFILE, m_script_file, scriptfile);
CASE_ADD_TO_POOL(ASSET_TYPE_STRINGTABLE, m_string_table, stringTable);
CASE_ADD_TO_POOL(ASSET_TYPE_LEADERBOARD, m_leaderboard, leaderboardDef);
CASE_ADD_TO_POOL(ASSET_TYPE_STRUCTURED_DATA_DEF, m_structed_data_def_set, structuredDataDefSet);
CASE_ADD_TO_POOL(ASSET_TYPE_TRACER, m_tracer, tracerDef);
CASE_ADD_TO_POOL(ASSET_TYPE_VEHICLE, m_vehicle, vehDef);
CASE_ADD_TO_POOL(ASSET_TYPE_ADDON_MAP_ENTS, m_addon_map_ents, addonMapEnts);
default:
assert(false);
break;
}
return nullptr;
#undef CASE_ADD_TO_POOL
}
XAssetInfoGeneric* GameAssetPoolIW5::GetAsset(const asset_type_t type, std::string name) const
{
#define CASE_GET_ASSET(assetType, poolName) \
case assetType: \
{ \
if((poolName) != nullptr) \
return (poolName)->GetAsset(std::move(name)); \
break; \
}
switch (type)
{
CASE_GET_ASSET(ASSET_TYPE_PHYSPRESET, m_phys_preset);
CASE_GET_ASSET(ASSET_TYPE_PHYSCOLLMAP, m_phys_collmap);
CASE_GET_ASSET(ASSET_TYPE_XANIMPARTS, m_xanim_parts);
CASE_GET_ASSET(ASSET_TYPE_XMODEL_SURFS, m_xmodel_surfs);
CASE_GET_ASSET(ASSET_TYPE_XMODEL, m_xmodel);
CASE_GET_ASSET(ASSET_TYPE_MATERIAL, m_material);
CASE_GET_ASSET(ASSET_TYPE_PIXELSHADER, m_material_pixel_shader);
CASE_GET_ASSET(ASSET_TYPE_VERTEXSHADER, m_material_vertex_shader);
CASE_GET_ASSET(ASSET_TYPE_VERTEXDECL, m_material_vertex_decl);
CASE_GET_ASSET(ASSET_TYPE_TECHNIQUE_SET, m_technique_set);
CASE_GET_ASSET(ASSET_TYPE_IMAGE, m_image);
CASE_GET_ASSET(ASSET_TYPE_SOUND, m_sound);
CASE_GET_ASSET(ASSET_TYPE_SOUND_CURVE, m_sound_curve);
CASE_GET_ASSET(ASSET_TYPE_LOADED_SOUND, m_loaded_sound);
CASE_GET_ASSET(ASSET_TYPE_CLIPMAP, m_clip_map);
CASE_GET_ASSET(ASSET_TYPE_COMWORLD, m_com_world);
CASE_GET_ASSET(ASSET_TYPE_GLASSWORLD, m_glass_world);
CASE_GET_ASSET(ASSET_TYPE_PATHDATA, m_path_data);
CASE_GET_ASSET(ASSET_TYPE_VEHICLE_TRACK, m_vehicle_track);
CASE_GET_ASSET(ASSET_TYPE_MAP_ENTS, m_map_ents);
CASE_GET_ASSET(ASSET_TYPE_FXWORLD, m_fx_world);
CASE_GET_ASSET(ASSET_TYPE_GFXWORLD, m_gfx_world);
CASE_GET_ASSET(ASSET_TYPE_LIGHT_DEF, m_gfx_light_def);
CASE_GET_ASSET(ASSET_TYPE_FONT, m_font);
CASE_GET_ASSET(ASSET_TYPE_MENULIST, m_menu_list);
CASE_GET_ASSET(ASSET_TYPE_MENU, m_menu_def);
CASE_GET_ASSET(ASSET_TYPE_LOCALIZE_ENTRY, m_localize);
CASE_GET_ASSET(ASSET_TYPE_ATTACHMENT, m_attachment);
CASE_GET_ASSET(ASSET_TYPE_WEAPON, m_weapon);
CASE_GET_ASSET(ASSET_TYPE_FX, m_fx);
CASE_GET_ASSET(ASSET_TYPE_IMPACT_FX, m_fx_impact_table);
CASE_GET_ASSET(ASSET_TYPE_SURFACE_FX, m_surface_fx_table);
CASE_GET_ASSET(ASSET_TYPE_RAWFILE, m_raw_file);
CASE_GET_ASSET(ASSET_TYPE_SCRIPTFILE, m_script_file);
CASE_GET_ASSET(ASSET_TYPE_STRINGTABLE, m_string_table);
CASE_GET_ASSET(ASSET_TYPE_LEADERBOARD, m_leaderboard);
CASE_GET_ASSET(ASSET_TYPE_STRUCTURED_DATA_DEF, m_structed_data_def_set);
CASE_GET_ASSET(ASSET_TYPE_TRACER, m_tracer);
CASE_GET_ASSET(ASSET_TYPE_VEHICLE, m_vehicle);
CASE_GET_ASSET(ASSET_TYPE_ADDON_MAP_ENTS, m_addon_map_ents);
default:
assert(false);
break;
}
return nullptr;
#undef CASE_GET_ASSET
}
const char* GameAssetPoolIW5::AssetTypeNameByType(asset_type_t assetType)
{
if (assetType >= 0 && assetType < static_cast<int>(std::extent<decltype(ASSET_TYPE_NAMES)>::value))
return ASSET_TYPE_NAMES[assetType];
return ASSET_TYPE_INVALID;
}
const char* GameAssetPoolIW5::GetAssetTypeName(const asset_type_t assetType) const
{
return AssetTypeNameByType(assetType);
}

View File

@ -0,0 +1,70 @@
#pragma once
#include <memory>
#include "Pool/ZoneAssetPools.h"
#include "Pool/AssetPool.h"
#include "Game/IW5/IW5.h"
class GameAssetPoolIW5 final : public ZoneAssetPools
{
int m_priority;
static constexpr const char* ASSET_TYPE_INVALID = "invalid_asset_type";
static const char* ASSET_TYPE_NAMES[];
protected:
XAssetInfoGeneric* AddAssetToPool(asset_type_t type, std::string name, void* asset, std::vector<XAssetInfoGeneric*> dependencies, std::vector<scr_string_t> usedScriptStrings, Zone* zone) override;
public:
std::unique_ptr<AssetPool<IW5::PhysPreset>> m_phys_preset;
std::unique_ptr<AssetPool<IW5::PhysCollmap>> m_phys_collmap;
std::unique_ptr<AssetPool<IW5::XAnimParts>> m_xanim_parts;
std::unique_ptr<AssetPool<IW5::XModelSurfs>> m_xmodel_surfs;
std::unique_ptr<AssetPool<IW5::XModel>> m_xmodel;
std::unique_ptr<AssetPool<IW5::Material>> m_material;
std::unique_ptr<AssetPool<IW5::MaterialPixelShader>> m_material_pixel_shader;
std::unique_ptr<AssetPool<IW5::MaterialVertexShader>> m_material_vertex_shader;
std::unique_ptr<AssetPool<IW5::MaterialVertexDeclaration>> m_material_vertex_decl;
std::unique_ptr<AssetPool<IW5::MaterialTechniqueSet>> m_technique_set;
std::unique_ptr<AssetPool<IW5::GfxImage>> m_image;
std::unique_ptr<AssetPool<IW5::snd_alias_list_t>> m_sound;
std::unique_ptr<AssetPool<IW5::SndCurve>> m_sound_curve;
std::unique_ptr<AssetPool<IW5::LoadedSound>> m_loaded_sound;
std::unique_ptr<AssetPool<IW5::clipMap_t>> m_clip_map;
std::unique_ptr<AssetPool<IW5::ComWorld>> m_com_world;
std::unique_ptr<AssetPool<IW5::GlassWorld>> m_glass_world;
std::unique_ptr<AssetPool<IW5::PathData>> m_path_data;
std::unique_ptr<AssetPool<IW5::VehicleTrack>> m_vehicle_track;
std::unique_ptr<AssetPool<IW5::MapEnts>> m_map_ents;
std::unique_ptr<AssetPool<IW5::FxWorld>> m_fx_world;
std::unique_ptr<AssetPool<IW5::GfxWorld>> m_gfx_world;
std::unique_ptr<AssetPool<IW5::GfxLightDef>> m_gfx_light_def;
std::unique_ptr<AssetPool<IW5::Font_s>> m_font;
std::unique_ptr<AssetPool<IW5::MenuList>> m_menu_list;
std::unique_ptr<AssetPool<IW5::menuDef_t>> m_menu_def;
std::unique_ptr<AssetPool<IW5::LocalizeEntry>> m_localize;
std::unique_ptr<AssetPool<IW5::WeaponAttachment>> m_attachment;
std::unique_ptr<AssetPool<IW5::WeaponCompleteDef>> m_weapon;
std::unique_ptr<AssetPool<IW5::FxEffectDef>> m_fx;
std::unique_ptr<AssetPool<IW5::FxImpactTable>> m_fx_impact_table;
std::unique_ptr<AssetPool<IW5::SurfaceFxTable>> m_surface_fx_table;
std::unique_ptr<AssetPool<IW5::RawFile>> m_raw_file;
std::unique_ptr<AssetPool<IW5::ScriptFile>> m_script_file;
std::unique_ptr<AssetPool<IW5::StringTable>> m_string_table;
std::unique_ptr<AssetPool<IW5::LeaderboardDef>> m_leaderboard;
std::unique_ptr<AssetPool<IW5::StructuredDataDefSet>> m_structed_data_def_set;
std::unique_ptr<AssetPool<IW5::TracerDef>> m_tracer;
std::unique_ptr<AssetPool<IW5::VehicleDef>> m_vehicle;
std::unique_ptr<AssetPool<IW5::AddonMapEnts>> m_addon_map_ents;
GameAssetPoolIW5(Zone* zone, int priority);
~GameAssetPoolIW5() override = default;
void InitPoolStatic(asset_type_t type, size_t capacity) override;
void InitPoolDynamic(asset_type_t type) override;
XAssetInfoGeneric* GetAsset(asset_type_t type, std::string name) const override;
static const char* AssetTypeNameByType(asset_type_t assetType);
const char* GetAssetTypeName(asset_type_t assetType) const override;
};

View File

@ -0,0 +1,69 @@
#pragma once
#include <cstdint>
#include <string>
#include "Zone/ZoneTypes.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class ZoneConstants final
{
ZoneConstants() = default;
public:
static constexpr const char* MAGIC_SIGNED_INFINITY_WARD = "IWff0100";
static constexpr const char* MAGIC_SIGNED_OAT = "ABff0100";
static constexpr const char* MAGIC_UNSIGNED = "IWffu100";
static constexpr int ZONE_VERSION = 1;
static_assert(std::char_traits<char>::length(MAGIC_SIGNED_INFINITY_WARD) == sizeof(ZoneHeader::m_magic));
static_assert(std::char_traits<char>::length(MAGIC_SIGNED_OAT) == sizeof(ZoneHeader::m_magic));
static_assert(std::char_traits<char>::length(MAGIC_UNSIGNED) == sizeof(ZoneHeader::m_magic));
static constexpr const char* MAGIC_AUTH_HEADER = "IWffs100";
inline static const uint8_t RSA_PUBLIC_KEY_INFINITY_WARD[]
{
0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01,
0x00, 0xA5, 0x86, 0xCC, 0x18, 0xA9, 0x12, 0x17,
0x4F, 0x3A, 0xC9, 0x0C, 0xD2, 0x38, 0x5D, 0xDB,
0x67, 0x62, 0xA4, 0xE3, 0xD4, 0x42, 0x05, 0x8A,
0x57, 0x0C, 0x31, 0x4E, 0x19, 0xE4, 0xBA, 0x89,
0x73, 0x13, 0xDB, 0x72, 0x25, 0x63, 0xB1, 0x2F,
0xD7, 0xF1, 0x08, 0x48, 0x34, 0x06, 0xD7, 0x84,
0x5F, 0xC8, 0xCF, 0x2F, 0xB6, 0xA3, 0x5A, 0x8F,
0x7E, 0xAA, 0x9D, 0x51, 0xE7, 0x0F, 0xB9, 0x07,
0xB7, 0x30, 0x91, 0x04, 0x39, 0x9C, 0xDC, 0x1C,
0xF1, 0x16, 0xCB, 0x96, 0x10, 0xEB, 0x38, 0xB1,
0x3B, 0xBA, 0x42, 0xE3, 0xE2, 0x78, 0xBD, 0x77,
0x82, 0x1A, 0x2B, 0x54, 0x27, 0x0A, 0xF7, 0x66,
0x06, 0xAD, 0x46, 0x39, 0xC0, 0xEB, 0xB5, 0xC2,
0x27, 0xDD, 0x2C, 0x08, 0x62, 0x2C, 0x0B, 0xC4,
0x00, 0x0D, 0xCB, 0xAD, 0x22, 0x67, 0x01, 0xA6,
0x92, 0x9C, 0x00, 0xAF, 0x9D, 0x55, 0xCC, 0x68,
0xEC, 0x39, 0x49, 0x85, 0x7E, 0x2C, 0x98, 0xCF,
0x4C, 0x12, 0x8D, 0xED, 0xC7, 0x1D, 0x21, 0x54,
0x9C, 0x2F, 0xC9, 0x54, 0x36, 0x08, 0xA9, 0x67,
0xEE, 0x91, 0xE6, 0xD9, 0xB1, 0xFA, 0xA9, 0x2B,
0x88, 0xAD, 0x2A, 0xD0, 0xAA, 0x28, 0xF9, 0x47,
0xA6, 0x0F, 0xCF, 0x55, 0x4C, 0x9B, 0x26, 0x41,
0x89, 0x76, 0x11, 0xFD, 0x1B, 0x83, 0xE4, 0xE8,
0x8E, 0x7E, 0xB4, 0x03, 0xA3, 0x29, 0xDD, 0x4F,
0xAC, 0x99, 0xBE, 0x7C, 0xD3, 0xFD, 0x14, 0x28,
0x1C, 0x59, 0x69, 0xE0, 0x79, 0x5F, 0x4B, 0xDA,
0x6B, 0xAB, 0x48, 0x4E, 0x28, 0x39, 0x84, 0xC6,
0x2B, 0xC6, 0x20, 0x05, 0xDB, 0x05, 0x21, 0xC3,
0xE1, 0xD4, 0x20, 0x28, 0xDD, 0x3A, 0x4D, 0x51,
0xE7, 0x49, 0x8A, 0x49, 0xEF, 0xF5, 0xDA, 0xDA,
0x7D, 0x5D, 0xA8, 0x0B, 0xA1, 0x77, 0xCD, 0x62,
0x7D, 0x9D, 0x40, 0x26, 0x44, 0x4B, 0x3B, 0x0A,
0x89, 0x02, 0x03, 0x01, 0x00, 0x01
};
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
static constexpr int OFFSET_BLOCK_BIT_COUNT = 4;
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
};
}

View File

@ -0,0 +1,203 @@
#include "ContentLoaderIW5.h"
#include "Game/IW5/IW5.h"
#include "Loading/Exception/UnsupportedAssetTypeException.h"
#include <cassert>
#include "Game/IW5/XAssets/addonmapents/addonmapents_load_db.h"
#include "Game/IW5/XAssets/clipmap_t/clipmap_t_load_db.h"
#include "Game/IW5/XAssets/comworld/comworld_load_db.h"
#include "Game/IW5/XAssets/font_s/font_s_load_db.h"
#include "Game/IW5/XAssets/fxeffectdef/fxeffectdef_load_db.h"
#include "Game/IW5/XAssets/fximpacttable/fximpacttable_load_db.h"
#include "Game/IW5/XAssets/fxworld/fxworld_load_db.h"
#include "Game/IW5/XAssets/gfximage/gfximage_load_db.h"
#include "Game/IW5/XAssets/gfxlightdef/gfxlightdef_load_db.h"
#include "Game/IW5/XAssets/gfxworld/gfxworld_load_db.h"
#include "Game/IW5/XAssets/glassworld/glassworld_load_db.h"
#include "Game/IW5/XAssets/leaderboarddef/leaderboarddef_load_db.h"
#include "Game/IW5/XAssets/loadedsound/loadedsound_load_db.h"
#include "Game/IW5/XAssets/localizeentry/localizeentry_load_db.h"
#include "Game/IW5/XAssets/mapents/mapents_load_db.h"
#include "Game/IW5/XAssets/material/material_load_db.h"
#include "Game/IW5/XAssets/materialpixelshader/materialpixelshader_load_db.h"
#include "Game/IW5/XAssets/materialtechniqueset/materialtechniqueset_load_db.h"
#include "Game/IW5/XAssets/materialvertexdeclaration/materialvertexdeclaration_load_db.h"
#include "Game/IW5/XAssets/materialvertexshader/materialvertexshader_load_db.h"
#include "Game/IW5/XAssets/menudef_t/menudef_t_load_db.h"
#include "Game/IW5/XAssets/menulist/menulist_load_db.h"
#include "Game/IW5/XAssets/pathdata/pathdata_load_db.h"
#include "Game/IW5/XAssets/physcollmap/physcollmap_load_db.h"
#include "Game/IW5/XAssets/physpreset/physpreset_load_db.h"
#include "Game/IW5/XAssets/rawfile/rawfile_load_db.h"
#include "Game/IW5/XAssets/scriptfile/scriptfile_load_db.h"
#include "Game/IW5/XAssets/snd_alias_list_t/snd_alias_list_t_load_db.h"
#include "Game/IW5/XAssets/sndcurve/sndcurve_load_db.h"
#include "Game/IW5/XAssets/stringtable/stringtable_load_db.h"
#include "Game/IW5/XAssets/structureddatadefset/structureddatadefset_load_db.h"
#include "Game/IW5/XAssets/surfacefxtable/surfacefxtable_load_db.h"
#include "Game/IW5/XAssets/tracerdef/tracerdef_load_db.h"
#include "Game/IW5/XAssets/vehicledef/vehicledef_load_db.h"
#include "Game/IW5/XAssets/vehicletrack/vehicletrack_load_db.h"
#include "Game/IW5/XAssets/weaponattachment/weaponattachment_load_db.h"
#include "Game/IW5/XAssets/weaponcompletedef/weaponcompletedef_load_db.h"
#include "Game/IW5/XAssets/xanimparts/xanimparts_load_db.h"
#include "Game/IW5/XAssets/xmodel/xmodel_load_db.h"
#include "Game/IW5/XAssets/xmodelsurfs/xmodelsurfs_load_db.h"
using namespace IW5;
ContentLoader::ContentLoader()
{
varXAsset = nullptr;
varScriptStringList = nullptr;
}
void ContentLoader::LoadScriptStringList(const bool atStreamStart)
{
assert(m_zone->m_script_strings.Empty());
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
if (atStreamStart)
m_stream->Load<ScriptStringList>(varScriptStringList);
if (varScriptStringList->strings != nullptr)
{
assert(varScriptStringList->strings == PTR_FOLLOWING);
varScriptStringList->strings = m_stream->Alloc<const char*>(alignof(const char*));
varXString = varScriptStringList->strings;
LoadXStringArray(true, varScriptStringList->count);
for (int i = 0; i < varScriptStringList->count; i++)
{
if (varScriptStringList->strings[i])
{
m_zone->m_script_strings.AddScriptString(varScriptStringList->strings[i]);
}
else
{
m_zone->m_script_strings.AddScriptString("");
}
}
}
m_stream->PopBlock();
assert(m_zone->m_script_strings.Count() <= SCR_STRING_MAX + 1);
}
void ContentLoader::LoadXAsset(const bool atStreamStart)
{
#define LOAD_ASSET(type_index, typeName, headerEntry) \
case type_index: \
{ \
Loader_##typeName loader(m_zone, m_stream); \
loader.Load(&varXAsset->header.headerEntry); \
break; \
}
#define SKIP_ASSET(type_index, typeName, headerEntry) \
case type_index: \
break;
assert(varXAsset != nullptr);
if (atStreamStart)
m_stream->Load<XAsset>(varXAsset);
switch (varXAsset->type)
{
LOAD_ASSET(ASSET_TYPE_PHYSPRESET, PhysPreset, physPreset)
LOAD_ASSET(ASSET_TYPE_PHYSCOLLMAP, PhysCollmap, physCollmap)
LOAD_ASSET(ASSET_TYPE_XANIMPARTS, XAnimParts, parts)
LOAD_ASSET(ASSET_TYPE_XMODEL_SURFS, XModelSurfs, modelSurfs)
LOAD_ASSET(ASSET_TYPE_XMODEL, XModel, model)
LOAD_ASSET(ASSET_TYPE_MATERIAL, Material, material)
LOAD_ASSET(ASSET_TYPE_PIXELSHADER, MaterialPixelShader, pixelShader)
LOAD_ASSET(ASSET_TYPE_VERTEXSHADER, MaterialVertexShader, vertexShader)
LOAD_ASSET(ASSET_TYPE_VERTEXDECL, MaterialVertexDeclaration, vertexDecl)
LOAD_ASSET(ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet, techniqueSet)
LOAD_ASSET(ASSET_TYPE_IMAGE, GfxImage, image)
LOAD_ASSET(ASSET_TYPE_SOUND, snd_alias_list_t, sound)
LOAD_ASSET(ASSET_TYPE_SOUND_CURVE, SndCurve, sndCurve)
LOAD_ASSET(ASSET_TYPE_LOADED_SOUND, LoadedSound, loadSnd)
LOAD_ASSET(ASSET_TYPE_CLIPMAP, clipMap_t, clipMap)
LOAD_ASSET(ASSET_TYPE_COMWORLD, ComWorld, comWorld)
LOAD_ASSET(ASSET_TYPE_GLASSWORLD, GlassWorld, glassWorld)
LOAD_ASSET(ASSET_TYPE_PATHDATA, PathData, pathData)
LOAD_ASSET(ASSET_TYPE_VEHICLE_TRACK, VehicleTrack, vehicleTrack)
LOAD_ASSET(ASSET_TYPE_MAP_ENTS, MapEnts, mapEnts)
LOAD_ASSET(ASSET_TYPE_FXWORLD, FxWorld, fxWorld)
LOAD_ASSET(ASSET_TYPE_GFXWORLD, GfxWorld, gfxWorld)
LOAD_ASSET(ASSET_TYPE_LIGHT_DEF, GfxLightDef, lightDef)
LOAD_ASSET(ASSET_TYPE_FONT, Font_s, font)
LOAD_ASSET(ASSET_TYPE_MENULIST, MenuList, menuList)
LOAD_ASSET(ASSET_TYPE_MENU, menuDef_t, menu)
LOAD_ASSET(ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry, localize)
LOAD_ASSET(ASSET_TYPE_ATTACHMENT, WeaponAttachment, attachment)
LOAD_ASSET(ASSET_TYPE_WEAPON, WeaponCompleteDef, weapon)
LOAD_ASSET(ASSET_TYPE_FX, FxEffectDef, fx)
LOAD_ASSET(ASSET_TYPE_IMPACT_FX, FxImpactTable, impactFx)
LOAD_ASSET(ASSET_TYPE_SURFACE_FX, SurfaceFxTable, surfaceFx)
LOAD_ASSET(ASSET_TYPE_RAWFILE, RawFile, rawfile)
LOAD_ASSET(ASSET_TYPE_SCRIPTFILE, ScriptFile, scriptfile)
LOAD_ASSET(ASSET_TYPE_STRINGTABLE, StringTable, stringTable)
LOAD_ASSET(ASSET_TYPE_LEADERBOARD, LeaderboardDef, leaderboardDef)
LOAD_ASSET(ASSET_TYPE_STRUCTURED_DATA_DEF, StructuredDataDefSet, structuredDataDefSet)
LOAD_ASSET(ASSET_TYPE_TRACER, TracerDef, tracerDef)
LOAD_ASSET(ASSET_TYPE_VEHICLE, VehicleDef, vehDef)
LOAD_ASSET(ASSET_TYPE_ADDON_MAP_ENTS, AddonMapEnts, addonMapEnts)
default:
{
throw UnsupportedAssetTypeException(varXAsset->type);
}
}
#undef LOAD_ASSET
}
void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count)
{
assert(varXAsset != nullptr);
if (atStreamStart)
m_stream->Load<XAsset>(varXAsset, count);
for (asset_type_t assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
{
m_zone->m_pools->InitPoolDynamic(assetType);
}
for (size_t index = 0; index < count; index++)
{
LoadXAsset(false);
varXAsset++;
}
}
void ContentLoader::Load(Zone* zone, IZoneInputStream* stream)
{
m_zone = zone;
m_stream = stream;
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
XAssetList assetList{};
m_stream->LoadDataRaw(&assetList, sizeof assetList);
varScriptStringList = &assetList.stringList;
LoadScriptStringList(false);
if (assetList.assets != nullptr)
{
assert(assetList.assets == PTR_FOLLOWING);
assetList.assets = m_stream->Alloc<XAsset>(alignof(XAsset));
varXAsset = assetList.assets;
LoadXAssetArray(true, assetList.assetCount);
}
m_stream->PopBlock();
}

View File

@ -0,0 +1,23 @@
#pragma once
#include "Loading/ContentLoaderBase.h"
#include "Loading/IContentLoadingEntryPoint.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
{
XAsset* varXAsset;
ScriptStringList* varScriptStringList;
void LoadScriptStringList(bool atStreamStart);
void LoadXAsset(bool atStreamStart);
void LoadXAssetArray(bool atStreamStart, size_t count);
public:
ContentLoader();
void Load(Zone* zone, IZoneInputStream* stream) override;
};
}

View File

@ -0,0 +1,24 @@
#include "gfximage_actions.h"
#include <cassert>
#include <cstring>
using namespace IW5;
Actions_GfxImage::Actions_GfxImage(Zone* zone)
: AssetLoadingActions(zone)
{
}
void Actions_GfxImage::OnImageLoaded(GfxImage* image) const
{
image->cardMemory.platform[0] = 0;
}
void Actions_GfxImage::LoadImageData(GfxImageLoadDef* loadDef, GfxImage* image) const
{
const size_t loadDefSize = offsetof(IW5::GfxImageLoadDef, data) + loadDef->resourceSize;
image->texture.loadDef = static_cast<GfxImageLoadDef*>(m_zone->GetMemory()->Alloc(loadDefSize));
memcpy(image->texture.loadDef, loadDef, loadDefSize);
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "Loading/AssetLoadingActions.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class Actions_GfxImage final : public AssetLoadingActions
{
public:
explicit Actions_GfxImage(Zone* zone);
void OnImageLoaded(GfxImage* image) const;
void LoadImageData(GfxImageLoadDef* loadDef, GfxImage* image) const;
};
}

View File

@ -0,0 +1,24 @@
#include "loadedsound_actions.h"
#include <cstring>
using namespace IW5;
Actions_LoadedSound::Actions_LoadedSound(Zone* zone)
: AssetLoadingActions(zone)
{
}
void Actions_LoadedSound::SetSoundData(MssSound* sound) const
{
if (sound->info.data_len > 0)
{
char* tempData = sound->data;
sound->data = static_cast<char*>(m_zone->GetMemory()->Alloc(sound->info.data_len));
memcpy(sound->data, tempData, sound->info.data_len);
}
else
{
sound->data = nullptr;
}
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "Loading/AssetLoadingActions.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class Actions_LoadedSound final : public AssetLoadingActions
{
public:
explicit Actions_LoadedSound(Zone* zone);
void SetSoundData(MssSound* sound) const;
};
}

View File

@ -0,0 +1,19 @@
#include "xmodel_actions.h"
#include <cstring>
using namespace IW5;
Actions_XModel::Actions_XModel(Zone* zone)
: AssetLoadingActions(zone)
{
}
void Actions_XModel::SetModelSurfs(XModelLodInfo* lodInfo, XModelSurfs* modelSurfs) const
{
if(modelSurfs)
{
lodInfo->modelSurfs = m_zone->GetMemory()->Create<XModelSurfs>();
memcpy(lodInfo->modelSurfs, modelSurfs, sizeof(XModelSurfs));
}
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "Loading/AssetLoadingActions.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class Actions_XModel final : public AssetLoadingActions
{
public:
explicit Actions_XModel(Zone* zone);
void SetModelSurfs(XModelLodInfo* lodInfo, XModelSurfs* modelSurfs) const;
};
}

View File

@ -0,0 +1,198 @@
#include "ZoneLoaderFactoryIW5.h"
#include <cassert>
#include <cstring>
#include <type_traits>
#include "Game/IW5/IW5.h"
#include "Utils/ClassUtils.h"
#include "ContentLoaderIW5.h"
#include "Game/IW5/GameAssetPoolIW5.h"
#include "Game/IW5/GameIW5.h"
#include "Game/GameLanguage.h"
#include "Game/IW5/ZoneConstantsIW5.h"
#include "Loading/Processor/ProcessorAuthedBlocks.h"
#include "Loading/Processor/ProcessorCaptureData.h"
#include "Loading/Processor/ProcessorInflate.h"
#include "Loading/Steps/StepVerifyMagic.h"
#include "Loading/Steps/StepSkipBytes.h"
#include "Loading/Steps/StepVerifyFileName.h"
#include "Loading/Steps/StepLoadSignature.h"
#include "Loading/Steps/StepVerifySignature.h"
#include "Loading/Steps/StepAddProcessor.h"
#include "Loading/Steps/StepAllocXBlocks.h"
#include "Loading/Steps/StepLoadZoneContent.h"
#include "Loading/Steps/StepLoadHash.h"
#include "Loading/Steps/StepRemoveProcessor.h"
#include "Loading/Steps/StepVerifyHash.h"
using namespace IW5;
class ZoneLoaderFactory::Impl
{
static GameLanguage GetZoneLanguage(std::string& zoneName)
{
return GameLanguage::LANGUAGE_NONE;
}
static bool CanLoad(ZoneHeader& header, bool* isSecure, bool* isOfficial)
{
assert(isSecure != nullptr);
assert(isOfficial != nullptr);
if (header.m_version != ZoneConstants::ZONE_VERSION)
{
return false;
}
if (!memcmp(header.m_magic, ZoneConstants::MAGIC_SIGNED_INFINITY_WARD, std::char_traits<char>::length(ZoneConstants::MAGIC_SIGNED_INFINITY_WARD)))
{
*isSecure = true;
*isOfficial = true;
return true;
}
if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, std::char_traits<char>::length(ZoneConstants::MAGIC_UNSIGNED)))
{
*isSecure = false;
*isOfficial = true;
return true;
}
return false;
}
static void SetupBlock(ZoneLoader* zoneLoader)
{
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
zoneLoader->AddXBlock(XBLOCK_DEF(IW5::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP));
zoneLoader->AddXBlock(XBLOCK_DEF(IW5::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL));
zoneLoader->AddXBlock(XBLOCK_DEF(IW5::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
zoneLoader->AddXBlock(XBLOCK_DEF(IW5::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL));
zoneLoader->AddXBlock(XBLOCK_DEF(IW5::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL));
zoneLoader->AddXBlock(XBLOCK_DEF(IW5::XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL));
zoneLoader->AddXBlock(XBLOCK_DEF(IW5::XFILE_BLOCK_SCRIPT, XBlock::Type::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF
}
static std::unique_ptr<IPublicKeyAlgorithm> SetupRSA(const bool isOfficial)
{
if (isOfficial)
{
auto rsa = Crypto::CreateRSA(IPublicKeyAlgorithm::HashingAlgorithm::RSA_HASH_SHA256,
Crypto::RSAPaddingMode::RSA_PADDING_PSS);
if (!rsa->SetKey(ZoneConstants::RSA_PUBLIC_KEY_INFINITY_WARD, sizeof(ZoneConstants::RSA_PUBLIC_KEY_INFINITY_WARD)))
{
printf("Invalid public key for signature checking\n");
return nullptr;
}
return rsa;
}
else
{
assert(false);
// TODO: Load custom RSA key here
return nullptr;
}
}
static void AddAuthHeaderSteps(const bool isSecure, const bool isOfficial, ZoneLoader* zoneLoader,
std::string& fileName)
{
// Unsigned zones do not have an auth header
if (!isSecure)
return;
// If file is signed setup a RSA instance.
auto rsa = SetupRSA(isOfficial);
zoneLoader->AddLoadingStep(std::make_unique<StepVerifyMagic>(ZoneConstants::MAGIC_AUTH_HEADER));
zoneLoader->AddLoadingStep(std::make_unique<StepSkipBytes>(4)); // Skip reserved
auto subHeaderHash = std::make_unique<StepLoadHash>(sizeof DB_AuthHash::bytes, 1);
auto* subHeaderHashPtr = subHeaderHash.get();
zoneLoader->AddLoadingStep(std::move(subHeaderHash));
auto subHeaderHashSignature = std::make_unique<StepLoadSignature>(sizeof DB_AuthSignature::bytes);
auto* subHeaderHashSignaturePtr = subHeaderHashSignature.get();
zoneLoader->AddLoadingStep(std::move(subHeaderHashSignature));
zoneLoader->AddLoadingStep(std::make_unique<StepVerifySignature>(std::move(rsa), subHeaderHashSignaturePtr, subHeaderHashPtr));
auto subHeaderCapture = std::make_unique<ProcessorCaptureData>(sizeof(DB_AuthSubHeader));
auto* subHeaderCapturePtr = subHeaderCapture.get();
zoneLoader->AddLoadingStep(std::make_unique<StepAddProcessor>(std::move(subHeaderCapture)));
zoneLoader->AddLoadingStep(std::make_unique<StepVerifyFileName>(fileName, sizeof(DB_AuthSubHeader::fastfileName)));
zoneLoader->AddLoadingStep(std::make_unique<StepSkipBytes>(4)); // Skip reserved
auto masterBlockHashes = std::make_unique<StepLoadHash>(sizeof DB_AuthHash::bytes, std::extent<decltype(DB_AuthSubHeader::masterBlockHashes)>::value);
auto* masterBlockHashesPtr = masterBlockHashes.get();
zoneLoader->AddLoadingStep(std::move(masterBlockHashes));
zoneLoader->AddLoadingStep(std::make_unique<StepVerifyHash>(std::unique_ptr<IHashFunction>(Crypto::CreateSHA256()), 0, subHeaderHashPtr, subHeaderCapturePtr));
zoneLoader->AddLoadingStep(std::make_unique<StepRemoveProcessor>(subHeaderCapturePtr));
// Skip the rest of the first chunk
zoneLoader->AddLoadingStep(std::make_unique<StepSkipBytes>(ZoneConstants::AUTHED_CHUNK_SIZE - sizeof(DB_AuthHeader)));
zoneLoader->AddLoadingStep(std::make_unique<StepAddProcessor>(std::make_unique<ProcessorAuthedBlocks>(
ZoneConstants::AUTHED_CHUNK_COUNT_PER_GROUP, ZoneConstants::AUTHED_CHUNK_SIZE, std::extent<decltype(DB_AuthSubHeader::masterBlockHashes)>::value,
std::unique_ptr<IHashFunction>(Crypto::CreateSHA256()), masterBlockHashesPtr)));
}
public:
static ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName)
{
bool isSecure;
bool isOfficial;
// Check if this file is a supported IW4 zone.
if (!CanLoad(header, &isSecure, &isOfficial))
return nullptr;
// Create new zone
auto zone = std::make_unique<Zone>(fileName, 0, &g_GameIW5);
auto* zonePtr = zone.get();
zone->m_pools = std::make_unique<GameAssetPoolIW5>(zonePtr, 0);
zone->m_language = GetZoneLanguage(fileName);
// File is supported. Now setup all required steps for loading this file.
auto* zoneLoader = new ZoneLoader(std::move(zone));
SetupBlock(zoneLoader);
// Skip unknown 1 byte field that the game ignores as well
zoneLoader->AddLoadingStep(std::make_unique<StepSkipBytes>(1));
// Skip timestamp
zoneLoader->AddLoadingStep(std::make_unique<StepSkipBytes>(8));
// Add steps for loading the auth header which also contain the signature of the zone if it is signed.
AddAuthHeaderSteps(isSecure, isOfficial, zoneLoader, fileName);
zoneLoader->AddLoadingStep(std::make_unique<StepAddProcessor>(std::make_unique<ProcessorInflate>(ZoneConstants::AUTHED_CHUNK_SIZE)));
// Start of the XFile struct
zoneLoader->AddLoadingStep(std::make_unique<StepSkipBytes>(8));
// Skip size and externalSize fields since they are not interesting for us
zoneLoader->AddLoadingStep(std::make_unique<StepAllocXBlocks>());
// Start of the zone content
zoneLoader->AddLoadingStep(std::make_unique<StepLoadZoneContent>(std::make_unique<ContentLoader>(), zonePtr, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK));
// Return the fully setup zoneloader
return zoneLoader;
}
};
ZoneLoader* ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName)
{
return Impl::CreateLoaderForHeader(header, fileName);
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "Loading/IZoneLoaderFactory.h"
#include <string>
namespace IW5
{
class ZoneLoaderFactory final : public IZoneLoaderFactory
{
class Impl;
public:
ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) override;
};
}

View File

@ -6,6 +6,7 @@
#include "Game/IW3/ZoneLoaderFactoryIW3.h"
#include "Game/IW4/ZoneLoaderFactoryIW4.h"
#include "Game/IW5/ZoneLoaderFactoryIW5.h"
#include "Game/T5/ZoneLoaderFactoryT5.h"
#include "Game/T6/ZoneLoaderFactoryT6.h"
#include "Utils/ObjFileStream.h"
@ -16,6 +17,7 @@ IZoneLoaderFactory* ZoneLoaderFactories[]
{
new IW3::ZoneLoaderFactory(),
new IW4::ZoneLoaderFactory(),
new IW5::ZoneLoaderFactory(),
new T5::ZoneLoaderFactory(),
new T6::ZoneLoaderFactory()
};

View File

@ -0,0 +1,231 @@
#include "ContentWriterIW5.h"
#include <cassert>
#include <sstream>
#include "Game/IW5/XAssets/addonmapents/addonmapents_write_db.h"
#include "Game/IW5/XAssets/clipmap_t/clipmap_t_write_db.h"
#include "Game/IW5/XAssets/comworld/comworld_write_db.h"
#include "Game/IW5/XAssets/font_s/font_s_write_db.h"
#include "Game/IW5/XAssets/fxeffectdef/fxeffectdef_write_db.h"
#include "Game/IW5/XAssets/fximpacttable/fximpacttable_write_db.h"
#include "Game/IW5/XAssets/fxworld/fxworld_write_db.h"
#include "Game/IW5/XAssets/gfximage/gfximage_write_db.h"
#include "Game/IW5/XAssets/gfxlightdef/gfxlightdef_write_db.h"
#include "Game/IW5/XAssets/gfxworld/gfxworld_write_db.h"
#include "Game/IW5/XAssets/glassworld/glassworld_write_db.h"
#include "Game/IW5/XAssets/leaderboarddef/leaderboarddef_write_db.h"
#include "Game/IW5/XAssets/loadedsound/loadedsound_write_db.h"
#include "Game/IW5/XAssets/localizeentry/localizeentry_write_db.h"
#include "Game/IW5/XAssets/mapents/mapents_write_db.h"
#include "Game/IW5/XAssets/material/material_write_db.h"
#include "Game/IW5/XAssets/materialpixelshader/materialpixelshader_write_db.h"
#include "Game/IW5/XAssets/materialtechniqueset/materialtechniqueset_write_db.h"
#include "Game/IW5/XAssets/materialvertexdeclaration/materialvertexdeclaration_write_db.h"
#include "Game/IW5/XAssets/materialvertexshader/materialvertexshader_write_db.h"
#include "Game/IW5/XAssets/menudef_t/menudef_t_write_db.h"
#include "Game/IW5/XAssets/menulist/menulist_write_db.h"
#include "Game/IW5/XAssets/pathdata/pathdata_write_db.h"
#include "Game/IW5/XAssets/physcollmap/physcollmap_write_db.h"
#include "Game/IW5/XAssets/physpreset/physpreset_write_db.h"
#include "Game/IW5/XAssets/rawfile/rawfile_write_db.h"
#include "Game/IW5/XAssets/scriptfile/scriptfile_write_db.h"
#include "Game/IW5/XAssets/snd_alias_list_t/snd_alias_list_t_write_db.h"
#include "Game/IW5/XAssets/sndcurve/sndcurve_write_db.h"
#include "Game/IW5/XAssets/stringtable/stringtable_write_db.h"
#include "Game/IW5/XAssets/structureddatadefset/structureddatadefset_write_db.h"
#include "Game/IW5/XAssets/surfacefxtable/surfacefxtable_write_db.h"
#include "Game/IW5/XAssets/tracerdef/tracerdef_write_db.h"
#include "Game/IW5/XAssets/vehicledef/vehicledef_write_db.h"
#include "Game/IW5/XAssets/vehicletrack/vehicletrack_write_db.h"
#include "Game/IW5/XAssets/weaponattachment/weaponattachment_write_db.h"
#include "Game/IW5/XAssets/weaponcompletedef/weaponcompletedef_write_db.h"
#include "Game/IW5/XAssets/xanimparts/xanimparts_write_db.h"
#include "Game/IW5/XAssets/xmodel/xmodel_write_db.h"
#include "Game/IW5/XAssets/xmodelsurfs/xmodelsurfs_write_db.h"
#include "Writing/WritingException.h"
using namespace IW5;
ContentWriter::ContentWriter()
: varXAssetList(nullptr),
varXAsset(nullptr),
varScriptStringList(nullptr)
{
}
void ContentWriter::CreateXAssetList(XAssetList& xAssetList, MemoryManager& memory) const
{
if (!m_zone->m_script_strings.Empty())
{
assert(m_zone->m_script_strings.Count() <= SCR_STRING_MAX + 1);
xAssetList.stringList.count = m_zone->m_script_strings.Count();
xAssetList.stringList.strings = static_cast<const char**>(memory.Alloc(sizeof(const char*) * m_zone->m_script_strings.Count()));
for (auto i = 0u; i < m_zone->m_script_strings.Count(); i++)
{
xAssetList.stringList.strings[i] = m_zone->m_script_strings[i].c_str();
}
}
else
{
xAssetList.stringList.count = 0;
xAssetList.stringList.strings = nullptr;
}
const auto assetCount = m_zone->m_pools->GetTotalAssetCount();
if (assetCount > 0)
{
xAssetList.assetCount = assetCount;
xAssetList.assets = static_cast<XAsset*>(memory.Alloc(sizeof(XAsset) * assetCount));
const auto end = m_zone->m_pools->end();
auto index = 0u;
for (auto i = m_zone->m_pools->begin(); i != end; ++i)
{
auto& asset = xAssetList.assets[index++];
asset.type = static_cast<XAssetType>((*i)->m_type);
asset.header.data = (*i)->m_ptr;
}
}
else
{
xAssetList.assetCount = 0;
xAssetList.assets = nullptr;
}
}
void ContentWriter::WriteScriptStringList(const bool atStreamStart)
{
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
if (atStreamStart)
varScriptStringList = m_stream->Write(varScriptStringList);
if (varScriptStringList->strings != nullptr)
{
m_stream->Align(alignof(const char*));
varXString = varScriptStringList->strings;
WriteXStringArray(true, varScriptStringList->count);
m_stream->MarkFollowing(varScriptStringList->strings);
}
m_stream->PopBlock();
}
void ContentWriter::WriteXAsset(const bool atStreamStart)
{
#define WRITE_ASSET(type_index, typeName, headerEntry) \
case type_index: \
{ \
Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, m_stream); \
writer.Write(&varXAsset->header.headerEntry); \
break; \
}
#define SKIP_ASSET(type_index, typeName, headerEntry) \
case type_index: \
break;
assert(varXAsset != nullptr);
if (atStreamStart)
varXAsset = m_stream->Write(varXAsset);
switch (varXAsset->type)
{
WRITE_ASSET(ASSET_TYPE_PHYSPRESET, PhysPreset, physPreset)
WRITE_ASSET(ASSET_TYPE_PHYSCOLLMAP, PhysCollmap, physCollmap)
WRITE_ASSET(ASSET_TYPE_XANIMPARTS, XAnimParts, parts)
WRITE_ASSET(ASSET_TYPE_XMODEL_SURFS, XModelSurfs, modelSurfs)
WRITE_ASSET(ASSET_TYPE_XMODEL, XModel, model)
WRITE_ASSET(ASSET_TYPE_MATERIAL, Material, material)
WRITE_ASSET(ASSET_TYPE_PIXELSHADER, MaterialPixelShader, pixelShader)
WRITE_ASSET(ASSET_TYPE_VERTEXSHADER, MaterialVertexShader, vertexShader)
WRITE_ASSET(ASSET_TYPE_VERTEXDECL, MaterialVertexDeclaration, vertexDecl)
WRITE_ASSET(ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet, techniqueSet)
WRITE_ASSET(ASSET_TYPE_IMAGE, GfxImage, image)
WRITE_ASSET(ASSET_TYPE_SOUND, snd_alias_list_t, sound)
WRITE_ASSET(ASSET_TYPE_SOUND_CURVE, SndCurve, sndCurve)
WRITE_ASSET(ASSET_TYPE_LOADED_SOUND, LoadedSound, loadSnd)
WRITE_ASSET(ASSET_TYPE_CLIPMAP, clipMap_t, clipMap)
WRITE_ASSET(ASSET_TYPE_COMWORLD, ComWorld, comWorld)
WRITE_ASSET(ASSET_TYPE_GLASSWORLD, GlassWorld, glassWorld)
WRITE_ASSET(ASSET_TYPE_PATHDATA, PathData, pathData)
WRITE_ASSET(ASSET_TYPE_VEHICLE_TRACK, VehicleTrack, vehicleTrack)
WRITE_ASSET(ASSET_TYPE_MAP_ENTS, MapEnts, mapEnts)
WRITE_ASSET(ASSET_TYPE_FXWORLD, FxWorld, fxWorld)
WRITE_ASSET(ASSET_TYPE_GFXWORLD, GfxWorld, gfxWorld)
WRITE_ASSET(ASSET_TYPE_LIGHT_DEF, GfxLightDef, lightDef)
WRITE_ASSET(ASSET_TYPE_FONT, Font_s, font)
WRITE_ASSET(ASSET_TYPE_MENULIST, MenuList, menuList)
WRITE_ASSET(ASSET_TYPE_MENU, menuDef_t, menu)
WRITE_ASSET(ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry, localize)
WRITE_ASSET(ASSET_TYPE_ATTACHMENT, WeaponAttachment, attachment)
WRITE_ASSET(ASSET_TYPE_WEAPON, WeaponCompleteDef, weapon)
WRITE_ASSET(ASSET_TYPE_FX, FxEffectDef, fx)
WRITE_ASSET(ASSET_TYPE_IMPACT_FX, FxImpactTable, impactFx)
WRITE_ASSET(ASSET_TYPE_SURFACE_FX, SurfaceFxTable, surfaceFx)
WRITE_ASSET(ASSET_TYPE_RAWFILE, RawFile, rawfile)
WRITE_ASSET(ASSET_TYPE_SCRIPTFILE, ScriptFile, scriptfile)
WRITE_ASSET(ASSET_TYPE_STRINGTABLE, StringTable, stringTable)
WRITE_ASSET(ASSET_TYPE_LEADERBOARD, LeaderboardDef, leaderboardDef)
WRITE_ASSET(ASSET_TYPE_STRUCTURED_DATA_DEF, StructuredDataDefSet, structuredDataDefSet)
WRITE_ASSET(ASSET_TYPE_TRACER, TracerDef, tracerDef)
WRITE_ASSET(ASSET_TYPE_VEHICLE, VehicleDef, vehDef)
WRITE_ASSET(ASSET_TYPE_ADDON_MAP_ENTS, AddonMapEnts, addonMapEnts)
default:
{
std::ostringstream str;
str << "Unsupported asset type: " << varXAsset->type << ".";
throw WritingException(str.str());
}
}
#undef WRITE_ASSET
#undef SKIP_ASSET
}
void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t count)
{
assert(varXAsset != nullptr);
if (atStreamStart)
varXAsset = m_stream->Write(varXAsset, count);
for (size_t index = 0; index < count; index++)
{
WriteXAsset(false);
varXAsset++;
}
}
void ContentWriter::WriteContent(Zone* zone, IZoneOutputStream* stream)
{
m_zone = zone;
m_stream = stream;
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
MemoryManager memory;
XAssetList assetList{};
CreateXAssetList(assetList, memory);
varXAssetList = static_cast<XAssetList*>(m_stream->WriteDataRaw(&assetList, sizeof(assetList)));
varScriptStringList = &varXAssetList->stringList;
WriteScriptStringList(false);
if (varXAssetList->assets != nullptr)
{
m_stream->Align(alignof(XAsset));
varXAsset = varXAssetList->assets;
WriteXAssetArray(true, varXAssetList->assetCount);
m_stream->MarkFollowing(varXAssetList->assets);
}
m_stream->PopBlock();
}

View File

@ -0,0 +1,26 @@
#pragma once
#include "Writing/ContentWriterBase.h"
#include "Writing/IContentWritingEntryPoint.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class ContentWriter final : public ContentWriterBase, public IContentWritingEntryPoint
{
XAssetList* varXAssetList;
XAsset* varXAsset;
ScriptStringList* varScriptStringList;
void CreateXAssetList(XAssetList& xAssetList, MemoryManager& memory) const;
void WriteScriptStringList(bool atStreamStart);
void WriteXAsset(bool atStreamStart);
void WriteXAssetArray(bool atStreamStart, size_t count);
public:
ContentWriter();
void WriteContent(Zone* zone, IZoneOutputStream* stream) override;
};
}

View File

@ -0,0 +1,111 @@
#include "ZoneWriterFactoryIW5.h"
#include <cstring>
#include "ContentWriterIW5.h"
#include "Game/IW5/IW5.h"
#include "Game/IW5/GameIW5.h"
#include "Game/IW5/ZoneConstantsIW5.h"
#include "Writing/Processor/OutputProcessorDeflate.h"
#include "Writing/Steps/StepAddOutputProcessor.h"
#include "Writing/Steps/StepWriteTimestamp.h"
#include "Writing/Steps/StepWriteXBlockSizes.h"
#include "Writing/Steps/StepWriteZero.h"
#include "Writing/Steps/StepWriteZoneContentToFile.h"
#include "Writing/Steps/StepWriteZoneContentToMemory.h"
#include "Writing/Steps/StepWriteZoneHeader.h"
#include "Writing/Steps/StepWriteZoneSizes.h"
using namespace IW5;
class ZoneWriterFactory::Impl
{
Zone* m_zone;
std::unique_ptr<ZoneWriter> m_writer;
public:
explicit Impl(Zone* zone)
: m_zone(zone),
m_writer(std::make_unique<ZoneWriter>())
{
}
void SetupBlocks() const
{
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP));
m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL));
m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL));
m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL));
m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL));
m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_SCRIPT, XBlock::Type::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF
}
static ZoneHeader CreateHeaderForParams(const bool isSecure, const bool isOfficial)
{
ZoneHeader header{};
header.m_version = ZoneConstants::ZONE_VERSION;
if (isSecure)
{
if (isOfficial)
memcpy(header.m_magic, ZoneConstants::MAGIC_SIGNED_INFINITY_WARD, sizeof(ZoneHeader::m_magic));
else
memcpy(header.m_magic, ZoneConstants::MAGIC_SIGNED_OAT, sizeof(ZoneHeader::m_magic));
}
else
{
memcpy(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, sizeof(ZoneHeader::m_magic));
}
return header;
}
std::unique_ptr<ZoneWriter> CreateWriter()
{
// TODO Support signed fastfiles
bool isSecure = false;
SetupBlocks();
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(std::make_unique<ContentWriter>(), m_zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
auto* contentInMemoryPtr = contentInMemory.get();
m_writer->AddWritingStep(std::move(contentInMemory));
// Write zone header
m_writer->AddWritingStep(std::make_unique<StepWriteZoneHeader>(CreateHeaderForParams(isSecure, false)));
// Write dummy byte that the game ignores as well. No clue what it means.
m_writer->AddWritingStep(std::make_unique<StepWriteZero>(1));
// Write timestamp
m_writer->AddWritingStep(std::make_unique<StepWriteTimestamp>());
m_writer->AddWritingStep(std::make_unique<StepAddOutputProcessor>(std::make_unique<OutputProcessorDeflate>()));
// Start of the XFile struct
m_writer->AddWritingStep(std::make_unique<StepWriteZoneSizes>(contentInMemoryPtr));
m_writer->AddWritingStep(std::make_unique<StepWriteXBlockSizes>(m_zone));
// Start of the zone content
m_writer->AddWritingStep(std::make_unique<StepWriteZoneContentToFile>(contentInMemoryPtr));
// Return the fully setup zoneloader
return std::move(m_writer);
}
};
bool ZoneWriterFactory::SupportsZone(Zone* zone) const
{
return zone->m_game == &g_GameIW5;
}
std::unique_ptr<ZoneWriter> ZoneWriterFactory::CreateWriter(Zone* zone) const
{
Impl impl(zone);
return impl.CreateWriter();
}

Some files were not shown because too many files have changed in this diff Show More