iw3 basis

This commit is contained in:
Jan 2021-04-12 19:18:55 +02:00
parent 62d9309922
commit 1267b8aa7b
76 changed files with 3722 additions and 0 deletions

View File

View File

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

View File

@ -0,0 +1,43 @@
#include "GameIW3.h"
#include <algorithm>
#include "IW3.h"
using namespace IW3;
GameIW3 g_GameIW3;
std::string GameIW3::GetFullName()
{
return "Call Of Duty 4: Modern Warfare";
}
std::string GameIW3::GetShortName()
{
return "IW3";
}
void GameIW3::AddZone(Zone* zone)
{
m_zones.push_back(zone);
}
void GameIW3::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*> GameIW3::GetZones()
{
return m_zones;
}
std::vector<GameLanguagePrefix> GameIW3::GetLanguagePrefixes()
{
std::vector<GameLanguagePrefix> prefixes;
return prefixes;
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "Game/IGame.h"
class GameIW3 : 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 GameIW3 g_GameIW3;

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

@ -0,0 +1,82 @@
#pragma once
//#include <d3d11.h>
#include "Image/Texture.h"
#include "IW3_Assets.h"
namespace IW3
{
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_FLOAT,
CSPFT_MILLISECONDS,
CSPFT_FX,
CSPFT_XMODEL,
CSPFT_MATERIAL,
CSPFT_SOUND,
CSPFT_NUM_BASE_FIELD_TYPES
};
enum weapFieldType_t
{
WFT_WEAPONTYPE = CSPFT_NUM_BASE_FIELD_TYPES,
WFT_WEAPONCLASS,
WFT_OVERLAYRETICLE,
WFT_PENETRATE_TYPE,
WFT_IMPACT_TYPE,
WFT_STANCE,
WFT_PROJ_EXPLOSION,
WFT_OFFHAND_CLASS,
WFT_ANIMTYPE,
WFT_ACTIVE_RETICLE_TYPE,
WFT_GUIDED_MISSILE_TYPE,
WFT_BOUNCE_SOUND,
WFT_STICKINESS,
WFT_OVERLAYINTERFACE,
WFT_INVENTORYTYPE,
WFT_FIRETYPE,
WFT_AMMOCOUNTER_CLIPTYPE,
WFT_ICONRATIO_HUD,
WFT_ICONRATIO_AMMOCOUNTER,
WFT_ICONRATIO_KILL,
WFT_ICONRATIO_DPAD,
WFT_HIDETAGS,
WFT_NOTETRACKSOUNDMAP,
WFT_NUM_FIELD_TYPES
};
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,43 @@
#include "ZoneCreatorIW3.h"
#include "Game/IW3/GameIW3.h"
#include "Game/IW3/GameAssetPoolIW3.h"
using namespace IW3;
ZoneCreator::ZoneCreator()
{
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
{
AddAssetTypeName(assetType, GameAssetPoolIW3::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));
}
void ZoneCreator::CreateZoneAssetPools(Zone* zone) const
{
zone->m_pools = std::make_unique<GameAssetPoolIW3>(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_GameIW3.GetShortName();
}
std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const
{
auto zone = std::make_unique<Zone>(context.m_zone_name, 0, &g_GameIW3);
zone->m_pools = std::make_unique<GameAssetPoolIW3>(zone.get(), zone->m_priority);
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
zone->m_pools->InitPoolDynamic(assetType);
return zone;
}

View File

@ -0,0 +1,23 @@
#pragma once
#include <unordered_map>
#include <string>
#include "Zone/ZoneTypes.h"
#include "ZoneCreation/IZoneCreator.h"
namespace IW3
{
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);
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

@ -0,0 +1,43 @@
#include "AssetLoaderRawFile.h"
#include <cstring>
#include "Game/IW3/IW3.h"
#include "Pool/GlobalAssetPool.h"
using namespace IW3;
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->buffer = fileBuffer;
manager->AddAsset(ASSET_TYPE_RAWFILE, assetName, rawFile);
return true;
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "Game/IW3/IW3.h"
#include "AssetLoading/BasicAssetLoader.h"
#include "AssetLoading/IAssetLoadingManager.h"
#include "SearchPath/ISearchPath.h"
namespace IW3
{
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,152 @@
#include "ObjLoaderIW3.h"
#include "Game/IW4/GameIW4.h"
#include "Game/IW4/GameAssetPoolIW4.h"
#include "ObjContainer/IPak/IPak.h"
#include "ObjLoading.h"
#include "AssetLoaders/AssetLoaderRawFile.h"
#include "AssetLoading/AssetLoadingManager.h"
#include "Image/Texture.h"
#include "Image/IwiLoader.h"
using namespace IW3;
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_XANIMPARTS, XAnimParts))
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_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_CLIPMAP_PVS, clipMap_t))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_COMWORLD, ComWorld))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_GAMEWORLD_SP, GameWorldSp))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_GAMEWORLD_MP, GameWorldMp))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MAP_ENTS, MapEnts))
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(BASIC_LOADER(ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_WEAPON, WeaponDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SNDDRIVER_GLOBALS, SndDriverGlobals))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FX, FxEffectDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_IMPACT_FX, FxImpactTable))
REGISTER_ASSET_LOADER(AssetLoaderRawFile)
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_STRINGTABLE, StringTable))
#undef BASIC_LOADER
#undef REGISTER_ASSET_LOADER
}
bool ObjLoader::SupportsZone(Zone* zone) const
{
return zone->m_game == &g_GameIW4;
}
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)
{
// TODO: Load Texture from LoadDef here
}
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<GameAssetPoolIW4*>(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/IW3/IW3.h"
namespace IW3
{
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

View File

@ -0,0 +1,45 @@
#include "ZoneDefWriterIW3.h"
#include <cassert>
#include "Game/IW3/GameIW3.h"
#include "Game/IW3/GameAssetPoolIW3.h"
using namespace IW3;
bool ZoneDefWriter::CanHandleZone(Zone* zone) const
{
return zone->m_game == &g_GameIW3;
}
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<GameAssetPoolIW3*>(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 IW3
{
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

@ -1,6 +1,34 @@
ZoneCode = {}
ZoneCode.Assets = {
IW3 = {
"PhysPreset",
"XAnimParts",
"XModel",
"Material",
"MaterialTechniqueSet",
"GfxImage",
"snd_alias_list_t",
"SndCurve",
"LoadedSound",
"clipMap_t",
"ComWorld",
"GameWorldSp",
"GameWorldMp",
"MapEnts",
"GfxWorld",
"GfxLightDef",
"Font_s",
"MenuList",
"menuDef_t",
"LocalizeEntry",
"WeaponDef",
"FxEffectDef",
"FxImpactTable",
"RawFile",
"StringTable"
},
IW4 = {
"PhysPreset",
"PhysCollmap",
@ -207,6 +235,10 @@ function ZoneCode:project()
}
filter {}
filter "files:**/IW3.gen"
self:outputForAssets(self.Assets.IW3)
filter {}
filter "files:**/IW4.gen"
self:outputForAssets(self.Assets.IW4)
filter {}

View File

View File

View File

@ -0,0 +1,69 @@
// Game: Modern Warfare (IW3)
game IW3;
architecture x86;
// Game Assets
asset PhysPreset ASSET_TYPE_PHYSPRESET;
asset XAnimParts ASSET_TYPE_XANIMPARTS;
asset XModel ASSET_TYPE_XMODEL;
asset Material ASSET_TYPE_MATERIAL;
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_MP;
asset ComWorld ASSET_TYPE_COMWORLD;
asset GameWorldSp ASSET_TYPE_GAMEWORLD_SP;
asset GameWorldMp ASSET_TYPE_GAMEWORLD_MP;
asset MapEnts ASSET_TYPE_MAP_ENTS;
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 WeaponDef ASSET_TYPE_WEAPON;
asset FxEffectDef ASSET_TYPE_FX;
asset FxImpactTable ASSET_TYPE_IMPACT_FX;
asset RawFile ASSET_TYPE_RAWFILE;
asset StringTable ASSET_TYPE_STRINGTABLE;
// Setup blocks
block temp XFILE_BLOCK_TEMP default;
block runtime XFILE_BLOCK_RUNTIME default;
block runtime XFILE_BLOCK_LARGE_RUNTIME;
block runtime XFILE_BLOCK_PHYSICAL_RUNTIME;
block normal XFILE_BLOCK_VIRTUAL default;
block normal XFILE_BLOCK_LARGE;
block normal XFILE_BLOCK_PHYSICAL;
block normal XFILE_BLOCK_VERTEX;
block normal XFILE_BLOCK_INDEX;
#include "XAssets/PhysPreset.txt"
#include "XAssets/XAnimParts.txt"
#include "XAssets/XModel.txt"
#include "XAssets/Material.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/GameWorldSp.txt"
#include "XAssets/GameWorldMp.txt"
#include "XAssets/MapEnts.txt"
#include "XAssets/GfxWorld.txt"
#include "XAssets/LocalizeEntry.txt"
#include "XAssets/WeaponDef.txt"
#include "XAssets/MenuList.txt"
#include "XAssets/menuDef_t.txt"
#include "XAssets/FxEffectDef.txt"
#include "XAssets/FxImpactTable.txt"
#include "XAssets/GfxLightDef.txt"
#include "XAssets/Font_s.txt"
#include "XAssets/RawFile.txt"
#include "XAssets/StringTable.txt"
// EOF

View File

View File

@ -0,0 +1,7 @@
// =========================================
// PhysPreset
// =========================================
use PhysPreset;
set string name;
set name name;
set string sndAliasPrefix;

View File

@ -0,0 +1,68 @@
// =========================================
// XAnimParts
// =========================================
use XAnimParts;
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 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;
// 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,75 @@
// =========================================
// XModel
// =========================================
use XModel;
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 surfs numsurfs;
set count materialHandles numsurfs;
set count collSurfs numCollSurfs;
set count boneInfo numBones;
set reusable physGeoms;
set count physGeoms 1;
// PhysGeomList
use PhysGeomList;
set reusable geoms;
set count geoms count;
// PhysGeomInfo
use PhysGeomInfo;
// 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,70 @@
// =========================================
// clipMap_t
// =========================================
use clipMap_t;
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,203 @@
#include "ContentWriterIW3.h"
#include <cassert>
#include <sstream>
#include "Game/IW3/XAssets/clipmap_t/clipmap_t_write_db.h"
#include "Game/IW3/XAssets/comworld/comworld_write_db.h"
#include "Game/IW3/XAssets/font_s/font_s_write_db.h"
#include "Game/IW3/XAssets/fxeffectdef/fxeffectdef_write_db.h"
#include "Game/IW3/XAssets/fximpacttable/fximpacttable_write_db.h"
#include "Game/IW3/XAssets/gameworldmp/gameworldmp_write_db.h"
#include "Game/IW3/XAssets/gameworldsp/gameworldsp_write_db.h"
#include "Game/IW3/XAssets/gfximage/gfximage_write_db.h"
#include "Game/IW3/XAssets/gfxlightdef/gfxlightdef_write_db.h"
#include "Game/IW3/XAssets/gfxworld/gfxworld_write_db.h"
#include "Game/IW3/XAssets/loadedsound/loadedsound_write_db.h"
#include "Game/IW3/XAssets/localizeentry/localizeentry_write_db.h"
#include "Game/IW3/XAssets/mapents/mapents_write_db.h"
#include "Game/IW3/XAssets/material/material_write_db.h"
#include "Game/IW3/XAssets/materialtechniqueset/materialtechniqueset_write_db.h"
#include "Game/IW3/XAssets/menudef_t/menudef_t_write_db.h"
#include "Game/IW3/XAssets/menulist/menulist_write_db.h"
#include "Game/IW3/XAssets/physpreset/physpreset_write_db.h"
#include "Game/IW3/XAssets/rawfile/rawfile_write_db.h"
#include "Game/IW3/XAssets/snd_alias_list_t/snd_alias_list_t_write_db.h"
#include "Game/IW3/XAssets/sndcurve/sndcurve_write_db.h"
#include "Game/IW3/XAssets/stringtable/stringtable_write_db.h"
#include "Game/IW3/XAssets/weapondef/weapondef_write_db.h"
#include "Game/IW3/XAssets/xanimparts/xanimparts_write_db.h"
#include "Game/IW3/XAssets/xmodel/xmodel_write_db.h"
#include "Writing/WritingException.h"
using namespace IW3;
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_XANIMPARTS, XAnimParts, parts)
WRITE_ASSET(ASSET_TYPE_XMODEL, XModel, model)
WRITE_ASSET(ASSET_TYPE_MATERIAL, Material, material)
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_CLIPMAP_PVS, clipMap_t, clipMap)
WRITE_ASSET(ASSET_TYPE_COMWORLD, ComWorld, comWorld)
WRITE_ASSET(ASSET_TYPE_GAMEWORLD_SP, GameWorldSp, gameWorldSp)
WRITE_ASSET(ASSET_TYPE_GAMEWORLD_MP, GameWorldMp, gameWorldMp)
WRITE_ASSET(ASSET_TYPE_MAP_ENTS, MapEnts, mapEnts)
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_WEAPON, WeaponDef, weapon)
SKIP_ASSET(ASSET_TYPE_SNDDRIVER_GLOBALS, SndDriverGlobals, sndDriverGlobals)
WRITE_ASSET(ASSET_TYPE_FX, FxEffectDef, fx)
WRITE_ASSET(ASSET_TYPE_IMPACT_FX, FxImpactTable, impactFx)
WRITE_ASSET(ASSET_TYPE_RAWFILE, RawFile, rawfile)
WRITE_ASSET(ASSET_TYPE_STRINGTABLE, StringTable, stringTable)
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/IW3/IW3.h"
namespace IW3
{
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;
};
}