2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2026-06-17 14:02:12 +00:00

feat: initial T4 support (#807)

* feat: initial T4 support

* chore: adjust t4 symbols a bit for accuracy

* chore: add PackIndex asset to T4

* chore: remove unused AssetXModelPieces

* chore: add default and global asset pools loader for T4

* chore: use separate defines for T4 in ImageDumper

* chore: remove unnecessary namespaces in gfximage_actions

* chore: small things

* chore: fix T4 PhysPreset type

* chore: use proper XQuat2 type for T4 xanims

* chore: fix errors on T4 types

* chore: use iw3 like struct for XModelStreamInfo

* docs: add basic docs for T4

* chore: add basic ObjCompiler setup for T4

* chore: adjust loaded sound definition

* chore: make sure t4 material has the correct alignment

* chore: make sure t4 uses similar names for assets as other games

* fix: asset references should not be reusable

* chore: add content writer for t4

* feat: add t4 localize loader

* chore: reorder game ids to be alphabetically ordered

---------

Co-authored-by: Jan Laupetin <jan@laupetin.net>
This commit is contained in:
mo
2026-06-07 13:06:33 +01:00
committed by GitHub
parent 04628fc52c
commit 44d6710991
88 changed files with 6787 additions and 18 deletions
+4 -1
View File
@@ -3,6 +3,7 @@
#include "IW3/CommonAssetIW3.h"
#include "IW4/CommonAssetIW4.h"
#include "IW5/CommonAssetIW5.h"
#include "T4/CommonAssetT4.h"
#include "T5/CommonAssetT5.h"
#include "T6/CommonAssetT6.h"
@@ -10,13 +11,15 @@
ICommonAssetTypeMapper* ICommonAssetTypeMapper::GetCommonAssetMapperByGame(GameId gameId)
{
static ICommonAssetTypeMapper* assetTypeMappers[static_cast<unsigned>(GameId::COUNT)]{
static ICommonAssetTypeMapper* assetTypeMappers[]{
new IW3::CommonAssetTypeMapper(),
new IW4::CommonAssetTypeMapper(),
new IW5::CommonAssetTypeMapper(),
new T4::CommonAssetTypeMapper(),
new T5::CommonAssetTypeMapper(),
new T6::CommonAssetTypeMapper(),
};
static_assert(std::extent_v<decltype(assetTypeMappers)> == static_cast<unsigned>(GameId::COUNT));
assert(static_cast<unsigned>(gameId) < static_cast<unsigned>(GameId::COUNT));
auto* result = assetTypeMappers[static_cast<unsigned>(gameId)];
+4 -1
View File
@@ -3,6 +3,7 @@
#include "IW3/GameIW3.h"
#include "IW4/GameIW4.h"
#include "IW5/GameIW5.h"
#include "T4/GameT4.h"
#include "T5/GameT5.h"
#include "T6/GameT6.h"
#include "Utils/StringUtils.h"
@@ -11,13 +12,15 @@
IGame* IGame::GetGameById(GameId gameId)
{
static IGame* games[static_cast<unsigned>(GameId::COUNT)]{
static IGame* games[]{
new IW3::Game(),
new IW4::Game(),
new IW5::Game(),
new T4::Game(),
new T5::Game(),
new T6::Game(),
};
static_assert(std::extent_v<decltype(games)> == static_cast<unsigned>(GameId::COUNT));
assert(static_cast<unsigned>(gameId) < static_cast<unsigned>(GameId::COUNT));
auto* result = games[static_cast<unsigned>(gameId)];
+2
View File
@@ -15,6 +15,7 @@ enum class GameId : std::uint8_t
IW3,
IW4,
IW5,
T4,
T5,
T6,
@@ -48,6 +49,7 @@ static constexpr const char* GameId_Names[]{
"IW3",
"IW4",
"IW5",
"T4",
"T5",
"T6",
};
-2
View File
@@ -159,7 +159,6 @@ namespace IW3
WFT_NUM_FIELD_TYPES
};
using AssetXModelPieces = Asset<ASSET_TYPE_XMODELPIECES, XModelPieces>;
using AssetPhysPreset = Asset<ASSET_TYPE_PHYSPRESET, PhysPreset>;
using AssetXAnim = Asset<ASSET_TYPE_XANIMPARTS, XAnimParts>;
using AssetXModel = Asset<ASSET_TYPE_XMODEL, XModel>;
@@ -194,7 +193,6 @@ namespace IW3
using SubAssetPixelShader = SubAsset<SUB_ASSET_TYPE_PIXEL_SHADER, MaterialPixelShader>;
} // namespace IW3
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetXModelPieces, name);
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetPhysPreset, name);
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetXAnim, name);
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetXModel, name);
+104
View File
@@ -0,0 +1,104 @@
#include "CommonAssetT4.h"
#include "T4.h"
#include <cassert>
namespace T4
{
CommonAssetTypeMapper::CommonAssetTypeMapper() = default;
CommonAssetType CommonAssetTypeMapper::GameToCommonAssetType(const asset_type_t gameAssetType) const
{
static CommonAssetType lookupTable[static_cast<unsigned>(ASSET_TYPE_COUNT)]{
CommonAssetType::XMODEL_PIECES, // ASSET_TYPE_XMODELPIECES
CommonAssetType::PHYS_PRESET, // ASSET_TYPE_PHYSPRESET
CommonAssetType::PHYS_CONSTRAINTS, // ASSET_TYPE_PHYSCONSTRAINTS
CommonAssetType::DESTRUCTIBLE_DEF, // ASSET_TYPE_DESTRUCTIBLEDEF
CommonAssetType::XANIM, // ASSET_TYPE_XANIMPARTS
CommonAssetType::XMODEL, // ASSET_TYPE_XMODEL
CommonAssetType::MATERIAL, // ASSET_TYPE_MATERIAL
CommonAssetType::TECHNIQUE_SET, // ASSET_TYPE_TECHNIQUE_SET
CommonAssetType::IMAGE, // ASSET_TYPE_IMAGE
CommonAssetType::SOUND, // ASSET_TYPE_SOUND
CommonAssetType::LOADED_SOUND, // ASSET_TYPE_LOADED_SOUND
CommonAssetType::CLIP_MAP, // ASSET_TYPE_CLIPMAP
CommonAssetType::CLIP_MAP, // ASSET_TYPE_CLIPMAP_PVS
CommonAssetType::COM_WORLD, // ASSET_TYPE_COMWORLD
CommonAssetType::GAME_WORLD_SP, // ASSET_TYPE_GAMEWORLD_SP
CommonAssetType::GAME_WORLD_MP, // ASSET_TYPE_GAMEWORLD_MP
CommonAssetType::MAP_ENTS, // ASSET_TYPE_MAP_ENTS
CommonAssetType::GFX_WORLD, // ASSET_TYPE_GFXWORLD
CommonAssetType::LIGHT_DEF, // ASSET_TYPE_LIGHT_DEF
CommonAssetType::UI_MAP, // ASSET_TYPE_UI_MAP
CommonAssetType::FONT, // ASSET_TYPE_FONT
CommonAssetType::MENU_LIST, // ASSET_TYPE_MENULIST
CommonAssetType::MENU, // ASSET_TYPE_MENU
CommonAssetType::LOCALIZE_ENTRY, // ASSET_TYPE_LOCALIZE_ENTRY
CommonAssetType::WEAPON, // ASSET_TYPE_WEAPON
CommonAssetType::SOUND_DRIVER_GLOBALS, // ASSET_TYPE_SNDDRIVER_GLOBALS
CommonAssetType::FX, // ASSET_TYPE_FX
CommonAssetType::IMPACT_FX, // ASSET_TYPE_IMPACT_FX
CommonAssetType::AI_TYPE, // ASSET_TYPE_AITYPE
CommonAssetType::MP_TYPE, // ASSET_TYPE_MPTYPE
CommonAssetType::CHARACTER, // ASSET_TYPE_CHARACTER
CommonAssetType::XMODEL_ALIAS, // ASSET_TYPE_XMODELALIAS
CommonAssetType::RAW_FILE, // ASSET_TYPE_RAWFILE
CommonAssetType::STRING_TABLE, // ASSET_TYPE_STRINGTABLE
CommonAssetType::PACK_INDEX, // ASSET_TYPE_PACK_INDEX
};
assert(gameAssetType < ASSET_TYPE_COUNT);
return lookupTable[gameAssetType];
}
std::optional<asset_type_t> CommonAssetTypeMapper::CommonToGameAssetType(const CommonAssetType commonAssetType) const
{
#define MAP_COMMON(common, game) \
case common: \
return game;
switch (commonAssetType)
{
MAP_COMMON(CommonAssetType::XMODEL_PIECES, ASSET_TYPE_XMODELPIECES)
MAP_COMMON(CommonAssetType::PHYS_PRESET, ASSET_TYPE_PHYSPRESET)
MAP_COMMON(CommonAssetType::PHYS_CONSTRAINTS, ASSET_TYPE_PHYSCONSTRAINTS)
MAP_COMMON(CommonAssetType::DESTRUCTIBLE_DEF, ASSET_TYPE_DESTRUCTIBLEDEF)
MAP_COMMON(CommonAssetType::XANIM, ASSET_TYPE_XANIMPARTS)
MAP_COMMON(CommonAssetType::XMODEL, ASSET_TYPE_XMODEL)
MAP_COMMON(CommonAssetType::MATERIAL, ASSET_TYPE_MATERIAL)
MAP_COMMON(CommonAssetType::TECHNIQUE_SET, ASSET_TYPE_TECHNIQUE_SET)
MAP_COMMON(CommonAssetType::IMAGE, ASSET_TYPE_IMAGE)
MAP_COMMON(CommonAssetType::SOUND, ASSET_TYPE_SOUND)
MAP_COMMON(CommonAssetType::LOADED_SOUND, ASSET_TYPE_LOADED_SOUND)
MAP_COMMON(CommonAssetType::CLIP_MAP, ASSET_TYPE_CLIPMAP_PVS)
MAP_COMMON(CommonAssetType::COM_WORLD, ASSET_TYPE_COMWORLD)
MAP_COMMON(CommonAssetType::GAME_WORLD_SP, ASSET_TYPE_GAMEWORLD_SP)
MAP_COMMON(CommonAssetType::GAME_WORLD_MP, ASSET_TYPE_GAMEWORLD_MP)
MAP_COMMON(CommonAssetType::MAP_ENTS, ASSET_TYPE_MAP_ENTS)
MAP_COMMON(CommonAssetType::GFX_WORLD, ASSET_TYPE_GFXWORLD)
MAP_COMMON(CommonAssetType::LIGHT_DEF, ASSET_TYPE_LIGHT_DEF)
MAP_COMMON(CommonAssetType::UI_MAP, ASSET_TYPE_UI_MAP)
MAP_COMMON(CommonAssetType::FONT, ASSET_TYPE_FONT)
MAP_COMMON(CommonAssetType::MENU_LIST, ASSET_TYPE_MENULIST)
MAP_COMMON(CommonAssetType::MENU, ASSET_TYPE_MENU)
MAP_COMMON(CommonAssetType::LOCALIZE_ENTRY, ASSET_TYPE_LOCALIZE_ENTRY)
MAP_COMMON(CommonAssetType::WEAPON, ASSET_TYPE_WEAPON)
MAP_COMMON(CommonAssetType::SOUND_DRIVER_GLOBALS, ASSET_TYPE_SNDDRIVER_GLOBALS)
MAP_COMMON(CommonAssetType::FX, ASSET_TYPE_FX)
MAP_COMMON(CommonAssetType::IMPACT_FX, ASSET_TYPE_IMPACT_FX)
MAP_COMMON(CommonAssetType::AI_TYPE, ASSET_TYPE_AITYPE)
MAP_COMMON(CommonAssetType::MP_TYPE, ASSET_TYPE_MPTYPE)
MAP_COMMON(CommonAssetType::CHARACTER, ASSET_TYPE_CHARACTER)
MAP_COMMON(CommonAssetType::XMODEL_ALIAS, ASSET_TYPE_XMODELALIAS)
MAP_COMMON(CommonAssetType::RAW_FILE, ASSET_TYPE_RAWFILE)
MAP_COMMON(CommonAssetType::STRING_TABLE, ASSET_TYPE_STRINGTABLE)
MAP_COMMON(CommonAssetType::PACK_INDEX, ASSET_TYPE_PACK_INDEX)
default:
return std::nullopt;
}
#undef MAP_COMMON
}
} // namespace T4
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include "Game/CommonAsset.h"
namespace T4
{
class CommonAssetTypeMapper final : public ICommonAssetTypeMapper
{
public:
CommonAssetTypeMapper();
[[nodiscard]] CommonAssetType GameToCommonAssetType(asset_type_t gameAssetType) const override;
[[nodiscard]] std::optional<asset_type_t> CommonToGameAssetType(CommonAssetType commonAssetType) const override;
};
} // namespace T4
+35
View File
@@ -0,0 +1,35 @@
#include "CommonT4.h"
#include "Utils/Pack.h"
using namespace T4;
PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2])
{
return PackedTexCoords{pack32::Vec2PackTexCoordsVU(in)};
}
PackedUnitVec Common::Vec3PackUnitVec(const float (&in)[3])
{
return PackedUnitVec{pack32::Vec3PackUnitVecScaleBased(in)};
}
GfxColor Common::Vec4PackGfxColor(const float (&in)[4])
{
return GfxColor{pack32::Vec4PackGfxColor(in)};
}
void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2])
{
pack32::Vec2UnpackTexCoordsVU(in.packed, out);
}
void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3])
{
pack32::Vec3UnpackUnitVecScaleBased(in.packed, out);
}
void Common::Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4])
{
pack32::Vec4UnpackGfxColor(in.packed, out);
}
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include "T4.h"
#include "Utils/Djb2.h"
#include <iostream>
namespace T4
{
class Common
{
public:
static constexpr uint32_t R_HashString(const char* str, const uint32_t hash)
{
return djb2_xor_nocase(str, hash);
}
static constexpr uint32_t R_HashString(const char* string)
{
// Using djb2 with a 0 starting value makes a worse hash func apparently
// but who am I to judge
return R_HashString(string, 0u);
}
static PackedTexCoords Vec2PackTexCoords(const float (&in)[2]);
static PackedUnitVec Vec3PackUnitVec(const float (&in)[3]);
static GfxColor Vec4PackGfxColor(const float (&in)[4]);
static void Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2]);
static void Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3]);
static void Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4]);
};
} // namespace T4
+93
View File
@@ -0,0 +1,93 @@
#include "GameT4.h"
#include "T4.h"
#include <algorithm>
using namespace T4;
namespace
{
constexpr const char* ASSET_TYPE_NAMES[]{
"xmodelpieces",
"physpreset",
"physconstraints",
"destructibledef",
"xanim",
"xmodel",
"material",
"techniqueset",
"image",
"sound",
"loadedsound",
"clipmap_unused",
"clipmap",
"comworld",
"gameworldsp",
"gameworldmp",
"mapents",
"gfxworld",
"lightdef",
"uimap",
"font",
"menulist",
"menu",
"localize",
"weapon",
"snddriverglobals",
"fx",
"impactfx",
"aitype",
"mptype",
"character",
"xmodelalias",
"rawfile",
"stringtable",
"packindex",
};
static_assert(std::extent_v<decltype(ASSET_TYPE_NAMES)> == ASSET_TYPE_COUNT);
constexpr const char* SUB_ASSET_TYPE_NAMES[]{
"technique",
"vertexdecl",
"vertexshader",
"pixelshader",
};
static_assert(std::extent_v<decltype(SUB_ASSET_TYPE_NAMES)> == SUB_ASSET_TYPE_COUNT);
} // namespace
namespace T4
{
Game::Game()
: AbstractGame(ASSET_TYPE_NAMES, std::extent_v<decltype(ASSET_TYPE_NAMES)>, SUB_ASSET_TYPE_NAMES, std::extent_v<decltype(SUB_ASSET_TYPE_NAMES)>)
{
AddAssetTypeNameAlias<AssetTechniqueSet>("techset");
AddAssetTypeNameAlias<AssetLoadedSound>("loaded_sound");
AddAssetTypeNameAlias<AssetClipMap>("col_map_sp");
AddAssetTypeNameAlias<AssetClipMapPvs>("col_map_mp");
AddAssetTypeNameAlias<AssetComWorld>("com_map");
AddAssetTypeNameAlias<AssetGameWorldSp>("game_map_sp");
AddAssetTypeNameAlias<AssetGameWorldMp>("game_map_mp");
AddAssetTypeNameAlias<AssetMapEnts>("map_ents");
AddAssetTypeNameAlias<AssetGfxWorld>("gfx_map");
AddAssetTypeNameAlias<AssetLightDef>("gfxlightdef");
AddAssetTypeNameAlias<AssetMenuList>("menufile");
}
GameId Game::GetId() const
{
return GameId::T4;
}
const std::string& Game::GetFullName() const
{
static std::string fullName = "Call Of Duty: World at War";
return fullName;
}
const std::string& Game::GetShortName() const
{
static std::string shortName = "T4";
return shortName;
}
} // namespace T4
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include "Game/IGame.h"
namespace T4
{
class Game final : public AbstractGame
{
public:
Game();
[[nodiscard]] GameId GetId() const override;
[[nodiscard]] const std::string& GetFullName() const override;
[[nodiscard]] const std::string& GetShortName() const override;
};
} // namespace T4
+150
View File
@@ -0,0 +1,150 @@
#pragma once
// clang-format off: Order of includes matters here
#include "Game/IAsset.h"
#include "T4_Assets.h"
// clang-format on
namespace T4
{
enum XAssetType
{
ASSET_TYPE_XMODELPIECES,
ASSET_TYPE_PHYSPRESET,
ASSET_TYPE_PHYSCONSTRAINTS,
ASSET_TYPE_DESTRUCTIBLEDEF,
ASSET_TYPE_XANIMPARTS,
ASSET_TYPE_XMODEL,
ASSET_TYPE_MATERIAL,
ASSET_TYPE_TECHNIQUE_SET,
ASSET_TYPE_IMAGE,
ASSET_TYPE_SOUND,
ASSET_TYPE_LOADED_SOUND,
ASSET_TYPE_CLIPMAP,
ASSET_TYPE_CLIPMAP_PVS,
ASSET_TYPE_COMWORLD,
ASSET_TYPE_GAMEWORLD_SP,
ASSET_TYPE_GAMEWORLD_MP,
ASSET_TYPE_MAP_ENTS,
ASSET_TYPE_GFXWORLD,
ASSET_TYPE_LIGHT_DEF,
ASSET_TYPE_UI_MAP,
ASSET_TYPE_FONT,
ASSET_TYPE_MENULIST,
ASSET_TYPE_MENU,
ASSET_TYPE_LOCALIZE_ENTRY,
ASSET_TYPE_WEAPON,
ASSET_TYPE_SNDDRIVER_GLOBALS,
ASSET_TYPE_FX,
ASSET_TYPE_IMPACT_FX,
ASSET_TYPE_AITYPE,
ASSET_TYPE_MPTYPE,
ASSET_TYPE_CHARACTER,
ASSET_TYPE_XMODELALIAS,
ASSET_TYPE_RAWFILE,
ASSET_TYPE_STRINGTABLE,
ASSET_TYPE_PACK_INDEX,
ASSET_TYPE_COUNT,
ASSET_TYPE_STRING = ASSET_TYPE_COUNT,
ASSET_TYPE_ASSETLIST
};
enum SubAssetType
{
SUB_ASSET_TYPE_TECHNIQUE,
SUB_ASSET_TYPE_VERTEX_DECL,
SUB_ASSET_TYPE_VERTEX_SHADER,
SUB_ASSET_TYPE_PIXEL_SHADER,
SUB_ASSET_TYPE_COUNT
};
struct ScriptStringList
{
int count;
const char** strings;
};
struct XAsset
{
XAssetType type;
XAssetHeader header;
};
struct XAssetList
{
ScriptStringList stringList;
int assetCount;
XAsset* assets;
};
using AssetPhysPreset = Asset<ASSET_TYPE_PHYSPRESET, PhysPreset>;
using AssetPhysConstraints = Asset<ASSET_TYPE_PHYSCONSTRAINTS, PhysConstraints>;
using AssetDestructibleDef = Asset<ASSET_TYPE_DESTRUCTIBLEDEF, DestructibleDef>;
using AssetXAnim = Asset<ASSET_TYPE_XANIMPARTS, XAnimParts>;
using AssetXModel = Asset<ASSET_TYPE_XMODEL, XModel>;
using AssetMaterial = Asset<ASSET_TYPE_MATERIAL, Material>;
using AssetTechniqueSet = Asset<ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet>;
using AssetImage = Asset<ASSET_TYPE_IMAGE, GfxImage>;
using AssetSound = Asset<ASSET_TYPE_SOUND, snd_alias_list_t>;
using AssetLoadedSound = Asset<ASSET_TYPE_LOADED_SOUND, LoadedSound>;
using AssetClipMap = Asset<ASSET_TYPE_CLIPMAP, clipMap_t>;
using AssetClipMapPvs = Asset<ASSET_TYPE_CLIPMAP_PVS, clipMap_t>;
using AssetComWorld = Asset<ASSET_TYPE_COMWORLD, ComWorld>;
using AssetGameWorldSp = Asset<ASSET_TYPE_GAMEWORLD_SP, GameWorldSp>;
using AssetGameWorldMp = Asset<ASSET_TYPE_GAMEWORLD_MP, GameWorldMp>;
using AssetMapEnts = Asset<ASSET_TYPE_MAP_ENTS, MapEnts>;
using AssetGfxWorld = Asset<ASSET_TYPE_GFXWORLD, GfxWorld>;
using AssetLightDef = Asset<ASSET_TYPE_LIGHT_DEF, GfxLightDef>;
using AssetFont = Asset<ASSET_TYPE_FONT, Font_s>;
using AssetMenuList = Asset<ASSET_TYPE_MENULIST, MenuList>;
using AssetMenu = Asset<ASSET_TYPE_MENU, menuDef_t>;
using AssetLocalize = Asset<ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry>;
using AssetWeapon = Asset<ASSET_TYPE_WEAPON, WeaponDef>;
using AssetSoundDriverGlobals = Asset<ASSET_TYPE_SNDDRIVER_GLOBALS, SndDriverGlobals>;
using AssetFx = Asset<ASSET_TYPE_FX, FxEffectDef>;
using AssetImpactFx = Asset<ASSET_TYPE_IMPACT_FX, FxImpactTable>;
using AssetRawFile = Asset<ASSET_TYPE_RAWFILE, RawFile>;
using AssetStringTable = Asset<ASSET_TYPE_STRINGTABLE, StringTable>;
using AssetPackIndex = Asset<ASSET_TYPE_PACK_INDEX, PackIndex>;
using SubAssetTechnique = SubAsset<SUB_ASSET_TYPE_TECHNIQUE, MaterialTechnique>;
using SubAssetVertexDecl = SubAsset<SUB_ASSET_TYPE_VERTEX_DECL, MaterialVertexDeclaration>;
using SubAssetVertexShader = SubAsset<SUB_ASSET_TYPE_VERTEX_SHADER, MaterialVertexShader>;
using SubAssetPixelShader = SubAsset<SUB_ASSET_TYPE_PIXEL_SHADER, MaterialPixelShader>;
} // namespace T4
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetPhysPreset, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetPhysConstraints, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetDestructibleDef, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetXAnim, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetXModel, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetMaterial, info.name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetTechniqueSet, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetImage, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetSound, aliasName);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetLoadedSound, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetClipMap, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetClipMapPvs, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetComWorld, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetGameWorldSp, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetGameWorldMp, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetMapEnts, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetGfxWorld, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetLightDef, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetFont, fontName);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetMenuList, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetMenu, window.name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetLocalize, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetWeapon, szInternalName);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetSoundDriverGlobals, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetFx, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetImpactFx, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetRawFile, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetStringTable, name);
DEFINE_ASSET_NAME_ACCESSOR(T4::AssetPackIndex, name);
File diff suppressed because it is too large Load Diff
+1
View File
@@ -10,6 +10,7 @@ NLOHMANN_JSON_SERIALIZE_ENUM(GameId,
{GameId::IW3, "IW3"},
{GameId::IW4, "IW4"},
{GameId::IW5, "IW5"},
{GameId::T4, "T4" },
{GameId::T5, "T5" },
{GameId::T6, "T6" },
});
+1
View File
@@ -2,6 +2,7 @@ export enum GameId {
IW3 = "IW3",
IW4 = "IW4",
IW5 = "IW5",
T4 = "T4",
T5 = "T5",
T6 = "T6",
}
@@ -0,0 +1,39 @@
#include "ObjCompilerT4.h"
#include "Game/T4/T4.h"
#include "Image/ImageIwdPostProcessor.h"
#include <memory>
using namespace T4;
namespace
{
void ConfigureCompilers(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath) {}
void ConfigurePostProcessors(AssetCreatorCollection& collection,
Zone& zone,
const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath,
ZoneAssetCreationStateContainer& zoneStates,
IOutputPath& outDir)
{
auto& memory = zone.Memory();
if (image::IwdPostProcessor<AssetImage>::AppliesToZoneDefinition(zoneDefinition))
collection.AddAssetPostProcessor(std::make_unique<image::IwdPostProcessor<AssetImage>>(zoneDefinition, searchPath, zoneStates, outDir));
}
} // namespace
void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection,
Zone& zone,
const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath,
IGdtQueryable& gdt,
ZoneAssetCreationStateContainer& zoneStates,
IOutputPath& outDir,
IOutputPath& cacheDir) const
{
ConfigureCompilers(collection, zone, searchPath);
ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, zoneStates, outDir);
}
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include "IObjCompiler.h"
namespace T4
{
class ObjCompiler final : public IObjCompiler
{
public:
void ConfigureCreatorCollection(AssetCreatorCollection& collection,
Zone& zone,
const ZoneDefinitionContext& zoneDefinition,
ISearchPath& searchPath,
IGdtQueryable& gdt,
ZoneAssetCreationStateContainer& zoneStates,
IOutputPath& outDir,
IOutputPath& cacheDir) const override;
};
} // namespace T4
+3 -1
View File
@@ -3,6 +3,7 @@
#include "Game/IW3/ObjCompilerIW3.h"
#include "Game/IW4/ObjCompilerIW4.h"
#include "Game/IW5/ObjCompilerIW5.h"
#include "Game/T4/ObjCompilerT4.h"
#include "Game/T5/ObjCompilerT5.h"
#include "Game/T6/ObjCompilerT6.h"
@@ -10,10 +11,11 @@
const IObjCompiler* IObjCompiler::GetObjCompilerForGame(GameId game)
{
static const IObjCompiler* objCompilers[static_cast<unsigned>(GameId::COUNT)]{
static const IObjCompiler* objCompilers[]{
new IW3::ObjCompiler(),
new IW4::ObjCompiler(),
new IW5::ObjCompiler(),
new T4::ObjCompiler(),
new T5::ObjCompiler(),
new T6::ObjCompiler(),
};
@@ -0,0 +1,45 @@
#include "AssetLoaderLocalizeT4.h"
#include "Localize/CommonLocalizeLoader.h"
using namespace T4;
namespace
{
class LocalizeLoader final : public AssetCreator<AssetLocalize>, public CommonLocalizeLoader
{
public:
LocalizeLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
: CommonLocalizeLoader(searchPath, zone),
m_memory(memory)
{
}
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
{
return CreateLocalizeAsset(assetName, context);
}
protected:
AssetCreationResult CreateAssetFromCommonAsset(const CommonLocalizeEntry& localizeEntry, AssetCreationContext& context) override
{
auto* asset = m_memory.Alloc<LocalizeEntry>();
asset->name = m_memory.Dup(localizeEntry.m_key.c_str());
asset->value = m_memory.Dup(localizeEntry.m_value.c_str());
return AssetCreationResult::Success(context.AddAsset<AssetLocalize>(localizeEntry.m_key, asset));
}
private:
MemoryManager& m_memory;
};
} // namespace
namespace localize
{
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLoaderT4(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
{
return std::make_unique<LocalizeLoader>(memory, searchPath, zone);
}
} // namespace localize
@@ -0,0 +1,14 @@
#pragma once
#include "Asset/IAssetCreator.h"
#include "Game/T4/T4.h"
#include "SearchPath/ISearchPath.h"
#include "Utils/MemoryManager.h"
#include "Zone/Zone.h"
#include <memory>
namespace localize
{
std::unique_ptr<AssetCreator<T4::AssetLocalize>> CreateLoaderT4(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
} // namespace localize
+97
View File
@@ -0,0 +1,97 @@
#include "ObjLoaderT4.h"
#include "Asset/GlobalAssetPoolsLoader.h"
#include "Game/T4/AssetMarkerT4.h"
#include "Game/T4/T4.h"
#include "Localize/AssetLoaderLocalizeT4.h"
using namespace T4;
void ObjLoader::LoadReferencedContainersForZone(ISearchPath& searchPath, Zone& zone) const {}
void ObjLoader::UnloadContainersOfZone(Zone& zone) const {}
namespace
{
void ConfigureDefaultCreators(AssetCreatorCollection& collection, const Zone& zone)
{
auto& memory = zone.Memory();
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetPhysPreset>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetPhysConstraints>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetDestructibleDef>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetXAnim>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetXModel>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetMaterial>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetTechniqueSet>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetImage>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetSound>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetLoadedSound>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetClipMap>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetClipMapPvs>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetComWorld>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetGameWorldSp>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetGameWorldMp>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetMapEnts>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetGfxWorld>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetLightDef>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetFont>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetMenuList>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetMenu>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetLocalize>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetWeapon>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetSoundDriverGlobals>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetFx>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetImpactFx>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetRawFile>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetStringTable>>(memory));
collection.AddDefaultAssetCreator(std::make_unique<DefaultAssetCreator<AssetPackIndex>>(memory));
}
void ConfigureGlobalAssetPoolsLoaders(AssetCreatorCollection& collection, Zone& zone)
{
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetPhysPreset>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetPhysConstraints>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetDestructibleDef>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetXAnim>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetXModel>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetMaterial>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetTechniqueSet>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetImage>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetSound>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetLoadedSound>>(zone));
// collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetClipMap>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetClipMapPvs>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetComWorld>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetGameWorldSp>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetGameWorldMp>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetMapEnts>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetGfxWorld>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetLightDef>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetFont>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetMenuList>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetMenu>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetLocalize>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetWeapon>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetSoundDriverGlobals>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetFx>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetImpactFx>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetRawFile>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetStringTable>>(zone));
collection.AddAssetCreator(std::make_unique<GlobalAssetPoolsLoader<AssetPackIndex>>(zone));
}
void ConfigureLoaders(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath, IGdtQueryable& gdt)
{
auto& memory = zone.Memory();
collection.AddAssetCreator(localize::CreateLoaderT4(memory, searchPath, zone));
}
} // namespace
void ObjLoader::ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath, IGdtQueryable& gdt) const
{
ConfigureDefaultCreators(collection, zone);
ConfigureLoaders(collection, zone, searchPath, gdt);
ConfigureGlobalAssetPoolsLoaders(collection, zone);
}
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include "IObjLoader.h"
#include "SearchPath/ISearchPath.h"
namespace T4
{
class ObjLoader final : public IObjLoader
{
public:
void LoadReferencedContainersForZone(ISearchPath& searchPath, Zone& zone) const override;
void UnloadContainersOfZone(Zone& zone) const override;
void ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath, IGdtQueryable& gdt) const override;
};
} // namespace T4
+3 -1
View File
@@ -3,6 +3,7 @@
#include "Game/IW3/ObjLoaderIW3.h"
#include "Game/IW4/ObjLoaderIW4.h"
#include "Game/IW5/ObjLoaderIW5.h"
#include "Game/T4/ObjLoaderT4.h"
#include "Game/T5/ObjLoaderT5.h"
#include "Game/T6/ObjLoaderT6.h"
@@ -10,10 +11,11 @@
const IObjLoader* IObjLoader::GetObjLoaderForGame(GameId game)
{
static const IObjLoader* zoneCreators[static_cast<unsigned>(GameId::COUNT)]{
static const IObjLoader* zoneCreators[]{
new IW3::ObjLoader(),
new IW4::ObjLoader(),
new IW5::ObjLoader(),
new T4::ObjLoader(),
new T5::ObjLoader(),
new T6::ObjLoader(),
};
@@ -0,0 +1,44 @@
#include "LocalizeDumperT4.h"
#include "Dumping/Localize/StringFileDumper.h"
#include "Localize/LocalizeCommon.h"
#include "Utils/Logging/Log.h"
#include <format>
using namespace T4;
namespace localize
{
void DumperT4::Dump(AssetDumpingContext& context)
{
auto localizeAssets = context.m_zone.m_pools.PoolAssets<AssetLocalize>();
if (localizeAssets.empty())
return;
const auto language = LocalizeCommon::GetNameOfLanguage(context.m_zone.m_language);
const auto assetFile = context.OpenAssetFile(std::format("{}/localizedstrings/{}.str", language, context.m_zone.m_name));
if (assetFile)
{
StringFileDumper stringFileDumper(context.m_zone, *assetFile);
stringFileDumper.SetLanguageName(language);
stringFileDumper.SetConfigFile(R"(G:\CoD5\cod\cod5\bin\StringEd.cfg)");
stringFileDumper.SetNotes("");
for (const auto* localizeEntry : localizeAssets)
{
stringFileDumper.WriteLocalizeEntry(localizeEntry->m_name, localizeEntry->Asset()->value);
}
stringFileDumper.Finalize();
}
else
{
con::error("Could not create string file for dumping localized strings of zone '{}'", context.m_zone.m_name);
}
context.IncrementProgress();
}
} // namespace localize
@@ -0,0 +1,13 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/T4/T4.h"
namespace localize
{
class DumperT4 final : public AbstractSingleProgressAssetDumper<T4::AssetLocalize>
{
public:
void Dump(AssetDumpingContext& context) override;
};
} // namespace localize
+16
View File
@@ -0,0 +1,16 @@
#include "ObjWriterT4.h"
#include "Game/T4/Image/ImageDumperT4.h"
#include "Localize/LocalizeDumperT4.h"
#include "RawFile/RawFileDumperT4.h"
#include "StringTable/StringTableDumperT4.h"
using namespace T4;
void ObjWriter::RegisterAssetDumpers(AssetDumpingContext& context)
{
RegisterAssetDumper(std::make_unique<image::DumperT4>());
RegisterAssetDumper(std::make_unique<localize::DumperT4>());
RegisterAssetDumper(std::make_unique<raw_file::DumperT4>());
RegisterAssetDumper(std::make_unique<string_table::DumperT4>());
}
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include "ObjWriter.h"
namespace T4
{
class ObjWriter final : public IObjWriter
{
protected:
void RegisterAssetDumpers(AssetDumpingContext& context) override;
};
} // namespace T4
@@ -0,0 +1,18 @@
#include "RawFileDumperT4.h"
using namespace T4;
namespace raw_file
{
void DumperT4::DumpAsset(AssetDumpingContext& context, const XAssetInfo<RawFile>& asset)
{
const auto* rawFile = asset.Asset();
const auto assetFile = context.OpenAssetFile(asset.m_name);
if (!assetFile)
return;
auto& stream = *assetFile;
stream.write(rawFile->buffer, rawFile->len);
}
} // namespace raw_file
@@ -0,0 +1,13 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/T4/T4.h"
namespace raw_file
{
class DumperT4 final : public AbstractAssetDumper<T4::AssetRawFile>
{
protected:
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<T4::RawFile>& asset) override;
};
} // namespace raw_file
@@ -0,0 +1,29 @@
#include "StringTableDumperT4.h"
#include "Csv/CsvStream.h"
using namespace T4;
namespace string_table
{
void DumperT4::DumpAsset(AssetDumpingContext& context, const XAssetInfo<StringTable>& asset)
{
const auto* stringTable = asset.Asset();
const auto assetFile = context.OpenAssetFile(asset.m_name);
if (!assetFile)
return;
CsvOutputStream csv(*assetFile);
for (auto row = 0; row < stringTable->rowCount; row++)
{
for (auto column = 0; column < stringTable->columnCount; column++)
{
csv.WriteColumn(stringTable->values[column + row * stringTable->columnCount]);
}
csv.NextRow();
}
}
} // namespace string_table
@@ -0,0 +1,13 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/T4/T4.h"
namespace string_table
{
class DumperT4 final : public AbstractAssetDumper<T4::AssetStringTable>
{
protected:
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<T4::StringTable>& asset) override;
};
} // namespace string_table
@@ -1,4 +1,4 @@
#options GAME (IW3, IW4, IW5, T5, T6)
#options GAME (IW3, IW4, IW5, T4, T5, T6)
#filename "Game/" + GAME + "/Image/ImageDumper" + GAME + ".cpp"
@@ -8,6 +8,10 @@
#define FEATURE_IW3
#define DX9
#define IWI6
#elif GAME == "T4"
#define FEATURE_T4
#define DX9
#define IWI6
#elif GAME == "IW4"
#define FEATURE_IW4
#define DX9
@@ -80,7 +84,7 @@ namespace
#endif
const auto& loadDef = *image.texture.loadDef;
#ifdef FEATURE_IW3
#if defined(FEATURE_IW3) || defined(FEATURE_T4)
textureLoader.Width(loadDef.dimensions[0]).Height(loadDef.dimensions[1]).Depth(loadDef.dimensions[2]);
#else
textureLoader.Width(image.width).Height(image.height).Depth(image.depth);
+1 -1
View File
@@ -1,4 +1,4 @@
#options GAME(IW3, IW4, IW5, T5, T6)
#options GAME(IW3, IW4, IW5, T4, T5, T6)
#filename "Game/" + GAME + "/Image/ImageDumper" + GAME + ".h"
+3 -1
View File
@@ -3,6 +3,7 @@
#include "Game/IW3/ObjWriterIW3.h"
#include "Game/IW4/ObjWriterIW4.h"
#include "Game/IW5/ObjWriterIW5.h"
#include "Game/T4/ObjWriterT4.h"
#include "Game/T5/ObjWriterT5.h"
#include "Game/T6/ObjWriterT6.h"
#include "ObjWriting.h"
@@ -40,10 +41,11 @@ void IObjWriter::RegisterAssetDumper(std::unique_ptr<IAssetDumper> dumper)
IObjWriter* IObjWriter::GetObjWriterForGame(GameId game)
{
static IObjWriter* objWriters[static_cast<unsigned>(GameId::COUNT)]{
static IObjWriter* objWriters[]{
new IW3::ObjWriter(),
new IW4::ObjWriter(),
new IW5::ObjWriter(),
new T4::ObjWriter(),
new T5::ObjWriter(),
new T6::ObjWriter(),
};
+31
View File
@@ -110,6 +110,37 @@ ZoneCode.Assets = {
"AddonMapEnts",
},
T4 = {
"PhysPreset",
"PhysConstraints",
"DestructibleDef",
"XAnimParts",
"XModel",
"Material",
"MaterialTechniqueSet",
"GfxImage",
"snd_alias_list_t",
"SndDriverGlobals",
"LoadedSound",
"clipMap_t",
"ComWorld",
"GameWorldSp",
"GameWorldMp",
"MapEnts",
"GfxWorld",
"GfxLightDef",
"Font_s",
"MenuList",
"menuDef_t",
"LocalizeEntry",
"WeaponDef",
"FxEffectDef",
"FxImpactTable",
"RawFile",
"StringTable",
"PackIndex",
},
T5 = {
"PhysPreset",
"PhysConstraints",
+1
View File
@@ -0,0 +1 @@
# This file exists for automatically generating zone loading code.
+71
View File
@@ -0,0 +1,71 @@
// Game: World at War (T4)
game T4;
wordsize 32;
// Game Assets
asset PhysPreset AssetPhysPreset;
asset PhysConstraints AssetPhysConstraints;
asset DestructibleDef AssetDestructibleDef;
asset XAnimParts AssetXAnim;
asset XModel AssetXModel;
asset Material AssetMaterial;
asset MaterialTechniqueSet AssetTechniqueSet;
asset GfxImage AssetImage;
asset snd_alias_list_t AssetSound;
asset SndDriverGlobals AssetSoundDriverGlobals;
asset LoadedSound AssetLoadedSound;
asset clipMap_t AssetClipMapPvs;
asset ComWorld AssetComWorld;
asset GameWorldSp AssetGameWorldSp;
asset GameWorldMp AssetGameWorldMp;
asset MapEnts AssetMapEnts;
asset GfxWorld AssetGfxWorld;
asset GfxLightDef AssetLightDef;
asset Font_s AssetFont;
asset MenuList AssetMenuList;
asset menuDef_t AssetMenu;
asset LocalizeEntry AssetLocalize;
asset WeaponDef AssetWeapon;
asset FxEffectDef AssetFx;
asset FxImpactTable AssetImpactFx;
asset RawFile AssetRawFile;
asset StringTable AssetStringTable;
asset PackIndex AssetPackIndex;
// 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;
#include "XAssets/PhysPreset.txt"
#include "XAssets/PhysConstraints.txt"
#include "XAssets/DestructibleDef.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/SndDriverGlobals.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/FxEffectDef.txt"
#include "XAssets/LocalizeEntry.txt"
#include "XAssets/WeaponDef.txt"
#include "XAssets/MenuList.txt"
#include "XAssets/menuDef_t.txt"
#include "XAssets/FxImpactTable.txt"
#include "XAssets/GfxLightDef.txt"
#include "XAssets/Font_s.txt"
#include "XAssets/RawFile.txt"
#include "XAssets/StringTable.txt"
#include "XAssets/PackIndex.txt"
+12
View File
@@ -0,0 +1,12 @@
#pragma once
// Entry point for T4 code generation
// clang-format off: Order of includes matters here
#include "../Common.h"
#include "../../../Common/Game/T4/T4_Assets.h"
// clang-format on
// EOF
+18
View File
@@ -0,0 +1,18 @@
// =========================================
// ComWorld
// =========================================
use ComWorld;
set block XFILE_BLOCK_TEMP;
set string name;
set count primaryLights primaryLightCount;
set allocalign waterCells 4;
set count waterCells numWaterCells;
set count burnableCells numBurnableCells;
// ComPrimaryLight
use ComPrimaryLight;
set string defName;
// ComBurnableCell
use ComBurnableCell;
set count data 32;
@@ -0,0 +1,27 @@
// =========================================
// DestructibleDef
// =========================================
use DestructibleDef;
set block XFILE_BLOCK_TEMP;
set string name;
set count pieces numPieces;
// DestructiblePiece
use DestructiblePiece;
set string attachBone;
set scriptstring attachBoneHash;
set scriptstring enableLabel;
// DestructibleModel
use DestructibleModel;
set string breakNotify;
set string loopSound;
// 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;
+8
View File
@@ -0,0 +1,8 @@
// =========================================
// Font_s
// =========================================
use Font_s;
set block XFILE_BLOCK_TEMP;
set string fontName;
set reusable glyphs;
set count glyphs glyphCount;
@@ -0,0 +1,44 @@
// =========================================
// FxEffectDef
// =========================================
use FxEffectDef;
set block XFILE_BLOCK_TEMP;
set string 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;
// FxEffectDefRef
use FxEffectDefRef;
set condition handle never;
set string name;
set assetref name AssetFx;
// FxTrailDef
use FxTrailDef;
set count verts vertCount;
set count inds indCount;
@@ -0,0 +1,7 @@
// =========================================
// FxImpactTable
// =========================================
use FxImpactTable;
set block XFILE_BLOCK_TEMP;
set string name;
set count table 16;
@@ -0,0 +1,6 @@
// =========================================
// GameWorldMp
// =========================================
use GameWorldMp;
set block XFILE_BLOCK_TEMP;
set string name;
@@ -0,0 +1,39 @@
// =========================================
// GameWorldSp
// =========================================
use GameWorldSp;
set block XFILE_BLOCK_TEMP;
set string name;
// PathData
use PathData;
set count nodes nodeCount;
set block basenodes XFILE_BLOCK_RUNTIME;
set count basenodes nodeCount;
set count chainNodeForNode nodeCount;
set count nodeForChainNode nodeCount;
set count pathVis visBytes;
set count nodeTree nodeTreeCount;
// pathnode_t
set condition pathnode_t::transient never;
// pathnode_constant_t
use pathnode_constant_t;
set scriptstring targetname;
set scriptstring script_linkName;
set scriptstring script_noteworthy;
set scriptstring target;
set scriptstring animscript;
set count Links totalLinkCount;
// pathnode_dynamic_t
set condition pathnode_dynamic_t::pOwner never;
// pathnode_tree_t
use pathnode_tree_t;
set condition u::child axis >= 0;
set reusable u::child;
// pathnode_tree_nodes_t
set count pathnode_tree_nodes_t::nodes nodeCount;
+20
View File
@@ -0,0 +1,20 @@
// =========================================
// GfxImage
// =========================================
use GfxImage;
set block XFILE_BLOCK_TEMP;
set action OnImageLoaded(GfxImage);
set string name;
reorder:
name
texture;
// GfxTexture
use GfxTexture;
set reusable loadDef;
set block loadDef XFILE_BLOCK_TEMP;
// GfxImageLoadDef
use GfxImageLoadDef;
set action LoadImageData(GfxImageLoadDef, GfxImage);
set arraysize data resourceSize;
@@ -0,0 +1,6 @@
// =========================================
// GfxLightDef
// =========================================
use GfxLightDef;
set block XFILE_BLOCK_TEMP;
set string name;
+138
View File
@@ -0,0 +1,138 @@
// =========================================
// GfxWorld
// =========================================
use GfxWorld;
set block XFILE_BLOCK_TEMP;
set string name;
set string baseName;
set count indices indexCount;
set count skyStartSurfs skySurfCount;
set string skyBoxModel;
set reusable sunLight;
set count reflectionProbes reflectionProbeCount;
set block reflectionProbeTextures XFILE_BLOCK_RUNTIME;
set count reflectionProbeTextures reflectionProbeCount;
set count coronas coronaCount;
set count cells dpvsPlanes::cellCount;
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 models modelCount;
set count materialMemory materialMemoryCount;
set block cellCasterBits XFILE_BLOCK_RUNTIME;
set count cellCasterBits dpvsPlanes::cellCount * ((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 - sunPrimaryLightIndex - 1) * 0x2000;
set block primaryLightDynEntShadowVis XFILE_BLOCK_RUNTIME;
set count primaryLightDynEntShadowVis[0] dpvsDyn::dynEntClientCount[0] * (primaryLightCount - sunPrimaryLightIndex - 1);
set count primaryLightDynEntShadowVis[1] dpvsDyn::dynEntClientCount[1] * (primaryLightCount - sunPrimaryLightIndex - 1);
set block nonSunPrimaryLightForModelDynEnt XFILE_BLOCK_RUNTIME;
set count nonSunPrimaryLightForModelDynEnt dpvsDyn::dynEntClientCount[0];
set count shadowGeom primaryLightCount;
set count lightRegion primaryLightCount;
set count worldLodChains worldLodChainCount;
set count worldLodInfos worldLodInfoCount;
set count worldLodSurfaces worldLodSurfaceCount;
reorder:
...
materialMemory
vd
vld;
// 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 * 0x100;
// GfxCell
use GfxCell;
set count aabbTree aabbTreeCount;
set count portals portalCount;
set count cullGroups cullGroupCount;
set count reflectionProbes reflectionProbeCount;
// GfxAabbTree
use GfxAabbTree;
set reusable smodelIndexes;
set count smodelIndexes smodelIndexCount;
// GfxPortal
use GfxPortal;
set condition writable never;
set reusable cell;
set count vertices vertexCount;
// GfxLightGrid
use GfxLightGrid;
set count rowDataStart maxs[rowAxis] - mins[rowAxis] + 1;
set count rawRowData rawRowDataSize;
set count entries entryCount;
set count colors colorCount;
// GfxWorldVertexData
use GfxWorldVertexData;
set count vertices GfxWorld::vertexCount;
set condition worldVb never;
// GfxWorldVertexLayerData
use GfxWorldVertexLayerData;
set count data GfxWorld::vertexLayerDataSize;
set condition layerVb never;
// GfxShadowGeometry
use GfxShadowGeometry;
set count sortedSurfIndex surfaceCount;
set count smodelIndex smodelCount;
// GfxLightRegion
use GfxLightRegion;
set count hulls hullCount;
// GfxLightRegionHull
use GfxLightRegionHull;
set count 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 block lodData XFILE_BLOCK_RUNTIME;
set count lodData 2 * smodelVisDataCount;
set count sortedSurfIndex staticSurfaceCount;
set count smodelInsts smodelCount;
set count surfaces GfxWorld::surfaceCount;
set count cullGroups GfxWorld::cullGroupCount;
set count smodelDrawInsts smodelCount;
set block surfaceMaterials XFILE_BLOCK_RUNTIME;
set count surfaceMaterials staticSurfaceCount;
set allocalign surfaceMaterials 4;
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];
// GfxWaterBuffer
use GfxWaterBuffer;
set count buffer bufferSize / 16;
@@ -0,0 +1,10 @@
// =========================================
// LoadedSound
// =========================================
use LoadedSound;
set block XFILE_BLOCK_TEMP;
set string name;
// snd_asset
use snd_asset;
set count data data_size;
@@ -0,0 +1,7 @@
// =========================================
// LocalizeEntry
// =========================================
use LocalizeEntry;
set block XFILE_BLOCK_TEMP;
set string name;
set string value;
+7
View File
@@ -0,0 +1,7 @@
// =========================================
// MapEnts
// =========================================
use MapEnts;
set block XFILE_BLOCK_TEMP;
set string name;
set count entityString numEntityChars;
+23
View File
@@ -0,0 +1,23 @@
// =========================================
// Material
// =========================================
use Material;
set block XFILE_BLOCK_TEMP;
set allocalign Material 4;
set string 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;
@@ -0,0 +1,55 @@
// =========================================
// MaterialTechniqueSet
// =========================================
use MaterialTechniqueSet;
set block XFILE_BLOCK_TEMP;
set string 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;
set reusable vertexDecl;
set reusable vertexShader;
set reusable pixelShader;
// MaterialShaderArgument
use MaterialShaderArgument;
set condition u::literalConst type == MTL_ARG_LITERAL_VERTEX_CONST
|| type == MTL_ARG_LITERAL_PIXEL_CONST;
set reusable u::literalConst;
set condition u::codeConst type == MTL_ARG_CODE_VERTEX_CONST
|| type == MTL_ARG_CODE_PIXEL_CONST;
set condition u::codeSampler type == MTL_ARG_CODE_PIXEL_SAMPLER;
set condition u::nameHash type == MTL_ARG_MATERIAL_VERTEX_CONST
|| type == MTL_ARG_MATERIAL_PIXEL_CONST || type == MTL_ARG_MATERIAL_PIXEL_SAMPLER;
// MaterialPixelShader
set string MaterialPixelShader::name;
// GfxPixelShaderLoadDef
set count GfxPixelShaderLoadDef::program programSize;
// MaterialPixelShaderProgram
set condition MaterialPixelShaderProgram::ps never;
// MaterialVertexStreamRouting
set condition MaterialVertexStreamRouting::decl never;
// MaterialVertexShader
set string MaterialVertexShader::name;
// GfxVertexShaderLoadDef
set count GfxVertexShaderLoadDef::program programSize;
// MaterialVertexShaderProgram
set condition MaterialVertexShaderProgram::vs never;
@@ -0,0 +1,7 @@
// =========================================
// MenuList
// =========================================
use MenuList;
set block XFILE_BLOCK_TEMP;
set string name;
set count menus menuCount;
@@ -0,0 +1,7 @@
// =========================================
// PackIndex
// =========================================
use PackIndex;
set block XFILE_BLOCK_TEMP;
set string name;
set count entries header::count;
@@ -0,0 +1,13 @@
// =========================================
// PhysConstraints
// =========================================
use PhysConstraints;
set block XFILE_BLOCK_TEMP;
set string name;
use PhysConstraint;
set scriptstring targetname;
set scriptstring target_ent1;
set string target_bone1;
set scriptstring target_ent2;
set string target_bone2;
@@ -0,0 +1,7 @@
// =========================================
// PhysPreset
// =========================================
use PhysPreset;
set block XFILE_BLOCK_TEMP;
set string name;
set string sndAliasPrefix;
+7
View File
@@ -0,0 +1,7 @@
// =========================================
// RawFile
// =========================================
use RawFile;
set block XFILE_BLOCK_TEMP;
set string name;
set count buffer len + 1;
@@ -0,0 +1,6 @@
// =========================================
// SndDriverGlobals
// =========================================
use SndDriverGlobals;
set block XFILE_BLOCK_TEMP;
set string name;
@@ -0,0 +1,8 @@
// =========================================
// StringTable
// =========================================
use StringTable;
// String table is not in the temp block for some reason. nice.
set string name;
set string values;
set count values columnCount * rowCount;
@@ -0,0 +1,64 @@
// =========================================
// WeaponDef
// =========================================
use WeaponDef;
set block XFILE_BLOCK_TEMP;
set string szInternalName;
set string szDisplayName;
set string szOverlayName;
set string szXAnims;
set assetref szXAnims AssetXAnim;
set string szModeName;
set scriptstring hideTags;
set scriptstring notetrackSoundMapKeys;
set scriptstring notetrackSoundMapValues;
set reusable bounceSound;
set count bounceSound 31;
set string standMountedWeapdef;
set string crouchMountedWeapdef;
set string proneMountedWeapdef;
set string szAmmoName;
set string szClipName;
set string szSharedAmmoCapName;
set string szAltWeaponName;
set string aiVsAiAccuracyGraphName;
set string aiVsPlayerAccuracyGraphName;
set reusable aiVsAiAccuracyGraphKnots;
set count aiVsAiAccuracyGraphKnots aiVsAiAccuracyGraphKnotCount;
set reusable aiVsPlayerAccuracyGraphKnots;
set count aiVsPlayerAccuracyGraphKnots aiVsPlayerAccuracyGraphKnotCount;
set reusable originalAiVsAiAccuracyGraphKnots;
set count originalAiVsAiAccuracyGraphKnots aiVsAiAccuracyGraphKnotCount; // yeah it does not use original count
set reusable originalAiVsPlayerAccuracyGraphKnots;
set count originalAiVsPlayerAccuracyGraphKnots aiVsPlayerAccuracyGraphKnotCount; // yeah it does not use original count
set string szUseHintString;
set string dropHintString;
set string szScript;
set string fireRumble;
set string meleeImpactRumble;
set string flameTableFirstPerson;
set string flameTableThirdPerson;
set reusable flameTableFirstPersonPtr;
set reusable flameTableThirdPersonPtr;
reorder:
...
aiVsAiAccuracyGraphName
aiVsAiAccuracyGraphKnots
originalAiVsAiAccuracyGraphKnots
aiVsPlayerAccuracyGraphName
aiVsPlayerAccuracyGraphKnots
originalAiVsPlayerAccuracyGraphKnots;
// 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;
// flameTable
use flameTable;
set string name;
@@ -0,0 +1,68 @@
// =========================================
// XAnimParts
// =========================================
use XAnimParts;
set block XFILE_BLOCK_TEMP;
set string 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;
+88
View File
@@ -0,0 +1,88 @@
// =========================================
// XModel
// =========================================
use XModel;
set block XFILE_BLOCK_TEMP;
set string 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;
// This is actually the count but it looks like a bug? It is used like a vec3, but it takes as much memory as vec4
set count trans (numBones - numRootBones) * 4;
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;
set reusable collmap;
set count collmap 1;
// PhysGeomList
use PhysGeomList;
set reusable geoms;
set count geoms count;
// PhysGeomInfo
set reusable PhysGeomInfo::brush;
set allocalign PhysGeomInfo::brush 4;
// BrushWrapper
use BrushWrapper;
set count sides numsides;
set count baseAdjacentSide totalEdgeCount;
set reusable verts;
set count verts numverts;
set reusable planes;
set count planes numsides;
// cbrushside_t
set reusable cbrushside_t::plane;
// XSurface
use XSurface;
set reusable verts0;
set block verts0 XFILE_BLOCK_VIRTUAL;
set count verts0 vertCount;
set condition vb0 never;
set reusable vertList;
set count vertList vertListCount;
set reusable triIndices;
set block triIndices XFILE_BLOCK_VIRTUAL;
set allocalign triIndices 16;
set count triIndices triCount;
set condition indexBuffer never;
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;
@@ -0,0 +1,85 @@
// =========================================
// clipMap_t
// =========================================
use clipMap_t;
set block XFILE_BLOCK_TEMP;
set string 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 brushVerts numBrushVerts;
set count uinds nuinds;
set count triIndices 3 * triCount;
set count triEdgeIsWalkable ((3 * triCount + 31) / 32) * 4;
set count borders borderCount;
set count partitions partitionCount;
set allocalign aabbTrees 16;
set count aabbTrees aabbTreeCount;
set count cmodels numSubModels;
set count brushes numBrushes;
set count visibility numClusters * clusterBytes;
set reusable box_brush;
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 dynEntServerList XFILE_BLOCK_RUNTIME;
set count dynEntServerList[0] dynEntCount[2];
set count dynEntServerList[1] dynEntCount[3];
set block dynEntCollList XFILE_BLOCK_RUNTIME;
set count dynEntCollList[0] dynEntCount[0];
set count dynEntCollList[1] dynEntCount[1];
set count dynEntCollList[2] dynEntCount[2];
set count dynEntCollList[3] dynEntCount[3];
set count constraints num_constraints;
reorder:
...
leafs
leafbrushes
leafbrushNodes
leafsurfaces;
// cbrushside_t
set reusable cbrushside_t::plane;
// 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;
set reusable verts;
// DynEntityDef
use DynEntityDef;
set reusable destroyPieces;
set scriptstring targetname;
// XModelPieces
use XModelPieces;
set string name;
set count pieces numpieces;
@@ -0,0 +1,80 @@
// =========================================
// menuDef_t
// =========================================
use menuDef_t;
set block XFILE_BLOCK_TEMP;
set string window::name;
set string font;
set string onOpen;
set string onFocus;
set string onClose;
set string onESC;
set reusable visibleExp;
set string allowedBinding;
set string soundName;
set reusable rectXExp;
set reusable rectYExp;
set count items itemCount;
// windowDef_t
use windowDef_t;
set string name;
set string group;
// ItemKeyHandler
set string ItemKeyHandler::action;
// statement_s
set count statement_s::entries numEntries;
// expressionEntry
set condition expressionEntry::data::operand type == EET_OPERAND;
// Operand
use Operand;
set condition internals::intVal dataType == VAL_INT;
set condition internals::floatVal dataType == VAL_FLOAT;
set condition internals::string dataType == VAL_STRING;
set string internals::string;
// itemDef_s
use itemDef_s;
set string text;
set condition parent never;
set string mouseEnterText;
set string mouseExitText;
set string mouseEnter;
set string mouseExit;
set string action;
set string onAccept;
set string onFocus;
set string leaveFocus;
set string dvar;
set string dvarTest;
set string onListboxSelectionChange;
set string enableDvar;
// itemDefData_t
use itemDefData_t;
set string enumDvarName;
set condition data never;
set condition listBox itemDef_s::type == ITEM_TYPE_LISTBOX;
set condition editField itemDef_s::type == ITEM_TYPE_TEXT
|| itemDef_s::type == ITEM_TYPE_EDITFIELD
|| itemDef_s::type == ITEM_TYPE_NUMERICFIELD
|| itemDef_s::type == ITEM_TYPE_SLIDER
|| itemDef_s::type == ITEM_TYPE_YESNO
|| itemDef_s::type == ITEM_TYPE_BIND
|| itemDef_s::type == ITEM_TYPE_VALIDFILEFIELD
|| itemDef_s::type == ITEM_TYPE_DECIMALFIELD
|| itemDef_s::type == ITEM_TYPE_UPREDITFIELD;
set condition multi itemDef_s::type == ITEM_TYPE_MULTI;
set condition enumDvarName itemDef_s::type == ITEM_TYPE_DVARENUM;
// listBoxDef_s
set string listBoxDef_s::doubleClick;
// multiDef_s
use multiDef_s;
set string dvarList;
set string dvarStr;
@@ -0,0 +1,44 @@
// =========================================
// snd_alias_list_t
// =========================================
use snd_alias_list_t;
set block XFILE_BLOCK_TEMP;
set string 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 reusable soundFile;
// SoundFile
use SoundFile;
set condition u::loadSnd type == SAT_LOADED;
set reusable u::streamSnd;
// LoadedSound
set string LoadedSound::name;
// snd_asset
use snd_asset;
set count data data_size;
// StreamedSound
use StreamedSound;
set reusable primeSnd;
// StreamFileName
use StreamFileName;
set string dir;
set string name;
// PrimedSound
use PrimedSound;
set string name;
set count buffer size;
set block buffer XFILE_BLOCK_LARGE;
set allocalign buffer 2048;
@@ -0,0 +1,33 @@
#include "ZoneDefWriterT4.h"
#include "Game/T4/T4.h"
using namespace T4;
void ZoneDefWriter::WriteMetaData(ZoneDefinitionOutputStream& stream, const Zone& zone) const {}
void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const Zone& zone, const ZoneDefFilter& filter) const
{
const auto* game = IGame::GetGameById(zone.m_game_id);
// Localized strings are all collected in one string file. So only add this to the zone file.
auto localizePoolAssets = zone.m_pools.PoolAssets<AssetLocalize>();
if (localizePoolAssets.begin() != localizePoolAssets.end())
stream.WriteEntry(*game->GetAssetTypeName(ASSET_TYPE_LOCALIZE_ENTRY), zone.m_name);
for (const auto& asset : zone.m_pools)
{
if (!filter.ShouldWriteAsset(*asset))
continue;
switch (asset->m_type)
{
case ASSET_TYPE_LOCALIZE_ENTRY:
break;
default:
stream.WriteEntry(*game->GetAssetTypeName(asset->m_type), asset->m_name);
break;
}
}
}
@@ -0,0 +1,13 @@
#pragma once
#include "Zone/Definition/ZoneDefWriter.h"
namespace T4
{
class ZoneDefWriter final : public AbstractZoneDefWriter
{
protected:
void WriteMetaData(ZoneDefinitionOutputStream& stream, const Zone& zone) const override;
void WriteContent(ZoneDefinitionOutputStream& stream, const Zone& zone, const ZoneDefFilter& filter) const override;
};
} // namespace T4
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include "Game/T4/T4.h"
#include "Zone/ZoneTypes.h"
#include <cstdint>
#include <string>
namespace T4
{
class ZoneConstants final
{
ZoneConstants() = default;
public:
static constexpr const char* MAGIC_UNSIGNED = "IWffu100";
static constexpr int ZONE_VERSION_PC = 387;
static_assert(std::char_traits<char>::length(MAGIC_UNSIGNED) == sizeof(ZoneHeader::m_magic));
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 3u;
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
};
} // namespace T4
+3 -1
View File
@@ -196,13 +196,15 @@ XAssetInfoGeneric* GameGlobalAssetPools::GetAsset(const asset_type_t assetType,
GameGlobalAssetPools* GameGlobalAssetPools::GetGlobalPoolsForGame(GameId gameId)
{
static GameGlobalAssetPools* globalAssetPools[static_cast<unsigned>(GameId::COUNT)]{
static GameGlobalAssetPools* globalAssetPools[]{
new GameGlobalAssetPools(GameId::IW3),
new GameGlobalAssetPools(GameId::IW4),
new GameGlobalAssetPools(GameId::IW5),
new GameGlobalAssetPools(GameId::T4),
new GameGlobalAssetPools(GameId::T5),
new GameGlobalAssetPools(GameId::T6),
};
static_assert(std::extent_v<decltype(globalAssetPools)> == static_cast<unsigned>(GameId::COUNT));
assert(static_cast<unsigned>(gameId) < static_cast<unsigned>(GameId::COUNT));
auto* result = globalAssetPools[static_cast<unsigned>(gameId)];
@@ -3,6 +3,7 @@
#include "Game/IW3/Zone/Definition/ZoneDefWriterIW3.h"
#include "Game/IW4/Zone/Definition/ZoneDefWriterIW4.h"
#include "Game/IW5/Zone/Definition/ZoneDefWriterIW5.h"
#include "Game/T4/Zone/Definition/ZoneDefWriterT4.h"
#include "Game/T5/Zone/Definition/ZoneDefWriterT5.h"
#include "Game/T6/Zone/Definition/ZoneDefWriterT6.h"
#include "Pool/XAssetInfo.h"
@@ -43,13 +44,15 @@ bool ZoneDefFilter::ShouldWriteAsset(const XAssetInfoGeneric& asset) const
const IZoneDefWriter* IZoneDefWriter::GetZoneDefWriterForGame(GameId game)
{
static const IZoneDefWriter* zoneDefWriters[static_cast<unsigned>(GameId::COUNT)]{
static const IZoneDefWriter* zoneDefWriters[]{
new IW3::ZoneDefWriter(),
new IW4::ZoneDefWriter(),
new IW5::ZoneDefWriter(),
new T4::ZoneDefWriter(),
new T5::ZoneDefWriter(),
new T6::ZoneDefWriter(),
};
static_assert(std::extent_v<decltype(zoneDefWriters)> == static_cast<unsigned>(GameId::COUNT));
assert(static_cast<unsigned>(game) < static_cast<unsigned>(GameId::COUNT));
const auto* result = zoneDefWriters[static_cast<unsigned>(game)];
@@ -17,7 +17,7 @@ void Actions_GfxImage::OnImageLoaded(GfxImage* image) const
void Actions_GfxImage::LoadImageData(GfxImageLoadDef* loadDef, GfxImage* image) const
{
const size_t loadDefSize = offsetof(IW3::GfxImageLoadDef, data) + loadDef->resourceSize;
const size_t loadDefSize = offsetof(GfxImageLoadDef, data) + loadDef->resourceSize;
image->texture.loadDef = static_cast<GfxImageLoadDef*>(m_zone.Memory().AllocRaw(loadDefSize));
memcpy(image->texture.loadDef, loadDef, loadDefSize);
@@ -17,7 +17,7 @@ void Actions_GfxImage::OnImageLoaded(GfxImage* image) const
void Actions_GfxImage::LoadImageData(GfxImageLoadDef* loadDef, GfxImage* image) const
{
const size_t loadDefSize = offsetof(IW4::GfxImageLoadDef, data) + loadDef->resourceSize;
const size_t loadDefSize = offsetof(GfxImageLoadDef, data) + loadDef->resourceSize;
image->texture.loadDef = static_cast<GfxImageLoadDef*>(m_zone.Memory().AllocRaw(loadDefSize));
memcpy(image->texture.loadDef, loadDef, loadDefSize);
@@ -17,7 +17,7 @@ void Actions_GfxImage::OnImageLoaded(GfxImage* image) const
void Actions_GfxImage::LoadImageData(GfxImageLoadDef* loadDef, GfxImage* image) const
{
const size_t loadDefSize = offsetof(IW5::GfxImageLoadDef, data) + loadDef->resourceSize;
const size_t loadDefSize = offsetof(GfxImageLoadDef, data) + loadDef->resourceSize;
image->texture.loadDef = static_cast<GfxImageLoadDef*>(m_zone.Memory().AllocRaw(loadDefSize));
memcpy(image->texture.loadDef, loadDef, loadDefSize);
+174
View File
@@ -0,0 +1,174 @@
#include "ContentLoaderT4.h"
#include "Game/T4/AssetLoaderT4.h"
#include "Game/T4/T4.h"
#include "Loading/Exception/UnsupportedAssetTypeException.h"
#include <cassert>
using namespace T4;
ContentLoader::ContentLoader(Zone& zone, ZoneInputStream& stream)
: ContentLoaderBase(zone, stream),
varXAssetList(nullptr),
varXAsset(nullptr),
varScriptStringList(nullptr)
{
}
void ContentLoader::LoadScriptStringList(const bool atStreamStart)
{
assert(!atStreamStart);
if (varScriptStringList->strings != nullptr)
{
assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING);
#ifdef ARCH_x86
varScriptStringList->strings = m_stream.Alloc<const char*>(4);
#else
varScriptStringList->strings = m_stream.AllocOutOfBlock<const char*>(4, varScriptStringList->count);
#endif
varXString = varScriptStringList->strings;
LoadXStringArray(true, varScriptStringList->count);
if (varScriptStringList->strings && varScriptStringList->count > 0)
m_zone.m_script_strings.InitializeForExistingZone(varScriptStringList->strings, static_cast<size_t>(varScriptStringList->count));
}
assert(m_zone.m_script_strings.Count() <= SCR_STRING_MAX + 1);
}
void ContentLoader::LoadXAsset(const bool atStreamStart) const
{
#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)
{
SKIP_ASSET(ASSET_TYPE_XMODELPIECES, XModelPieces, data)
LOAD_ASSET(ASSET_TYPE_PHYSPRESET, PhysPreset, physPreset)
LOAD_ASSET(ASSET_TYPE_PHYSCONSTRAINTS, PhysConstraints, physConstraints)
LOAD_ASSET(ASSET_TYPE_DESTRUCTIBLEDEF, DestructibleDef, destructibleDef)
LOAD_ASSET(ASSET_TYPE_XANIMPARTS, XAnimParts, parts)
LOAD_ASSET(ASSET_TYPE_XMODEL, XModel, model)
LOAD_ASSET(ASSET_TYPE_MATERIAL, Material, material)
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_LOADED_SOUND, LoadedSound, loadSnd)
LOAD_ASSET(ASSET_TYPE_CLIPMAP, clipMap_t, clipMap)
LOAD_ASSET(ASSET_TYPE_CLIPMAP_PVS, clipMap_t, clipMap)
LOAD_ASSET(ASSET_TYPE_COMWORLD, ComWorld, comWorld)
LOAD_ASSET(ASSET_TYPE_GAMEWORLD_SP, GameWorldSp, gameWorldSp)
LOAD_ASSET(ASSET_TYPE_GAMEWORLD_MP, GameWorldMp, gameWorldMp)
LOAD_ASSET(ASSET_TYPE_MAP_ENTS, MapEnts, mapEnts)
LOAD_ASSET(ASSET_TYPE_GFXWORLD, GfxWorld, gfxWorld)
LOAD_ASSET(ASSET_TYPE_LIGHT_DEF, GfxLightDef, lightDef)
SKIP_ASSET(ASSET_TYPE_UI_MAP, UiMap, data)
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_WEAPON, WeaponDef, weapon)
LOAD_ASSET(ASSET_TYPE_SNDDRIVER_GLOBALS, SndDriverGlobals, sndDriverGlobals)
LOAD_ASSET(ASSET_TYPE_FX, FxEffectDef, fx)
LOAD_ASSET(ASSET_TYPE_IMPACT_FX, FxImpactTable, impactFx)
SKIP_ASSET(ASSET_TYPE_AITYPE, AiType, data)
SKIP_ASSET(ASSET_TYPE_MPTYPE, MpType, data)
SKIP_ASSET(ASSET_TYPE_CHARACTER, Character, data)
SKIP_ASSET(ASSET_TYPE_XMODELALIAS, XModelAlias, data)
LOAD_ASSET(ASSET_TYPE_RAWFILE, RawFile, rawfile)
LOAD_ASSET(ASSET_TYPE_STRINGTABLE, StringTable, stringTable)
LOAD_ASSET(ASSET_TYPE_PACK_INDEX, PackIndex, packIndex)
default:
{
throw UnsupportedAssetTypeException(varXAsset->type);
}
}
#undef LOAD_ASSET
}
void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count)
{
assert(varXAsset != nullptr);
if (atStreamStart)
{
#ifdef ARCH_x86
m_stream.Load<XAsset>(varXAsset, count);
#else
const auto fill = m_stream.LoadWithFill(8u * count);
for (size_t index = 0; index < count; index++)
{
fill.Fill(varXAsset[index].type, 8u * index);
fill.FillPtr(varXAsset[index].header.data, 8u * index + 4u);
m_stream.AddPointerLookup(&varXAsset[index].header.data, fill.BlockBuffer(8u * index + 4u));
}
#endif
}
for (size_t index = 0; index < count; index++)
{
LoadXAsset(false);
varXAsset++;
#ifdef DEBUG_OFFSETS
m_stream.DebugOffsets(index);
#endif
}
}
void ContentLoader::Load()
{
XAssetList assetList{};
varXAssetList = &assetList;
#ifdef ARCH_x86
m_stream.LoadDataRaw(&assetList, sizeof(assetList));
#else
const auto fillAccessor = m_stream.LoadWithFill(16u);
varScriptStringList = &varXAssetList->stringList;
fillAccessor.Fill(varScriptStringList->count, 0u);
fillAccessor.FillPtr(varScriptStringList->strings, 4u);
fillAccessor.Fill(varXAssetList->assetCount, 8u);
fillAccessor.FillPtr(varXAssetList->assets, 12u);
#endif
m_stream.PushBlock(XFILE_BLOCK_VIRTUAL);
varScriptStringList = &assetList.stringList;
LoadScriptStringList(false);
if (assetList.assets != nullptr)
{
assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING);
#ifdef ARCH_x86
assetList.assets = m_stream.Alloc<XAsset>(4);
#else
assetList.assets = m_stream.AllocOutOfBlock<XAsset>(4, assetList.assetCount);
#endif
varXAsset = assetList.assets;
LoadXAssetArray(true, assetList.assetCount);
}
m_stream.PopBlock();
}
+25
View File
@@ -0,0 +1,25 @@
#pragma once
#include "Game/T4/T4.h"
#include "Loading/ContentLoaderBase.h"
#include "Loading/IContentLoadingEntryPoint.h"
namespace T4
{
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
{
public:
ContentLoader(Zone& zone, ZoneInputStream& stream);
void Load() override;
private:
void LoadScriptStringList(bool atStreamStart);
void LoadXAsset(bool atStreamStart) const;
void LoadXAssetArray(bool atStreamStart, size_t count);
XAssetList* varXAssetList;
XAsset* varXAsset;
ScriptStringList* varScriptStringList;
};
} // namespace T4
@@ -0,0 +1,24 @@
#include "gfximage_actions.h"
#include <cassert>
#include <cstring>
using namespace T4;
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(GfxImageLoadDef, data) + loadDef->resourceSize;
image->texture.loadDef = static_cast<GfxImageLoadDef*>(m_zone.Memory().AllocRaw(loadDefSize));
memcpy(image->texture.loadDef, loadDef, loadDefSize);
}
@@ -0,0 +1,16 @@
#pragma once
#include "Game/T4/T4.h"
#include "Loading/AssetLoadingActions.h"
namespace T4
{
class Actions_GfxImage final : public AssetLoadingActions
{
public:
explicit Actions_GfxImage(Zone& zone);
void OnImageLoaded(GfxImage* image) const;
void LoadImageData(GfxImageLoadDef* loadDef, GfxImage* image) const;
};
} // namespace T4
@@ -0,0 +1,89 @@
#include "ZoneLoaderFactoryT4.h"
#include "ContentLoaderT4.h"
#include "Game/GameLanguage.h"
#include "Game/T4/T4.h"
#include "Game/T4/ZoneConstantsT4.h"
#include "Loading/Processor/ProcessorInflate.h"
#include "Loading/Steps/StepAddProcessor.h"
#include "Loading/Steps/StepAllocXBlocks.h"
#include "Loading/Steps/StepLoadZoneContent.h"
#include "Loading/Steps/StepLoadZoneSizes.h"
#include "Utils/ClassUtils.h"
#include "Utils/Endianness.h"
#include <cstring>
using namespace T4;
namespace
{
void SetupBlock(ZoneLoader& zoneLoader)
{
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
zoneLoader.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneLoader.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_LARGE_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF
}
} // namespace
std::optional<ZoneLoaderInspectionResult> ZoneLoaderFactory::InspectZoneHeader(const ZoneHeader& header) const
{
if (endianness::FromLittleEndian(header.m_version) == ZoneConstants::ZONE_VERSION_PC
&& !memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, std::char_traits<char>::length(ZoneConstants::MAGIC_UNSIGNED)))
{
return ZoneLoaderInspectionResult{
.m_game_id = GameId::T4,
.m_endianness = GameEndianness::LE,
.m_word_size = GameWordSize::ARCH_32,
.m_platform = GamePlatform::PC,
// There is no way to know whether unsigned zones are official.
.m_is_official = false,
.m_is_signed = false,
.m_is_encrypted = false,
};
}
return std::nullopt;
}
std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(const ZoneHeader& header,
const std::string& fileName,
std::optional<std::unique_ptr<ProgressCallback>> progressCallback) const
{
const auto inspectResult = InspectZoneHeader(header);
if (!inspectResult)
return nullptr;
// Create new zone
auto zone = std::make_unique<Zone>(fileName, 0, GameId::T4, inspectResult->m_platform);
auto* zonePtr = zone.get();
zone->m_language = GameLanguage::LANGUAGE_NONE;
// File is supported. Now setup all required steps for loading this file.
auto zoneLoader = std::make_unique<ZoneLoader>(std::move(zone));
SetupBlock(*zoneLoader);
zoneLoader->AddLoadingStep(step::CreateStepAddProcessor(processor::CreateProcessorInflate(ZoneConstants::AUTHED_CHUNK_SIZE)));
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneSizes());
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
[zonePtr](ZoneInputStream& stream)
{
return std::make_unique<ContentLoader>(*zonePtr, stream);
},
32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr->Memory(),
std::move(progressCallback)));
return zoneLoader;
}
@@ -0,0 +1,17 @@
#pragma once
#include "Loading/IZoneLoaderFactory.h"
#include <string>
namespace T4
{
class ZoneLoaderFactory final : public IZoneLoaderFactory
{
public:
[[nodiscard]] std::optional<ZoneLoaderInspectionResult> InspectZoneHeader(const ZoneHeader& header) const override;
[[nodiscard]] std::unique_ptr<ZoneLoader> CreateLoaderForHeader(const ZoneHeader& header,
const std::string& fileName,
std::optional<std::unique_ptr<ProgressCallback>> progressCallback) const override;
};
} // namespace T4
@@ -17,7 +17,7 @@ void Actions_GfxImage::OnImageLoaded(GfxImage* image) const
void Actions_GfxImage::LoadImageData(GfxImageLoadDef* loadDef, GfxImage* image) const
{
const size_t loadDefSize = offsetof(T6::GfxImageLoadDef, data) + loadDef->resourceSize;
const size_t loadDefSize = offsetof(GfxImageLoadDef, data) + loadDef->resourceSize;
image->texture.loadDef = static_cast<GfxImageLoadDef*>(m_zone.Memory().AllocRaw(loadDefSize));
memcpy(image->texture.loadDef, loadDef, loadDefSize);
@@ -3,6 +3,7 @@
#include "Game/IW3/ZoneLoaderFactoryIW3.h"
#include "Game/IW4/ZoneLoaderFactoryIW4.h"
#include "Game/IW5/ZoneLoaderFactoryIW5.h"
#include "Game/T4/ZoneLoaderFactoryT4.h"
#include "Game/T5/ZoneLoaderFactoryT5.h"
#include "Game/T6/ZoneLoaderFactoryT6.h"
@@ -10,10 +11,11 @@
const IZoneLoaderFactory* IZoneLoaderFactory::GetZoneLoaderFactoryForGame(GameId game)
{
static const IZoneLoaderFactory* zoneCreators[static_cast<unsigned>(GameId::COUNT)]{
static const IZoneLoaderFactory* zoneCreators[]{
new IW3::ZoneLoaderFactory(),
new IW4::ZoneLoaderFactory(),
new IW5::ZoneLoaderFactory(),
new T4::ZoneLoaderFactory(),
new T5::ZoneLoaderFactory(),
new T6::ZoneLoaderFactory(),
};
+220
View File
@@ -0,0 +1,220 @@
#include "ContentWriterT4.h"
#include "Game/T4/AssetWriterT4.h"
#include "Writing/WritingException.h"
#include <cassert>
#include <format>
using namespace T4;
ContentWriter::ContentWriter(const Zone& zone)
: ContentWriterBase(zone),
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 = static_cast<int>(m_zone.m_script_strings.Count());
xAssetList.stringList.strings = memory.Alloc<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.CValue(i);
}
else
{
xAssetList.stringList.count = 0;
xAssetList.stringList.strings = nullptr;
}
const auto assetCount = m_zone.m_pools.GetTotalAssetCount();
if (assetCount > 0)
{
xAssetList.assetCount = static_cast<int>(assetCount);
xAssetList.assets = memory.Alloc<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)
{
assert(!atStreamStart);
if (varScriptStringList->strings != nullptr)
{
m_stream->Align(4);
varXString = varScriptStringList->strings;
WriteXStringArray(true, varScriptStringList->count);
#ifdef ARCH_x86
static_assert(offsetof(ScriptStringList, strings) == 4u);
#endif
m_stream->MarkFollowing(varScriptStringListWritten.AtOffset(4));
}
}
void ContentWriter::WriteXAsset(const bool atStreamStart)
{
#ifdef ARCH_x86
static_assert(offsetof(XAsset, header.data) == 4u);
#endif
#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, varXAssetWritten.AtOffset(4)); \
break; \
}
#define SKIP_ASSET(type_index, typeName, headerEntry) \
case type_index: \
break;
assert(varXAsset != nullptr);
if (atStreamStart)
varXAssetWritten = m_stream->Write(varXAsset);
switch (varXAsset->type)
{
SKIP_ASSET(ASSET_TYPE_XMODELPIECES, XModelPieces, data)
WRITE_ASSET(ASSET_TYPE_PHYSPRESET, PhysPreset, physPreset)
WRITE_ASSET(ASSET_TYPE_PHYSCONSTRAINTS, PhysConstraints, physConstraints)
WRITE_ASSET(ASSET_TYPE_DESTRUCTIBLEDEF, DestructibleDef, destructibleDef)
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_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)
SKIP_ASSET(ASSET_TYPE_UI_MAP, UiMap, data)
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)
WRITE_ASSET(ASSET_TYPE_SNDDRIVER_GLOBALS, SndDriverGlobals, sndDriverGlobals)
WRITE_ASSET(ASSET_TYPE_FX, FxEffectDef, fx)
WRITE_ASSET(ASSET_TYPE_IMPACT_FX, FxImpactTable, impactFx)
SKIP_ASSET(ASSET_TYPE_AITYPE, AiType, data)
SKIP_ASSET(ASSET_TYPE_MPTYPE, MpType, data)
SKIP_ASSET(ASSET_TYPE_CHARACTER, Character, data)
SKIP_ASSET(ASSET_TYPE_XMODELALIAS, XModelAlias, data)
WRITE_ASSET(ASSET_TYPE_RAWFILE, RawFile, rawfile)
WRITE_ASSET(ASSET_TYPE_STRINGTABLE, StringTable, stringTable)
WRITE_ASSET(ASSET_TYPE_PACK_INDEX, PackIndex, packIndex)
default:
{
throw WritingException(std::format("Unsupported asset type: {}.", static_cast<unsigned>(varXAsset->type)));
}
}
#undef WRITE_ASSET
#undef SKIP_ASSET
}
void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t count)
{
assert(varXAsset != nullptr);
#ifdef ARCH_x86
static_assert(sizeof(XAsset) == 8u);
#endif
if (atStreamStart)
{
#ifdef ARCH_x86
varXAssetWritten = m_stream->Write(varXAsset, count);
#else
const auto fill = m_stream->WriteWithFill(8u * count);
varXAssetWritten = fill.Offset();
for (size_t index = 0; index < count; index++)
fill.Fill(varXAsset[index].type, 8u * index);
#endif
}
for (size_t index = 0; index < count; index++)
{
WriteXAsset(false);
varXAsset++;
varXAssetWritten.Inc(8u);
}
}
void ContentWriter::WriteContent(ZoneOutputStream& stream)
{
m_stream = &stream;
MemoryManager memory;
XAssetList assetList{};
CreateXAssetList(assetList, memory);
varXAssetList = &assetList;
#ifdef ARCH_x86
static_assert(sizeof(XAssetList) == 16);
static_assert(offsetof(XAssetList, assetCount) == 8u);
varXAssetListWritten = m_stream->WriteDataRaw(&assetList, sizeof(assetList));
#else
const auto fillAccessor = m_stream->WriteWithFill(16u);
varXAssetListWritten = fillAccessor.Offset();
varScriptStringList = &varXAssetList->stringList;
fillAccessor.Fill(varScriptStringList->count, 0u);
fillAccessor.Fill(varXAssetList->assetCount, 8u);
#endif
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
#ifdef ARCH_x86
static_assert(offsetof(XAssetList, stringList) == 0u);
#endif
varScriptStringList = &varXAssetList->stringList;
varScriptStringListWritten = varXAssetListWritten.AtOffset(0);
WriteScriptStringList(false);
if (varXAssetList->assets != nullptr)
{
m_stream->Align(4);
varXAsset = varXAssetList->assets;
WriteXAssetArray(true, varXAssetList->assetCount);
#ifdef ARCH_x86
static_assert(offsetof(XAssetList, assets) == 12u);
#endif
m_stream->MarkFollowing(varXAssetListWritten.AtOffset(12));
}
m_stream->PopBlock();
}
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include "Game/T4/T4.h"
#include "Writing/ContentWriterBase.h"
#include "Writing/IContentWritingEntryPoint.h"
namespace T4
{
class ContentWriter final : public ContentWriterBase, public IContentWritingEntryPoint
{
public:
explicit ContentWriter(const Zone& zone);
void WriteContent(ZoneOutputStream& stream) override;
private:
void CreateXAssetList(XAssetList& xAssetList, MemoryManager& memory) const;
void WriteScriptStringList(bool atStreamStart);
void WriteXAsset(bool atStreamStart);
void WriteXAssetArray(bool atStreamStart, size_t count);
XAssetList* varXAssetList;
XAsset* varXAsset;
ScriptStringList* varScriptStringList;
ZoneOutputOffset varXAssetListWritten;
ZoneOutputOffset varXAssetWritten;
ZoneOutputOffset varScriptStringListWritten;
};
} // namespace T4
@@ -0,0 +1,71 @@
#include "ZoneWriterFactoryT4.h"
#include "ContentWriterT4.h"
#include "Game/T4/GameT4.h"
#include "Game/T4/T4.h"
#include "Game/T4/ZoneConstantsT4.h"
#include "Utils/ClassUtils.h"
#include "Writing/Processor/OutputProcessorDeflate.h"
#include "Writing/Steps/StepAddOutputProcessor.h"
#include "Writing/Steps/StepWriteXBlockSizes.h"
#include "Writing/Steps/StepWriteZoneContentToFile.h"
#include "Writing/Steps/StepWriteZoneContentToMemory.h"
#include "Writing/Steps/StepWriteZoneHeader.h"
#include "Writing/Steps/StepWriteZoneSizes.h"
#include <cstring>
using namespace T4;
namespace
{
void SetupBlocks(ZoneWriter& writer)
{
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
writer.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
writer.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
writer.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_LARGE_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
writer.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
writer.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(T4::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF
}
ZoneHeader CreateHeaderForParams()
{
ZoneHeader header{};
header.m_version = ZoneConstants::ZONE_VERSION_PC;
memcpy(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, sizeof(ZoneHeader::m_magic));
return header;
}
} // namespace
std::unique_ptr<ZoneWriter> ZoneWriterFactory::CreateWriter(const Zone& zone) const
{
auto writer = std::make_unique<ZoneWriter>();
SetupBlocks(*writer);
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
std::make_unique<ContentWriter>(zone), zone, 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
auto* contentInMemoryPtr = contentInMemory.get();
writer->AddWritingStep(std::move(contentInMemory));
// Write zone header
writer->AddWritingStep(std::make_unique<StepWriteZoneHeader>(CreateHeaderForParams()));
writer->AddWritingStep(std::make_unique<StepAddOutputProcessor>(std::make_unique<OutputProcessorDeflate>()));
// Start of the XFile struct
writer->AddWritingStep(std::make_unique<StepWriteZoneSizes>(contentInMemoryPtr));
writer->AddWritingStep(std::make_unique<StepWriteXBlockSizes>(zone));
// Start of the zone content
writer->AddWritingStep(std::make_unique<StepWriteZoneContentToFile>(contentInMemoryPtr));
return std::move(writer);
}
@@ -0,0 +1,14 @@
#pragma once
#include "Writing/IZoneWriterFactory.h"
#include <memory>
namespace T4
{
class ZoneWriterFactory final : public IZoneWriterFactory
{
public:
[[nodiscard]] std::unique_ptr<ZoneWriter> CreateWriter(const Zone& zone) const override;
};
} // namespace T4
@@ -3,6 +3,7 @@
#include "Game/IW3/ZoneWriterFactoryIW3.h"
#include "Game/IW4/ZoneWriterFactoryIW4.h"
#include "Game/IW5/ZoneWriterFactoryIW5.h"
#include "Game/T4/ZoneWriterFactoryT4.h"
#include "Game/T5/ZoneWriterFactoryT5.h"
#include "Game/T6/ZoneWriterFactoryT6.h"
@@ -10,10 +11,11 @@
const IZoneWriterFactory* IZoneWriterFactory::GetZoneWriterFactoryForGame(GameId game)
{
static const IZoneWriterFactory* zoneCreators[static_cast<unsigned>(GameId::COUNT)]{
static const IZoneWriterFactory* zoneCreators[]{
new IW3::ZoneWriterFactory(),
new IW4::ZoneWriterFactory(),
new IW5::ZoneWriterFactory(),
new T4::ZoneWriterFactory(),
new T5::ZoneWriterFactory(),
new T6::ZoneWriterFactory(),
};