diff --git a/src/Common/Game/IW5/CommonIW5.cpp b/src/Common/Game/IW5/CommonIW5.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/Common/Game/IW5/CommonIW5.h b/src/Common/Game/IW5/CommonIW5.h new file mode 100644 index 00000000..6c1b246a --- /dev/null +++ b/src/Common/Game/IW5/CommonIW5.h @@ -0,0 +1,5 @@ +#pragma once + +namespace IW5 +{ +} diff --git a/src/Common/Game/IW5/GameIW5.cpp b/src/Common/Game/IW5/GameIW5.cpp new file mode 100644 index 00000000..5ff78490 --- /dev/null +++ b/src/Common/Game/IW5/GameIW5.cpp @@ -0,0 +1,43 @@ +#include "GameIW5.h" + +#include + +#include "IW5.h" + +using namespace IW5; + +GameIW5 g_GameIW5; + +std::string GameIW5::GetFullName() +{ + return "Call Of Duty: Modern Warfare 3"; +} + +std::string GameIW5::GetShortName() +{ + return "IW5"; +} + +void GameIW5::AddZone(Zone* zone) +{ + m_zones.push_back(zone); +} + +void GameIW5::RemoveZone(Zone* zone) +{ + const auto foundEntry = std::find(m_zones.begin(), m_zones.end(), zone); + + if (foundEntry != m_zones.end()) + m_zones.erase(foundEntry); +} + +std::vector GameIW5::GetZones() +{ + return m_zones; +} + +std::vector GameIW5::GetLanguagePrefixes() +{ + std::vector prefixes; + return prefixes; +} diff --git a/src/Common/Game/IW5/GameIW5.h b/src/Common/Game/IW5/GameIW5.h new file mode 100644 index 00000000..57b942fa --- /dev/null +++ b/src/Common/Game/IW5/GameIW5.h @@ -0,0 +1,17 @@ +#pragma once +#include "Game/IGame.h" + +class GameIW5 : public IGame +{ + std::vector m_zones; + +public: + std::string GetFullName() override; + std::string GetShortName() override; + void AddZone(Zone* zone) override; + void RemoveZone(Zone* zone) override; + std::vector GetZones() override; + std::vector GetLanguagePrefixes() override; +}; + +extern GameIW5 g_GameIW5; \ No newline at end of file diff --git a/src/Common/Game/IW5/IW5.h b/src/Common/Game/IW5/IW5.h new file mode 100644 index 00000000..727ea2a0 --- /dev/null +++ b/src/Common/Game/IW5/IW5.h @@ -0,0 +1,82 @@ +#pragma once + +//#include +#include "Image/Texture.h" + +#include "IW5_Assets.h" + +namespace IW5 +{ + struct DB_AuthHash + { + char bytes[32]; + }; + + struct DB_AuthSignature + { + char bytes[256]; + }; + + struct DB_AuthSubHeader + { + char fastfileName[32]; + unsigned int reserved; + DB_AuthHash masterBlockHashes[244]; + }; + + struct DB_AuthHeader + { + char magic[8]; // + 0 + unsigned int reserved; // + 8 + DB_AuthHash subheaderHash; // + 12 + DB_AuthSignature signedSubheaderHash; // + 44 + DB_AuthSubHeader subheader; // + 300 + }; + + struct ScriptStringList + { + int count; + const char** strings; + }; + + struct XAsset + { + XAssetType type; + XAssetHeader header; + }; + + struct XAssetList + { + ScriptStringList stringList; + int assetCount; + XAsset* assets; + }; + + struct cspField_t + { + const char* szName; + int iOffset; + int iFieldType; + }; + + enum csParseFieldType_t + { + CSPFT_STRING = 0, + CSPFT_STRING_MAX_STRING_CHARS, + CSPFT_STRING_MAX_QPATH, + CSPFT_STRING_MAX_OSPATH, + CSPFT_INT, + CSPFT_QBOOLEAN, + CSPFT_BOOL, + CSPFT_FLOAT, + CSPFT_MPH_TO_INCHES_PER_SEC, + CSPFT_MILLISECONDS, + CSPFT_FX, + CSPFT_XMODEL, + CSPFT_MATERIAL, + CSPFT_SOUND, + CSPFT_TRACER, + + CSPFT_NUM_BASE_FIELD_TYPES, + }; +} \ No newline at end of file diff --git a/src/Common/Game/IW5/IW5_Assets.h b/src/Common/Game/IW5/IW5_Assets.h new file mode 100644 index 00000000..389ab5b8 --- /dev/null +++ b/src/Common/Game/IW5/IW5_Assets.h @@ -0,0 +1,4676 @@ +#pragma once + +#ifndef __IW5_ASSETS_H +#define __IW5_ASSETS_H + +#ifndef __cplusplus +#define __ida +#endif + +#include "../../Utils/TypeAlignment.h" + +#ifndef __zonecodegenerator +#ifndef __ida +namespace IW5 +{ +#endif +#endif + enum XAssetType + { + ASSET_TYPE_PHYSPRESET = 0x0, + ASSET_TYPE_PHYSCOLLMAP = 0x1, + ASSET_TYPE_XANIMPARTS = 0x2, + ASSET_TYPE_XMODEL_SURFS = 0x3, + ASSET_TYPE_XMODEL = 0x4, + ASSET_TYPE_MATERIAL = 0x5, + ASSET_TYPE_PIXELSHADER = 0x6, + ASSET_TYPE_VERTEXSHADER = 0x7, + ASSET_TYPE_VERTEXDECL = 0x8, + ASSET_TYPE_TECHNIQUE_SET = 0x9, + ASSET_TYPE_IMAGE = 0xA, + ASSET_TYPE_SOUND = 0xB, + ASSET_TYPE_SOUND_CURVE = 0xC, + ASSET_TYPE_LOADED_SOUND = 0xD, + ASSET_TYPE_CLIPMAP = 0xE, + ASSET_TYPE_COMWORLD = 0xF, + ASSET_TYPE_GLASSWORLD = 0x10, + ASSET_TYPE_PATHDATA = 0x11, + ASSET_TYPE_VEHICLE_TRACK = 0x12, + ASSET_TYPE_MAP_ENTS = 0x13, + ASSET_TYPE_FXWORLD = 0x14, + ASSET_TYPE_GFXWORLD = 0x15, + ASSET_TYPE_LIGHT_DEF = 0x16, + ASSET_TYPE_UI_MAP = 0x17, + ASSET_TYPE_FONT = 0x18, + ASSET_TYPE_MENULIST = 0x19, + ASSET_TYPE_MENU = 0x1A, + ASSET_TYPE_LOCALIZE_ENTRY = 0x1B, + ASSET_TYPE_ATTACHMENT = 0x1C, + ASSET_TYPE_WEAPON = 0x1D, + ASSET_TYPE_FX = 0x1F, + ASSET_TYPE_IMPACT_FX = 0x20, + ASSET_TYPE_SURFACE_FX = 0x21, + ASSET_TYPE_AITYPE = 0x22, + ASSET_TYPE_MPTYPE = 0x23, + ASSET_TYPE_CHARACTER = 0x24, + ASSET_TYPE_XMODELALIAS = 0x25, + ASSET_TYPE_RAWFILE = 0x26, + ASSET_TYPE_SCRIPTFILE = 0x27, + ASSET_TYPE_STRINGTABLE = 0x28, + ASSET_TYPE_LEADERBOARD = 0x29, + ASSET_TYPE_STRUCTURED_DATA_DEF = 0x2A, + ASSET_TYPE_TRACER = 0x2B, + ASSET_TYPE_VEHICLE = 0x2C, + ASSET_TYPE_ADDON_MAP_ENTS = 0x2D, + ASSET_TYPE_COUNT, + + ASSET_TYPE_STRING = ASSET_TYPE_COUNT, + ASSET_TYPE_ASSETLIST = 0x2F, + + ASSET_TYPE_FULLCOUNT + }; + + enum XFileBlock + { + XFILE_BLOCK_TEMP, + XFILE_BLOCK_PHYSICAL, + XFILE_BLOCK_RUNTIME, + XFILE_BLOCK_VIRTUAL, + XFILE_BLOCK_LARGE, + XFILE_BLOCK_CALLBACK, + XFILE_BLOCK_SCRIPT, + + MAX_XFILE_COUNT + }; + + struct PhysPreset; + struct PhysCollmap; + struct XAnimParts; + struct XModelSurfs; + struct XModel; + struct Material; + struct MaterialPixelShader; + struct MaterialVertexShader; + struct MaterialVertexDeclaration; + struct MaterialTechniqueSet; + struct GfxImage; + struct snd_alias_list_t; + struct SndCurve; + struct LoadedSound; + struct clipMap_t; + struct ComWorld; + struct GlassWorld; + struct PathData; + struct VehicleTrack; + struct MapEnts; + struct FxWorld; + struct GfxWorld; + struct GfxLightDef; + struct Font_s; + struct MenuList; + struct menuDef_t; + struct LocalizeEntry; + struct WeaponAttachment; + struct WeaponCompleteDef; + struct FxEffectDef; + struct FxImpactTable; + struct SurfaceFxTable; + struct RawFile; + struct ScriptFile; + struct StringTable; + struct LeaderboardDef; + struct StructuredDataDefSet; + struct TracerDef; + struct VehicleDef; + struct AddonMapEnts; + + typedef unsigned short ScriptString; + + union XAssetHeader + { + PhysPreset* physPreset; + PhysCollmap* physCollmap; + XAnimParts* parts; + XModelSurfs* modelSurfs; + XModel* model; + Material* material; + MaterialPixelShader* pixelShader; + MaterialVertexShader* vertexShader; + MaterialVertexDeclaration* vertexDecl; + MaterialTechniqueSet* techniqueSet; + GfxImage* image; + snd_alias_list_t* sound; + SndCurve* sndCurve; + LoadedSound* loadSnd; + clipMap_t* clipMap; + ComWorld* comWorld; + GlassWorld* glassWorld; + PathData* pathData; + VehicleTrack* vehicleTrack; + MapEnts* mapEnts; + FxWorld* fxWorld; + GfxWorld* gfxWorld; + GfxLightDef* lightDef; + Font_s* font; + MenuList* menuList; + menuDef_t* menu; + LocalizeEntry* localize; + WeaponAttachment* attachment; + WeaponCompleteDef* weapon; + // SndDriverGlobals* sndDriverGlobals; // UNUSED ON PC + FxEffectDef* fx; + FxImpactTable* impactFx; + SurfaceFxTable* surfaceFx; + RawFile* rawfile; + ScriptFile* scriptfile; + StringTable* stringTable; + LeaderboardDef* leaderboardDef; + StructuredDataDefSet* structuredDataDefSet; + TracerDef* tracerDef; + VehicleDef* vehDef; + AddonMapEnts* addonMapEnts; + void* data; + }; + + typedef float vec2_t[2]; + typedef float vec3_t[3]; + + typedef tdef_align(16) uint16_t r_index16_t; + typedef tdef_align(16) char raw_byte16; + typedef tdef_align(16) float raw_float16; + typedef tdef_align(128) unsigned int raw_uint128; + typedef unsigned char raw_byte; + typedef unsigned int raw_uint; + typedef unsigned short r_index_t; + + enum PhysPresetScaling + { + PHYSPRESET_SCALING_LINEAR = 0x0, + PHYSPRESET_SCALING_QUADRATIC = 0x1, + PHYSPRESET_SCALING_COUNT = 0x2 + }; + + struct PhysPreset + { + const char* name; + int type; + float mass; + float bounce; + float friction; + float bulletForceScale; + float explosiveForceScale; + const char* sndAliasPrefix; + float piecesSpreadFraction; + float piecesUpwardVelocity; + float minMomentum; + float maxMomentum; + float minPitch; + float maxPitch; + PhysPresetScaling volumeType; + PhysPresetScaling pitchType; + bool tempDefaultToCylinder; + bool perSurfaceSndAlias; + }; + + struct Bounds + { + float midPoint[3]; + float halfSize[3]; + }; + + struct cplane_s + { + float normal[3]; + float dist; + unsigned char type; + unsigned char pad[3]; + }; + + struct cbrushside_t + { + cplane_s* plane; + unsigned short materialNum; + unsigned char firstAdjacentSideOffset; + unsigned char edgeCount; + }; + + typedef unsigned char cbrushedge_t; + + struct cbrush_t + { + unsigned short numsides; + unsigned short glassPieceIndex; + cbrushside_t* sides; + cbrushedge_t* baseAdjacentSide; + short axialMaterialNum[2][3]; + unsigned char firstAdjacentSideOffsets[2][3]; + unsigned char edgeCount[2][3]; + }; + + typedef struct cbrush_t cbrushWrapper_t; + + struct BrushWrapper + { + Bounds bounds; + cbrushWrapper_t brush; + int totalEdgeCount; + cplane_s* planes; + }; + + struct PhysGeomInfo + { + BrushWrapper* brushWrapper; + int type; + float orientation[3][3]; + Bounds bounds; + }; + + struct PhysMass + { + float centerOfMass[3]; + float momentsOfInertia[3]; + float productsOfInertia[3]; + }; + + struct PhysCollmap + { + const char* name; + unsigned int count; + PhysGeomInfo* geoms; + PhysMass mass; + Bounds bounds; + }; + + union XAnimIndices + { + unsigned char* _1; + unsigned short* _2; + void* data; + }; + + struct XAnimNotifyInfo + { + ScriptString name; + float time; + }; + + typedef unsigned char ByteVec[3]; + typedef tdef_align(4) unsigned short UShortVec[3]; + + union XAnimDynamicFrames + { + ByteVec* _1; + UShortVec* _2; + }; + + union XAnimDynamicIndicesTrans + { + char _1[1]; + uint16_t _2[1]; + }; + + struct type_align(4) XAnimPartTransFrames + { + float mins[3]; + float size[3]; + XAnimDynamicFrames frames; + XAnimDynamicIndicesTrans indices; + }; + + union XAnimPartTransData + { + XAnimPartTransFrames frames; + vec3_t frame0; + }; + + struct XAnimPartTrans + { + unsigned short size; + unsigned char smallTrans; + XAnimPartTransData u; + }; + + union XAnimDynamicIndicesQuat2 + { + char _1[1]; + uint16_t _2[1]; + }; + + typedef tdef_align(4) short XQuat2[2]; + + struct type_align(4) XAnimDeltaPartQuatDataFrames2 + { + XQuat2* frames; + XAnimDynamicIndicesQuat2 indices; + }; + + union XAnimDeltaPartQuatData2 + { + XAnimDeltaPartQuatDataFrames2 frames; + short frame0[2]; + }; + + struct XAnimDeltaPartQuat2 + { + unsigned short size; + XAnimDeltaPartQuatData2 u; + }; + + union XAnimDynamicIndicesQuat + { + char _1[1]; + uint16_t _2[1]; + }; + + typedef tdef_align(4) short XQuat[4]; + + struct XAnimDeltaPartQuatDataFrames + { + XQuat* frames; + XAnimDynamicIndicesQuat indices; + }; + + union XAnimDeltaPartQuatData + { + XAnimDeltaPartQuatDataFrames frames; + short frame0[4]; + }; + + struct XAnimDeltaPartQuat + { + uint16_t size; + XAnimDeltaPartQuatData u; + }; + + struct XAnimDeltaPart + { + XAnimPartTrans* trans; + XAnimDeltaPartQuat2* quat2; + XAnimDeltaPartQuat* quat; + }; + + struct XAnimParts + { + const char* name; + unsigned short dataByteCount; + unsigned short dataShortCount; + unsigned short dataIntCount; + unsigned short randomDataByteCount; + unsigned short randomDataIntCount; + unsigned short numframes; + unsigned char flags; + unsigned char boneCount[10]; + unsigned char notifyCount; + unsigned char assetType; + bool isDefault; + unsigned int randomDataShortCount; + unsigned int indexCount; + float framerate; + float frequency; + ScriptString* names; + unsigned char* dataByte; + short* dataShort; + int* dataInt; + short* randomDataShort; + unsigned char* randomDataByte; + int* randomDataInt; + XAnimIndices indices; + XAnimNotifyInfo* notify; + XAnimDeltaPart* deltaPart; + }; + + struct XSurfaceVertexInfo + { + short vertCount[4]; + unsigned short* vertsBlend; + }; + + union PackedUnitVec + { + unsigned int packed; + char array[4]; + }; + + union PackedTexCoords + { + unsigned int packed; + }; + + struct GfxQuantizedNoColorVertex + { + short xyz[3]; + short binormalSign; + PackedUnitVec normal; + PackedUnitVec tangent; + PackedTexCoords texCoord; + }; + + union GfxColor + { + unsigned char array[4]; + unsigned int packed; + }; + + struct GfxQuantizedVertex + { + short xyz[3]; + short binormalSign; + PackedUnitVec normal; + PackedUnitVec tangent; + PackedTexCoords texCoord; + GfxColor color; + }; + + struct type_align(16) GfxPackedVertex + { + float xyz[3]; + float binormalSign; + GfxColor color; + PackedTexCoords texCoord; + PackedUnitVec normal; + PackedUnitVec tangent; + }; + + union GfxVertexUnion0 + { + GfxQuantizedNoColorVertex* quantizedNoColorVerts0; + GfxQuantizedVertex* quantizedVerts0; + GfxPackedVertex* packedVerts0; + void* verts0; + }; + + struct XSurfaceCollisionAabb + { + unsigned short mins[3]; + unsigned short maxs[3]; + }; + + struct type_align(16) XSurfaceCollisionNode + { + XSurfaceCollisionAabb aabb; + unsigned short childBeginIndex; + unsigned short childCount; + }; + + struct XSurfaceCollisionLeaf + { + unsigned short triangleBeginIndex; + }; + + struct XSurfaceCollisionTree + { + float trans[3]; + float scale[3]; + unsigned int nodeCount; + XSurfaceCollisionNode* nodes; + unsigned int leafCount; + XSurfaceCollisionLeaf* leafs; + }; + + struct XRigidVertList + { + unsigned short boneOffset; + unsigned short vertCount; + unsigned short triOffset; + unsigned short triCount; + XSurfaceCollisionTree* collisionTree; + }; + + struct XSurface + { + unsigned char tileMode; + unsigned char flags; + unsigned short vertCount; + unsigned short triCount; + char zoneHandle; + float quantizeScale; + uint16_t baseTriIndex; + uint16_t baseVertIndex; + r_index16_t(*triIndices)[3]; + XSurfaceVertexInfo vertInfo; + GfxVertexUnion0 verts0; + unsigned int vertListCount; + XRigidVertList* vertList; + int partBits[6]; + }; + + struct XModelSurfs + { + const char* name; + XSurface* surfs; + unsigned short numsurfs; + int partBits[6]; + }; + + struct DObjAnimMat + { + float quat[4]; + float trans[3]; + float transWeight; + }; + + struct XModelLodInfo + { + float dist; + unsigned short numsurfs; + unsigned short surfIndex; + XModelSurfs* modelSurfs; + int partBits[6]; + XSurface* surfs; + char lod; + char smcBaseIndexPlusOne; + char smcSubIndexMask; + char smcBucket; + }; + + struct XModelCollTri_s + { + float plane[4]; + float svec[4]; + float tvec[4]; + }; + + struct XModelCollSurf_s + { + XModelCollTri_s* collTris; + int numCollTris; + Bounds bounds; + int boneIdx; + int contents; + int surfFlags; + }; + + struct XBoneInfo + { + Bounds bounds; + float radiusSquared; + }; + + struct XModel + { + const char* name; + unsigned char numBones; + unsigned char numRootBones; + unsigned char numsurfs; + float scale; + unsigned int noScalePartBits[6]; + ScriptString* boneNames; + unsigned char* parentList; + short(*quats)[4]; + float(*trans)[3]; + unsigned char* partClassification; + DObjAnimMat* baseMat; + Material** materialHandles; + XModelLodInfo lodInfo[4]; + char maxLoadedLod; + unsigned char numLods; + unsigned char collLod; + unsigned char flags; + XModelCollSurf_s* collSurfs; + int numCollSurfs; + int contents; + XBoneInfo* boneInfo; + float radius; + Bounds bounds; + unsigned short* invHighMipRadius; + int memUsage; + PhysPreset* physPreset; + PhysCollmap* physCollmap; + float quantization; + }; + + struct gcc_align(8) GfxDrawSurfFields + { + uint64_t unused : 1; + uint64_t primarySortKey : 6; + uint64_t surfType : 4; + uint64_t viewModelRender : 1; + uint64_t sceneLightIndex : 8; + uint64_t useHeroLighting : 1; + uint64_t prepass : 2; + uint64_t materialSortedIndex : 12; + uint64_t customIndex : 5; + uint64_t hasGfxEntIndex : 1; + uint64_t reflectionProbeIndex : 8; + uint64_t objectId : 15; + }; + + union GfxDrawSurf + { + gcc_align(8) GfxDrawSurfFields fields; + gcc_align(8) uint64_t packed; + }; + + struct MaterialInfo + { + const char* name; + unsigned char gameFlags; + unsigned char sortKey; + unsigned char textureAtlasRowCount; + unsigned char textureAtlasColumnCount; + GfxDrawSurf drawSurf; + unsigned int surfaceTypeBits; + }; + + struct WaterWritable + { + float floatTime; + }; + + struct water_t + { + WaterWritable writable; + float* H0; + float* wTerm; + int M; + int N; + float Lx; + float Lz; + float gravity; + float windvel; + float winddir[2]; + float amplitude; + float codeConstant[4]; + GfxImage* image; + }; + + union MaterialTextureDefInfo + { + GfxImage* image; + water_t* water; + }; + + struct MaterialTextureDef + { + unsigned int nameHash; + char nameStart; + char nameEnd; + unsigned char samplerState; + unsigned char semantic; + MaterialTextureDefInfo u; + }; + + struct type_align(16) MaterialConstantDef + { + unsigned int nameHash; + char name[12]; + float literal[4]; + }; + + struct GfxStateBits + { + unsigned int loadBits[2]; + }; + + struct Material + { + MaterialInfo info; + unsigned char stateBitsEntry[54]; + unsigned char textureCount; + unsigned char constantCount; + unsigned char stateBitsCount; + unsigned char stateFlags; + unsigned char cameraRegion; + MaterialTechniqueSet* techniqueSet; + MaterialTextureDef* textureTable; + MaterialConstantDef* constantTable; + GfxStateBits* stateBitsTable; + const char** subMaterials; + }; + + struct GfxShaderLoadDef + { + unsigned char* cachedPart; + unsigned char* physicalPart; + unsigned short cachedPartSize; + unsigned short physicalPartSize; + }; + + struct GfxPixelShaderLoadDef + { + unsigned int* program; + uint16_t programSize; + uint16_t loadForRenderer; + }; + + union MaterialPixelShaderProgram + { + void* ps; + GfxPixelShaderLoadDef loadDef; + }; + + struct MaterialPixelShader + { + const char* name; + MaterialPixelShaderProgram prog; + }; + + struct GfxVertexShaderLoadDef + { + unsigned int* program; + uint16_t programSize; + uint16_t loadForRenderer; + }; + + struct MaterialVertexShaderProgram + { + void* vs; + GfxVertexShaderLoadDef loadDef; + }; + + struct MaterialVertexShader + { + const char* name; + MaterialVertexShaderProgram prog; + }; + + struct MaterialStreamRouting + { + char source; + char dest; + }; + + struct MaterialVertexStreamRouting + { + MaterialStreamRouting data[13]; + void* decl[16]; + }; + + struct MaterialVertexDeclaration + { + const char* name; + char streamCount; + bool hasOptionalSource; + MaterialVertexStreamRouting routing; + }; + + struct MaterialArgumentCodeConst + { + unsigned short index; + unsigned char firstRow; + unsigned char rowCount; + }; + + union MaterialArgumentDef + { + const float(*literalConst)[4]; + MaterialArgumentCodeConst codeConst; + unsigned int codeSampler; + unsigned int nameHash; + }; + + struct MaterialShaderArgument + { + unsigned short type; + unsigned short dest; + MaterialArgumentDef u; + }; + + struct MaterialPass + { + MaterialVertexDeclaration* vertexDecl; + MaterialVertexShader* vertexShader; + MaterialPixelShader* pixelShader; + unsigned char perPrimArgCount; + unsigned char perObjArgCount; + unsigned char stableArgCount; + unsigned char customSamplerFlags; + MaterialShaderArgument* args; + }; + + struct MaterialTechnique + { + const char* name; + unsigned short flags; + unsigned short passCount; + MaterialPass passArray[1]; + }; + + struct MaterialTechniqueSet + { + const char* name; + unsigned char worldVertFormat; + unsigned char unused[2]; + MaterialTechniqueSet* remappedTechniqueSet; + MaterialTechnique* techniques[54]; + }; + + struct type_align(4) GfxImageLoadDef + { + char levelCount; + char pad[3]; + int flags; + int format; + int resourceSize; + char data[1]; + }; + + union GfxTexture + { + // IDirect3DBaseTexture9* basemap; + // IDirect3DTexture9* map; + // IDirect3DVolumeTexture9* volmap; + // IDirect3DCubeTexture9* cubemap; +#ifndef __ida + Texture* texture; +#endif + GfxImageLoadDef* loadDef; + }; + + struct Picmip + { + char platform[2]; + }; + + struct CardMemory + { + int platform[2]; + }; + + struct GfxImage + { + GfxTexture texture; + char mapType; + char semantic; + char category; + unsigned char flags; + Picmip picmip; + bool noPicmip; + char track; + CardMemory cardMemory; + unsigned short width; + unsigned short height; + unsigned short depth; + unsigned char levelCount; + const char* name; + }; + + struct StreamedSound + { + const char* dir; + const char* name; + }; + + struct AILSOUNDINFO + { + int format; + const void* data_ptr; + unsigned int data_len; + unsigned int rate; + int bits; + int channels; + unsigned int samples; + unsigned int block_size; + const void* initial_ptr; + }; + + struct MssSound + { + AILSOUNDINFO info; + char* data; + }; + + struct LoadedSound + { + const char* name; + MssSound sound; + }; + + union SoundFileRef + { + LoadedSound* loadSnd; + StreamedSound streamSnd; + }; + + struct SoundFile + { + unsigned char type; + unsigned char exists; + SoundFileRef u; + }; + + struct MSSSpeakerLevels + { + int speaker; + int numLevels; + float levels[2]; + }; + + struct MSSChannelMap + { + int speakerCount; + MSSSpeakerLevels speakers[6]; + }; + + struct SpeakerMap + { + bool isDefault; + const char* name; + MSSChannelMap channelMaps[2][2]; + }; + + struct SndCurve + { + const char* filename; + unsigned short knotCount; + float knots[16][2]; + }; + + struct snd_alias_t + { + const char* aliasName; + const char* subtitle; + const char* secondaryAliasName; + const char* chainAliasName; + const char* mixerGroup; + SoundFile* soundFile; + int sequence; + float volMin; + float volMax; + int volModIndex; + float pitchMin; + float pitchMax; + float distMin; + float distMax; + float velocityMin; + int flags; + unsigned char masterPriority; + float masterPercentage; + float slavePercentage; + float probability; + float lfePercentage; + float centerPercentage; + int startDelay; + SndCurve* volumeFalloffCurve; + float envelopMin; + float envelopMax; + float envelopPercentage; + SpeakerMap* speakerMap; + }; + + struct snd_alias_list_t + { + const char* aliasName; + snd_alias_t* head; + int count; + }; + + typedef unsigned short LeafBrush; + + struct ClipMaterial + { + const char* name; + int surfaceFlags; + int contents; + }; + + struct cLeafBrushNodeLeaf_t + { + LeafBrush* brushes; + }; + + struct cLeafBrushNodeChildren_t + { + float dist; + float range; + unsigned short childOffset[2]; + }; + + union cLeafBrushNodeData_t + { + cLeafBrushNodeLeaf_t leaf; + cLeafBrushNodeChildren_t children; + }; + + struct cLeafBrushNode_s + { + unsigned char axis; + short leafBrushCount; + int contents; + cLeafBrushNodeData_t data; + }; + typedef tdef_align(128) cbrush_t cbrush_array_t; + typedef tdef_align(128) Bounds BoundsArray; + + struct ClipInfo + { + int planeCount; + cplane_s* planes; + unsigned int numMaterials; + ClipMaterial* materials; + unsigned int numBrushSides; + cbrushside_t* brushsides; + unsigned int numBrushEdges; + cbrushedge_t* brushEdges; + unsigned int leafbrushNodesCount; + cLeafBrushNode_s* leafbrushNodes; + unsigned int numLeafBrushes; + LeafBrush* leafbrushes; + unsigned short numBrushes; + cbrush_array_t* brushes; + BoundsArray* brushBounds; + int* brushContents; + }; + + struct cStaticModel_s + { + XModel* xmodel; + float origin[3]; + float invScaledAxis[3][3]; + Bounds absBounds; + }; + + struct cNode_t + { + cplane_s* plane; + short children[2]; + }; + + struct cLeaf_t + { + unsigned short firstCollAabbIndex; + unsigned short collAabbCount; + int brushContents; + int terrainContents; + Bounds bounds; + int leafBrushNode; + }; + + struct CollisionBorder + { + float distEq[3]; + float zBase; + float zSlope; + float start; + float length; + }; + + struct CollisionPartition + { + unsigned char triCount; + unsigned char borderCount; + unsigned char firstVertSegment; + int firstTri; + CollisionBorder* borders; + }; + + union CollisionAabbTreeIndex + { + int firstChildIndex; + int partitionIndex; + }; + + struct CollisionAabbTree + { + float midPoint[3]; + unsigned short materialIndex; + unsigned short childCount; + float halfSize[3]; + CollisionAabbTreeIndex u; + }; + + struct cmodel_t + { + Bounds bounds; + float radius; + ClipInfo* info; + cLeaf_t leaf; + }; + + struct Stage + { + const char* name; + float origin[3]; + unsigned short triggerIndex; + unsigned char sunPrimaryLightIndex; + }; + + struct TriggerModel + { + int contents; + unsigned short hullCount; + unsigned short firstHull; + }; + + struct TriggerHull + { + Bounds bounds; + int contents; + unsigned short slabCount; + unsigned short firstSlab; + }; + + struct TriggerSlab + { + float dir[3]; + float midPoint; + float halfSize; + }; + + struct MapTriggers + { + unsigned int count; + TriggerModel* models; + unsigned int hullCount; + TriggerHull* hulls; + unsigned int slabCount; + TriggerSlab* slabs; + }; + + struct SModelAabbNode + { + Bounds bounds; + unsigned short firstChild; + unsigned short childCount; + }; + + enum DynEntityType + { + DYNENT_TYPE_INVALID = 0x0, + DYNENT_TYPE_CLUTTER = 0x1, + DYNENT_TYPE_DESTRUCT = 0x2, + DYNENT_TYPE_HINGE = 0x3, + DYNENT_TYPE_COUNT = 0x4 + }; + + struct GfxPlacement + { + float quat[4]; + float origin[3]; + }; + + struct DynEntityHingeDef + { + float axisOrigin[3]; + float axisDir[3]; + bool isLimited; + float angleMin; + float angleMax; + float momentOfInertia; + float friction; + }; + + struct DynEntityDef + { + DynEntityType type; + GfxPlacement pose; + XModel* xModel; + unsigned short brushModel; + unsigned short physicsBrushModel; + FxEffectDef* destroyFx; + PhysPreset* physPreset; + int health; + DynEntityHingeDef* hinge; + PhysMass mass; + int contents; + }; + + struct DynEntityPose + { + GfxPlacement pose; + float radius; + }; + + struct Hinge + { + float angle; + float quat[4]; + float angularVel; + float torqueAccum; + bool active; + float autoDisableTimeLeft; + DynEntityHingeDef* def; + PhysPreset* physPreset; + float centerOfMassRelToAxisOriginAtAngleZero[3]; + }; + + struct DynEntityClient + { + int physObjId; + unsigned short flags; + unsigned short lightingHandle; + int health; + Hinge* hinge; + }; + + struct DynEntityColl + { + unsigned short sector; + unsigned short nextEntInSector; + float linkMins[2]; + float linkMaxs[2]; + }; + + struct clipMap_t + { + const char* name; + int isInUse; + ClipInfo info; + ClipInfo* pInfo; + unsigned int numStaticModels; + cStaticModel_s* staticModelList; + unsigned int numNodes; + cNode_t* nodes; + unsigned int numLeafs; + cLeaf_t* leafs; + unsigned int vertCount; + vec3_t* verts; + int triCount; + unsigned short* triIndices; + unsigned char* triEdgeIsWalkable; + int borderCount; + CollisionBorder* borders; + int partitionCount; + CollisionPartition* partitions; + int aabbTreeCount; + CollisionAabbTree* aabbTrees; + unsigned int numSubModels; + cmodel_t* cmodels; + MapEnts* mapEnts; + Stage* stages; + unsigned char stageCount; + MapTriggers stageTrigger; + unsigned short smodelNodeCount; + SModelAabbNode* smodelNodes; + unsigned short dynEntCount[2]; + DynEntityDef* dynEntDefList[2]; + DynEntityPose* dynEntPoseList[2]; + DynEntityClient* dynEntClientList[2]; + DynEntityColl* dynEntCollList[2]; + unsigned int checksum; + unsigned char padding[20]; + }; + + struct ComPrimaryLight + { + unsigned char type; + unsigned char canUseShadowMap; + unsigned char exponent; + unsigned char unused; + float color[3]; + float dir[3]; + float up[3]; + float origin[3]; + float radius; + float cosHalfFovOuter; + float cosHalfFovInner; + float cosHalfFovExpanded; + float rotationLimit; + float translationLimit; + const char* defName; + }; + + struct ComWorld + { + const char* name; + int isInUse; + unsigned int primaryLightCount; + ComPrimaryLight* primaryLights; + }; + + struct G_GlassName + { + char* nameStr; + unsigned short name; + unsigned short pieceCount; + unsigned short* pieceIndices; + }; + + struct G_GlassPiece + { + unsigned short damageTaken; + unsigned short collapseTime; + int lastStateChangeTime; + unsigned char impactDir; + unsigned char impactPos[2]; + }; + + struct G_GlassData + { + G_GlassPiece* glassPieces; + unsigned int pieceCount; + unsigned short damageToWeaken; + unsigned short damageToDestroy; + unsigned int glassNameCount; + G_GlassName* glassNames; + unsigned char pad[108]; + }; + + struct GlassWorld + { + const char* name; + G_GlassData* g_glassData; + }; + + struct pathlink_s + { + float fDist; + unsigned short nodeNum; + unsigned char disconnectCount; + unsigned char negotiationLink; + unsigned char flags; + unsigned char ubBadPlaceCount[3]; + }; + + enum nodeType + { + NODE_ERROR = 0x0, + NODE_PATHNODE = 0x1, + NODE_COVER_STAND = 0x2, + NODE_COVER_CROUCH = 0x3, + NODE_COVER_CROUCH_WINDOW = 0x4, + NODE_COVER_PRONE = 0x5, + NODE_COVER_RIGHT = 0x6, + NODE_COVER_LEFT = 0x7, + NODE_AMBUSH = 0x8, + NODE_EXPOSED = 0x9, + NODE_CONCEALMENT_STAND = 0xA, + NODE_CONCEALMENT_CROUCH = 0xB, + NODE_CONCEALMENT_PRONE = 0xC, + NODE_DOOR = 0xD, + NODE_DOOR_INTERIOR = 0xE, + NODE_SCRIPTED = 0xF, + NODE_NEGOTIATION_BEGIN = 0x10, + NODE_NEGOTIATION_END = 0x11, + NODE_TURRET = 0x12, + NODE_GUARD = 0x13, + NODE_NUMTYPES = 0x14, + NODE_DONTLINK = 0x14 + }; + + enum PathNodeErrorCode + { + PNERR_NONE = 0x0, + PNERR_INSOLID = 0x1, + PNERR_FLOATING = 0x2, + PNERR_NOLINK = 0x3, + PNERR_DUPLICATE = 0x4, + PNERR_NOSTANCE = 0x5, + PNERR_INVALIDDOOR = 0x6, + PNERR_NOANGLES = 0x7, + PNERR_BADPLACEMENT = 0x8, + NUM_PATH_NODE_ERRORS = 0x9 + }; + + struct pathnode_constant_t + { + nodeType type; + unsigned short spawnflags; + ScriptString targetname; + ScriptString script_linkName; + ScriptString script_noteworthy; + ScriptString target; + ScriptString animscript; + int animscriptfunc; + float vOrigin[3]; + float fAngle; + float forward[2]; + float minUseDistSq; + PathNodeErrorCode error; + short wOverlapNode[2]; + unsigned short totalLinkCount; + pathlink_s* Links; + }; + + struct pathnode_dynamic_t + { + void* pOwner; + int iFreeTime; + int iValidTime[3]; + int dangerousNodeTime[3]; + int inPlayerLOSTime; + short wLinkCount; + short wOverlapCount; + short turretEntNumber; + unsigned char userCount; + bool hasBadPlaceLink; + }; + + struct pathnode_t; + + struct pathnode_transient_t + { + int iSearchFrame; + pathnode_t* pNextOpen; + pathnode_t* pPrevOpen; + pathnode_t* pParent; + float fCost; + float fHeuristic; + union + { + float nodeCost; + int linkIndex; + }; + }; + + struct pathnode_t + { + pathnode_constant_t constant; + pathnode_dynamic_t dynamic; + pathnode_transient_t transient; + }; + + struct type_align(16) pathbasenode_t + { + float vOrigin[3]; + unsigned int type; + }; + + struct pathnode_tree_nodes_t + { + int nodeCount; + unsigned short* nodes; + }; + + struct pathnode_tree_t; + + union pathnode_tree_info_t + { + pathnode_tree_t* child[2]; + pathnode_tree_nodes_t s; + }; + + struct pathnode_tree_t + { + int axis; + float dist; + pathnode_tree_info_t u; + }; + + struct PathData + { + const char* name; + unsigned int nodeCount; + pathnode_t* nodes; + pathbasenode_t* basenodes; + unsigned int chainNodeCount; + unsigned short* chainNodeForNode; + unsigned short* nodeForChainNode; + int visBytes; + unsigned char* pathVis; + int nodeTreeCount; + pathnode_tree_t* nodeTree; + }; + + struct VehicleTrackObstacle + { + float origin[2]; + float radius; + }; + + struct VehicleTrackSector + { + float startEdgeDir[2]; + float startEdgeDist; + float leftEdgeDir[2]; + float leftEdgeDist; + float rightEdgeDir[2]; + float rightEdgeDist; + float sectorLength; + float sectorWidth; + float totalPriorLength; + float totalFollowingLength; + VehicleTrackObstacle* obstacles; + unsigned int obstacleCount; + }; + + struct VehicleTrackSegment + { + const char* targetName; + VehicleTrackSector* sectors; + unsigned int sectorCount; + VehicleTrackSegment** nextBranches; + unsigned int nextBranchesCount; + VehicleTrackSegment** prevBranches; + unsigned int prevBranchesCount; + float endEdgeDir[2]; + float endEdgeDist; + float totalLength; + }; + + struct VehicleTrack + { + const char* name; + VehicleTrackSegment* segments; + unsigned int segmentCount; + }; + + struct ClientTriggerAabbNode + { + Bounds bounds; + unsigned short firstChild; + unsigned short childCount; + }; + + struct ClientTriggers + { + MapTriggers trigger; + unsigned short numClientTriggerNodes; + ClientTriggerAabbNode* clientTriggerAabbTree; + unsigned int triggerStringLength; + char* triggerString; + unsigned short* triggerStringOffsets; + unsigned char* triggerType; + vec3_t* origins; + float* scriptDelay; + short* audioTriggers; + }; + + struct MapEnts + { + const char* name; + char* entityString; + int numEntityChars; + MapTriggers trigger; + ClientTriggers clientTrigger; + }; + + struct FxGlassDef + { + float halfThickness; + float texVecs[2][2]; + GfxColor color; + Material* material; + Material* materialShattered; + PhysPreset* physPreset; + }; + + struct FxSpatialFrame + { + float quat[4]; + float origin[3]; + }; + + union FxGlassPiecePlace + { + struct + { + FxSpatialFrame frame; + float radius; + }; + unsigned int nextFree; + }; + + struct FxGlassPieceState + { + float texCoordOrigin[2]; + unsigned int supportMask; + unsigned short initIndex; + unsigned short geoDataStart; + unsigned char defIndex; + unsigned char pad[5]; + unsigned char vertCount; + unsigned char holeDataCount; + unsigned char crackDataCount; + unsigned char fanDataCount; + unsigned short flags; + float areaX2; + }; + + struct FxGlassPieceDynamics + { + int fallTime; + int physObjId; + int physJointId; + float vel[3]; + float avel[3]; + }; + + struct FxGlassVertex + { + short x; + short y; + }; + + struct FxGlassHoleHeader + { + unsigned short uniqueVertCount; + unsigned char touchVert; + unsigned char pad[1]; + }; + + struct FxGlassCrackHeader + { + unsigned short uniqueVertCount; + unsigned char beginVertIndex; + unsigned char endVertIndex; + }; + + union FxGlassGeometryData + { + FxGlassVertex vert; + FxGlassHoleHeader hole; + FxGlassCrackHeader crack; + unsigned char asBytes[4]; + short anonymous[2]; + }; + + struct FxGlassInitPieceState + { + FxSpatialFrame frame; + float radius; + float texCoordOrigin[2]; + unsigned int supportMask; + float areaX2; + unsigned char defIndex; + unsigned char vertCount; + unsigned char fanDataCount; + unsigned char pad[1]; + }; + + struct FxGlassSystem + { + int time; + int prevTime; + unsigned int defCount; + unsigned int pieceLimit; + unsigned int pieceWordCount; + unsigned int initPieceCount; + unsigned int cellCount; + unsigned int activePieceCount; + unsigned int firstFreePiece; + unsigned int geoDataLimit; + unsigned int geoDataCount; + unsigned int initGeoDataCount; + FxGlassDef* defs; + FxGlassPiecePlace* piecePlaces; + FxGlassPieceState* pieceStates; + FxGlassPieceDynamics* pieceDynamics; + FxGlassGeometryData* geoData; + raw_uint* isInUse; + raw_uint* cellBits; + raw_byte16* visData; + vec3_t* linkOrg; + raw_float16* halfThickness; + unsigned short* lightingHandles; + FxGlassInitPieceState* initPieceStates; + FxGlassGeometryData* initGeoData; + bool needToCompactData; + unsigned char initCount; + float effectChanceAccum; + int lastPieceDeletionTime; + }; + + struct FxWorld + { + const char* name; + FxGlassSystem glassSys; + }; + + struct GfxSky + { + int skySurfCount; + int* skyStartSurfs; + GfxImage* skyImage; + unsigned char skySamplerState; + }; + + struct GfxWorldDpvsPlanes + { + int cellCount; + cplane_s* planes; + unsigned short* nodes; + raw_uint* sceneEntCellBits; + }; + + struct GfxCellTreeCount + { + int aabbTreeCount; + }; + + typedef unsigned short StaticModelIndex; + + struct GfxAabbTree + { + Bounds bounds; + unsigned short childCount; + unsigned short surfaceCount; + unsigned short startSurfIndex; + unsigned short surfaceCountNoDecal; + unsigned short startSurfIndexNoDecal; + unsigned short smodelIndexCount; + StaticModelIndex* smodelIndexes; + int childrenOffset; + }; + + struct GfxCellTree + { + GfxAabbTree* aabbTree; + }; + + struct GfxPortal; + + struct GfxPortalWritable + { + bool isQueued; + bool isAncestor; + unsigned char recursionDepth; + unsigned char hullPointCount; + float(*hullPoints)[2]; + GfxPortal* queuedParent; + }; + + struct DpvsPlane + { + float coeffs[4]; + }; + + struct GfxPortal + { + GfxPortalWritable writable; + DpvsPlane plane; + vec3_t* vertices; + unsigned short cellIndex; + unsigned char vertexCount; + float hullAxis[2][3]; + }; + + struct GfxCell + { + Bounds bounds; + int portalCount; + GfxPortal* portals; + unsigned char reflectionProbeCount; + unsigned char* reflectionProbes; + unsigned char reflectionProbeReferenceCount; + unsigned char* reflectionProbeReferences; + }; + + struct GfxReflectionProbe + { + float origin[3]; + }; + + struct GfxReflectionProbeReferenceOrigin + { + float origin[3]; + }; + + struct GfxReflectionProbeReference + { + unsigned char index; + }; + + struct GfxLightmapArray + { + GfxImage* primary; + GfxImage* secondary; + }; + + struct GfxWorldVertex + { + float xyz[3]; + float binormalSign; + GfxColor color; + float texCoord[2]; + float lmapCoord[2]; + PackedUnitVec normal; + PackedUnitVec tangent; + }; + + struct GfxWorldVertexData + { + GfxWorldVertex* vertices; + void* worldVb; + }; + + struct GfxWorldVertexLayerData + { + unsigned char* data; + void* layerVb; + }; + + struct GfxWorldDraw + { + unsigned int reflectionProbeCount; + GfxImage** reflectionProbes; + GfxReflectionProbe* reflectionProbeOrigins; + GfxTexture* reflectionProbeTextures; + unsigned int reflectionProbeReferenceCount; + GfxReflectionProbeReferenceOrigin* reflectionProbeReferenceOrigins; + GfxReflectionProbeReference* reflectionProbeReferences; + int lightmapCount; + GfxLightmapArray* lightmaps; + GfxTexture* lightmapPrimaryTextures; + GfxTexture* lightmapSecondaryTextures; + GfxImage* lightmapOverridePrimary; + GfxImage* lightmapOverrideSecondary; + unsigned int vertexCount; + GfxWorldVertexData vd; + unsigned int vertexLayerDataSize; + GfxWorldVertexLayerData vld; + unsigned int indexCount; + r_index_t* indices; + }; + + struct type_align(4) GfxLightGridEntry + { + unsigned short colorsIndex; + unsigned char primaryLightIndex; + unsigned char needsTrace; + }; + + struct type_align(4) GfxLightGridColors + { + unsigned char rgb[56][3]; + }; + + struct GfxLightGrid + { + bool hasLightRegions; + bool useSkyForLowZ; + unsigned int lastSunPrimaryLightIndex; + unsigned short mins[3]; + unsigned short maxs[3]; + unsigned int rowAxis; + unsigned int colAxis; + unsigned short* rowDataStart; + unsigned int rawRowDataSize; + unsigned char* rawRowData; + unsigned int entryCount; + GfxLightGridEntry* entries; + unsigned int colorCount; + GfxLightGridColors* colors; + }; + + struct GfxBrushModelWritable + { + Bounds bounds; + }; + + struct type_align(4) GfxBrushModel + { + GfxBrushModelWritable writable; + Bounds bounds; + float radius; + unsigned short surfaceCount; + unsigned short startSurfIndex; + uint16_t surfaceCountNoDecal; + }; + + struct MaterialMemory + { + Material* material; + int memory; + }; + + struct sunflare_t + { + bool hasValidData; + Material* spriteMaterial; + Material* flareMaterial; + float spriteSize; + float flareMinSize; + float flareMinDot; + float flareMaxSize; + float flareMaxDot; + float flareMaxAlpha; + int flareFadeInTime; + int flareFadeOutTime; + float blindMinDot; + float blindMaxDot; + float blindMaxDarken; + int blindFadeInTime; + int blindFadeOutTime; + float glareMinDot; + float glareMaxDot; + float glareMaxLighten; + int glareFadeInTime; + int glareFadeOutTime; + float sunFxPosition[3]; + }; + + struct XModelDrawInfo + { + unsigned char hasGfxEntIndex; + unsigned char lod; + unsigned short surfId; + }; + + struct GfxSceneDynModel + { + XModelDrawInfo info; + unsigned short dynEntId; + }; + + struct BModelDrawInfo + { + unsigned short surfId; + }; + + struct type_align(4) GfxSceneDynBrush + { + BModelDrawInfo info; + unsigned short dynEntId; + }; + + struct GfxShadowGeometry + { + unsigned short surfaceCount; + unsigned short smodelCount; + unsigned short* sortedSurfIndex; + unsigned short* smodelIndex; + }; + + struct GfxLightRegionAxis + { + float dir[3]; + float midPoint; + float halfSize; + }; + + struct GfxLightRegionHull + { + float kdopMidPoint[9]; + float kdopHalfSize[9]; + unsigned int axisCount; + GfxLightRegionAxis* axis; + }; + + struct GfxLightRegion + { + unsigned int hullCount; + GfxLightRegionHull* hulls; + }; + + struct GfxStaticModelInst + { + Bounds bounds; + float lightingOrigin[3]; + }; + + struct srfTriangles_t + { + unsigned int vertexLayerData; + unsigned int firstVertex; + unsigned short vertexCount; + unsigned short triCount; + unsigned int baseIndex; + }; + + struct GfxSurfaceLightingAndFlagsFields + { + unsigned char lightmapIndex; + unsigned char reflectionProbeIndex; + unsigned char primaryLightIndex; + unsigned char flags; + }; + + union GfxSurfaceLightingAndFlags + { + GfxSurfaceLightingAndFlagsFields fields; + unsigned int packed; + }; + + struct GfxSurface + { + srfTriangles_t tris; + Material* material; + GfxSurfaceLightingAndFlags laf; + }; + + struct GfxSurfaceBounds + { + Bounds bounds; + }; + + struct GfxPackedPlacement + { + float origin[3]; + float axis[3][3]; + float scale; + }; + + struct GfxStaticModelDrawInst + { + GfxPackedPlacement placement; + XModel* model; + unsigned short cullDist; + unsigned short lightingHandle; + unsigned char reflectionProbeIndex; + unsigned char primaryLightIndex; + unsigned char flags; + unsigned char firstMtlSkinIndex; + GfxColor groundLighting; + uint16_t cacheId[4]; + }; + + struct GfxWorldDpvsStatic + { + unsigned int smodelCount; + unsigned int staticSurfaceCount; + unsigned int staticSurfaceCountNoDecal; + unsigned int litOpaqueSurfsBegin; + unsigned int litOpaqueSurfsEnd; + unsigned int litTransSurfsBegin; + unsigned int litTransSurfsEnd; + unsigned int shadowCasterSurfsBegin; + unsigned int shadowCasterSurfsEnd; + unsigned int emissiveSurfsBegin; + unsigned int emissiveSurfsEnd; + unsigned int smodelVisDataCount; + unsigned int surfaceVisDataCount; + raw_byte* smodelVisData[3]; + raw_byte* surfaceVisData[3]; + unsigned short* sortedSurfIndex; + GfxStaticModelInst* smodelInsts; + GfxSurface* surfaces; + GfxSurfaceBounds* surfacesBounds; + GfxStaticModelDrawInst* smodelDrawInsts; + GfxDrawSurf* surfaceMaterials; + raw_uint128* surfaceCastsSunShadow; + volatile long usageCount; + }; + + struct GfxWorldDpvsDynamic + { + unsigned int dynEntClientWordCount[2]; + unsigned int dynEntClientCount[2]; + raw_uint* dynEntCellBits[2]; + raw_byte16* dynEntVisData[2][3]; + }; + + struct GfxHeroOnlyLight + { + unsigned char type; + unsigned char unused[3]; + float color[3]; + float dir[3]; + float up[3]; + float origin[3]; + float radius; + float cosHalfFovOuter; + float cosHalfFovInner; + int exponent; + }; + + typedef tdef_align(128) GfxCellTree GfxCellTree128; + + struct GfxWorld + { + const char* name; + const char* baseName; + int planeCount; + int nodeCount; + unsigned int surfaceCount; + int skyCount; + GfxSky* skies; + unsigned int lastSunPrimaryLightIndex; + unsigned int primaryLightCount; + unsigned int sortKeyLitDecal; + unsigned int sortKeyEffectDecal; + unsigned int sortKeyEffectAuto; + unsigned int sortKeyDistortion; + GfxWorldDpvsPlanes dpvsPlanes; + GfxCellTreeCount* aabbTreeCounts; + GfxCellTree128* aabbTrees; + GfxCell* cells; + GfxWorldDraw draw; + GfxLightGrid lightGrid; + int modelCount; + GfxBrushModel* models; + Bounds bounds; + unsigned int checksum; + int materialMemoryCount; + MaterialMemory* materialMemory; + sunflare_t sun; + float outdoorLookupMatrix[4][4]; + GfxImage* outdoorImage; + raw_uint* cellCasterBits; + raw_uint* cellHasSunLitSurfsBits; + GfxSceneDynModel* sceneDynModel; + GfxSceneDynBrush* sceneDynBrush; + raw_uint* primaryLightEntityShadowVis; + raw_uint* primaryLightDynEntShadowVis[2]; + raw_byte* nonSunPrimaryLightForModelDynEnt; + GfxShadowGeometry* shadowGeom; + GfxLightRegion* lightRegion; + GfxWorldDpvsStatic dpvs; + GfxWorldDpvsDynamic dpvsDyn; + unsigned int mapVtxChecksum; + unsigned int heroOnlyLightCount; + GfxHeroOnlyLight* heroOnlyLights; + unsigned char fogTypesAllowed; + }; + + struct GfxLightImage + { + GfxImage* image; + unsigned char samplerState; + }; + + struct GfxLightDef + { + const char* name; + GfxLightImage attenuation; + GfxLightImage cucoloris; + int lmapLookupStart; + }; + + struct Glyph + { + unsigned short letter; + char x0; + char y0; + unsigned char dx; + unsigned char pixelWidth; + unsigned char pixelHeight; + float s0; + float t0; + float s1; + float t1; + }; + + struct Font_s + { + const char* fontName; + int pixelHeight; + int glyphCount; + Material* material; + Material* glowMaterial; + Glyph* glyphs; + }; + + struct MenuList + { + const char* name; + int menuCount; + menuDef_t** menus; + }; + + struct Statement_s; + + enum expDataType + { + VAL_INT = 0x0, + VAL_FLOAT = 0x1, + VAL_STRING = 0x2, + NUM_INTERNAL_DATATYPES = 0x3, + VAL_FUNCTION = 0x3, + + NUM_DATATYPES + }; + + struct ExpressionString + { + const char* string; + }; + + union operandInternalDataUnion + { + int intVal; + float floatVal; + ExpressionString stringVal; + Statement_s* function; + }; + + struct Operand + { + expDataType dataType; + operandInternalDataUnion internals; + }; + + enum operationEnum + { + OP_NOOP = 0x0, + OP_RIGHTPAREN = 0x1, + OP_MULTIPLY = 0x2, + OP_DIVIDE = 0x3, + OP_MODULUS = 0x4, + OP_ADD = 0x5, + OP_SUBTRACT = 0x6, + OP_NOT = 0x7, + OP_LESSTHAN = 0x8, + OP_LESSTHANEQUALTO = 0x9, + OP_GREATERTHAN = 0xA, + OP_GREATERTHANEQUALTO = 0xB, + OP_EQUALS = 0xC, + OP_NOTEQUAL = 0xD, + OP_AND = 0xE, + OP_OR = 0xF, + OP_LEFTPAREN = 0x10, + OP_COMMA = 0x11, + OP_BITWISEAND = 0x12, + OP_BITWISEOR = 0x13, + OP_BITWISENOT = 0x14, + OP_BITSHIFTLEFT = 0x15, + OP_BITSHIFTRIGHT = 0x16, + OP_STATICDVARINT = 0x17, + OP_FIRSTFUNCTIONCALL = 0x17, + OP_STATICDVARBOOL = 0x18, + OP_STATICDVARFLOAT = 0x19, + OP_STATICDVARSTRING = 0x1A, + OP_TOINT = 0x1B, + OP_TOSTRING = 0x1C, + OP_TOFLOAT = 0x1D, + LAST_COMMONLY_CALLED_FUNCTION = 0x1D, + OP_SIN = 0x1E, + OP_COS = 0x1F, + OP_MIN = 0x20, + OP_MAX = 0x21, + OP_MILLISECONDS = 0x22, + OP_LOCALCLIENTUIMILLISECONDS = 0x23, + OP_DVARINT = 0x24, + OP_DVARBOOL = 0x25, + OP_DVARFLOAT = 0x26, + OP_DVARSTRING = 0x27, + OP_UIACTIVE = 0x28, + OP_FLASHBANGED = 0x29, + OP_USINGVEHICLE = 0x2A, + OP_MISSILECAM = 0x2B, + OP_SCOPED = 0x2C, + OP_SCOPEDTHERMAL = 0x2D, + OP_SCOREBOARDVISIBLE = 0x2E, + OP_INKILLCAM = 0x2F, + OP_INKILLCAM_NPC = 0x30, + OP_PLAYERFIELD = 0x31, + OP_GET_PLAYER_PERK = 0x32, + OP_SELECTINGLOCATION = 0x33, + OP_SELECTINGDIRECTION = 0x34, + OP_TEAMFIELD = 0x35, + OP_OTHERTEAMFIELD = 0x36, + OP_MARINESFIELD = 0x37, + OP_OPFORFIELD = 0x38, + OP_MENUISOPEN = 0x39, + OP_WRITINGDATA = 0x3A, + OP_INLOBBY = 0x3B, + OP_INGAMELOBBY = 0x3C, + OP_INPRIVATEPARTY = 0x3D, + OP_PRIVATEPARTYHOST = 0x3E, + OP_PRIVATEPARTYHOSTINLOBBY = 0x3F, + OP_ALONEINPARTY = 0x40, + OP_ADSJAVELIN = 0x41, + OP_WEAPLOCKBLINK = 0x42, + OP_WEAPATTACKTOP = 0x43, + OP_WEAPATTACKDIRECT = 0x44, + OP_WEAPLOCKING = 0x45, + OP_WEAPLOCKED = 0x46, + OP_WEAPLOCKTOOCLOSE = 0x47, + OP_WEAPLOCKSCREENPOSX = 0x48, + OP_WEAPLOCKSCREENPOSY = 0x49, + OP_SECONDSASTIME = 0x4A, + OP_TABLELOOKUP = 0x4B, + OP_TABLELOOKUPBYROW = 0x4C, + OP_TABLEGETROWNUM = 0x4D, + OP_LOCALIZESTRING = 0x4E, + OP_LOCALVARINT = 0x4F, + OP_LOCALVARBOOL = 0x50, + OP_LOCALVARFLOAT = 0x51, + OP_LOCALVARSTRING = 0x52, + OP_TIMELEFT = 0x53, + OP_SECONDSASCOUNTDOWN = 0x54, + OP_GAMEMSGWNDACTIVE = 0x55, + OP_GAMETYPENAME = 0x56, + OP_GAMETYPE = 0x57, + OP_GAMETYPEDESCRIPTION = 0x58, + OP_SCORE = 0x59, + OP_FOLLOWING = 0x5A, + OP_SPECTATINGFREE = 0x5B, + OP_KEYBINDING = 0x5C, + OP_ACTIONSLOTUSABLE = 0x5D, + OP_HUDFADE = 0x5E, + OP_MAXPLAYERS = 0x5F, + OP_ACCEPTINGINVITE = 0x60, + OP_ISINTERMISSION = 0x61, + OP_GAMEHOST = 0x62, + OP_PARTYHASMISSINGMAPPACK = 0x63, + OP_PARTYMISSINGMAPPACKERROR = 0x64, + OP_ANYNEWMAPPACKS = 0x65, + OP_AMISELECTED = 0x66, + OP_PARTYSTATUSSTRING = 0x67, + OP_ATTACHED_CONTROLLER_COUNT = 0x68, + OP_IS_SPLIT_SCREEN_ONLINE_POSSIBLE = 0x69, + OP_SPLITSCREENPLAYERCOUNT = 0x6A, + OP_GETPLAYERDATA = 0x6B, + OP_GETPLAYERDATASPLITSCREEN = 0x6C, + OP_GET_MATCHRULES_DATA = 0x6D, + OP_GET_SAVED_MATCHRULES_METADATA = 0x6E, + OP_LEVEL_FOR_EXPERIENCE_MP = 0x6F, + OP_LEVEL_FOR_EXPERIENCE_SO = 0x70, + OP_IS_ITEM_UNLOCKED = 0x71, + OP_IS_ITEM_UNLOCKEDSPLITSCREEN = 0x72, + OP_IS_CARDICON_UNLOCKED = 0x73, + OP_IS_CARDTITLE_UNLOCKED = 0x74, + OP_IS_CARDICON_NEW = 0x75, + OP_IS_CARDTITLE_NEW = 0x76, + OP_IS_CARDICON_UNLOCKED_SPLITSCREEN = 0x77, + OP_IS_CARDTITLE_UNLOCKED_SPLITSCREEN = 0x78, + OP_IS_CARDICON_NEW_SPLITSCREEN = 0x79, + OP_IS_CARDTITLE_NEW_SPLITSCREEN = 0x7A, + OP_IS_PROFILEITEM_UNLOCKED = 0x7B, + OP_IS_PROFILEITEM_UNLOCKED_SPLITSCREEN = 0x7C, + OP_IS_PROFILEITEM_NEW = 0x7D, + OP_IS_PROFILEITEM_NEW_SPLITSCREEN = 0x7E, + OP_DEBUG_PRINT = 0x7F, + OP_GETPLAYERDATA_ANYBOOLTRUE = 0x80, + OP_GETPROFILE_ANYBOOLTRUE = 0x81, + OP_WEAPON_CLASS_NEW = 0x82, + OP_WEAPONNAME = 0x83, + OP_ISRELOADING = 0x84, + OP_SAVE_GAME_AVAILABLE = 0x85, + OP_UNLOCKED_ITEM_COUNT = 0x86, + OP_UNLOCKED_ITEM_COUNT_SPLITSCREEN = 0x87, + OP_UNLOCKED_ITEM = 0x88, + OP_UNLOCKED_ITEM_SPLITSCREEN = 0x89, + OP_RADAR_IS_JAMMED = 0x8A, + OP_RADAR_JAM_INTENSITY = 0x8B, + OP_RADAR_IS_ENABLED = 0x8C, + OP_EMP_JAMMED = 0x8D, + OP_PLAYERADS = 0x8E, + OP_WEAPON_HEAT_ACTIVE = 0x8F, + OP_WEAPON_HEAT_VALUE = 0x90, + OP_WEAPON_HEAT_OVERHEATED = 0x91, + OP_SPLASH_TEXT = 0x92, + OP_SPLASH_DESCRIPTION = 0x93, + OP_SPLASH_MATERIAL = 0x94, + OP_SPLASH_HAS_ICON = 0x95, + OP_SPLASH_ROWNUM = 0x96, + OP_GETFOCUSED_NAME = 0x97, + OP_GETFOCUSED_X = 0x98, + OP_GETFOCUSED_Y = 0x99, + OP_GETFOCUSED_W = 0x9A, + OP_GETFOCUSED_H = 0x9B, + OP_GETITEMDEF_X = 0x9C, + OP_GETITEMDEF_Y = 0x9D, + OP_GETITEMDEF_W = 0x9E, + OP_GETITEMDEF_H = 0x9F, + OP_PLAYLISTFIELD = 0xA0, + OP_SCOREBOARD_EXTERNALMUTE_NOTICE = 0xA1, + OP_CLIENT_MATCH_DATA = 0xA2, + OP_CLIENT_MATCH_DATA_DEF = 0xA3, + OP_GET_MAP_NAME = 0xA4, + OP_GET_MAP_IMAGE = 0xA5, + OP_GET_MAP_CUSTOM = 0xA6, + OP_GET_MIGRATION_STATUS = 0xA7, + OP_GET_PLAYERCARD_INFO = 0xA8, + OP_IS_OFFLINE_PROFILE_SELECTED = 0xA9, + OP_COOP_PLAYERFIELD = 0xAA, + OP_IS_COOP = 0xAB, + OP_GETPARTYSTATUS = 0xAC, + OP_GETSEARCHPARAMS = 0xAD, + OP_GETTIMEPLAYED = 0xAE, + OP_IS_SELECTED_PLAYER_FRIEND = 0xAF, + OP_GETCHARBYINDEX = 0xB0, + OP_GETPLAYERPROFILEDATA = 0xB1, + OP_GETPLAYERPROFILEDATASPLITSCREEN = 0xB2, + OP_IS_PROFILE_SIGNED_IN = 0xB3, + OP_GET_WAIT_POPUP_STATUS = 0xB4, + OP_GETNATTYPE = 0xB5, + OP_GETLOCALIZEDNATTYPE = 0xB6, + OP_GET_ADJUSTED_SAFEAREA_HORIZONTAL = 0xB7, + OP_GET_ADJUSTED_SAFEAREA_VERTICAL = 0xB8, + OP_CONNECTION_INFO = 0xB9, + OP_OFFLINE_PROFILE_CAN_SAVE = 0xBA, + OP_USER_WITHOUT_OFFLINE_PROFILE = 0xBB, + OP_ALL_SPLITSCREEN_PROFILES_CAN_SAVE = 0xBC, + OP_ALL_SPLITSCREEN_PROFILES_ARE_SIGNED_IN = 0xBD, + OP_DO_WE_HAVE_MAP_PACK = 0xBE, + OP_MAY_INVITE_PLAYER_TO_PARTY = 0xBF, + OP_GETPATCHNOTES = 0xC0, + OP_GETGAMEINFOS = 0xC1, + OP_COOP_READY = 0xC2, + OP_VOTE_CAST = 0xC3, + OP_VOTE_PASSED = 0xC4, + OP_GET_MAP_VOTE_MAP_IMAGE = 0xC5, + OP_GET_MAP_VOTE_MAP_NAME = 0xC6, + OP_GET_MAP_VOTE_GAME_TYPE_NAME = 0xC7, + OP_IS_FRIEND_INVITABLE = 0xC8, + OP_IS_FRIEND_JOINABLE = 0xC9, + OP_GET_SORTED_CHALLENGE_INDEX = 0xCA, + OP_GET_SORTED_CHALLENGE_NAME = 0xCB, + OP_GET_SORTED_CHALLENGE_COUNT = 0xCC, + OP_GET_FILTER_CHALLENGE_COUNT = 0xCD, + OP_GET_FILTER_CHALLENGE_LOCKED_COUNT = 0xCE, + OP_GET_FILTER_CHALLENGE_COMPLETE_COUNT = 0xCF, + OP_IS_SORTED_CHALLENGE_TIERED = 0xD0, + OP_GET_CHALLENGE_FILTER_CACHE_COUNT = 0xD1, + OP_GET_CHALLENGE_FILTER_CACHE_COMPLETE_COUNT = 0xD2, + OP_IS_COOP_SEARCHING = 0xD3, + OP_IS_COOP_PUBLIC = 0xD4, + OP_GET_COOP_DISPLAYABLE_GROUP_NUM = 0xD5, + OP_COOP_HAS_REQUIRED_ONLINE_FILES = 0xD6, + OP_GET_TEXTWIDTH = 0xD7, + OP_GET_TEXTHEIGHT = 0xD8, + OP_DEVELOPER = 0xD9, + OP_IS_USING_AIRBURST_WEAPON = 0xDA, + OP_GET_AIRBURST_METERS = 0xDB, + OP_GET_CROSSHAIR_TRACE_METERS = 0xDC, + OP_GET_FACEBOOK_STATUS_TEXT = 0xDD, + OP_IS_FACEBOOK_LOGGED_IN = 0xDE, + OP_IS_FACEBOOK_CHECKING = 0xDF, + OP_IS_FACEBOOK_ALLOWED = 0xE0, + OP_GETPRIVATELOBBYSTATUS = 0xE1, + OP_INCLUDEDINMAPROTATION = 0xE2, + OP_SELECT = 0xE3, + OP_IS_DEMO_PLAYING = 0xE4, + OP_GET_USER_GROUP_TEXT = 0xE5, + OP_GET_USER_GROUP_COMMON_INTEREST_TOTAL = 0xE6, + OP_IS_DEMO_FOLLOW_CAMERA = 0xE7, + OP_IS_DEMO_FREE_CAMERA = 0xE8, + OP_IS_DEMO_CAPTURING_SCREENSHOT = 0xE9, + OP_PARTY_HOST_WAITING_ON_MEMBERS = 0xEA, + OP_POPUP_PARTY_MEMBER_AWAY = 0xEB, + OP_SELECTED_PARTY_MEMBER_AWAY = 0xEC, + OP_GAMETIME = 0xED, + OP_GAMEENDTIME = 0xEE, + OP_HAS_FOCUS = 0xEF, + OP_MENU_HAS_FOCUS = 0xF0, + OP_GET_DEMO_SEGMENT_COUNT = 0xF1, + OP_GET_DEMO_SEGMENT_INFORMATION = 0xF2, + OP_IS_CLIP_MODIFIED = 0xF3, + OP_IS_USING_RECIPE = 0xF4, + OP_IS_GUEST = 0xF5, + OP_GET_FACEBOOK_HELP_TEXT = 0xF6, + OP_IS_ELITE_CLAN_ALLOWED = 0xF7, + OP_IS_ENTITLEMENTS_ALLOWED = 0xF8, + OP_IS_USERGROUPS_ALLOWED = 0xF9, + OP_IS_WAITING_FOR_ONLINE_SERVICES = 0xFA, + OP_GET_TEXTWIDTHMODCASE = 0xFB, + OP_GET_SAVE_SCREEN_TITLE = 0xFC, + OP_GET_SAVE_SCREEN_DESCRIPTION = 0xFD, + OP_GET_ONLINEVAULT_SELECTEDITEM_DATA = 0xFE, + OP_ONLINEVAULT_IS_RESTRICTED = 0xFF, + OP_IS_CONTENTSERVER_TASK_IN_PROGRESS = 0x100, + OP_IS_CONTENTSERVER_GET_TASK_PROGRESS = 0x101, + OP_GET_RECENTGAMES_SELECTEDITEM_DATA = 0x102, + OP_GAMETYPENAME_ABBREVIATED = 0x103, + OP_GET_MAP_VOTE_GAME_TYPE_NAME_ABBREVIATED = 0x104, + OP_IS_USER_SIGNED_IN_TO_LIVE = 0x105, + OP_USER_CAN_PLAY_ONLINE = 0x106, + OP_GET_PAST_TITLE_RANK = 0x107, + OP_GET_FEEDER_DATA = 0x108, + OP_PARTY_CLIENTS_UP_TO_DATE = 0x109, + OP_TRUNCATETEXTWITHELLIPSIS = 0x10A, + OP_UI_STARTED = 0x10B, + OP_CAN_RENDER_CLIP = 0x10C, + OP_GET_PREVIEW_MAP_CUSTOM = 0x10D, + OP_GET_DLC_MAPS_AVAILABLE_COUNT = 0x10E, + OP_IS_USER_SIGNED_IN = 0x10F, + OP_USINGINTERMISSIONTIMER = 0x110, + OP_ISUSINGCUSTOMMAPROTATION = 0x111, + OP_MENU_IS_TOPMOST = 0x112, + OP_FACEBOOK_IS_PLATFORM_FRIEND = 0x113, + OP_ELITE_CLAN_IS_PLATFORM_FRIEND = 0x114, + OP_ELITE_CLAN_IS_ME = 0x115, + OP_ELITE_CLAN_IS_LEADER = 0x116, + OP_IS_USER_SIGNED_IN_FOR_VAULT = 0x117, + OP_GET_USING_MATCHRULES_DATA = 0x118, + OP_CAN_USER_ACCESS_ONLINEVAULT = 0x119, + OP_FRIEND_GET_GAMERTAG = 0x11A, + OP_RECENTPLAYER_GET_GAMERTAG = 0x11B, + OP_LIVEPARTY_GET_GAMERTAG = 0x11C, + OP_FACEBOOK_GET_GAMERTAG = 0x11D, + OP_ELITECLAN_GET_GAMERTAG = 0x11E, + OP_LIVEPARTY_IS_ME = 0x11F, + OP_LIVEPARTY_IS_LOCAL = 0x120, + OP_DOUBLECLICK_WAS_RIGHT_CLICK = 0x121, + OP_IS_DEMO_CLIP_RECORDING = 0x122, + OP_GET_INDEX_FROM_STRING = 0x123, + OP_GET_STRING_WIHTOUT_INDEX = 0x124, + OP_ELITECLAN_GET_NAME = 0x125, + OP_ELITECLAN_GET_HELP = 0x126, + OP_ELITECLAN_GET_MOTD = 0x127, + OP_ELITECLAN_IS_MEMBER = 0x128, + OP_ELITECLAN_IS_EMBLEM_OK = 0x129, + OP_FACEBOOKFRIENDS_SHOW_NEXT = 0x12A, + OP_FACEBOOKFRIENDS_SHOW_PREV = 0x12B, + OP_GET_ONLINEVAULT_FRIEND_GAMERTAG = 0x12C, + OP_GET_OBJECTIVE_LIST_HEIGHT = 0x12D, + OP_IS_CLIENT_DEMO_ENABLED = 0x12E, + OP_IS_USER_SIGNED_IN_TO_DEMONWARE = 0x12F, + OP_IS_CUSTOM_CLASS_RESTRICTED = 0x130, + OP_IS_WEAPON_RESTRICTED = 0x131, + OP_ANY_SPLITSCREEN_PROFILES_ARE_SIGNED_IN = 0x132, + OP_IS_GUEST_SPLITSCREEN = 0x133, + OP_IS_ITEM_UNLOCKED_BY_CLIENT = 0x134, + OP_IS_ANY_USER_SIGNED_IN_TO_LIVE = 0x135, + OP_GET_PAST_TITLE_PRESTIGE = 0x136, + OP_SPLITSCREENACTIVEGAMEPADCOUNT = 0x137, + OP_SHOW_FRIEND_PLAYERCARD = 0x138, + OP_GET_FRIEND_PLAYERCARD_PRESENCE = 0x139, + OP_SHOW_RECENT_PLAYERS_GROUP_ICON = 0x13A, + OP_GET_WRAPPED_TEXT_HEIGHT = 0x13B, + OP_CAN_SAVE = 0x13C, + OP_GET_GAME_INVITES_COUNT = 0x13D, + OP_IS_SPLITSCREEN_GAMER_LIVE_ENABLED = 0x13E, + OP_SO_COOP_SHOW_COMMON_GROUP_ICON = 0x13F, + OP_STRIP_COLORS_FROM_STRING = 0x140, + OP_CAN_USER_ACCESS_THEATRE = 0x141, + OP_IS_CHALLENGE_PERIODIC = 0x142, + OP_GET_CHALLENGE_DATA = 0x143, + OP_IS_ELITE_APP_PRESENT = 0x144, + OP_ELITE_CLAN_SELECTED_IS_ME = 0x145, + OP_ENOUGH_STORAGE_SPACE_FOR_CLIENT_DEMO = 0x146, + + NUM_OPERATORS + }; + + union entryInternalData + { + operationEnum op; + Operand operand; + }; + + struct expressionEntry + { + int type; + entryInternalData data; + }; + + struct UIFunctionList + { + int totalFunctions; + Statement_s** functions; + }; + + union DvarValue + { + bool enabled; + int integer; + unsigned int unsignedInt; + float value; + float vector[4]; + const char* string; + unsigned char color[4]; + }; + + union DvarLimits + { + struct + { + int stringCount; + const char** strings; + } enumeration; + + struct + { + int min; + int max; + } integer; + + struct + { + float min; + float max; + } value; + + struct + { + float min; + float max; + } vector; + }; + + struct dvar_t + { + const char* name; + const char* description; + unsigned short flags; + unsigned char type; + bool modified; + DvarValue current; + DvarValue latched; + DvarValue reset; + DvarLimits domain; + dvar_t* hashNext; + }; + + struct StaticDvar + { + dvar_t* dvar; + char* dvarName; + }; + + struct StaticDvarList + { + int numStaticDvars; + StaticDvar** staticDvars; + }; + + struct StringList + { + int totalStrings; + const char** strings; + }; + + struct ExpressionSupportingData + { + UIFunctionList uifunctions; + StaticDvarList staticDvarList; + StringList uiStrings; + }; + + struct ExpressionPersistentState + { + int flags; + int playerDataKey[4]; + int lastExecuteTime[4]; + Operand lastResult[4]; + }; + + struct Statement_s + { + int numEntries; + expressionEntry* entries; + ExpressionSupportingData* supportingData; + ExpressionPersistentState persistentState; + }; + + struct MenuEventHandlerSet; + + struct ConditionalScript + { + MenuEventHandlerSet* eventHandlerSet; + Statement_s* eventExpression; + }; + + struct SetLocalVarData + { + const char* localVarName; + Statement_s* expression; + }; + + union EventData + { + const char* unconditionalScript; + ConditionalScript* conditionalScript; + MenuEventHandlerSet* elseScript; + SetLocalVarData* setLocalVarData; + }; + + struct MenuEventHandler + { + EventData eventData; + unsigned char eventType; + }; + + struct MenuEventHandlerSet + { + int eventHandlerCount; + MenuEventHandler** eventHandlers; + }; + + struct ItemKeyHandler + { + int key; + MenuEventHandlerSet* action; + ItemKeyHandler* next; + }; + + struct menuTransition + { + int transitionType; + int startTime; + float startVal; + float endVal; + float time; + int endTriggerType; + }; + + struct menuData_t + { + int fullScreen; + int fadeCycle; + float fadeClamp; + float fadeAmount; + float fadeInAmount; + float blurRadius; + MenuEventHandlerSet* onOpen; + MenuEventHandlerSet* onCloseRequest; + MenuEventHandlerSet* onClose; + MenuEventHandlerSet* onESC; + MenuEventHandlerSet* onFocusDueToClose; + ItemKeyHandler* onKey; + Statement_s* visibleExp; + const char* allowedBinding; + const char* soundName; + float focusColor[4]; + Statement_s* rectXExp; + Statement_s* rectYExp; + Statement_s* rectWExp; + Statement_s* rectHExp; + Statement_s* openSoundExp; + Statement_s* closeSoundExp; + Statement_s* soundLoopExp; + int cursorItem[4]; + menuTransition scaleTransition[4]; + menuTransition alphaTransition[4]; + menuTransition xTransition[4]; + menuTransition yTransition[4]; + ExpressionSupportingData* expressionData; + unsigned char priority; + }; + + struct rectDef_s + { + float x; + float y; + float w; + float h; + unsigned char horzAlign; + unsigned char vertAlign; + }; + + struct windowDef_t + { + const char* name; + rectDef_s rect; + rectDef_s rectClient; + const char* group; + int style; + int border; + int ownerDraw; + int ownerDrawFlags; + float borderSize; + int staticFlags; + int dynamicFlags[4]; + int nextTime; + float foreColor[4]; + float backColor[4]; + float borderColor[4]; + float outlineColor[4]; + float disableColor[4]; + Material* background; + }; + + struct columnInfo_s + { + int xpos; + int ypos; + int width; + int height; + int maxChars; + int alignment; + }; + + struct listBoxDef_s + { + int startPos[4]; + int endPos[4]; + int drawPadding; + float elementWidth; + float elementHeight; + int elementStyle; + int numColumns; + columnInfo_s columnInfo[16]; + MenuEventHandlerSet* onDoubleClick; + int notselectable; + int noScrollBars; + int usePaging; + float selectBorder[4]; + Material* selectIcon; + Statement_s* elementHeightExp; + }; + + struct editFieldDef_s + { + float minVal; + float maxVal; + float stepVal; + float range; + int maxChars; + int maxCharsGotoNext; + int maxPaintChars; + int paintOffset; + }; + + struct multiDef_s + { + const char* dvarList[32]; + const char* dvarStr[32]; + float dvarValue[32]; + int count; + int strDef; + }; + + struct newsTickerDef_s + { + int feedId; + int speed; + int spacing; + }; + + struct textScrollDef_s + { + int startTime; + }; + + union itemDefData_t + { + listBoxDef_s* listBox; + editFieldDef_s* editField; + multiDef_s* multi; + const char* enumDvarName; + newsTickerDef_s* ticker; + textScrollDef_s* scroll; + void* data; + }; + + struct ItemFloatExpression + { + int target; + Statement_s* expression; + }; + + struct itemDef_t + { + windowDef_t window; + rectDef_s textRect[4]; + int type; + int dataType; + int alignment; + int fontEnum; + int textAlignMode; + float textalignx; + float textaligny; + float textscale; + int textStyle; + int gameMsgWindowIndex; + int gameMsgWindowMode; + const char* text; + int itemFlags; + menuDef_t* parent; + MenuEventHandlerSet* mouseEnterText; + MenuEventHandlerSet* mouseExitText; + MenuEventHandlerSet* mouseEnter; + MenuEventHandlerSet* mouseExit; + MenuEventHandlerSet* action; + MenuEventHandlerSet* accept; + MenuEventHandlerSet* onFocus; + MenuEventHandlerSet* hasFocus; + MenuEventHandlerSet* leaveFocus; + const char* dvar; + const char* dvarTest; + ItemKeyHandler* onKey; + const char* enableDvar; + const char* localVar; + int dvarFlags; + snd_alias_list_t* focusSound; + float special; + int cursorPos[4]; + itemDefData_t typeData; + int floatExpressionCount; + ItemFloatExpression* floatExpressions; + Statement_s* visibleExp; + Statement_s* disabledExp; + Statement_s* textExp; + Statement_s* materialExp; + float glowColor[4]; + bool decayActive; + int fxBirthTime; + int fxLetterTime; + int fxDecayStartTime; + int fxDecayDuration; + int lastSoundPlayedTime; + Statement_s* textAlignYExp; + }; + + struct menuDef_t + { + menuData_t* data; + windowDef_t window; + int itemCount; + itemDef_t** items; + }; + + struct LocalizeEntry + { + const char* value; + const char* name; + }; + + enum AttachmentType + { + ATTACHMENT_SCOPE = 0x0, + ATTACHMENT_UNDERBARREL = 0x1, + ATTACHMENT_OTHER = 0x2, + + ATTACHMENT_COUNT + }; + + enum weapType_t + { + WEAPTYPE_NONE = 0x0, + WEAPTYPE_BULLET = 0x1, + WEAPTYPE_GRENADE = 0x2, + WEAPTYPE_PROJECTILE = 0x3, + WEAPTYPE_RIOTSHIELD = 0x4, + + WEAPTYPE_NUM + }; + + enum weapClass_t + { + WEAPCLASS_RIFLE = 0x0, + WEAPCLASS_SNIPER = 0x1, + WEAPCLASS_MG = 0x2, + WEAPCLASS_SMG = 0x3, + WEAPCLASS_SPREAD = 0x4, + WEAPCLASS_PISTOL = 0x5, + WEAPCLASS_GRENADE = 0x6, + WEAPCLASS_ROCKETLAUNCHER = 0x7, + WEAPCLASS_TURRET = 0x8, + WEAPCLASS_THROWINGKNIFE = 0x9, + WEAPCLASS_NON_PLAYER = 0xA, + WEAPCLASS_ITEM = 0xB, + + WEAPCLASS_NUM + }; + + enum PenetrateType + { + PENETRATE_TYPE_NONE = 0x0, + PENETRATE_TYPE_SMALL = 0x1, + PENETRATE_TYPE_MEDIUM = 0x2, + PENETRATE_TYPE_LARGE = 0x3, + + PENETRATE_TYPE_COUNT + }; + + enum ImpactType + { + IMPACT_TYPE_NONE = 0x0, + IMPACT_TYPE_BULLET_SMALL = 0x1, + IMPACT_TYPE_BULLET_LARGE = 0x2, + IMPACT_TYPE_BULLET_AP = 0x3, + IMPACT_TYPE_BULLET_EXPLODE = 0x4, + IMPACT_TYPE_SHOTGUN = 0x5, + IMPACT_TYPE_SHOTGUN_EXPLODE = 0x6, + IMPACT_TYPE_GRENADE_BOUNCE = 0x7, + IMPACT_TYPE_GRENADE_EXPLODE = 0x8, + IMPACT_TYPE_ROCKET_EXPLODE = 0x9, + IMPACT_TYPE_PROJECTILE_DUD = 0xA, + + IMPACT_TYPE_COUNT + }; + + enum weapFireType_t + { + WEAPON_FIRETYPE_FULLAUTO = 0x0, + WEAPON_FIRETYPE_SINGLESHOT = 0x1, + WEAPON_FIRETYPE_BURSTFIRE2 = 0x2, + WEAPON_FIRETYPE_BURSTFIRE3 = 0x3, + WEAPON_FIRETYPE_BURSTFIRE4 = 0x4, + WEAPON_FIRETYPE_DOUBLEBARREL = 0x5, + + WEAPON_FIRETYPECOUNT, + WEAPON_FIRETYPE_BURSTFIRE_FIRST = WEAPON_FIRETYPE_BURSTFIRE2, + WEAPON_FIRETYPE_BURSTFIRE_LAST = WEAPON_FIRETYPE_BURSTFIRE4 + }; + + struct AttAmmoGeneral + { + PenetrateType penetrateType; + float penetrateMultiplier; + ImpactType impactType; + weapFireType_t fireType; + TracerDef* tracerType; + bool rifleBullet; + bool armorPiercing; + }; + + struct AttSight + { + bool aimDownSight; + bool adsFire; + bool rechamberWhileAds; + bool noAdsWhenMagEmpty; + bool canHoldBreath; + bool canVariableZoom; + bool hideRailWithThisScope; + }; + + struct AttReload + { + bool noPartialReload; + bool segmentedReload; + }; + + struct AttAddOns + { + bool motionTracker; + bool silenced; + }; + + struct AttGeneral + { + bool boltAction; + bool inheritsPerks; + float enemyCrosshairRange; + Material* reticleCenter; + Material* reticleSide; + int reticleCenterSize; + int reticleSideSize; + float moveSpeedScale; + float adsMoveSpeedScale; + }; + + struct AttAimAssist + { + float autoAimRange; + float aimAssistRange; + float aimAssistRangeAds; + }; + + struct AttAmmunition + { + int maxAmmo; + int startAmmo; + int clipSize; + int shotCount; + int reloadAmmoAdd; + int reloadStartAdd; + }; + + struct AttDamage + { + int damage; + int minDamage; + int meleeDamage; + float maxDamageRange; + float minDamageRange; + int playerDamage; + int minPlayerDamage; + }; + + struct AttLocationDamage + { + float locNone; + float locHelmet; + float locHead; + float locNeck; + float locTorsoUpper; + float locTorsoLower; + float locRightArmUpper; + float locRightArmLower; + float locRightHand; + float locLeftArmUpper; + float locLeftArmLower; + float locLeftHand; + float locRightLegUpper; + float locRightLegLower; + float locRightFoot; + float locLeftLegUpper; + float locLeftLegLower; + float locLeftFoot; + float locGun; + }; + + struct AttIdleSettings + { + float hipIdleAmount; + float hipIdleSpeed; + float idleCrouchFactor; + float idleProneFactor; + float adsIdleLerpStartTime; + float adsIdleLerpTime; + }; + + struct AttADSSettings + { + float adsSpread; + float adsAimPitch; + float adsTransInTime; + float adsTransOutTime; + int adsReloadTransTime; + float adsCrosshairInFrac; + float adsCrosshairOutFrac; + float adsZoomFov; + float adsZoomInFrac; + float adsZoomOutFrac; + float adsBobFactor; + float adsViewBobMult; + float adsViewErrorMin; + float adsViewErrorMax; + }; + + struct AttHipSpread + { + float hipSpreadStandMin; + float hipSpreadDuckedMin; + float hipSpreadProneMin; + float hipSpreadMax; + float hipSpreadDuckedMax; + float hipSpreadProneMax; + float hipSpreadFireAdd; + float hipSpreadTurnAdd; + float hipSpreadMoveAdd; + float hipSpreadDecayRate; + float hipSpreadDuckedDecay; + float hipSpreadProneDecay; + }; + + struct AttGunKick + { + int hipGunKickReducedKickBullets; + float hipGunKickReducedKickPercent; + float hipGunKickPitchMin; + float hipGunKickPitchMax; + float hipGunKickYawMin; + float hipGunKickYawMax; + float hipGunKickAccel; + float hipGunKickSpeedMax; + float hipGunKickSpeedDecay; + float hipGunKickStaticDecay; + int adsGunKickReducedKickBullets; + float adsGunKickReducedKickPercent; + float adsGunKickPitchMin; + float adsGunKickPitchMax; + float adsGunKickYawMin; + float adsGunKickYawMax; + float adsGunKickAccel; + float adsGunKickSpeedMax; + float adsGunKickSpeedDecay; + float adsGunKickStaticDecay; + }; + + struct AttViewKick + { + float hipViewKickPitchMin; + float hipViewKickPitchMax; + float hipViewKickYawMin; + float hipViewKickYawMax; + float hipViewKickCenterSpeed; + float adsViewKickPitchMin; + float adsViewKickPitchMax; + float adsViewKickYawMin; + float adsViewKickYawMax; + float adsViewKickCenterSpeed; + }; + + enum weapOverlayReticle_t + { + WEAPOVERLAYRETICLE_NONE = 0x0, + WEAPOVERLAYRETICLE_CROSSHAIR = 0x1, + + WEAPOVERLAYRETICLE_NUM + }; + + struct ADSOverlay + { + Material* shader; + Material* shaderLowRes; + Material* shaderEMP; + Material* shaderEMPLowRes; + weapOverlayReticle_t reticle; + float width; + float height; + float widthSplitscreen; + float heightSplitscreen; + }; + + struct AttADSOverlay + { + ADSOverlay overlay; + bool thermalScope; + }; + + enum weaponIconRatioType_t + { + WEAPON_ICON_RATIO_1TO1 = 0x0, + WEAPON_ICON_RATIO_2TO1 = 0x1, + WEAPON_ICON_RATIO_4TO1 = 0x2, + + WEAPON_ICON_RATIO_COUNT + }; + + enum ammoCounterClipType_t + { + AMMO_COUNTER_CLIP_NONE = 0x0, + AMMO_COUNTER_CLIP_MAGAZINE = 0x1, + AMMO_COUNTER_CLIP_SHORTMAGAZINE = 0x2, + AMMO_COUNTER_CLIP_SHOTGUN = 0x3, + AMMO_COUNTER_CLIP_ROCKET = 0x4, + AMMO_COUNTER_CLIP_BELTFED = 0x5, + AMMO_COUNTER_CLIP_ALTWEAPON = 0x6, + + AMMO_COUNTER_CLIP_COUNT + }; + + struct AttUI + { + Material* dpadIcon; + Material* ammoCounterIcon; + weaponIconRatioType_t dpadIconRatio; + weaponIconRatioType_t ammoCounterIconRatio; + ammoCounterClipType_t ammoCounterClip; + }; + + struct AttRumbles + { + const char* fireRumble; + const char* meleeImpactRumble; + }; + + enum weapProjExposion_t + { + WEAPPROJEXP_GRENADE = 0x0, + WEAPPROJEXP_ROCKET = 0x1, + WEAPPROJEXP_FLASHBANG = 0x2, + WEAPPROJEXP_NONE = 0x3, + WEAPPROJEXP_DUD = 0x4, + WEAPPROJEXP_SMOKE = 0x5, + WEAPPROJEXP_HEAVY = 0x6, + + WEAPPROJEXP_NUM + }; + + struct AttProjectile + { + int explosionRadius; + int explosionInnerDamage; + int explosionOuterDamage; + float damageConeAngle; + int projectileSpeed; + int projectileSpeedUp; + int projectileActivateDist; + float projectileLifetime; + XModel* projectileModel; + weapProjExposion_t projExplosionType; + FxEffectDef* projExplosionEffect; + bool projExplosionEffectForceNormalUp; + snd_alias_list_t* projExplosionSound; + FxEffectDef* projDudEffect; + snd_alias_list_t* projDudSound; + bool projImpactExplode; + float destabilizationRateTime; + float destabilizationCurvatureMax; + int destabilizeDistance; + FxEffectDef* projTrailEffect; + int projIgnitionDelay; + FxEffectDef* projIgnitionEffect; + snd_alias_list_t* projIgnitionSound; + }; + + struct WeaponAttachment + { + const char* szInternalName; + const char* szDisplayName; + AttachmentType type; + weapType_t weaponType; + weapClass_t weapClass; + XModel** worldModels; + XModel** viewModels; + XModel** reticleViewModels; + AttAmmoGeneral* ammogeneral; + AttSight* sight; + AttReload* reload; + AttAddOns* addOns; + AttGeneral* general; + AttAimAssist* aimAssist; + AttAmmunition* ammunition; + AttDamage* damage; + AttLocationDamage* locationDamage; + AttIdleSettings* idleSettings; + AttADSSettings* adsSettings; + AttADSSettings* adsSettingsMain; + AttHipSpread* hipSpread; + AttGunKick* gunKick; + AttViewKick* viewKick; + AttADSOverlay* adsOverlay; + AttUI* ui; + AttRumbles* rumbles; + AttProjectile* projectile; + float ammunitionScale; + float damageScale; + float damageScaleMin; + float stateTimersScale; + float fireTimersScale; + float idleSettingsScale; + float adsSettingsScale; + float adsSettingsScaleMain; + float hipSpreadScale; + float gunKickScale; + float viewKickScale; + float viewCenterScale; + int loadIndex; + bool hideIronSightsWithThisAttachment; + bool shareAmmoWithAlt; + }; + + enum weapInventoryType_t + { + WEAPINVENTORY_PRIMARY = 0x0, + WEAPINVENTORY_OFFHAND = 0x1, + WEAPINVENTORY_ITEM = 0x2, + WEAPINVENTORY_ALTMODE = 0x3, + WEAPINVENTORY_EXCLUSIVE = 0x4, + WEAPINVENTORY_SCAVENGER = 0x5, + + WEAPINVENTORYCOUNT + }; + + enum OffhandClass + { + OFFHAND_CLASS_NONE = 0x0, + OFFHAND_CLASS_FRAG_GRENADE = 0x1, + OFFHAND_CLASS_SMOKE_GRENADE = 0x2, + OFFHAND_CLASS_FLASH_GRENADE = 0x3, + OFFHAND_CLASS_THROWINGKNIFE = 0x4, + OFFHAND_CLASS_OTHER = 0x5, + + OFFHAND_CLASS_COUNT + }; + + enum weapStance_t + { + WEAPSTANCE_STAND = 0x0, + WEAPSTANCE_DUCK = 0x1, + WEAPSTANCE_PRONE = 0x2, + + WEAPSTANCE_NUM + }; + + enum activeReticleType_t + { + VEH_ACTIVE_RETICLE_NONE = 0x0, + VEH_ACTIVE_RETICLE_PIP_ON_A_STICK = 0x1, + VEH_ACTIVE_RETICLE_BOUNCING_DIAMOND = 0x2, + + VEH_ACTIVE_RETICLE_COUNT + }; + + struct StateTimers + { + int iFireDelay; + int iMeleeDelay; + int meleeChargeDelay; + int iDetonateDelay; + int iRechamberTime; + int rechamberTimeOneHanded; + int iRechamberBoltTime; + int iHoldFireTime; + int iDetonateTime; + int iMeleeTime; + int meleeChargeTime; + int iReloadTime; + int reloadShowRocketTime; + int iReloadEmptyTime; + int iReloadAddTime; + int iReloadStartTime; + int iReloadStartAddTime; + int iReloadEndTime; + int iDropTime; + int iRaiseTime; + int iAltDropTime; + int quickDropTime; + int quickRaiseTime; + int iBreachRaiseTime; + int iEmptyRaiseTime; + int iEmptyDropTime; + int sprintInTime; + int sprintLoopTime; + int sprintOutTime; + int stunnedTimeBegin; + int stunnedTimeLoop; + int stunnedTimeEnd; + int nightVisionWearTime; + int nightVisionWearTimeFadeOutEnd; + int nightVisionWearTimePowerUp; + int nightVisionRemoveTime; + int nightVisionRemoveTimePowerDown; + int nightVisionRemoveTimeFadeInStart; + int fuseTime; + int aiFuseTime; + int blastFrontTime; + int blastRightTime; + int blastBackTime; + int blastLeftTime; + int raiseInterruptableTime; + int firstRaiseInterruptableTime; + int reloadInterruptableTime; + int reloadEmptyInterruptableTime; + int fireInterruptableTime; + }; + + enum WeapOverlayInteface_t + { + WEAPOVERLAYINTERFACE_NONE = 0x0, + WEAPOVERLAYINTERFACE_JAVELIN = 0x1, + WEAPOVERLAYINTERFACE_TURRETSCOPE = 0x2, + + WEAPOVERLAYINTERFACECOUNT + }; + + enum WeapStickinessType + { + WEAPSTICKINESS_NONE = 0x0, + WEAPSTICKINESS_ALL = 0x1, + WEAPSTICKINESS_ALL_ORIENT = 0x2, + WEAPSTICKINESS_GROUND = 0x3, + WEAPSTICKINESS_GROUND_WITH_YAW = 0x4, + WEAPSTICKINESS_KNIFE = 0x5, + + WEAPSTICKINESS_COUNT + }; + + enum guidedMissileType_t + { + MISSILE_GUIDANCE_NONE = 0x0, + MISSILE_GUIDANCE_SIDEWINDER = 0x1, + MISSILE_GUIDANCE_HELLFIRE = 0x2, + MISSILE_GUIDANCE_JAVELIN = 0x3, + + MISSILE_GUIDANCE_COUNT + }; + + struct WeaponDef + { + const char* szOverlayName; + XModel** gunXModel; + XModel* handXModel; + const char** szXAnimsRightHanded; + const char** szXAnimsLeftHanded; + const char* szModeName; + unsigned short* notetrackSoundMapKeys; + unsigned short* notetrackSoundMapValues; + unsigned short* notetrackRumbleMapKeys; + unsigned short* notetrackRumbleMapValues; + int playerAnimType; + weapType_t weapType; + weapClass_t weapClass; + PenetrateType penetrateType; + weapInventoryType_t inventoryType; + weapFireType_t fireType; + OffhandClass offhandClass; + weapStance_t stance; + FxEffectDef* viewFlashEffect; + FxEffectDef* worldFlashEffect; + snd_alias_list_t* pickupSound; + snd_alias_list_t* pickupSoundPlayer; + snd_alias_list_t* ammoPickupSound; + snd_alias_list_t* ammoPickupSoundPlayer; + snd_alias_list_t* projectileSound; + snd_alias_list_t* pullbackSound; + snd_alias_list_t* pullbackSoundPlayer; + snd_alias_list_t* fireSound; + snd_alias_list_t* fireSoundPlayer; + snd_alias_list_t* fireSoundPlayerAkimbo; + snd_alias_list_t* fireLoopSound; + snd_alias_list_t* fireLoopSoundPlayer; + snd_alias_list_t* fireStopSound; + snd_alias_list_t* fireStopSoundPlayer; + snd_alias_list_t* fireLastSound; + snd_alias_list_t* fireLastSoundPlayer; + snd_alias_list_t* emptyFireSound; + snd_alias_list_t* emptyFireSoundPlayer; + snd_alias_list_t* meleeSwipeSound; + snd_alias_list_t* meleeSwipeSoundPlayer; + snd_alias_list_t* meleeHitSound; + snd_alias_list_t* meleeMissSound; + snd_alias_list_t* rechamberSound; + snd_alias_list_t* rechamberSoundPlayer; + snd_alias_list_t* reloadSound; + snd_alias_list_t* reloadSoundPlayer; + snd_alias_list_t* reloadEmptySound; + snd_alias_list_t* reloadEmptySoundPlayer; + snd_alias_list_t* reloadStartSound; + snd_alias_list_t* reloadStartSoundPlayer; + snd_alias_list_t* reloadEndSound; + snd_alias_list_t* reloadEndSoundPlayer; + snd_alias_list_t* detonateSound; + snd_alias_list_t* detonateSoundPlayer; + snd_alias_list_t* nightVisionWearSound; + snd_alias_list_t* nightVisionWearSoundPlayer; + snd_alias_list_t* nightVisionRemoveSound; + snd_alias_list_t* nightVisionRemoveSoundPlayer; + snd_alias_list_t* altSwitchSound; + snd_alias_list_t* altSwitchSoundPlayer; + snd_alias_list_t* raiseSound; + snd_alias_list_t* raiseSoundPlayer; + snd_alias_list_t* firstRaiseSound; + snd_alias_list_t* firstRaiseSoundPlayer; + snd_alias_list_t* putawaySound; + snd_alias_list_t* putawaySoundPlayer; + snd_alias_list_t* scanSound; + snd_alias_list_t* changeVariableZoomSound; + snd_alias_list_t** bounceSound; + snd_alias_list_t** rollingSound; + FxEffectDef* viewShellEjectEffect; + FxEffectDef* worldShellEjectEffect; + FxEffectDef* viewLastShotEjectEffect; + FxEffectDef* worldLastShotEjectEffect; + Material* reticleCenter; + Material* reticleSide; + int iReticleCenterSize; + int iReticleSideSize; + int iReticleMinOfs; + activeReticleType_t activeReticleType; + float vStandMove[3]; + float vStandRot[3]; + float strafeMove[3]; + float strafeRot[3]; + float vDuckedOfs[3]; + float vDuckedMove[3]; + float vDuckedRot[3]; + float vProneOfs[3]; + float vProneMove[3]; + float vProneRot[3]; + float fPosMoveRate; + float fPosProneMoveRate; + float fStandMoveMinSpeed; + float fDuckedMoveMinSpeed; + float fProneMoveMinSpeed; + float fPosRotRate; + float fPosProneRotRate; + float fStandRotMinSpeed; + float fDuckedRotMinSpeed; + float fProneRotMinSpeed; + XModel** worldModel; + XModel* worldClipModel; + XModel* rocketModel; + XModel* knifeModel; + XModel* worldKnifeModel; + Material* hudIcon; + weaponIconRatioType_t hudIconRatio; + Material* pickupIcon; + weaponIconRatioType_t pickupIconRatio; + Material* ammoCounterIcon; + weaponIconRatioType_t ammoCounterIconRatio; + ammoCounterClipType_t ammoCounterClip; + int iStartAmmo; + const char* szAmmoName; + int iAmmoIndex; + const char* szClipName; + int iClipIndex; + int iMaxAmmo; + int shotCount; + const char* szSharedAmmoCapName; + int iSharedAmmoCapIndex; + int iSharedAmmoCap; + int damage; + int playerDamage; + int iMeleeDamage; + int iDamageType; + StateTimers stateTimers; + StateTimers akimboStateTimers; + float autoAimRange; + float aimAssistRange; + float aimAssistRangeAds; + float aimPadding; + float enemyCrosshairRange; + float moveSpeedScale; + float adsMoveSpeedScale; + float sprintDurationScale; + float fAdsZoomInFrac; + float fAdsZoomOutFrac; + ADSOverlay overlay; + WeapOverlayInteface_t overlayInterface; + float fAdsBobFactor; + float fAdsViewBobMult; + float fHipSpreadStandMin; + float fHipSpreadDuckedMin; + float fHipSpreadProneMin; + float hipSpreadStandMax; + float hipSpreadDuckedMax; + float hipSpreadProneMax; + float fHipSpreadDecayRate; + float fHipSpreadFireAdd; + float fHipSpreadTurnAdd; + float fHipSpreadMoveAdd; + float fHipSpreadDuckedDecay; + float fHipSpreadProneDecay; + float fHipReticleSidePos; + float fAdsIdleAmount; + float fHipIdleAmount; + float adsIdleSpeed; + float hipIdleSpeed; + float fIdleCrouchFactor; + float fIdleProneFactor; + float fGunMaxPitch; + float fGunMaxYaw; + float adsIdleLerpStartTime; + float adsIdleLerpTime; + float swayMaxAngle; + float swayLerpSpeed; + float swayPitchScale; + float swayYawScale; + float swayHorizScale; + float swayVertScale; + float swayShellShockScale; + float adsSwayMaxAngle; + float adsSwayLerpSpeed; + float adsSwayPitchScale; + float adsSwayYawScale; + float adsSwayHorizScale; + float adsSwayVertScale; + float adsViewErrorMin; + float adsViewErrorMax; + PhysCollmap* physCollmap; + float dualWieldViewModelOffset; + weaponIconRatioType_t killIconRatio; + int iReloadAmmoAdd; + int iReloadStartAdd; + int ammoDropStockMin; + int ammoDropClipPercentMin; + int ammoDropClipPercentMax; + int iExplosionRadius; + int iExplosionRadiusMin; + int iExplosionInnerDamage; + int iExplosionOuterDamage; + float damageConeAngle; + float bulletExplDmgMult; + float bulletExplRadiusMult; + int iProjectileSpeed; + int iProjectileSpeedUp; + int iProjectileSpeedForward; + int iProjectileActivateDist; + float projLifetime; + float timeToAccelerate; + float projectileCurvature; + XModel* projectileModel; + weapProjExposion_t projExplosion; + FxEffectDef* projExplosionEffect; + FxEffectDef* projDudEffect; + snd_alias_list_t* projExplosionSound; + snd_alias_list_t* projDudSound; + WeapStickinessType stickiness; + float lowAmmoWarningThreshold; + float ricochetChance; + bool riotShieldEnableDamage; + int riotShieldHealth; + float riotShieldDamageMult; + float* parallelBounce; + float* perpendicularBounce; + FxEffectDef* projTrailEffect; + FxEffectDef* projBeaconEffect; + float vProjectileColor[3]; + guidedMissileType_t guidedMissileType; + float maxSteeringAccel; + int projIgnitionDelay; + FxEffectDef* projIgnitionEffect; + snd_alias_list_t* projIgnitionSound; + float fAdsAimPitch; + float fAdsCrosshairInFrac; + float fAdsCrosshairOutFrac; + int adsGunKickReducedKickBullets; + float adsGunKickReducedKickPercent; + float fAdsGunKickPitchMin; + float fAdsGunKickPitchMax; + float fAdsGunKickYawMin; + float fAdsGunKickYawMax; + float fAdsGunKickAccel; + float fAdsGunKickSpeedMax; + float fAdsGunKickSpeedDecay; + float fAdsGunKickStaticDecay; + float fAdsViewKickPitchMin; + float fAdsViewKickPitchMax; + float fAdsViewKickYawMin; + float fAdsViewKickYawMax; + float fAdsViewScatterMin; + float fAdsViewScatterMax; + float fAdsSpread; + int hipGunKickReducedKickBullets; + float hipGunKickReducedKickPercent; + float fHipGunKickPitchMin; + float fHipGunKickPitchMax; + float fHipGunKickYawMin; + float fHipGunKickYawMax; + float fHipGunKickAccel; + float fHipGunKickSpeedMax; + float fHipGunKickSpeedDecay; + float fHipGunKickStaticDecay; + float fHipViewKickPitchMin; + float fHipViewKickPitchMax; + float fHipViewKickYawMin; + float fHipViewKickYawMax; + float fHipViewScatterMin; + float fHipViewScatterMax; + float fightDist; + float maxDist; + const char* accuracyGraphName[2]; + float(*originalAccuracyGraphKnots[2])[2]; + unsigned short originalAccuracyGraphKnotCount[2]; + int iPositionReloadTransTime; + float leftArc; + float rightArc; + float topArc; + float bottomArc; + float accuracy; + float aiSpread; + float playerSpread; + float minTurnSpeed[2]; + float maxTurnSpeed[2]; + float pitchConvergenceTime; + float yawConvergenceTime; + float suppressTime; + float maxRange; + float fAnimHorRotateInc; + float fPlayerPositionDist; + const char* szUseHintString; + const char* dropHintString; + int iUseHintStringIndex; + int dropHintStringIndex; + float horizViewJitter; + float vertViewJitter; + float scanSpeed; + float scanAccel; + int scanPauseTime; + const char* szScript; + float fOOPosAnimLength[2]; + int minDamage; + int minPlayerDamage; + float fMaxDamageRange; + float fMinDamageRange; + float destabilizationRateTime; + float destabilizationCurvatureMax; + int destabilizeDistance; + float* locationDamageMultipliers; + const char* fireRumble; + const char* meleeImpactRumble; + TracerDef* tracerType; + bool turretADSEnabled; + float turretADSTime; + float turretFov; + float turretFovADS; + float turretScopeZoomRate; + float turretScopeZoomMin; + float turretScopeZoomMax; + float turretOverheatUpRate; + float turretOverheatDownRate; + float turretOverheatPenalty; + snd_alias_list_t* turretOverheatSound; + FxEffectDef* turretOverheatEffect; + const char* turretBarrelSpinRumble; + float turretBarrelSpinSpeed; + float turretBarrelSpinUpTime; + float turretBarrelSpinDownTime; + snd_alias_list_t* turretBarrelSpinMaxSnd; + snd_alias_list_t* turretBarrelSpinUpSnd[4]; + snd_alias_list_t* turretBarrelSpinDownSnd[4]; + snd_alias_list_t* missileConeSoundAlias; + snd_alias_list_t* missileConeSoundAliasAtBase; + float missileConeSoundRadiusAtTop; + float missileConeSoundRadiusAtBase; + float missileConeSoundHeight; + float missileConeSoundOriginOffset; + float missileConeSoundVolumescaleAtCore; + float missileConeSoundVolumescaleAtEdge; + float missileConeSoundVolumescaleCoreSize; + float missileConeSoundPitchAtTop; + float missileConeSoundPitchAtBottom; + float missileConeSoundPitchTopSize; + float missileConeSoundPitchBottomSize; + float missileConeSoundCrossfadeTopSize; + float missileConeSoundCrossfadeBottomSize; + bool sharedAmmo; + bool lockonSupported; + bool requireLockonToFire; + bool isAirburstWeapon; + bool bigExplosion; + bool noAdsWhenMagEmpty; + bool avoidDropCleanup; + bool inheritsPerks; + bool crosshairColorChange; + bool bRifleBullet; + bool armorPiercing; + bool bBoltAction; + bool aimDownSight; + bool canHoldBreath; + bool canVariableZoom; + bool bRechamberWhileAds; + bool bBulletExplosiveDamage; + bool bCookOffHold; + bool bClipOnly; + bool noAmmoPickup; + bool adsFireOnly; + bool cancelAutoHolsterWhenEmpty; + bool disableSwitchToWhenEmpty; + bool suppressAmmoReserveDisplay; + bool laserSightDuringNightvision; + bool markableViewmodel; + bool noDualWield; + bool flipKillIcon; + bool bNoPartialReload; + bool bSegmentedReload; + bool blocksProne; + bool silenced; + bool isRollingGrenade; + bool projExplosionEffectForceNormalUp; + bool bProjImpactExplode; + bool stickToPlayers; + bool stickToVehicles; + bool stickToTurrets; + bool hasDetonator; + bool disableFiring; + bool timedDetonation; + bool rotate; + bool holdButtonToThrow; + bool freezeMovementWhenFiring; + bool thermalScope; + bool altModeSameWeapon; + bool turretBarrelSpinEnabled; + bool missileConeSoundEnabled; + bool missileConeSoundPitchshiftEnabled; + bool missileConeSoundCrossfadeEnabled; + bool offhandHoldIsCancelable; + bool doNotAllowAttachmentsToOverrideSpread; + unsigned short stowTag; + XModel* stowOffsetModel; + }; + + struct AnimOverrideEntry + { + unsigned short attachment1; + unsigned short attachment2; + const char* overrideAnim; + const char* altmodeAnim; + unsigned int animTreeType; + int animTime; + int altTime; + }; + + struct SoundOverrideEntry + { + unsigned short attachment1; + unsigned short attachment2; + snd_alias_list_t* overrideSound; + snd_alias_list_t* altmodeSound; + unsigned int soundType; + }; + + struct FXOverrideEntry + { + unsigned short attachment1; + unsigned short attachment2; + FxEffectDef* overrideFX; + FxEffectDef* altmodeFX; + unsigned int fxType; + }; + + struct ReloadStateTimerEntry + { + int attachment; + int reloadAddTime; + int reloadStartAddTime; + }; + + struct NoteTrackToSoundEntry + { + int attachment; + unsigned short* notetrackSoundMapKeys; + unsigned short* notetrackSoundMapValues; + }; + + struct WeaponCompleteDef + { + const char* szInternalName; + WeaponDef* weapDef; + const char* szDisplayName; + unsigned short* hideTags; + WeaponAttachment** scopes; + WeaponAttachment** underBarrels; + WeaponAttachment** others; + const char** szXAnims; + unsigned int numAnimOverrides; + AnimOverrideEntry* animOverrides; + unsigned int numSoundOverrides; + SoundOverrideEntry* soundOverrides; + unsigned int numFXOverrides; + FXOverrideEntry* fxOverrides; + unsigned int numReloadStateTimerOverrides; + ReloadStateTimerEntry* reloadOverrides; + unsigned int numNotetrackOverrides; + NoteTrackToSoundEntry* notetrackOverrides; + float fAdsZoomFov; + int iAdsTransInTime; + int iAdsTransOutTime; + int iClipSize; + ImpactType impactType; + int iFireTime; + int iFireTimeAkimbo; + weaponIconRatioType_t dpadIconRatio; + float penetrateMultiplier; + float fAdsViewKickCenterSpeed; + float fHipViewKickCenterSpeed; + const char* szAltWeaponName; + int altWeapon; + int iAltRaiseTime; + int iAltRaiseTimeAkimbo; + Material* killIcon; + Material* dpadIcon; + int fireAnimLength; + int fireAnimLengthAkimbo; + int iFirstRaiseTime; + int iFirstRaiseTimeAkimbo; + int ammoDropStockMax; + float adsDofStart; + float adsDofEnd; + unsigned short accuracyGraphKnotCount[2]; + float(*accuracyGraphKnots[2])[2]; + bool motionTracker; + bool enhanced; + bool dpadIconShowsAmmo; + }; + + struct FxFloatRange + { + float base; + float amplitude; + }; + + struct FxIntRange + { + int base; + int amplitude; + }; + + struct FxElemVec3Range + { + float base[3]; + float amplitude[3]; + }; + + struct FxSpawnDefLooping + { + int intervalMsec; + int count; + }; + + struct FxSpawnDefOneShot + { + FxIntRange count; + }; + + union FxSpawnDef + { + FxSpawnDefLooping looping; + FxSpawnDefOneShot oneShot; + }; + + struct FxElemAtlas + { + unsigned char behavior; + unsigned char index; + unsigned char fps; + unsigned char loopCount; + unsigned char colIndexBits; + unsigned char rowIndexBits; + short entryCount; + }; + + struct FxElemVelStateInFrame + { + FxElemVec3Range velocity; + FxElemVec3Range totalDelta; + }; + + struct FxElemVelStateSample + { + FxElemVelStateInFrame local; + FxElemVelStateInFrame world; + }; + + struct FxElemVisualState + { + unsigned char color[4]; + float rotationDelta; + float rotationTotal; + float size[2]; + float scale; + }; + + struct FxElemVisStateSample + { + FxElemVisualState base; + FxElemVisualState amplitude; + }; + + struct FxElemMarkVisuals + { + Material* materials[2]; + }; + + union FxEffectDefRef + { + FxEffectDef* handle; + const char* name; + }; + + union FxElemVisuals + { + const void* anonymous; + Material* material; + XModel* model; + FxEffectDefRef effectDef; + const char* soundName; + GfxLightDef* lightDef; + }; + + union FxElemDefVisuals + { + FxElemMarkVisuals* markArray; + FxElemVisuals* array; + FxElemVisuals instance; + }; + + struct FxTrailVertex + { + float pos[2]; + float normal[2]; + float texCoord; + }; + + struct FxTrailDef + { + int scrollTimeMsec; + int repeatDist; + float invSplitDist; + float invSplitArcDist; + float invSplitTime; + int vertCount; + FxTrailVertex* verts; + int indCount; + unsigned short* inds; + }; + + struct FxSparkFountainDef + { + float gravity; + float bounceFrac; + float bounceRand; + float sparkSpacing; + float sparkLength; + int sparkCount; + float loopTime; + float velMin; + float velMax; + float velConeFrac; + float restSpeed; + float boostTime; + float boostFactor; + }; + + struct FxSpotLightDef + { + float fovInnerFraction; + float startRadius; + float endRadius; + float brightness; + float maxLength; + int exponent; + }; + + union FxElemExtendedDefPtr + { + FxTrailDef* trailDef; + FxSparkFountainDef* sparkFountainDef; + FxSpotLightDef* spotLightDef; + void* unknownDef; + }; + + struct FxElemDef + { + int flags; + FxSpawnDef spawn; + FxFloatRange spawnRange; + FxFloatRange fadeInRange; + FxFloatRange fadeOutRange; + float spawnFrustumCullRadius; + FxIntRange spawnDelayMsec; + FxIntRange lifeSpanMsec; + FxFloatRange spawnOrigin[3]; + FxFloatRange spawnOffsetRadius; + FxFloatRange spawnOffsetHeight; + FxFloatRange spawnAngles[3]; + FxFloatRange angularVelocity[3]; + FxFloatRange initialRotation; + FxFloatRange gravity; + FxFloatRange reflectionFactor; + FxElemAtlas atlas; + unsigned char elemType; + unsigned char visualCount; + unsigned char velIntervalCount; + unsigned char visStateIntervalCount; + FxElemVelStateSample* velSamples; + FxElemVisStateSample* visSamples; + FxElemDefVisuals visuals; + Bounds collBounds; + FxEffectDefRef effectOnImpact; + FxEffectDefRef effectOnDeath; + FxEffectDefRef effectEmitted; + FxFloatRange emitDist; + FxFloatRange emitDistVariance; + FxElemExtendedDefPtr extended; + unsigned char sortOrder; + unsigned char lightingFrac; + unsigned char useItemClip; + unsigned char fadeInfo; + int randomSeed; + }; + + struct FxEffectDef + { + const char* name; + int flags; + int totalSize; + int msecLoopingLife; + int elemDefCountLooping; + int elemDefCountOneShot; + int elemDefCountEmission; + float occlusionQueryDepthBias; + int occlusionQueryFadeIn; + int occlusionQueryFadeOut; + FxFloatRange occlusionQueryScaleRange; + FxElemDef* elemDefs; + }; + + struct FxImpactEntry + { + FxEffectDef* nonflesh[31]; + FxEffectDef* flesh[4]; + }; + + struct FxImpactTable + { + const char* name; + FxImpactEntry* table; + }; + + struct SurfaceFxEntry + { + FxEffectDef* surfaceEffect[31]; + }; + + struct SurfaceFxTable + { + const char* name; + SurfaceFxEntry* table; + }; + + union RawFileBuffer + { + const char* compressedBuffer; + const char* buffer; + }; + + struct RawFile + { + const char* name; + int compressedLen; + int len; + RawFileBuffer data; + }; + + struct ScriptFile + { + const char* name; + int compressedLen; + int len; + int bytecodeLen; + const char* buffer; + unsigned char* bytecode; + }; + + struct StringTableCell + { + const char* string; + int hash; + }; + + struct StringTable + { + const char* name; + int columnCount; + int rowCount; + StringTableCell* values; + }; + + enum LbColType + { + LBCOL_TYPE_NUMBER = 0x0, + LBCOL_TYPE_TIME = 0x1, + LBCOL_TYPE_LEVELXP = 0x2, + LBCOL_TYPE_PRESTIGE = 0x3, + LBCOL_TYPE_BIGNUMBER = 0x4, + LBCOL_TYPE_PERCENT = 0x5, + LBCOL_TYPE_TIME_FULL = 0x6, + LBCOL_TYPE_COUNT = 0x7 + }; + + enum LbAggType + { + LBAGG_TYPE_MIN = 0x0, + LBAGG_TYPE_MAX = 0x1, + LBAGG_TYPE_SUM = 0x2, + LBAGG_TYPE_LAST = 0x3, + LBAGG_TYPE_COUNT = 0x4 + }; + + struct LbColumnDef + { + const char* name; + int id; + int propertyId; + bool hidden; + const char* statName; + LbColType type; + int precision; + LbAggType agg; + int uiCalColX; + int uiCalColY; + }; + + enum LbUpdateType + { + LBUPDATE_TYPE_NORMAL = 0x0, + LBUPDATE_TYPE_RANK = 0x1, + LBUPDATE_TYPE_COMBINE = 0x2, + LBUPDATE_TYPE_COUNT = 0x3 + }; + + struct LeaderboardDef + { + const char* name; + int id; + int columnCount; + int xpColId; + int prestigeColId; + LbColumnDef* columns; + LbUpdateType updateType; + int trackTypes; + }; + + struct StructuredDataEnumEntry + { + const char* string; + unsigned short index; + }; + + struct StructuredDataEnum + { + int entryCount; + int reservedEntryCount; + StructuredDataEnumEntry* entries; + }; + + enum StructuredDataTypeCategory + { + DATA_INT = 0x0, + DATA_BYTE = 0x1, + DATA_BOOL = 0x2, + DATA_STRING = 0x3, + DATA_ENUM = 0x4, + DATA_STRUCT = 0x5, + DATA_INDEXED_ARRAY = 0x6, + DATA_ENUM_ARRAY = 0x7, + DATA_FLOAT = 0x8, + DATA_SHORT = 0x9, + DATA_COUNT = 0xA + }; + + union StructuredDataTypeUnion + { + unsigned int stringDataLength; + int enumIndex; + int structIndex; + int indexedArrayIndex; + int enumedArrayIndex; + }; + + struct StructuredDataType + { + StructuredDataTypeCategory type; + StructuredDataTypeUnion u; + }; + + enum StructuredDataValidationType + { + VALIDATION_NONE = 0x0, + VALIDATION_CONSTANT = 0x1, + VALIDATION_INCREASECLAMP = 0x2, + VALIDATION_INCREASESTRICT = 0x3, + VALIDATION_DELTACLAMP = 0x4, + VALIDATION_DELTASTRICT = 0x5, + VALIDATION_XP = 0x6, + VALIDATION_COUNT = 0x7 + }; + + struct StructuredDataStructProperty + { + const char* name; + StructuredDataType type; + unsigned int offset; + StructuredDataValidationType validation; + }; + + struct StructuredDataStruct + { + int propertyCount; + StructuredDataStructProperty* properties; + int size; + unsigned int bitOffset; + }; + + struct StructuredDataIndexedArray + { + int arraySize; + StructuredDataType elementType; + unsigned int elementSize; + }; + + struct StructuredDataEnumedArray + { + int enumIndex; + StructuredDataType elementType; + unsigned int elementSize; + }; + + struct StructuredDataDef + { + int version; + unsigned int formatChecksum; + int enumCount; + StructuredDataEnum* enums; + int structCount; + StructuredDataStruct* structs; + int indexedArrayCount; + StructuredDataIndexedArray* indexedArrays; + int enumedArrayCount; + StructuredDataEnumedArray* enumedArrays; + StructuredDataType rootType; + unsigned int size; + }; + + struct StructuredDataDefSet + { + const char* name; + unsigned int defCount; + StructuredDataDef* defs; + }; + + struct TracerDef + { + const char* name; + Material* material; + unsigned int drawInterval; + float speed; + float beamLength; + float beamWidth; + float screwRadius; + float screwDist; + float colors[5][4]; + }; + + enum VehicleType + { + VEH_WHEELS_4 = 0x0, + VEH_TANK = 0x1, + VEH_PLANE = 0x2, + VEH_BOAT = 0x3, + VEH_ARTILLERY = 0x4, + VEH_HELICOPTER = 0x5, + VEH_SNOWMOBILE = 0x6, + VEH_SUBMARINE = 0x7, + VEH_UGV = 0x8, + VEH_TYPE_COUNT = 0x9 + }; + + enum VehicleAxleType + { + VEH_AXLE_FRONT = 0x0, + VEH_AXLE_REAR = 0x1, + VEH_AXLE_ALL = 0x2, + VEH_AXLE_COUNT = 0x3 + }; + + enum VehCamZOffsetMode + { + VEHCAM_ZMODE_WORLD = 0x0, + VEHCAM_ZMODE_VEHICLE = 0x1, + VEHCAM_ZMODE_VIEW = 0x2, + VEHCAM_ZMODE_COUNT = 0x3 + }; + + struct VehiclePhysDef + { + int physicsEnabled; + const char* physPresetName; + PhysPreset* physPreset; + const char* accelGraphName; + VehicleAxleType steeringAxle; + VehicleAxleType powerAxle; + VehicleAxleType brakingAxle; + float topSpeed; + float reverseSpeed; + float maxVelocity; + float maxPitch; + float maxRoll; + float suspensionTravelFront; + float suspensionTravelRear; + float suspensionStrengthFront; + float suspensionDampingFront; + float suspensionStrengthRear; + float suspensionDampingRear; + float frictionBraking; + float frictionCoasting; + float frictionTopSpeed; + float frictionSide; + float frictionSideRear; + float velocityDependentSlip; + float rollStability; + float rollResistance; + float pitchResistance; + float yawResistance; + float uprightStrengthPitch; + float uprightStrengthRoll; + float targetAirPitch; + float airYawTorque; + float airPitchTorque; + float minimumMomentumForCollision; + float collisionLaunchForceScale; + float wreckedMassScale; + float wreckedBodyFriction; + float minimumJoltForNotify; + float slipThresholdFront; + float slipThresholdRear; + float slipFricScaleFront; + float slipFricScaleRear; + float slipFricRateFront; + float slipFricRateRear; + float slipYawTorque; + }; + + struct VehicleDef + { + const char* name; + VehicleType type; + const char* useHintString; + int health; + int quadBarrel; + float texScrollScale; + float topSpeed; + float accel; + float rotRate; + float rotAccel; + float maxBodyPitch; + float maxBodyRoll; + int fakeBodyStabilizer; + float fakeBodyAccelPitch; + float fakeBodyAccelRoll; + float fakeBodyVelPitch; + float fakeBodyVelRoll; + float fakeBodySideVelPitch; + float fakeBodyPitchStrength; + float fakeBodyRollStrength; + float fakeBodyPitchDampening; + float fakeBodyRollDampening; + float fakeBodyBoatRockingAmplitude; + float fakeBodyBoatRockingPeriod; + float fakeBodyBoatRockingRotationPeriod; + float fakeBodyBoatRockingFadeoutSpeed; + float boatBouncingMinForce; + float boatBouncingMaxForce; + float boatBouncingRate; + float boatBouncingFadeinSpeed; + float boatBouncingFadeoutSteeringAngle; + float collisionDamage; + float collisionSpeed; + float killcamOffset[3]; + int playerProtected; + int bulletDamage; + int armorPiercingDamage; + int grenadeDamage; + int projectileDamage; + int projectileSplashDamage; + int heavyExplosiveDamage; + VehiclePhysDef vehPhysDef; + float boostDuration; + float boostRechargeTime; + float boostAcceleration; + float suspensionTravel; + float maxSteeringAngle; + float steeringLerp; + float minSteeringScale; + float minSteeringSpeed; + float vehHelicopterBoundsRadius; + float vehHelicopterMaxSpeed; + float vehHelicopterMaxSpeedVertical; + float vehHelicopterMaxAccel; + float vehHelicopterMaxAccelVertical; + float vehHelicopterDecelerationFwd; + float vehHelicopterDecelerationSide; + float vehHelicopterDecelerationUp; + float vehHelicopterMaxYawRate; + float vehHelicopterMaxYawAccel; + float vehHelicopterTiltFromVelocity; + float vehHelicopterTiltFromControllerAxes; + float vehHelicopterTiltFromAcceleration; + float vehHelicopterTiltFromDeceleration; + float vehHelicopterTiltFromFwdAndYaw_VelAtMaxTilt; + float vehHelicopterTiltFromFwdAndYaw; + float vehHelicopterTiltMomentum; + float vehHelicopterTiltSpeed; + float vehHelicopterMaxPitch; + float vehHelicopterMaxRoll; + float vehHelicopterHoverSpeedThreshold; + float vehHelicopterJitterJerkyness; + float vehHelicopterLookaheadTime; + int vehHelicopterSoftCollisions; + int camLookEnabled; + int camRelativeControl; + float camLerp; + float camHeight; + float camRadius; + float camPitchInfluence; + float camYawInfluence; + float camRollInfluence; + float camFovIncrease; + float camFovOffset; + float camFovSpeed; + float camReturnSpeed; + float camReturnLerp; + int vehCam_UseGDT; + float vehCam_anglesPitch; + float vehCam_anglesYaw; + float vehCam_anglesRoll; + float vehCam_offsetX; + float vehCam_offsetY; + float vehCam_offsetZ; + float vehCam_radius; + float vehCam_speedInfluence; + float vehCam_pitchTurnRate; + float vehCam_pitchClamp; + float vehCam_yawTurnRate; + float vehCam_yawClamp; + VehCamZOffsetMode vehCam_zOffsetMode; + float vehCam_anglesPitch3P; + float vehCam_anglesYaw3P; + float vehCam_anglesRoll3P; + float vehCam_offsetX3P; + float vehCam_offsetY3P; + float vehCam_offsetZ3P; + float vehCam_radius3P; + float vehCam_speedInfluence3P; + float vehCam_pitchTurnRate3P; + float vehCam_pitchClamp3P; + float vehCam_yawTurnRate3P; + float vehCam_yawClamp3P; + VehCamZOffsetMode vehCam_zOffsetMode3P; + const char* turretWeaponName; + WeaponCompleteDef* turretWeapon; + float turretHorizSpanLeft; + float turretHorizSpanRight; + float turretVertSpanUp; + float turretVertSpanDown; + float turretHorizResistLeft; + float turretHorizResistRight; + float turretVertResistUp; + float turretVertResistDown; + float turretRotRate; + snd_alias_list_t* turretSpinSnd; + snd_alias_list_t* turretStopSnd; + int trophyEnabled; + float trophyRadius; + float trophyInactiveRadius; + int trophyAmmoCount; + float trophyReloadTime; + unsigned short trophyTags[4]; + FxEffectDef* trophyExplodeFx; + FxEffectDef* trophyFlashFx; + Material* compassFriendlyIcon; + Material* compassEnemyIcon; + Material* compassFriendlyAltIcon; + Material* compassEnemyAltIcon; + int compassIconWidth; + int compassIconHeight; + snd_alias_list_t* idleLowSnd; + snd_alias_list_t* idleHighSnd; + snd_alias_list_t* engineLowSnd; + snd_alias_list_t* engineHighSnd; + float engineSndSpeed; + unsigned short audioOriginTag; + snd_alias_list_t* idleLowSndAlt; + snd_alias_list_t* idleHighSndAlt; + snd_alias_list_t* engineLowSndAlt; + snd_alias_list_t* engineHighSndAlt; + float engineSndSpeedAlt; + unsigned short audioOriginTagAlt; + snd_alias_list_t* turretSpinSndAlt; + snd_alias_list_t* turretStopSndAlt; + snd_alias_list_t* engineStartUpSnd; + int engineStartUpLength; + snd_alias_list_t* engineShutdownSnd; + snd_alias_list_t* engineIdleSnd; + snd_alias_list_t* engineSustainSnd; + snd_alias_list_t* engineRampUpSnd; + int engineRampUpLength; + snd_alias_list_t* engineRampDownSnd; + int engineRampDownLength; + snd_alias_list_t* suspensionSoftSnd; + float suspensionSoftCompression; + snd_alias_list_t* suspensionHardSnd; + float suspensionHardCompression; + snd_alias_list_t* collisionSnd; + float collisionBlendSpeed; + snd_alias_list_t* speedSnd; + float speedSndBlendSpeed; + const char* surfaceSndPrefix; + snd_alias_list_t* surfaceSnds[31]; + float surfaceSndBlendSpeed; + float slideVolume; + float slideBlendSpeed; + float inAirPitch; + }; + + struct AddonMapEnts + { + const char* name; + char* entityString; + int numEntityChars; + MapTriggers trigger; + ClipInfo* info; + unsigned int numSubModels; + cmodel_t* cmodels; + GfxBrushModel* models; + }; + +#ifndef __zonecodegenerator +#ifndef __ida +} +#endif +#endif + +#endif + +// EOF diff --git a/src/Common/Utils/TypeAlignment.h b/src/Common/Utils/TypeAlignment.h index 3f1be1e3..15192f08 100644 --- a/src/Common/Utils/TypeAlignment.h +++ b/src/Common/Utils/TypeAlignment.h @@ -20,6 +20,12 @@ #define memb_align(x) alignas(x) #define gcc_align(x) #else +#ifdef __ida +#define type_align(x) __declspec(align(x)) +#define tdef_align(x) __declspec(align(x)) +#define memb_align(x) __declspec(align(x)) +#define gcc_align(x) +#else #ifdef _MSVC_LANG #define type_align(x) __declspec(align(x)) #define tdef_align(x) __declspec(align(x)) @@ -31,4 +37,5 @@ #define memb_align(x) __attribute__((__aligned__(x))) #define gcc_align(x) __attribute__((__aligned__(x))) #endif +#endif #endif \ No newline at end of file diff --git a/src/Linker/Game/IW5/ZoneCreatorIW5.cpp b/src/Linker/Game/IW5/ZoneCreatorIW5.cpp new file mode 100644 index 00000000..5104ef44 --- /dev/null +++ b/src/Linker/Game/IW5/ZoneCreatorIW5.cpp @@ -0,0 +1,95 @@ +#include "ZoneCreatorIW5.h" + +#include + +#include "ObjLoading.h" +#include "Game/IW5/GameIW5.h" +#include "Game/IW5/GameAssetPoolIW5.h" + +using namespace IW5; + +ZoneCreator::ZoneCreator() +{ + for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++) + { + AddAssetTypeName(assetType, GameAssetPoolIW5::AssetTypeNameByType(assetType)); + } +} + +void ZoneCreator::AddAssetTypeName(asset_type_t assetType, std::string name) +{ + m_asset_types_by_name.emplace(std::make_pair(std::move(name), assetType)); +} + +std::vector ZoneCreator::CreateGdtList(ZoneCreationContext& context) +{ + std::vector gdtList; + gdtList.reserve(context.m_gdt_files.size()); + for (const auto& gdt : context.m_gdt_files) + gdtList.push_back(gdt.get()); + + return gdtList; +} + +bool ZoneCreator::CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const +{ + for (const auto& ignoreEntry : context.m_ignored_assets) + { + const auto foundAssetTypeEntry = m_asset_types_by_name.find(ignoreEntry.m_type); + if (foundAssetTypeEntry == m_asset_types_by_name.end()) + { + std::cout << "Unknown asset type \"" << ignoreEntry.m_type << "\" for ignore \"" << ignoreEntry.m_name << "\"" << std::endl; + return false; + } + + ignoredAssetMap[ignoreEntry.m_name] = foundAssetTypeEntry->second; + } + + return true; +} + +void ZoneCreator::CreateZoneAssetPools(Zone* zone) const +{ + zone->m_pools = std::make_unique(zone, zone->m_priority); + + for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++) + zone->m_pools->InitPoolDynamic(assetType); +} + +bool ZoneCreator::SupportsGame(const std::string& gameName) const +{ + return gameName == g_GameIW5.GetShortName(); +} + +std::unique_ptr ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const +{ + auto zone = std::make_unique(context.m_zone_name, 0, &g_GameIW5); + CreateZoneAssetPools(zone.get()); + + for (const auto& assetEntry : context.m_definition->m_assets) + { + if (!assetEntry.m_is_reference) + continue; + + context.m_ignored_assets.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name); + } + + const auto assetLoadingContext = std::make_unique(zone.get(), context.m_asset_search_path, CreateGdtList(context)); + if (!CreateIgnoredAssetMap(context, assetLoadingContext->m_ignored_asset_map)) + return nullptr; + + for (const auto& assetEntry : context.m_definition->m_assets) + { + const auto foundAssetTypeEntry = m_asset_types_by_name.find(assetEntry.m_asset_type); + if (foundAssetTypeEntry == m_asset_types_by_name.end()) + { + std::cout << "Unknown asset type \"" << assetEntry.m_asset_type << "\"" << std::endl; + return nullptr; + } + + if (!ObjLoading::LoadAssetForZone(assetLoadingContext.get(), foundAssetTypeEntry->second, assetEntry.m_asset_name)) + return nullptr; + } + + return zone; +} diff --git a/src/Linker/Game/IW5/ZoneCreatorIW5.h b/src/Linker/Game/IW5/ZoneCreatorIW5.h new file mode 100644 index 00000000..7584ebfc --- /dev/null +++ b/src/Linker/Game/IW5/ZoneCreatorIW5.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +#include "Zone/ZoneTypes.h" +#include "ZoneCreation/IZoneCreator.h" + +namespace IW5 +{ + class ZoneCreator final : public IZoneCreator + { + std::unordered_map m_asset_types_by_name; + + void AddAssetTypeName(asset_type_t assetType, std::string name); + static std::vector CreateGdtList(ZoneCreationContext& context); + bool CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const; + void CreateZoneAssetPools(Zone* zone) const; + + public: + ZoneCreator(); + + _NODISCARD bool SupportsGame(const std::string& gameName) const override; + _NODISCARD std::unique_ptr CreateZoneForDefinition(ZoneCreationContext& context) const override; + }; +} diff --git a/src/Linker/Linker.cpp b/src/Linker/Linker.cpp index 76ee0aeb..609f14ea 100644 --- a/src/Linker/Linker.cpp +++ b/src/Linker/Linker.cpp @@ -20,6 +20,7 @@ #include "ZoneCreation/ZoneCreationContext.h" #include "ZoneCreation/IZoneCreator.h" #include "Game/IW4/ZoneCreatorIW4.h" +#include "Game/IW5/ZoneCreatorIW5.h" #include "Game/T5/ZoneCreatorT5.h" #include "Game/T6/ZoneCreatorT6.h" @@ -34,6 +35,7 @@ const IZoneCreator* const ZONE_CREATORS[] { new IW3::ZoneCreator(), new IW4::ZoneCreator(), + new IW5::ZoneCreator(), new T5::ZoneCreator(), new T6::ZoneCreator() }; diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLocalizeEntry.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLocalizeEntry.cpp new file mode 100644 index 00000000..f5eb5978 --- /dev/null +++ b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLocalizeEntry.cpp @@ -0,0 +1,51 @@ +#include "AssetLoaderLocalizeEntry.h" + +#include + +#include "Localize/LocalizeCommon.h" +#include "Parsing/LocalizeFile/LocalizeFileReader.h" + +using namespace IW5; + +XAssetInfoGeneric* AssetLoaderLocalizeEntry::LoadFromGlobalAssetPools(const std::string& assetName) const +{ + return nullptr; +} + +void* AssetLoaderLocalizeEntry::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) +{ + return nullptr; +} + +bool AssetLoaderLocalizeEntry::CanLoadFromRaw() const +{ + return true; +} + +bool AssetLoaderLocalizeEntry::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const +{ + std::string fileName; + { + std::ostringstream str; + str << LocalizeCommon::GetNameOfLanguage(zone->m_language) << "/localizedstrings/" << assetName << ".str"; + fileName = str.str(); + } + + const auto file = searchPath->Open(fileName); + if (!file.IsOpen()) + return false; + + LocalizeFileReader reader(*file.m_stream, assetName, zone->m_language); + const auto localizeEntries = reader.ReadLocalizeFile(); + + for (const auto& entry : localizeEntries) + { + auto* localizeEntry = memory->Create(); + localizeEntry->name = memory->Dup(entry.m_key.c_str()); + localizeEntry->value = memory->Dup(entry.m_value.c_str()); + + manager->AddAsset(ASSET_TYPE_LOCALIZE_ENTRY, entry.m_key, localizeEntry); + } + + return true; +} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLocalizeEntry.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLocalizeEntry.h new file mode 100644 index 00000000..8d4c21c4 --- /dev/null +++ b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderLocalizeEntry.h @@ -0,0 +1,17 @@ +#pragma once +#include "Game/IW5/IW5.h" +#include "AssetLoading/BasicAssetLoader.h" +#include "AssetLoading/IAssetLoadingManager.h" +#include "SearchPath/ISearchPath.h" + +namespace IW5 +{ + class AssetLoaderLocalizeEntry final : public BasicAssetLoader + { + public: + _NODISCARD XAssetInfoGeneric* LoadFromGlobalAssetPools(const std::string& assetName) const override; + _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; + _NODISCARD bool CanLoadFromRaw() const override; + bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; + }; +} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.cpp new file mode 100644 index 00000000..02d813aa --- /dev/null +++ b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.cpp @@ -0,0 +1,43 @@ +#include "AssetLoaderRawFile.h" + +#include + +#include "Game/IW5/IW5.h" +#include "Pool/GlobalAssetPool.h" + +using namespace IW5; + +void* AssetLoaderRawFile::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) +{ + auto* rawFile = memory->Create(); + 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->name = memory->Dup(assetName.c_str()); + rawFile->len = static_cast(file.m_length); + + auto* fileBuffer = static_cast(memory->Alloc(static_cast(file.m_length + 1))); + file.m_stream->read(fileBuffer, file.m_length); + if (file.m_stream->gcount() != file.m_length) + return false; + fileBuffer[rawFile->len] = '\0'; + + rawFile->data.buffer = fileBuffer; + manager->AddAsset(ASSET_TYPE_RAWFILE, assetName, rawFile); + + return true; +} diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.h b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.h new file mode 100644 index 00000000..b5d4f9e3 --- /dev/null +++ b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.h @@ -0,0 +1,16 @@ +#pragma once +#include "Game/IW5/IW5.h" +#include "AssetLoading/BasicAssetLoader.h" +#include "AssetLoading/IAssetLoadingManager.h" +#include "SearchPath/ISearchPath.h" + +namespace IW5 +{ + class AssetLoaderRawFile final : public BasicAssetLoader + { + 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; + }; +} diff --git a/src/ObjLoading/Game/IW5/InfoString/InfoStringToStructConverter.cpp b/src/ObjLoading/Game/IW5/InfoString/InfoStringToStructConverter.cpp new file mode 100644 index 00000000..3233a77e --- /dev/null +++ b/src/ObjLoading/Game/IW5/InfoString/InfoStringToStructConverter.cpp @@ -0,0 +1,4 @@ +#include "InfoStringToStructConverter.h" + +using namespace IW5; + diff --git a/src/ObjLoading/Game/IW5/InfoString/InfoStringToStructConverter.h b/src/ObjLoading/Game/IW5/InfoString/InfoStringToStructConverter.h new file mode 100644 index 00000000..d9e957bb --- /dev/null +++ b/src/ObjLoading/Game/IW5/InfoString/InfoStringToStructConverter.h @@ -0,0 +1,25 @@ +#pragma once +#include "AssetLoading/IAssetLoadingManager.h" +#include "InfoString/InfoStringToStructConverterBase.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class InfoStringToStructConverter : public InfoStringToStructConverterBase + { + protected: + IAssetLoadingManager* m_loading_manager; + const cspField_t* m_fields; + size_t m_field_count; + + static bool GetHashValue(const std::string& value, unsigned int& hash); + + virtual bool ConvertExtensionField(const cspField_t& field, const std::string& value) = 0; + bool ConvertBaseField(const cspField_t& field, const std::string& value); + + public: + InfoStringToStructConverter(const InfoString& infoString, void* structure, ZoneScriptStrings& zoneScriptStrings, MemoryManager* memory, IAssetLoadingManager* manager, const cspField_t* fields, + size_t fieldCount); + bool Convert() override; + }; +} \ No newline at end of file diff --git a/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp b/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp new file mode 100644 index 00000000..b35da499 --- /dev/null +++ b/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp @@ -0,0 +1,193 @@ +#include "ObjLoaderIW5.h" + +#include "Game/IW5/GameIW5.h" +#include "Game/IW5/GameAssetPoolIW5.h" +#include "ObjContainer/IPak/IPak.h" +#include "ObjLoading.h" +#include "AssetLoaders/AssetLoaderLocalizeEntry.h" +#include "AssetLoaders/AssetLoaderRawFile.h" +#include "AssetLoading/AssetLoadingManager.h" +#include "Image/Dx9TextureLoader.h" +#include "Image/Texture.h" +#include "Image/IwiLoader.h" +#include "Image/IwiTypes.h" + +using namespace IW5; + +ObjLoader::ObjLoader() +{ +#define REGISTER_ASSET_LOADER(t) {auto l = std::make_unique(); m_asset_loaders_by_type[l->GetHandlingAssetType()] = std::move(l);} +#define BASIC_LOADER(assetType, assetClass) BasicAssetLoader + + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_PHYSPRESET, PhysPreset)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_PHYSCOLLMAP, PhysCollmap)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_XANIMPARTS, XAnimParts)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_XMODEL_SURFS, XModelSurfs)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_XMODEL, XModel)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MATERIAL, Material)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_PIXELSHADER, MaterialPixelShader)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_VERTEXSHADER, MaterialVertexShader)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_VERTEXDECL, MaterialVertexDeclaration)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_IMAGE, GfxImage)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SOUND, snd_alias_list_t)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SOUND_CURVE, SndCurve)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LOADED_SOUND, LoadedSound)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_CLIPMAP, clipMap_t)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_COMWORLD, ComWorld)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_GLASSWORLD, GlassWorld)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_PATHDATA, PathData)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_VEHICLE_TRACK, VehicleTrack)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MAP_ENTS, MapEnts)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FXWORLD, FxWorld)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_GFXWORLD, GfxWorld)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LIGHT_DEF, GfxLightDef)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FONT, Font_s)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MENULIST, MenuList)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MENU, menuDef_t)) + REGISTER_ASSET_LOADER(AssetLoaderLocalizeEntry) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_ATTACHMENT, WeaponAttachment)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_WEAPON, WeaponCompleteDef)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FX, FxEffectDef)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_IMPACT_FX, FxImpactTable)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SURFACE_FX, SurfaceFxTable)) + REGISTER_ASSET_LOADER(AssetLoaderRawFile) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SCRIPTFILE, ScriptFile)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_STRINGTABLE, StringTable)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LEADERBOARD, LeaderboardDef)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_STRUCTURED_DATA_DEF, StructuredDataDefSet)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_TRACER, TracerDef)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_VEHICLE, VehicleDef)) + REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_ADDON_MAP_ENTS, AddonMapEnts)) + +#undef BASIC_LOADER +#undef REGISTER_ASSET_LOADER +} + +bool ObjLoader::SupportsZone(Zone* zone) const +{ + return zone->m_game == &g_GameIW5; +} + +bool ObjLoader::IsMpZone(Zone* zone) +{ + return zone->m_name.compare(0, 3, "mp_") == 0 + || zone->m_name.compare(zone->m_name.length() - 3, 3, "_mp") == 0; +} + +bool ObjLoader::IsZmZone(Zone* zone) +{ + return zone->m_name.compare(0, 3, "zm_") == 0 + || zone->m_name.compare(zone->m_name.length() - 3, 3, "_zm") == 0; +} + +void ObjLoader::LoadReferencedContainersForZone(ISearchPath* searchPath, Zone* zone) const +{ +} + +void ObjLoader::UnloadContainersOfZone(Zone* zone) const +{ +} + +void ObjLoader::LoadImageFromLoadDef(GfxImage* image, Zone* zone) +{ + const auto* loadDef = image->texture.loadDef; + Dx9TextureLoader textureLoader(zone->GetMemory()); + + textureLoader.Width(image->width).Height(image->height).Depth(image->depth); + + if ((loadDef->flags & iwi8::IMG_FLAG_MAPTYPE_MASK) == iwi8::IMG_FLAG_MAPTYPE_3D) + textureLoader.Type(TextureType::T_3D); + else if ((loadDef->flags & iwi8::IMG_FLAG_MAPTYPE_MASK) == iwi8::IMG_FLAG_MAPTYPE_CUBE) + textureLoader.Type(TextureType::T_CUBE); + else + textureLoader.Type(TextureType::T_2D); + + textureLoader.Format(static_cast(loadDef->format)); + textureLoader.HasMipMaps(!(loadDef->flags & iwi8::IMG_FLAG_NOMIPMAPS)); + Texture* loadedTexture = textureLoader.LoadTexture(image->texture.loadDef->data); + + if (loadedTexture != nullptr) + { + image->texture.texture = loadedTexture; + image->cardMemory.platform[0] = 0; + + const auto textureMipCount = loadedTexture->GetMipMapCount(); + for (auto mipLevel = 0; mipLevel < textureMipCount; mipLevel++) + image->cardMemory.platform[0] += static_cast(loadedTexture->GetSizeOfMipLevel(mipLevel) * loadedTexture->GetFaceCount()); + } +} + +void ObjLoader::LoadImageFromIwi(GfxImage* image, ISearchPath* searchPath, Zone* zone) +{ + Texture* loadedTexture = nullptr; + IwiLoader loader(zone->GetMemory()); + + const auto imageFileName = "images/" + std::string(image->name) + ".iwi"; + + { + const auto filePathImage = searchPath->Open(imageFileName); + if (filePathImage.IsOpen()) + { + loadedTexture = loader.LoadIwi(*filePathImage.m_stream); + } + } + + if (loadedTexture != nullptr) + { + image->texture.texture = loadedTexture; + image->cardMemory.platform[0] = 0; + + const auto textureMipCount = loadedTexture->GetMipMapCount(); + for (auto mipLevel = 0; mipLevel < textureMipCount; mipLevel++) + image->cardMemory.platform[0] += static_cast(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(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); +} diff --git a/src/ObjLoading/Game/IW5/ObjLoaderIW5.h b/src/ObjLoading/Game/IW5/ObjLoaderIW5.h new file mode 100644 index 00000000..2dbf37a3 --- /dev/null +++ b/src/ObjLoading/Game/IW5/ObjLoaderIW5.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +#include "IObjLoader.h" +#include "AssetLoading/IAssetLoader.h" +#include "SearchPath/ISearchPath.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class ObjLoader final : public IObjLoader + { + std::unordered_map> 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; + }; +} diff --git a/src/ObjLoading/ObjLoading.cpp b/src/ObjLoading/ObjLoading.cpp index 5a6a9dec..eae6aa11 100644 --- a/src/ObjLoading/ObjLoading.cpp +++ b/src/ObjLoading/ObjLoading.cpp @@ -5,6 +5,7 @@ #include "IObjLoader.h" #include "Game/IW3/ObjLoaderIW3.h" #include "Game/IW4/ObjLoaderIW4.h" +#include "Game/IW5/ObjLoaderIW5.h" #include "Game/T5/ObjLoaderT5.h" #include "Game/T6/ObjLoaderT6.h" #include "ObjContainer/IWD/IWD.h" @@ -17,6 +18,7 @@ const IObjLoader* const OBJ_LOADERS[] { new IW3::ObjLoader(), new IW4::ObjLoader(), + new IW5::ObjLoader(), new T5::ObjLoader(), new T6::ObjLoader() }; diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperAddonMapEnts.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperAddonMapEnts.cpp new file mode 100644 index 00000000..1f8fd668 --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperAddonMapEnts.cpp @@ -0,0 +1,27 @@ +#define NOMINMAX +#include "AssetDumperAddonMapEnts.h" + +#include + +using namespace IW5; + +bool AssetDumperAddonMapEnts::ShouldDump(XAssetInfo* asset) +{ + return true; +} + +bool AssetDumperAddonMapEnts::CanDumpAsRaw() +{ + return true; +} + +std::string AssetDumperAddonMapEnts::GetFileNameForAsset(Zone* zone, XAssetInfo* asset) +{ + return asset->m_name; +} + +void AssetDumperAddonMapEnts::DumpRaw(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) +{ + const auto* addonMapEnts = asset->Asset(); + stream.write(addonMapEnts->entityString, std::max(addonMapEnts->numEntityChars - 1, 0)); +} diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperAddonMapEnts.h b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperAddonMapEnts.h new file mode 100644 index 00000000..4d3880f8 --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperAddonMapEnts.h @@ -0,0 +1,16 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class AssetDumperAddonMapEnts final : public AbstractAssetDumper + { + protected: + bool ShouldDump(XAssetInfo* asset) override; + bool CanDumpAsRaw() override; + std::string GetFileNameForAsset(Zone* zone, XAssetInfo* asset) override; + void DumpRaw(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) override; + }; +} diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperGfxImage.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperGfxImage.cpp new file mode 100644 index 00000000..ad09f43c --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperGfxImage.cpp @@ -0,0 +1,62 @@ +#include "AssetDumperGfxImage.h" + +#include + +#include "ObjWriting.h" +#include "Image/IwiWriter8.h" +#include "Image/DdsWriter.h" + +using namespace IW5; + +AssetDumperGfxImage::AssetDumperGfxImage() +{ + switch (ObjWriting::Configuration.ImageOutputFormat) + { + case ObjWriting::Configuration_t::ImageOutputFormat_e::DDS: + m_writer = std::make_unique(); + break; + case ObjWriting::Configuration_t::ImageOutputFormat_e::IWI: + m_writer = std::make_unique(); + break; + default: + assert(false); + m_writer = nullptr; + break; + } +} + +bool AssetDumperGfxImage::ShouldDump(XAssetInfo* asset) +{ + const auto* image = asset->Asset(); + return image->cardMemory.platform[0] > 0; +} + +bool AssetDumperGfxImage::CanDumpAsRaw() +{ + return true; +} + +std::string AssetDumperGfxImage::GetFileNameForAsset(Zone* zone, XAssetInfo* asset) +{ + std::string cleanAssetName = asset->m_name; + for (auto& c : cleanAssetName) + { + switch (c) + { + case '*': + c = '_'; + break; + + default: + break; + } + } + + return "images/" + cleanAssetName + m_writer->GetFileExtension(); +} + +void AssetDumperGfxImage::DumpRaw(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) +{ + const auto* image = asset->Asset(); + m_writer->DumpImage(stream, image->texture.texture); +} diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperGfxImage.h b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperGfxImage.h new file mode 100644 index 00000000..7c903bb5 --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperGfxImage.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/IW5/IW5.h" +#include "Image/IImageWriter.h" + +namespace IW5 +{ + class AssetDumperGfxImage final : public AbstractAssetDumper + { + std::unique_ptr m_writer; + + protected: + bool ShouldDump(XAssetInfo* asset) override; + bool CanDumpAsRaw() override; + std::string GetFileNameForAsset(Zone* zone, XAssetInfo* asset) override; + void DumpRaw(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) override; + + public: + AssetDumperGfxImage(); + }; +} diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLoadedSound.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLoadedSound.cpp new file mode 100644 index 00000000..32f3e388 --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLoadedSound.cpp @@ -0,0 +1,76 @@ +#include "AssetDumperLoadedSound.h" + +#include "Sound/WavTypes.h" + +using namespace IW5; + +bool AssetDumperLoadedSound::ShouldDump(XAssetInfo* asset) +{ + return true; +} + +bool AssetDumperLoadedSound::CanDumpAsRaw() +{ + return true; +} + +std::string AssetDumperLoadedSound::GetFileNameForAsset(Zone* zone, XAssetInfo* asset) +{ + return "sound/" + asset->m_name; +} + +void AssetDumperLoadedSound::DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream) +{ + const auto riffMasterChunkSize = sizeof(WAV_CHUNK_ID_RIFF) + + sizeof(uint32_t) + + sizeof(WAV_WAVE_ID) + + sizeof(WavChunkHeader) + + sizeof(WavFormatChunkPcm) + + sizeof(WavChunkHeader) + + sizeof(asset->sound.info.data_len); + + stream.write(reinterpret_cast(&WAV_CHUNK_ID_RIFF), sizeof(WAV_CHUNK_ID_RIFF)); + stream.write(reinterpret_cast(&riffMasterChunkSize), sizeof(riffMasterChunkSize)); + stream.write(reinterpret_cast(&WAV_WAVE_ID), sizeof(WAV_WAVE_ID)); + + const WavChunkHeader formatChunkHeader + { + WAV_CHUNK_ID_FMT, + sizeof(WavFormatChunkPcm) + }; + stream.write(reinterpret_cast(&formatChunkHeader), sizeof(formatChunkHeader)); + + WavFormatChunkPcm formatChunk + { + WavFormat::PCM, + static_cast(asset->sound.info.channels), + asset->sound.info.rate, + asset->sound.info.rate * asset->sound.info.channels * asset->sound.info.bits / 8, + static_cast(asset->sound.info.block_size), + static_cast(asset->sound.info.bits) + }; + stream.write(reinterpret_cast(&formatChunk), sizeof(formatChunk)); + + const WavChunkHeader dataChunkHeader + { + WAV_CHUNK_ID_DATA, + asset->sound.info.data_len + }; + stream.write(reinterpret_cast(&dataChunkHeader), sizeof(dataChunkHeader)); + stream.write(asset->sound.data, asset->sound.info.data_len); +} + +void AssetDumperLoadedSound::DumpRaw(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) +{ + const auto* loadedSound = asset->Asset(); + switch (static_cast(loadedSound->sound.info.format)) + { + case WavFormat::PCM: + DumpWavPcm(context, loadedSound, stream); + break; + + default: + printf("Unknown format %i for loaded sound: %s\n", loadedSound->sound.info.format, loadedSound->name); + break; + } +} diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLoadedSound.h b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLoadedSound.h new file mode 100644 index 00000000..de3cf038 --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLoadedSound.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class AssetDumperLoadedSound final : public AbstractAssetDumper + { + static void DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream); + protected: + bool ShouldDump(XAssetInfo* asset) override; + bool CanDumpAsRaw() override; + std::string GetFileNameForAsset(Zone* zone, XAssetInfo* asset) override; + void DumpRaw(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) override; + }; +} diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLocalizeEntry.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLocalizeEntry.cpp new file mode 100644 index 00000000..865d251c --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLocalizeEntry.cpp @@ -0,0 +1,53 @@ +#include "AssetDumperLocalizeEntry.h" + +#include +#include + +#include "Localize/LocalizeCommon.h" +#include "Dumping/Localize/StringFileDumper.h" + +using namespace IW5; +namespace fs = std::filesystem; + +void AssetDumperLocalizeEntry::DumpPool(AssetDumpingContext& context, AssetPool* pool) +{ + if (pool->m_asset_lookup.empty()) + return; + + const auto language = LocalizeCommon::GetNameOfLanguage(context.m_zone->m_language); + fs::path stringsPath(context.m_base_path); + stringsPath.append(language); + stringsPath.append("localizedstrings"); + + create_directories(stringsPath); + + auto stringFilePath(stringsPath); + stringFilePath.append(context.m_zone->m_name + ".str"); + + std::ofstream stringFile(stringFilePath, std::fstream::out | std::ofstream::binary); + + if (stringFile.is_open()) + { + StringFileDumper stringFileDumper(context.m_zone, stringFile); + + stringFileDumper.SetLanguageName(language); + + // Magic string. Original string files do have this config file. The purpose of the config file is unknown though. + stringFileDumper.SetConfigFile(R"(C:\trees\cod3\cod3\bin\StringEd.cfg)"); + + stringFileDumper.SetNotes(""); + + for (auto* localizeEntry : *pool) + { + stringFileDumper.WriteLocalizeEntry(localizeEntry->m_name, localizeEntry->Asset()->value); + } + + stringFileDumper.Finalize(); + + stringFile.close(); + } + else + { + printf("Could not create string file for dumping localized strings of zone '%s'\n", context.m_zone->m_name.c_str()); + } +} \ No newline at end of file diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLocalizeEntry.h b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLocalizeEntry.h new file mode 100644 index 00000000..ecbd837c --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperLocalizeEntry.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class AssetDumperLocalizeEntry final : public IAssetDumper + { + public: + void DumpPool(AssetDumpingContext& context, AssetPool* pool) override; + }; +} diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperRawFile.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperRawFile.cpp new file mode 100644 index 00000000..bd07ec0b --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperRawFile.cpp @@ -0,0 +1,70 @@ +#include "AssetDumperRawFile.h" + +#include +#include + +using namespace IW5; + +bool AssetDumperRawFile::ShouldDump(XAssetInfo* asset) +{ + return true; +} + +bool AssetDumperRawFile::CanDumpAsRaw() +{ + return true; +} + +std::string AssetDumperRawFile::GetFileNameForAsset(Zone* zone, XAssetInfo* asset) +{ + return asset->m_name; +} + +void AssetDumperRawFile::DumpRaw(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) +{ + const auto* rawFile = asset->Asset(); + if (rawFile->compressedLen > 0) + { + z_stream_s zs{}; + + zs.zalloc = Z_NULL; + zs.zfree = Z_NULL; + zs.opaque = Z_NULL; + zs.avail_in = 0; + zs.next_in = Z_NULL; + + int ret = inflateInit(&zs); + + if (ret != Z_OK) + { + throw std::runtime_error("Initializing inflate failed"); + } + + zs.next_in = reinterpret_cast(rawFile->data.compressedBuffer); + zs.avail_in = rawFile->compressedLen; + + Bytef buffer[0x1000]; + + while (zs.avail_in > 0) + { + zs.next_out = buffer; + zs.avail_out = sizeof buffer; + ret = inflate(&zs, Z_SYNC_FLUSH); + + if (ret < 0) + { + printf("Inflate failed for dumping rawfile '%s'\n", rawFile->name); + inflateEnd(&zs); + return; + } + + stream.write(reinterpret_cast(buffer), sizeof buffer - zs.avail_out); + } + + inflateEnd(&zs); + } + else if (rawFile->len > 0) + { + stream.write(rawFile->data.buffer, rawFile->len); + } +} diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperRawFile.h b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperRawFile.h new file mode 100644 index 00000000..6388ae6b --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperRawFile.h @@ -0,0 +1,16 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class AssetDumperRawFile final : public AbstractAssetDumper + { + protected: + bool ShouldDump(XAssetInfo* asset) override; + bool CanDumpAsRaw() override; + std::string GetFileNameForAsset(Zone* zone, XAssetInfo* asset) override; + void DumpRaw(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) override; + }; +} diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperStringTable.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperStringTable.cpp new file mode 100644 index 00000000..199f545a --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperStringTable.cpp @@ -0,0 +1,37 @@ +#include "AssetDumperStringTable.h" + +#include "Csv/CsvStream.h" + +using namespace IW5; + +bool AssetDumperStringTable::ShouldDump(XAssetInfo* asset) +{ + return true; +} + +bool AssetDumperStringTable::CanDumpAsRaw() +{ + return true; +} + +std::string AssetDumperStringTable::GetFileNameForAsset(Zone* zone, XAssetInfo* asset) +{ + return asset->m_name; +} + +void AssetDumperStringTable::DumpRaw(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) +{ + const auto* stringTable = asset->Asset(); + CsvOutputStream csv(stream); + + for (auto row = 0; row < stringTable->rowCount; row++) + { + for (auto column = 0; column < stringTable->columnCount; column++) + { + const auto* cell = &stringTable->values[column + row * stringTable->columnCount]; + csv.WriteColumn(cell->string); + } + + csv.NextRow(); + } +} diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperStringTable.h b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperStringTable.h new file mode 100644 index 00000000..faaee6c2 --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperStringTable.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class AssetDumperStringTable final : public AbstractAssetDumper + { + protected: + bool ShouldDump(XAssetInfo* asset) override; + bool CanDumpAsRaw() override; + + std::string GetFileNameForAsset(Zone* zone, XAssetInfo* asset) override; + void DumpRaw(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) override; + }; +} diff --git a/src/ObjWriting/Game/IW5/InfoString/InfoStringFromStructConverter.cpp b/src/ObjWriting/Game/IW5/InfoString/InfoStringFromStructConverter.cpp new file mode 100644 index 00000000..c3ec0365 --- /dev/null +++ b/src/ObjWriting/Game/IW5/InfoString/InfoStringFromStructConverter.cpp @@ -0,0 +1,159 @@ +#include "InfoStringFromStructConverter.h" + +#include + +using namespace IW5; + +void InfoStringFromStructConverter::FillFromBaseField(const cspField_t& field) +{ + switch (static_cast(field.iFieldType)) + { + case CSPFT_STRING: + FillFromString(std::string(field.szName), field.iOffset); + break; + + case CSPFT_STRING_MAX_STRING_CHARS: + FillFromStringBuffer(std::string(field.szName), field.iOffset, 1024); + break; + + case CSPFT_STRING_MAX_QPATH: + FillFromStringBuffer(std::string(field.szName), field.iOffset, 64); + break; + + case CSPFT_STRING_MAX_OSPATH: + FillFromStringBuffer(std::string(field.szName), field.iOffset, 256); + break; + + case CSPFT_INT: + FillFromInt(std::string(field.szName), field.iOffset); + break; + + case CSPFT_QBOOLEAN: + FillFromQBoolean(std::string(field.szName), field.iOffset); + break; + + case CSPFT_BOOL: + FillFromBool(std::string(field.szName), field.iOffset); + break; + + case CSPFT_FLOAT: + FillFromFloat(std::string(field.szName), field.iOffset); + break; + + case CSPFT_MPH_TO_INCHES_PER_SEC: + { + const auto* num = reinterpret_cast(reinterpret_cast(m_structure) + field.iOffset); + m_info_string.SetValueForKey(std::string(field.szName), std::to_string(*num / 17.6f)); + break; + } + + case CSPFT_MILLISECONDS: + FillFromMilliseconds(std::string(field.szName), field.iOffset); + break; + + case CSPFT_FX: + { + const auto* fx = *reinterpret_cast(reinterpret_cast(m_structure) + field.iOffset); + + if (fx) + m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(fx->name))); + else + m_info_string.SetValueForKey(std::string(field.szName), ""); + break; + } + + case CSPFT_XMODEL: + { + const auto* model = *reinterpret_cast(reinterpret_cast(m_structure) + field.iOffset); + + if (model) + m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(model->name))); + else + m_info_string.SetValueForKey(std::string(field.szName), ""); + break; + } + + case CSPFT_MATERIAL: + { + const auto* material = *reinterpret_cast(reinterpret_cast(m_structure) + field. + iOffset); + + if (material) + m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(material->info.name))); + else + m_info_string.SetValueForKey(std::string(field.szName), ""); + break; + } + + case CSPFT_PHYS_COLLMAP: + { + const auto* physCollMap = *reinterpret_cast(reinterpret_cast(m_structure) + field. + iOffset); + + if (physCollMap) + m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(physCollMap->name))); + else + m_info_string.SetValueForKey(std::string(field.szName), ""); + break; + } + + case CSPFT_SOUND: + { + const auto* sndAlias = reinterpret_cast(reinterpret_cast(m_structure) + field. + iOffset); + + if (sndAlias->name) + m_info_string.SetValueForKey(std::string(field.szName), std::string(sndAlias->name->soundName)); + else + m_info_string.SetValueForKey(std::string(field.szName), ""); + break; + } + + case CSPFT_TRACER: + { + const auto* tracer = *reinterpret_cast(reinterpret_cast(m_structure) + field. + iOffset); + + if (tracer) + m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(tracer->name))); + else + m_info_string.SetValueForKey(std::string(field.szName), ""); + break; + } + + case CSPFT_NUM_BASE_FIELD_TYPES: + default: + assert(false); + break; + } +} + +void InfoStringFromStructConverter::FillInfoString() +{ + for (auto fieldIndex = 0u; fieldIndex < m_field_count; fieldIndex++) + { + const auto& field = m_fields[fieldIndex]; + assert(field.iFieldType >= 0); + + if (field.iFieldType < CSPFT_NUM_BASE_FIELD_TYPES) + FillFromBaseField(field); + else + FillFromExtensionField(field); + } +} + +InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields, + const size_t fieldCount) + : InfoStringFromStructConverterBase(structure), + m_fields(fields), + m_field_count(fieldCount) +{ +} + +InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields, const size_t fieldCount, + std::function scriptStringValueCallback) + : InfoStringFromStructConverterBase(structure, std::move(scriptStringValueCallback)), + m_fields(fields), + m_field_count(fieldCount) +{ +} diff --git a/src/ObjWriting/Game/IW5/InfoString/InfoStringFromStructConverter.h b/src/ObjWriting/Game/IW5/InfoString/InfoStringFromStructConverter.h new file mode 100644 index 00000000..9521faae --- /dev/null +++ b/src/ObjWriting/Game/IW5/InfoString/InfoStringFromStructConverter.h @@ -0,0 +1,21 @@ +#pragma once +#include "InfoString/InfoStringFromStructConverterBase.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class InfoStringFromStructConverter : public InfoStringFromStructConverterBase + { + protected: + const cspField_t* m_fields; + size_t m_field_count; + + virtual void FillFromExtensionField(const cspField_t& field) = 0; + void FillFromBaseField(const cspField_t& field); + void FillInfoString() override; + + public: + InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount); + InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount, std::function scriptStringValueCallback); + }; +} \ No newline at end of file diff --git a/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp b/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp new file mode 100644 index 00000000..508deb3c --- /dev/null +++ b/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp @@ -0,0 +1,74 @@ +#include "ZoneDumperIW5.h" + +#include "Game/IW5/GameIW5.h" +#include "Game/IW5/GameAssetPoolIW5.h" + +#include "AssetDumpers/AssetDumperAddonMapEnts.h" +#include "AssetDumpers/AssetDumperGfxImage.h" +#include "AssetDumpers/AssetDumperLoadedSound.h" +#include "AssetDumpers/AssetDumperLocalizeEntry.h" +#include "AssetDumpers/AssetDumperRawFile.h" +#include "AssetDumpers/AssetDumperStringTable.h" + +using namespace IW5; + +bool ZoneDumper::CanHandleZone(AssetDumpingContext& context) const +{ + return context.m_zone->m_game == &g_GameIW5; +} + +bool ZoneDumper::DumpZone(AssetDumpingContext& context) const +{ +#define DUMP_ASSET_POOL(dumperType, poolName) \ + if(assetPools->poolName) \ + { \ + dumperType dumper; \ + dumper.DumpPool(context, assetPools->poolName.get()); \ + } + + const auto* assetPools = dynamic_cast(context.m_zone->m_pools.get()); + // DUMP_ASSET_POOL(AssetDumperPhysPreset, m_phys_preset) + // DUMP_ASSET_POOL(AssetDumperPhysCollmap, m_phys_collmap) + // DUMP_ASSET_POOL(AssetDumperXAnimParts, m_xanim_parts) + // DUMP_ASSET_POOL(AssetDumperXModelSurfs, m_xmodel_surfs) + // DUMP_ASSET_POOL(AssetDumperXModel, m_xmodel) + // DUMP_ASSET_POOL(AssetDumperMaterial, m_material) + // DUMP_ASSET_POOL(AssetDumperMaterialPixelShader, m_material_pixel_shader) + // DUMP_ASSET_POOL(AssetDumperMaterialVertexShader, m_material_vertex_shader) + // DUMP_ASSET_POOL(AssetDumperMaterialVertexDeclaration, m_material_vertex_decl) + // DUMP_ASSET_POOL(AssetDumperMaterialTechniqueSet, m_technique_set) + DUMP_ASSET_POOL(AssetDumperGfxImage, m_image) + // DUMP_ASSET_POOL(AssetDumpersnd_alias_list_t, m_sound) + // DUMP_ASSET_POOL(AssetDumperSndCurve, m_sound_curve) + DUMP_ASSET_POOL(AssetDumperLoadedSound, m_loaded_sound) + // DUMP_ASSET_POOL(AssetDumperclipMap_t, m_clip_map) + // DUMP_ASSET_POOL(AssetDumperComWorld, m_com_world) + // DUMP_ASSET_POOL(AssetDumperGlassWorld, m_glass_world) + // DUMP_ASSET_POOL(AssetDumperPathData, m_path_data) + // DUMP_ASSET_POOL(AssetDumperVehicleTrack, m_vehicle_track) + // DUMP_ASSET_POOL(AssetDumperMapEnts, m_map_ents) + // DUMP_ASSET_POOL(AssetDumperFxWorld, m_fx_world) + // DUMP_ASSET_POOL(AssetDumperGfxWorld, m_gfx_world) + // DUMP_ASSET_POOL(AssetDumperGfxLightDef, m_gfx_light_def) + // DUMP_ASSET_POOL(AssetDumperFont_s, m_font) + // DUMP_ASSET_POOL(AssetDumperMenuList, m_menu_list) + // DUMP_ASSET_POOL(AssetDumpermenuDef_t, m_menu_def) + DUMP_ASSET_POOL(AssetDumperLocalizeEntry, m_localize) + // DUMP_ASSET_POOL(AssetDumperWeaponAttachment, m_attachment) + // DUMP_ASSET_POOL(AssetDumperWeaponCompleteDef, m_weapon) + // DUMP_ASSET_POOL(AssetDumperFxEffectDef, m_fx) + // DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table) + // DUMP_ASSET_POOL(AssetDumperSurfaceFxTable, m_surface_fx_table) + DUMP_ASSET_POOL(AssetDumperRawFile, m_raw_file) + // DUMP_ASSET_POOL(AssetDumperScriptFile, m_script_file) + DUMP_ASSET_POOL(AssetDumperStringTable, m_string_table) + // DUMP_ASSET_POOL(AssetDumperLeaderboardDef, m_leaderboard) + // DUMP_ASSET_POOL(AssetDumperStructuredDataDefSet, m_structed_data_def_set) + // DUMP_ASSET_POOL(AssetDumperTracerDef, m_tracer) + // DUMP_ASSET_POOL(AssetDumperVehicleDef, m_vehicle) + DUMP_ASSET_POOL(AssetDumperAddonMapEnts, m_addon_map_ents) + + return true; + +#undef DUMP_ASSET_POOL +} diff --git a/src/ObjWriting/Game/IW5/ZoneDumperIW5.h b/src/ObjWriting/Game/IW5/ZoneDumperIW5.h new file mode 100644 index 00000000..6291a5a9 --- /dev/null +++ b/src/ObjWriting/Game/IW5/ZoneDumperIW5.h @@ -0,0 +1,12 @@ +#pragma once +#include "Dumping/IZoneDumper.h" + +namespace IW5 +{ + class ZoneDumper final : public IZoneDumper + { + public: + bool CanHandleZone(AssetDumpingContext& context) const override; + bool DumpZone(AssetDumpingContext& context) const override; + }; +} diff --git a/src/ObjWriting/ObjWriting.cpp b/src/ObjWriting/ObjWriting.cpp index 304eaa58..c39edc4e 100644 --- a/src/ObjWriting/ObjWriting.cpp +++ b/src/ObjWriting/ObjWriting.cpp @@ -2,6 +2,7 @@ #include "Dumping/IZoneDumper.h" #include "Game/IW3/ZoneDumperIW3.h" #include "Game/IW4/ZoneDumperIW4.h" +#include "Game/IW5/ZoneDumperIW5.h" #include "Game/T5/ZoneDumperT5.h" #include "Game/T6/ZoneDumperT6.h" @@ -11,6 +12,7 @@ const IZoneDumper* const ZONE_DUMPER[] { new IW3::ZoneDumper(), new IW4::ZoneDumper(), + new IW5::ZoneDumper(), new T5::ZoneDumper(), new T6::ZoneDumper() }; diff --git a/src/Unlinker/Game/IW5/ZoneDefWriterIW5.cpp b/src/Unlinker/Game/IW5/ZoneDefWriterIW5.cpp new file mode 100644 index 00000000..304a8019 --- /dev/null +++ b/src/Unlinker/Game/IW5/ZoneDefWriterIW5.cpp @@ -0,0 +1,45 @@ +#include "ZoneDefWriterIW5.h" + +#include + +#include "Game/IW5/GameIW5.h" +#include "Game/IW5/GameAssetPoolIW5.h" + +using namespace IW5; + +bool ZoneDefWriter::CanHandleZone(Zone* zone) const +{ + return zone->m_game == &g_GameIW5; +} + +void ZoneDefWriter::WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const +{ +} + +void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const +{ + const auto* pools = dynamic_cast(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; + } + } +} diff --git a/src/Unlinker/Game/IW5/ZoneDefWriterIW5.h b/src/Unlinker/Game/IW5/ZoneDefWriterIW5.h new file mode 100644 index 00000000..e68b942f --- /dev/null +++ b/src/Unlinker/Game/IW5/ZoneDefWriterIW5.h @@ -0,0 +1,16 @@ +#pragma once + +#include "ContentLister/ZoneDefWriter.h" + +namespace IW5 +{ + class ZoneDefWriter final : public AbstractZoneDefWriter + { + protected: + void WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const override; + void WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const override; + + public: + bool CanHandleZone(Zone* zone) const override; + }; +} \ No newline at end of file diff --git a/src/Unlinker/Unlinker.cpp b/src/Unlinker/Unlinker.cpp index f8c70111..ec9c9d6a 100644 --- a/src/Unlinker/Unlinker.cpp +++ b/src/Unlinker/Unlinker.cpp @@ -18,6 +18,7 @@ #include "UnlinkerArgs.h" #include "Game/IW3/ZoneDefWriterIW3.h" #include "Game/IW4/ZoneDefWriterIW4.h" +#include "Game/IW5/ZoneDefWriterIW5.h" #include "Game/T5/ZoneDefWriterT5.h" #include "Game/T6/ZoneDefWriterT6.h" #include "Utils/ObjFileStream.h" @@ -28,6 +29,7 @@ const IZoneDefWriter* const ZONE_DEF_WRITERS[] { new IW3::ZoneDefWriter(), new IW4::ZoneDefWriter(), + new IW5::ZoneDefWriter(), new T5::ZoneDefWriter(), new T6::ZoneDefWriter() }; diff --git a/src/ZoneCode.lua b/src/ZoneCode.lua index 52fee573..f64cbeee 100644 --- a/src/ZoneCode.lua +++ b/src/ZoneCode.lua @@ -67,6 +67,49 @@ ZoneCode.Assets = { "AddonMapEnts" }, + IW5 = { + "PhysPreset", + "PhysCollmap", + "XAnimParts", + "XModelSurfs", + "XModel", + "Material", + "MaterialPixelShader", + "MaterialVertexShader", + "MaterialVertexDeclaration", + "MaterialTechniqueSet", + "GfxImage", + "snd_alias_list_t", + "SndCurve", + "LoadedSound", + "clipMap_t", + "ComWorld", + "GlassWorld", + "PathData", + "VehicleTrack", + "MapEnts", + "FxWorld", + "GfxWorld", + "GfxLightDef", + "Font_s", + "MenuList", + "menuDef_t", + "LocalizeEntry", + "WeaponAttachment", + "WeaponCompleteDef", + "FxEffectDef", + "FxImpactTable", + "SurfaceFxTable", + "RawFile", + "ScriptFile", + "StringTable", + "LeaderboardDef", + "StructuredDataDefSet", + "TracerDef", + "VehicleDef", + "AddonMapEnts", + }, + T5 = { "PhysPreset", "PhysConstraints", @@ -278,6 +321,10 @@ function ZoneCode:project() self:outputForAssets(self.Assets.IW4) filter {} + filter "files:**/IW5.gen" + self:outputForAssets(self.Assets.IW5) + filter {} + filter "files:**/T5.gen" self:outputForAssets(self.Assets.T5) filter {} diff --git a/src/ZoneCode/Game/IW5/IW5.gen b/src/ZoneCode/Game/IW5/IW5.gen new file mode 100644 index 00000000..7bd8cb1e --- /dev/null +++ b/src/ZoneCode/Game/IW5/IW5.gen @@ -0,0 +1 @@ +# This file exists for automatically generating zone loading code. \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/IW5.h b/src/ZoneCode/Game/IW5/IW5.h new file mode 100644 index 00000000..46fba6de --- /dev/null +++ b/src/ZoneCode/Game/IW5/IW5.h @@ -0,0 +1,8 @@ +#pragma once + +// Entry point for IW5 code generation + +#include "../Common.h" +#include "../../../Common/Game/IW5/IW5_Assets.h" + +// EOF \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/IW5_Commands.txt b/src/ZoneCode/Game/IW5/IW5_Commands.txt new file mode 100644 index 00000000..f50bc026 --- /dev/null +++ b/src/ZoneCode/Game/IW5/IW5_Commands.txt @@ -0,0 +1,97 @@ +// Game: Modern Warfare 3 (IW5) +game IW5; +architecture x86; + +// Game Assets +asset PhysPreset ASSET_TYPE_PHYSPRESET; +asset PhysCollmap ASSET_TYPE_PHYSCOLLMAP; +asset XAnimParts ASSET_TYPE_XANIMPARTS; +asset XModelSurfs ASSET_TYPE_XMODEL_SURFS; +asset XModel ASSET_TYPE_XMODEL; +asset Material ASSET_TYPE_MATERIAL; +asset MaterialPixelShader ASSET_TYPE_PIXELSHADER; +asset MaterialVertexShader ASSET_TYPE_VERTEXSHADER; +asset MaterialVertexDeclaration ASSET_TYPE_VERTEXDECL; +asset MaterialTechniqueSet ASSET_TYPE_TECHNIQUE_SET; +asset GfxImage ASSET_TYPE_IMAGE; +asset snd_alias_list_t ASSET_TYPE_SOUND; +asset SndCurve ASSET_TYPE_SOUND_CURVE; +asset LoadedSound ASSET_TYPE_LOADED_SOUND; +asset clipMap_t ASSET_TYPE_CLIPMAP; +asset ComWorld ASSET_TYPE_COMWORLD; +asset GlassWorld ASSET_TYPE_GLASSWORLD; +asset PathData ASSET_TYPE_PATHDATA; +asset VehicleTrack ASSET_TYPE_VEHICLE_TRACK; +asset MapEnts ASSET_TYPE_MAP_ENTS; +asset FxWorld ASSET_TYPE_FXWORLD; +asset GfxWorld ASSET_TYPE_GFXWORLD; +asset GfxLightDef ASSET_TYPE_LIGHT_DEF; +asset Font_s ASSET_TYPE_FONT; +asset MenuList ASSET_TYPE_MENULIST; +asset menuDef_t ASSET_TYPE_MENU; +asset LocalizeEntry ASSET_TYPE_LOCALIZE_ENTRY; +asset WeaponAttachment ASSET_TYPE_ATTACHMENT; +asset WeaponCompleteDef ASSET_TYPE_WEAPON; +asset FxEffectDef ASSET_TYPE_FX; +asset FxImpactTable ASSET_TYPE_IMPACT_FX; +asset SurfaceFxTable ASSET_TYPE_SURFACE_FX; +asset RawFile ASSET_TYPE_RAWFILE; +asset ScriptFile ASSET_TYPE_SCRIPTFILE; +asset StringTable ASSET_TYPE_STRINGTABLE; +asset LeaderboardDef ASSET_TYPE_LEADERBOARD; +asset StructuredDataDefSet ASSET_TYPE_STRUCTURED_DATA_DEF; +asset TracerDef ASSET_TYPE_TRACER; +asset VehicleDef ASSET_TYPE_VEHICLE; +asset AddonMapEnts ASSET_TYPE_ADDON_MAP_ENTS; + +// Setup blocks +block temp XFILE_BLOCK_TEMP default; +block normal XFILE_BLOCK_PHYSICAL; +block runtime XFILE_BLOCK_RUNTIME default; +block normal XFILE_BLOCK_VIRTUAL default; +block normal XFILE_BLOCK_LARGE; +block normal XFILE_BLOCK_CALLBACK; +block normal XFILE_BLOCK_SCRIPT; + +#include "XAssets/PhysPreset.txt" +#include "XAssets/PhysCollmap.txt" +#include "XAssets/XAnimParts.txt" +#include "XAssets/XModelSurfs.txt" +#include "XAssets/XModel.txt" +#include "XAssets/Material.txt" +#include "XAssets/MaterialPixelShader.txt" +#include "XAssets/MaterialVertexShader.txt" +#include "XAssets/MaterialVertexDeclaration.txt" +#include "XAssets/MaterialTechniqueSet.txt" +#include "XAssets/GfxImage.txt" +#include "XAssets/snd_alias_list_t.txt" +#include "XAssets/SndCurve.txt" +#include "XAssets/LoadedSound.txt" +#include "XAssets/clipMap_t.txt" +#include "XAssets/ComWorld.txt" +#include "XAssets/GlassWorld.txt" +#include "XAssets/PathData.txt" +#include "XAssets/VehicleTrack.txt" +#include "XAssets/MapEnts.txt" +#include "XAssets/FxWorld.txt" +#include "XAssets/GfxWorld.txt" +#include "XAssets/GfxLightDef.txt" +#include "XAssets/Font_s.txt" +#include "XAssets/MenuList.txt" +#include "XAssets/menuDef_t.txt" +#include "XAssets/LocalizeEntry.txt" +#include "XAssets/WeaponAttachment.txt" +#include "XAssets/WeaponCompleteDef.txt" +#include "XAssets/FxEffectDef.txt" +#include "XAssets/FxImpactTable.txt" +#include "XAssets/SurfaceFxTable.txt" +#include "XAssets/RawFile.txt" +#include "XAssets/ScriptFile.txt" +#include "XAssets/StringTable.txt" +#include "XAssets/LeaderboardDef.txt" +#include "XAssets/StructuredDataDefSet.txt" +#include "XAssets/TracerDef.txt" +#include "XAssets/VehicleDef.txt" +#include "XAssets/AddonMapEnts.txt" + +// EOF \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/AddonMapEnts.txt b/src/ZoneCode/Game/IW5/XAssets/AddonMapEnts.txt new file mode 100644 index 00000000..213a8428 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/AddonMapEnts.txt @@ -0,0 +1,8 @@ +// ========================================= +// AddonMapEnts +// ========================================= +use AddonMapEnts; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set count entityString numEntityChars; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/ComWorld.txt b/src/ZoneCode/Game/IW5/XAssets/ComWorld.txt new file mode 100644 index 00000000..6bd5b8b9 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/ComWorld.txt @@ -0,0 +1,11 @@ +// ========================================= +// ComWorld +// ========================================= +use ComWorld; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set count primaryLights primaryLightCount; + +// ComPrimaryLight +set string ComPrimaryLight::defName; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/Font_s.txt b/src/ZoneCode/Game/IW5/XAssets/Font_s.txt new file mode 100644 index 00000000..f37cf707 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/Font_s.txt @@ -0,0 +1,9 @@ +// ========================================= +// Font_s +// ========================================= +use Font_s; +set block XFILE_BLOCK_TEMP; +set string fontName; +set name fontName; +set reusable glyphs; +set count glyphs glyphCount; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/FxEffectDef.txt b/src/ZoneCode/Game/IW5/XAssets/FxEffectDef.txt new file mode 100644 index 00000000..261df4c7 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/FxEffectDef.txt @@ -0,0 +1,50 @@ +// ========================================= +// FxEffectDef +// ========================================= +use FxEffectDef; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set count elemDefs elemDefCountEmission + elemDefCountLooping + elemDefCountOneShot; + +// FxElemDef +use FxElemDef; +set count velSamples velIntervalCount + 1; +set count visSamples visStateIntervalCount + 1; + +// FxElemDefVisuals +use FxElemDefVisuals; +set condition markArray FxElemDef::elemType == FX_ELEM_TYPE_DECAL; +set count markArray FxElemDef::visualCount; +set condition array FxElemDef::visualCount > 1; +set count array FxElemDef::visualCount; + +// FxElemVisuals +use FxElemVisuals; +set condition anonymous never; +set condition model FxElemDef::elemType == FX_ELEM_TYPE_MODEL; +set condition effectDef FxElemDef::elemType == FX_ELEM_TYPE_RUNNER; +set condition soundName FxElemDef::elemType == FX_ELEM_TYPE_SOUND; +set string soundName; +set condition material FxElemDef::elemType == FX_ELEM_TYPE_SPRITE_BILLBOARD +|| FxElemDef::elemType == FX_ELEM_TYPE_SPRITE_ORIENTED +|| FxElemDef::elemType == FX_ELEM_TYPE_TAIL +|| FxElemDef::elemType == FX_ELEM_TYPE_TRAIL +|| FxElemDef::elemType == FX_ELEM_TYPE_CLOUD +|| FxElemDef::elemType == FX_ELEM_TYPE_SPARK_CLOUD +|| FxElemDef::elemType == FX_ELEM_TYPE_SPARK_FOUNTAIN; + +// FxEffectDefRef +use FxEffectDefRef; +set condition handle never; +set string name; + +// FxElemExtendedDefPtr +use FxElemExtendedDefPtr; +set condition trailDef FxElemDef::elemType == FX_ELEM_TYPE_TRAIL; +set condition sparkFountainDef FxElemDef::elemType == FX_ELEM_TYPE_SPARK_FOUNTAIN; + +// FxTrailDef +use FxTrailDef; +set count verts vertCount; +set count inds indCount; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/FxImpactTable.txt b/src/ZoneCode/Game/IW5/XAssets/FxImpactTable.txt new file mode 100644 index 00000000..990b4fcc --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/FxImpactTable.txt @@ -0,0 +1,8 @@ +// ========================================= +// FxImpactTable +// ========================================= +use FxImpactTable; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set count table 15; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/FxWorld.txt b/src/ZoneCode/Game/IW5/XAssets/FxWorld.txt new file mode 100644 index 00000000..8f20223e --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/FxWorld.txt @@ -0,0 +1,38 @@ +// ========================================= +// FxWorld +// ========================================= +use FxWorld; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; + +// FxGlassSystem +use FxGlassSystem; +set count defs defCount; +set block piecePlaces XFILE_BLOCK_RUNTIME; +set count piecePlaces pieceLimit; +set block pieceStates XFILE_BLOCK_RUNTIME; +set count pieceStates pieceLimit; +set block pieceDynamics XFILE_BLOCK_RUNTIME; +set count pieceDynamics pieceLimit; +set block geoData XFILE_BLOCK_RUNTIME; +set count geoData geoDataLimit; +set block isInUse XFILE_BLOCK_RUNTIME; +set count isInUse pieceWordCount; +set block cellBits XFILE_BLOCK_RUNTIME; +set count cellBits pieceWordCount * cellCount; +set block visData XFILE_BLOCK_RUNTIME; +set count visData (pieceLimit + 15) / 16 * 16; +set block linkOrg XFILE_BLOCK_RUNTIME; +set count linkOrg pieceLimit; +set block halfThickness XFILE_BLOCK_RUNTIME; +set count halfThickness (pieceLimit + 3) / 4 * 4; +set count lightingHandles initPieceCount; +set count initPieceStates initPieceCount; +set count initGeoData initGeoDataCount; + +// FxGlassDef +reorder FxGlassDef: + physPreset + material + materialShattered; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/GfxImage.txt b/src/ZoneCode/Game/IW5/XAssets/GfxImage.txt new file mode 100644 index 00000000..38e3bec4 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/GfxImage.txt @@ -0,0 +1,22 @@ +// ========================================= +// GfxImage +// ========================================= +use GfxImage; +set block XFILE_BLOCK_TEMP; +set action OnImageLoaded(GfxImage); +set string name; +set name name; +reorder: + name + texture; + +// GfxTexture +use GfxTexture; +set reusable loadDef; +set block loadDef XFILE_BLOCK_TEMP; +set condition texture never; + +// GfxImageLoadDef +use GfxImageLoadDef; +set action LoadImageData(GfxImageLoadDef, GfxImage); +set arraysize data resourceSize; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/GfxLightDef.txt b/src/ZoneCode/Game/IW5/XAssets/GfxLightDef.txt new file mode 100644 index 00000000..ca07fc87 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/GfxLightDef.txt @@ -0,0 +1,7 @@ +// ========================================= +// GfxLightDef +// ========================================= +use GfxLightDef; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/GfxWorld.txt b/src/ZoneCode/Game/IW5/XAssets/GfxWorld.txt new file mode 100644 index 00000000..d8069d2c --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/GfxWorld.txt @@ -0,0 +1,128 @@ +// ========================================= +// GfxWorld +// ========================================= +use GfxWorld; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set string baseName; +set count skies skyCount; +set count aabbTreeCounts dpvsPlanes::cellCount; +set count aabbTrees dpvsPlanes::cellCount; +set count cells dpvsPlanes::cellCount; +set count models modelCount; +set count materialMemory materialMemoryCount; +set block cellCasterBits XFILE_BLOCK_RUNTIME; +set count cellCasterBits dpvsPlanes::cellCount * ((dpvsPlanes::cellCount + 31) / 32); +set block cellHasSunLitSurfsBits XFILE_BLOCK_RUNTIME; +set count cellHasSunLitSurfsBits (dpvsPlanes::cellCount + 31) / 32; +set block sceneDynModel XFILE_BLOCK_RUNTIME; +set count sceneDynModel dpvsDyn::dynEntClientCount[0]; +set block sceneDynBrush XFILE_BLOCK_RUNTIME; +set count sceneDynBrush dpvsDyn::dynEntClientCount[1]; +set block primaryLightEntityShadowVis XFILE_BLOCK_RUNTIME; +set count primaryLightEntityShadowVis (primaryLightCount - lastSunPrimaryLightIndex - 1) * 0x2000; +set block primaryLightDynEntShadowVis XFILE_BLOCK_RUNTIME; +set count primaryLightDynEntShadowVis[0] dpvsDyn::dynEntClientCount[0] * (primaryLightCount - lastSunPrimaryLightIndex - 1); +set count primaryLightDynEntShadowVis[1] dpvsDyn::dynEntClientCount[1] * (primaryLightCount - lastSunPrimaryLightIndex - 1); +set block nonSunPrimaryLightForModelDynEnt XFILE_BLOCK_RUNTIME; +set count nonSunPrimaryLightForModelDynEnt dpvsDyn::dynEntClientCount[0]; +set count shadowGeom primaryLightCount; +set count lightRegion primaryLightCount; +set count heroOnlyLights heroOnlyLightCount; + +// GfxSky +set count GfxSky::skyStartSurfs skySurfCount; + +// GfxWorldDpvsPlanes +use GfxWorldDpvsPlanes; +set reusable planes; +set count planes GfxWorld::planeCount; +set count nodes GfxWorld::nodeCount; +set block sceneEntCellBits XFILE_BLOCK_RUNTIME; +set count sceneEntCellBits cellCount * 0x200; + +// GfxCellTree +// Extremly dirty hack caused by IW doing an extremly dirty hack in their code as well. +// No idea why they decided to separate the count from the pointer that uses the count. +// Thank you Treyarch for doing better in your games at least. +set count GfxCellTree::aabbTree GfxWorld::aabbTreeCounts[GfxCellTree - GfxWorld::aabbTrees]; + +// GfxAabbTree +use GfxAabbTree; +set reusable smodelIndexes; +set count smodelIndexes smodelIndexCount; + +// GfxCell +use GfxCell; +set count portals portalCount; +set count reflectionProbes reflectionProbeCount; + +// GfxPortal +use GfxPortal; +set condition writable never; +set count vertices vertexCount; + +// GfxWorldDraw +use GfxWorldDraw; +set count reflectionProbes reflectionProbeCount; +set count reflectionProbeOrigins reflectionProbeCount; +set block reflectionProbeTextures XFILE_BLOCK_RUNTIME; +set count reflectionProbeTextures reflectionProbeCount; +set count lightmaps lightmapCount; +set block lightmapPrimaryTextures XFILE_BLOCK_RUNTIME; +set count lightmapPrimaryTextures lightmapCount; +set block lightmapSecondaryTextures XFILE_BLOCK_RUNTIME; +set count lightmapSecondaryTextures lightmapCount; +set count vd::vertices vertexCount; +set condition vd::worldVb never; +set count vld::data vertexLayerDataSize; +set condition vld::layerVb never; +set count indices indexCount; + +// GfxLightGrid +use GfxLightGrid; +set count rowDataStart maxs[rowAxis] - mins[rowAxis] + 1; +set count rawRowData rawRowDataSize; +set count entries entryCount; +set count colors colorCount; + +// GfxShadowGeometry +use GfxShadowGeometry; +set count sortedSurfIndex surfaceCount; +set count smodelIndex smodelCount; + +// GfxLightRegion +set count GfxLightRegion::hulls hullCount; + +// GfxLightRegionHull +set count GfxLightRegionHull::axis axisCount; + +// GfxWorldDpvsStatic +use GfxWorldDpvsStatic; +set block smodelVisData XFILE_BLOCK_RUNTIME; +set count smodelVisData smodelCount; +set block surfaceVisData XFILE_BLOCK_RUNTIME; +set count surfaceVisData staticSurfaceCount; +set count sortedSurfIndex staticSurfaceCount + staticSurfaceCountNoDecal; +set count smodelInsts smodelCount; +set count surfaces GfxWorld::surfaceCount; +set count surfacesBounds GfxWorld::surfaceCount; +set count smodelDrawInsts smodelCount; +set block surfaceMaterials XFILE_BLOCK_RUNTIME; +set count surfaceMaterials GfxWorld::surfaceCount; +set block surfaceCastsSunShadow XFILE_BLOCK_RUNTIME; +set count surfaceCastsSunShadow surfaceVisDataCount; + +// GfxWorldDpvsDynamic +use GfxWorldDpvsDynamic; +set block dynEntCellBits XFILE_BLOCK_RUNTIME; +set count dynEntCellBits[0] dynEntClientWordCount[0] * GfxWorld::dpvsPlanes::cellCount; +set count dynEntCellBits[1] dynEntClientWordCount[1] * GfxWorld::dpvsPlanes::cellCount; +set block dynEntVisData XFILE_BLOCK_RUNTIME; +set count dynEntVisData[0][0] 32 * dynEntClientWordCount[0]; +set count dynEntVisData[1][0] 32 * dynEntClientWordCount[1]; +set count dynEntVisData[0][1] 32 * dynEntClientWordCount[0]; +set count dynEntVisData[1][1] 32 * dynEntClientWordCount[1]; +set count dynEntVisData[0][2] 32 * dynEntClientWordCount[0]; +set count dynEntVisData[1][2] 32 * dynEntClientWordCount[1]; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/GlassWorld.txt b/src/ZoneCode/Game/IW5/XAssets/GlassWorld.txt new file mode 100644 index 00000000..dc283b17 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/GlassWorld.txt @@ -0,0 +1,7 @@ +// ========================================= +// GlassWorld +// ========================================= +use GlassWorld; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/LeaderboardDef.txt b/src/ZoneCode/Game/IW5/XAssets/LeaderboardDef.txt new file mode 100644 index 00000000..8dd30900 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/LeaderboardDef.txt @@ -0,0 +1,13 @@ +// ========================================= +// LeaderboardDef +// ========================================= +use LeaderboardDef; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set count columns columnCount; + +// LbColumnDef +use LbColumnDef; +set string name; +set string statName; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/LoadedSound.txt b/src/ZoneCode/Game/IW5/XAssets/LoadedSound.txt new file mode 100644 index 00000000..0cef20e5 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/LoadedSound.txt @@ -0,0 +1,16 @@ +// ========================================= +// LoadedSound +// ========================================= +use LoadedSound; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; + +// MssSound +use MssSound; +set block data XFILE_BLOCK_TEMP; +set reusable data; +set count data info::data_len; +set condition info::data_ptr never; +set condition info::initial_ptr never; +set action SetSoundData(MssSound); \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/LocalizeEntry.txt b/src/ZoneCode/Game/IW5/XAssets/LocalizeEntry.txt new file mode 100644 index 00000000..a93f61b4 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/LocalizeEntry.txt @@ -0,0 +1,8 @@ +// ========================================= +// LocalizeEntry +// ========================================= +use LocalizeEntry; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set string value; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/MapEnts.txt b/src/ZoneCode/Game/IW5/XAssets/MapEnts.txt new file mode 100644 index 00000000..e8edf78e --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/MapEnts.txt @@ -0,0 +1,18 @@ +// ========================================= +// MapEnts +// ========================================= +use MapEnts; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set count entityString numEntityChars; +set count stages stageCount; + +// MapTriggers +use MapTriggers; +set count models count; +set count hulls hullCount; +set count slabs slabCount; + +// Stage +set string Stage::name; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/Material.txt b/src/ZoneCode/Game/IW5/XAssets/Material.txt new file mode 100644 index 00000000..b0f52d34 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/Material.txt @@ -0,0 +1,23 @@ +// ========================================= +// Material +// ========================================= +use Material; +set block XFILE_BLOCK_TEMP; +set string info::name; +set name info::name; +set reusable textureTable; +set count textureTable textureCount; +set reusable constantTable; +set count constantTable constantCount; +set reusable stateBitsTable; +set count stateBitsTable stateBitsCount; + +// MaterialTextureDef +use MaterialTextureDef; +set condition u::water semantic == TS_WATER_MAP; +set reusable u::water; + +// water_t +use water_t; +set count H0 N * M; +set count wTerm N * M; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/MaterialPixelShader.txt b/src/ZoneCode/Game/IW5/XAssets/MaterialPixelShader.txt new file mode 100644 index 00000000..76a69ebc --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/MaterialPixelShader.txt @@ -0,0 +1,13 @@ +// ========================================= +// MaterialPixelShader +// ========================================= +use MaterialPixelShader; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; + +// GfxPixelShaderLoadDef +set count GfxPixelShaderLoadDef::program programSize; + +// MaterialPixelShaderProgram +set condition MaterialPixelShaderProgram::ps never; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/MaterialTechniqueSet.txt b/src/ZoneCode/Game/IW5/XAssets/MaterialTechniqueSet.txt new file mode 100644 index 00000000..1a6780c3 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/MaterialTechniqueSet.txt @@ -0,0 +1,27 @@ +// ========================================= +// MaterialTechniqueSet +// ========================================= +use MaterialTechniqueSet; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set condition remappedTechniqueSet never; +set reusable techniques; + +// MaterialTechnique +use MaterialTechnique; +set string name; +set arraysize passArray passCount; +reorder: + passArray + name; + +// MaterialPass +use MaterialPass; +set count args perPrimArgCount + perObjArgCount + stableArgCount; + +// MaterialShaderArgument +use MaterialShaderArgument; +set condition u::literalConst type == MTL_ARG_LITERAL_VERTEX_CONST +|| type == MTL_ARG_LITERAL_PIXEL_CONST; +set reusable u::literalConst; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/MaterialVertexDeclaration.txt b/src/ZoneCode/Game/IW5/XAssets/MaterialVertexDeclaration.txt new file mode 100644 index 00000000..fda4bd7a --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/MaterialVertexDeclaration.txt @@ -0,0 +1,10 @@ +// ========================================= +// MaterialVertexDeclaration +// ========================================= +use MaterialVertexDeclaration; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; + +// MaterialVertexStreamRouting +set condition MaterialVertexStreamRouting::decl never; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/MaterialVertexShader.txt b/src/ZoneCode/Game/IW5/XAssets/MaterialVertexShader.txt new file mode 100644 index 00000000..c4731d45 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/MaterialVertexShader.txt @@ -0,0 +1,13 @@ +// ========================================= +// MaterialVertexShader +// ========================================= +use MaterialVertexShader; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; + +// GfxVertexShaderLoadDef +set count GfxVertexShaderLoadDef::program programSize; + +// MaterialVertexShaderProgram +set condition MaterialVertexShaderProgram::vs never; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/MenuList.txt b/src/ZoneCode/Game/IW5/XAssets/MenuList.txt new file mode 100644 index 00000000..5db2bd62 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/MenuList.txt @@ -0,0 +1,8 @@ +// ========================================= +// MenuList +// ========================================= +use MenuList; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set count menus menuCount; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/PathData.txt b/src/ZoneCode/Game/IW5/XAssets/PathData.txt new file mode 100644 index 00000000..0d84a7e5 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/PathData.txt @@ -0,0 +1,7 @@ +// ========================================= +// PathData +// ========================================= +use PathData; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/PhysCollmap.txt b/src/ZoneCode/Game/IW5/XAssets/PhysCollmap.txt new file mode 100644 index 00000000..09f0540f --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/PhysCollmap.txt @@ -0,0 +1,27 @@ +// ========================================= +// PhysCollmap +// ========================================= +use PhysCollmap; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set count geoms count; + +// PhysGeomInfo +use PhysGeomInfo; +set count brushWrapper 1; + +// BrushWrapper +use BrushWrapper; +set reusable planes; +set count planes brush::numsides; + +// cbrushWrapper_t +use cbrushWrapper_t; +set count sides numsides; +set count baseAdjacentSide BrushWrapper::totalEdgeCount; + +// cbrushside_t +use cbrushside_t; +set reusable plane; +set count plane 1; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/PhysPreset.txt b/src/ZoneCode/Game/IW5/XAssets/PhysPreset.txt new file mode 100644 index 00000000..38346b9b --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/PhysPreset.txt @@ -0,0 +1,8 @@ +// ========================================= +// PhysPreset +// ========================================= +use PhysPreset; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set string sndAliasPrefix; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/RawFile.txt b/src/ZoneCode/Game/IW5/XAssets/RawFile.txt new file mode 100644 index 00000000..fd5cc065 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/RawFile.txt @@ -0,0 +1,10 @@ +// ========================================= +// RawFile +// ========================================= +use RawFile; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set condition data::compressedBuffer compressedLen > 0; +set count data::compressedBuffer compressedLen; +set count data::buffer len + 1; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/ScriptFile.txt b/src/ZoneCode/Game/IW5/XAssets/ScriptFile.txt new file mode 100644 index 00000000..5ec0dfb4 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/ScriptFile.txt @@ -0,0 +1,7 @@ +// ========================================= +// ScriptFile +// ========================================= +use ScriptFile; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/SndCurve.txt b/src/ZoneCode/Game/IW5/XAssets/SndCurve.txt new file mode 100644 index 00000000..7c90a72a --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/SndCurve.txt @@ -0,0 +1,7 @@ +// ========================================= +// SndCurve +// ========================================= +use SndCurve; +set block XFILE_BLOCK_TEMP; +set string filename; +set name filename; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/StringTable.txt b/src/ZoneCode/Game/IW5/XAssets/StringTable.txt new file mode 100644 index 00000000..7e818127 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/StringTable.txt @@ -0,0 +1,11 @@ +// ========================================= +// StringTable +// ========================================= +use StringTable; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set count values columnCount * rowCount; + +// StringTableCell +set string StringTableCell::string; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/StructuredDataDefSet.txt b/src/ZoneCode/Game/IW5/XAssets/StructuredDataDefSet.txt new file mode 100644 index 00000000..44c21d4e --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/StructuredDataDefSet.txt @@ -0,0 +1,27 @@ +// ========================================= +// StructuredDataDefSet +// ========================================= +use StructuredDataDefSet; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set count defs defCount; + +// StructuredDataDef +use StructuredDataDef; +set count enums enumCount; +set count structs structCount; +set count indexedArrays indexedArrayCount; +set count enumedArrays enumedArrayCount; + +// StructuredDataEnum +set count StructuredDataEnum::entries entryCount; + +// StructuredDataEnumEntry +set string StructuredDataEnumEntry::string; + +// StructuredDataStruct +set count StructuredDataStruct::properties propertyCount; + +// StructuredDataStructProperty +set string StructuredDataStructProperty::name; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/SurfaceFxTable.txt b/src/ZoneCode/Game/IW5/XAssets/SurfaceFxTable.txt new file mode 100644 index 00000000..bb8f9703 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/SurfaceFxTable.txt @@ -0,0 +1,7 @@ +// ========================================= +// SurfaceFxTable +// ========================================= +use SurfaceFxTable; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/TracerDef.txt b/src/ZoneCode/Game/IW5/XAssets/TracerDef.txt new file mode 100644 index 00000000..d51f996f --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/TracerDef.txt @@ -0,0 +1,7 @@ +// ========================================= +// TracerDef +// ========================================= +use TracerDef; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/VehicleDef.txt b/src/ZoneCode/Game/IW5/XAssets/VehicleDef.txt new file mode 100644 index 00000000..ec44c85a --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/VehicleDef.txt @@ -0,0 +1,16 @@ +// ========================================= +// VehicleDef +// ========================================= +use VehicleDef; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set string useHintString; +set string turretWeaponName; +set scriptstring trophyTags; +set string surfaceSndPrefix; + +// VehiclePhysDef +use VehiclePhysDef; +set string physPresetName; +set string accelGraphName; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/VehicleTrack.txt b/src/ZoneCode/Game/IW5/XAssets/VehicleTrack.txt new file mode 100644 index 00000000..55d00902 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/VehicleTrack.txt @@ -0,0 +1,7 @@ +// ========================================= +// VehicleTrack +// ========================================= +use VehicleTrack; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/WeaponAttachment.txt b/src/ZoneCode/Game/IW5/XAssets/WeaponAttachment.txt new file mode 100644 index 00000000..3d30b952 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/WeaponAttachment.txt @@ -0,0 +1,7 @@ +// ========================================= +// WeaponAttachment +// ========================================= +use WeaponAttachment; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt b/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt new file mode 100644 index 00000000..d55ed68f --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt @@ -0,0 +1,84 @@ +// ========================================= +// WeaponCompleteDef +// ========================================= +use WeaponCompleteDef; +set block XFILE_BLOCK_TEMP; +set string szInternalName; +set name szInternalName; +set reusable weapDef; +set string szDisplayName; +set reusable hideTags; +set scriptstring hideTags; +set count hideTags 32; +set string szXAnims; +set reusable szXAnims; +set count szXAnims 37; +set string szAltWeaponName; +set reusable accuracyGraphKnots; +set count accuracyGraphKnots[0] accuracyGraphKnotCount[0]; +set count accuracyGraphKnots[1] accuracyGraphKnotCount[1]; + +// WeaponDef +use WeaponDef; +set string szOverlayName; +set reusable gunXModel; +set count gunXModel 16; +set reusable szXAnimsRightHanded; +set string szXAnimsRightHanded; +set count szXAnimsRightHanded 37; +set reusable szXAnimsLeftHanded; +set string szXAnimsLeftHanded; +set count szXAnimsLeftHanded 37; +set string szModeName; +set reusable notetrackSoundMapKeys; +set scriptstring notetrackSoundMapKeys; +set count notetrackSoundMapKeys 16; +set reusable notetrackSoundMapValues; +set scriptstring notetrackSoundMapValues; +set count notetrackSoundMapValues 16; +set reusable notetrackRumbleMapKeys; +set scriptstring notetrackRumbleMapKeys; +set count notetrackRumbleMapKeys 16; +set reusable notetrackRumbleMapValues; +set scriptstring notetrackRumbleMapValues; +set count notetrackRumbleMapValues 16; +set reusable bounceSound; +set count bounceSound 31; +set reusable worldModel; +set count worldModel 16; +set string szAmmoName; +set string szClipName; +set string szSharedAmmoCapName; +set reusable parallelBounce; +set count parallelBounce 31; +set reusable perpendicularBounce; +set count perpendicularBounce 31; +set string accuracyGraphName0; +set string accuracyGraphName1; +set reusable originalAccuracyGraphKnots0; +set reusable originalAccuracyGraphKnots1; +set count originalAccuracyGraphKnots0 WeaponCompleteDef::accuracyGraphKnotCount[0]; +set count originalAccuracyGraphKnots1 WeaponCompleteDef::accuracyGraphKnotCount[1]; +set string szUseHintString; +set string dropHintString; +set string szScript; +set reusable locationDamageMultipliers; +set count locationDamageMultipliers 20; +set string fireRumble; +set string meleeImpactRumble; +set string turretBarrelSpinRumble; +reorder: + ... + accuracyGraphName0 + originalAccuracyGraphKnots0 + accuracyGraphName1 + originalAccuracyGraphKnots1; + +// SndAliasCustom +use SndAliasCustom; +set count name 1; +set reusable name; +set condition sound never; + +// snd_alias_list_name +set string snd_alias_list_name::soundName; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/XAnimParts.txt b/src/ZoneCode/Game/IW5/XAssets/XAnimParts.txt new file mode 100644 index 00000000..5e856218 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/XAnimParts.txt @@ -0,0 +1,83 @@ +// ========================================= +// XAnimParts +// ========================================= +use XAnimParts; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set scriptstring names; +set count names boneCount[9]; +set count notify notifyCount; +set count deltaPart 1; +set count dataByte dataByteCount; +set count dataShort dataShortCount; +set count dataInt dataIntCount; +set count randomDataShort randomDataShortCount; +set count randomDataByte randomDataByteCount; +set count randomDataInt randomDataIntCount; +set count indices::_1 indexCount; +set count indices::_2 indexCount; +set condition indices::_1 numframes < 256; +set condition indices::data never; +reorder: + name + names + notify + deltaPart + dataByte + dataShort + dataInt + randomDataShort + randomDataByte + randomDataInt + indices; + +// XAnimNotifyInfo +set scriptstring XAnimNotifyInfo::name; + +// XAnimDeltaPart +use XAnimDeltaPart; +set count trans 1; +set count quat2 1; +set count quat 1; + +// XAnimPartTrans +use XAnimPartTrans; +set condition u::frames size > 0; +set condition u::frames::indices::_1 XAnimParts::numframes < 256; +set arraysize u::frames::indices::_1 size + 1; +set arraysize u::frames::indices::_2 size + 1; +set condition u::frames::frames::_1 smallTrans; +set count u::frames::frames::_1 size + 1; +set count u::frames::frames::_2 size + 1; + +// XAnimPartTransFrames +reorder XAnimPartTransFrames: + indices + frames; + +// XAnimDeltaPartQuat2 +use XAnimDeltaPartQuat2; +set condition u::frames size > 0; +set condition u::frames::indices::_1 XAnimParts::numframes < 256; +set arraysize u::frames::indices::_1 size + 1; +set arraysize u::frames::indices::_2 size + 1; +set count u::frames::frames size + 1; + +// XAnimDeltaPartQuatDataFrames2 +reorder XAnimDeltaPartQuatDataFrames2: + indices + frames; + +// XAnimDeltaPartQuat +use XAnimDeltaPartQuat; +set condition u::frames size > 0; +set condition u::frames::indices::_1 XAnimParts::numframes < 256; +set arraysize u::frames::indices::_1 size + 1; +set arraysize u::frames::indices::_2 size + 1; +set count u::frames::frames size + 1; + +// XAnimDeltaPartQuatDataFrames +reorder XAnimDeltaPartQuatDataFrames: + indices + frames; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/XModel.txt b/src/ZoneCode/Game/IW5/XAssets/XModel.txt new file mode 100644 index 00000000..74f6b7e5 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/XModel.txt @@ -0,0 +1,72 @@ +// ========================================= +// XModel +// ========================================= +use XModel; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set scriptstring boneNames; +set reusable boneNames; +set count boneNames numBones; +set reusable parentList; +set count parentList numBones - numRootBones; +set reusable quats; +set count quats numBones - numRootBones; +set reusable trans; +set count trans numBones - numRootBones; +set reusable partClassification; +set count partClassification numBones; +set reusable baseMat; +set count baseMat numBones; +set count materialHandles numsurfs; +set count collSurfs numCollSurfs; +set count boneInfo numBones; + +// XModelLodInfo +use XModelLodInfo; +set block modelSurfs XFILE_BLOCK_TEMP; +set action modelSurfs SetModelSurfs(XModelLodInfo, XModelSurfs); +set reusable modelSurfs; +set condition surfs never; + +// XModelSurfs +use XModelSurfs; +set block XFILE_BLOCK_VIRTUAL; +set string name; +set count surfs XModelLodInfo::numsurfs; // No this is not a mistake. This is how the game does it. + +// XSurface +use XSurface; +set reusable verts0; +set block verts0 XFILE_BLOCK_VERTEX; +set count verts0 vertCount; +set reusable vertList; +set count vertList vertListCount; +set reusable triIndices; +set block triIndices XFILE_BLOCK_INDEX; +set count triIndices triCount; +reorder: + zoneHandle + vertInfo + verts0 + vertList + triIndices; + +// XSurfaceVertexInfo +use XSurfaceVertexInfo; +set reusable vertsBlend; +set count vertsBlend vertCount[0] + + 3 * vertCount[1] + + 5 * vertCount[2] + + 7 * vertCount[3]; + +// XRigidVertList +set reusable XRigidVertList::collisionTree; + +// XSurfaceCollisionTree +use XSurfaceCollisionTree; +set count nodes nodeCount; +set count leafs leafCount; + +// XModelCollSurf_s +set count XModelCollSurf_s::collTris numCollTris; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/XModelSurfs.txt b/src/ZoneCode/Game/IW5/XAssets/XModelSurfs.txt new file mode 100644 index 00000000..cfe348a9 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/XModelSurfs.txt @@ -0,0 +1,7 @@ +// ========================================= +// XModelSurfs +// ========================================= +use XModelSurfs; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/clipMap_t.txt b/src/ZoneCode/Game/IW5/XAssets/clipMap_t.txt new file mode 100644 index 00000000..f2636192 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/clipMap_t.txt @@ -0,0 +1,71 @@ +// ========================================= +// clipMap_t +// ========================================= +use clipMap_t; +set block XFILE_BLOCK_TEMP; +set string name; +set name name; +set reusable planes; +set count planes planeCount; +set count staticModelList numStaticModels; +set count materials numMaterials; +set count brushsides numBrushSides; +set count brushEdges numBrushEdges; +set count nodes numNodes; +set count leafs numLeafs; +set count leafbrushNodes leafbrushNodesCount; +set count leafbrushes numLeafBrushes; +set count leafsurfaces numLeafSurfaces; +set count verts vertCount; +set count triIndices 3 * triCount; +set count triEdgeIsWalkable ((3 * triCount + 31) / 32) * 4; +set count borders borderCount; +set count partitions partitionCount; +set count aabbTrees aabbTreeCount; +set count cmodels numSubModels; +set count brushes numBrushes; +set count brushBounds numBrushes; +set count brushContents numBrushes; +set count smodelNodes smodelNodeCount; +set count dynEntDefList[0] dynEntCount[0]; +set count dynEntDefList[1] dynEntCount[1]; +set block dynEntPoseList XFILE_BLOCK_RUNTIME; +set count dynEntPoseList[0] dynEntCount[0]; +set count dynEntPoseList[1] dynEntCount[1]; +set block dynEntClientList XFILE_BLOCK_RUNTIME; +set count dynEntClientList[0] dynEntCount[0]; +set count dynEntClientList[1] dynEntCount[1]; +set block dynEntCollList XFILE_BLOCK_RUNTIME; +set count dynEntCollList[0] dynEntCount[0]; +set count dynEntCollList[1] dynEntCount[1]; +reorder: + ... + leafs + leafbrushes + leafbrushNodes; +reorder: + ... + brushContents + smodelNodes + mapEnts; + +// ClipMaterial +set string ClipMaterial::name; + +// cNode_t +set reusable cNode_t::plane; + +// cLeafBrushNode_s +use cLeafBrushNode_s; +set condition data::leaf leafBrushCount > 0; +set reusable data::leaf::brushes; +set count data::leaf::brushes leafBrushCount; + +// CollisionPartition +use CollisionPartition; +set reusable borders; + +// cbrush_t +use cbrush_t; +set reusable sides; +set reusable baseAdjacentSide; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/menuDef_t.txt b/src/ZoneCode/Game/IW5/XAssets/menuDef_t.txt new file mode 100644 index 00000000..70db6feb --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/menuDef_t.txt @@ -0,0 +1,150 @@ +// ========================================= +// menuDef_t +// ========================================= +use menuDef_t; +set block XFILE_BLOCK_TEMP; +set string window::name; +set name window::name; +set string font; +set reusable visibleExp; +set string allowedBinding; +set string soundName; +set reusable rectXExp; +set reusable rectYExp; +set reusable rectWExp; +set reusable rectHExp; +set reusable openSoundExp; +set reusable closeSoundExp; +set count items itemCount; +set reusable expressionData; +reorder: + expressionData + window + font + onOpen + onClose + onCloseRequest + onESC + onKey + visibleExp + allowedBinding + soundName + rectXExp + rectYExp + rectWExp + rectHExp + openSoundExp + closeSoundExp + items; + +// windowDef_t +use windowDef_t; +set string name; +set string group; + +// MenuEventHandlerSet +set count MenuEventHandlerSet::eventHandlers eventHandlerCount; + +// MenuEventHandler +use MenuEventHandler; +set string eventData::unconditionalScript; +set condition eventData::unconditionalScript eventType == EVENT_UNCONDITIONAL; +set condition eventData::conditionalScript eventType == EVENT_IF; +set condition eventData::elseScript eventType == EVENT_ELSE; +set condition eventData::setLocalVarData eventType == EVENT_SET_LOCAL_VAR_BOOL + || eventType == EVENT_SET_LOCAL_VAR_INT + || eventType == EVENT_SET_LOCAL_VAR_FLOAT + || eventType == EVENT_SET_LOCAL_VAR_STRING; + +// ConditionalScript +use ConditionalScript; +set reusable eventExpression; +reorder: + eventExpression + eventHandlerSet; + +// SetLocalVarData +use SetLocalVarData; +set string localVarName; +set reusable expression; + +// Statement_s +use Statement_s; +set count entries numEntries; +set reusable supportingData; +set condition lastResult never; + +// expressionEntry +set condition expressionEntry::data::operand type == EET_OPERAND; + +// Operand +use Operand; +set reusable internals::function; +set condition internals::intVal dataType == VAL_INT; +set condition internals::floatVal dataType == VAL_FLOAT; +set condition internals::stringVal dataType == VAL_STRING; +set condition internals::function dataType == VAL_FUNCTION; + +// ExpressionString +set string ExpressionString::string; + +// itemDef_s +use itemDef_s; +set string text; +set condition parent never; +set string dvar; +set string dvarTest; +set string enableDvar; +set string localVar; +set count floatExpressions floatExpressionCount; +set reusable visibleExp; +set reusable disabledExp; +set reusable textExp; +set reusable materialExp; + +// itemDefData_t +use itemDefData_t; +set string enumDvarName; +set condition data never; +set condition listBox itemDef_s::type == 6; +set condition editField itemDef_s::type == 0 + || itemDef_s::type == 4 + || itemDef_s::type == 9 + || itemDef_s::type == 10 + || itemDef_s::type == 11 + || itemDef_s::type == 14 + || itemDef_s::type == 16 + || itemDef_s::type == 17 + || itemDef_s::type == 18 + || itemDef_s::type == 22 + || itemDef_s::type == 23; +set condition multi itemDef_s::type == 12; +set condition enumDvarName itemDef_s::type == 13; +set condition ticker itemDef_s::type == 20; +set condition scroll itemDef_s::type == 21; + +// multiDef_s +use multiDef_s; +set string dvarList; +set string dvarStr; + +// ItemFloatExpression +set reusable ItemFloatExpression::expression; + +// UIFunctionList +use UIFunctionList; +set count functions totalFunctions; +set reusable functions; // This statement makes both the array of pointers and the pointers in the array reusable. only the second one is correct however this shouldn't be a problem with vanilla fastfiles. + +// StaticDvarList +set count StaticDvarList::staticDvars numStaticDvars; + +// StaticDvar +use StaticDvar; +set condition dvar never; +set string dvarName; + +// StringList +use StringList; +set count strings totalStrings; +set string strings; \ No newline at end of file diff --git a/src/ZoneCode/Game/IW5/XAssets/snd_alias_list_t.txt b/src/ZoneCode/Game/IW5/XAssets/snd_alias_list_t.txt new file mode 100644 index 00000000..8558afc7 --- /dev/null +++ b/src/ZoneCode/Game/IW5/XAssets/snd_alias_list_t.txt @@ -0,0 +1,30 @@ +// ========================================= +// snd_alias_list_t +// ========================================= +use snd_alias_list_t; +set block XFILE_BLOCK_TEMP; +set string aliasName; +set name aliasName; +set reusable head; +set count head count; + +// snd_alias_t +use snd_alias_t; +set string aliasName; +set string subtitle; +set string secondaryAliasName; +set string chainAliasName; +set string mixerGroup; +set reusable soundFile; +set reusable speakerMap; + +// SoundFile +set condition SoundFile::u::loadSnd type == SAT_LOADED; + +// SpeakerMap +set string SpeakerMap::name; + +// StreamedSound +use StreamedSound; +set string dir; +set string name; \ No newline at end of file diff --git a/src/ZoneCommon/Game/IW5/GameAssetPoolIW5.cpp b/src/ZoneCommon/Game/IW5/GameAssetPoolIW5.cpp new file mode 100644 index 00000000..2b9c6b9e --- /dev/null +++ b/src/ZoneCommon/Game/IW5/GameAssetPoolIW5.cpp @@ -0,0 +1,422 @@ +#include "GameAssetPoolIW5.h" + +#include +#include + +#include "Pool/AssetPoolStatic.h" +#include "Pool/AssetPoolDynamic.h" + +using namespace IW5; + +const char* GameAssetPoolIW5::ASSET_TYPE_NAMES[] +{ + "physpreset", + "physcollmap", + "xanim", + "xmodelsurfs", + "xmodel", + "material", + "pixelshader", + "vertexshader", + "vertexdecl", + "techniqueset", + "image", + "sound", + "soundcurve", + "loadedsound", + "clipmap", + "comworld", + "glassworld", + "pathdata", + "vehicletrack", + "mapents", + "fxworld", + "gfxworld", + "lightdef", + "uimap", + "font", + "menulist", + "menu", + "localize", + "attachment", + "weapon", + "fx", + "impactfx", + "surfacefx", + "aitype", + "mptype", + "character", + "xmodelalias", + "rawfile", + "scriptfile", + "stringtable", + "leaderboard", + "structureddatadef", + "tracer", + "vehicle", + "addonmapents" +}; + +/* + Asset Pool Table + Useful for macro generation via regex-replace for example + + #assetType, #typeName, #unionEntry, #poolName + ASSET_TYPE_PHYSPRESET, PhysPreset, physPreset, m_phys_preset + ASSET_TYPE_PHYSCOLLMAP, PhysCollmap, physCollmap, m_phys_collmap + ASSET_TYPE_XANIMPARTS, XAnimParts, parts, m_xanim_parts + ASSET_TYPE_XMODEL_SURFS, XModelSurfs, modelSurfs, m_xmodel_surfs + ASSET_TYPE_XMODEL, XModel, model, m_xmodel + ASSET_TYPE_MATERIAL, Material, material, m_material + ASSET_TYPE_PIXELSHADER, MaterialPixelShader, pixelShader, m_material_pixel_shader + ASSET_TYPE_VERTEXSHADER, MaterialVertexShader, vertexShader, m_material_vertex_shader + ASSET_TYPE_VERTEXDECL, MaterialVertexDeclaration, vertexDecl, m_material_vertex_decl + ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet, techniqueSet, m_technique_set + ASSET_TYPE_IMAGE, GfxImage, image, m_image + ASSET_TYPE_SOUND, snd_alias_list_t, sound, m_sound + ASSET_TYPE_SOUND_CURVE, SndCurve, sndCurve, m_sound_curve + ASSET_TYPE_LOADED_SOUND, LoadedSound, loadSnd, m_loaded_sound + ASSET_TYPE_CLIPMAP, clipMap_t, clipMap, m_clip_map + ASSET_TYPE_COMWORLD, ComWorld, comWorld, m_com_world + ASSET_TYPE_GLASSWORLD, GlassWorld, glassWorld, m_glass_world + ASSET_TYPE_PATHDATA, PathData, pathData, m_path_data + ASSET_TYPE_VEHICLE_TRACK, VehicleTrack, vehicleTrack, m_vehicle_track + ASSET_TYPE_MAP_ENTS, MapEnts, mapEnts, m_map_ents + ASSET_TYPE_FXWORLD, FxWorld, fxWorld, m_fx_world + ASSET_TYPE_GFXWORLD, GfxWorld, gfxWorld, m_gfx_world + ASSET_TYPE_LIGHT_DEF, GfxLightDef, lightDef, m_gfx_light_def + ASSET_TYPE_FONT, Font_s, font, m_font + ASSET_TYPE_MENULIST, MenuList, menuList, m_menu_list + ASSET_TYPE_MENU, menuDef_t, menu, m_menu_def + ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry, localize, m_localize + ASSET_TYPE_ATTACHMENT, WeaponAttachment, attachment, m_attachment + ASSET_TYPE_WEAPON, WeaponCompleteDef, weapon, m_weapon + ASSET_TYPE_FX, FxEffectDef, fx, m_fx + ASSET_TYPE_IMPACT_FX, FxImpactTable, impactFx, m_fx_impact_table + ASSET_TYPE_SURFACE_FX, SurfaceFxTable, surfaceFx, m_surface_fx_table + ASSET_TYPE_RAWFILE, RawFile, rawfile, m_raw_file + ASSET_TYPE_SCRIPTFILE, ScriptFile, scriptfile, m_script_file + ASSET_TYPE_STRINGTABLE, StringTable, stringTable, m_string_table + ASSET_TYPE_LEADERBOARD, LeaderboardDef, leaderboardDef, m_leaderboard + ASSET_TYPE_STRUCTURED_DATA_DEF, StructuredDataDefSet, structuredDataDefSet, m_structed_data_def_set + ASSET_TYPE_TRACER, TracerDef, tracerDef, m_tracer + ASSET_TYPE_VEHICLE, VehicleDef, vehDef, m_vehicle + ASSET_TYPE_ADDON_MAP_ENTS, AddonMapEnts, addonMapEnts, m_addon_map_ents + */ + +GameAssetPoolIW5::GameAssetPoolIW5(Zone* zone, const int priority) + : ZoneAssetPools(zone), + m_priority(priority) +{ + assert(std::extent::value == ASSET_TYPE_COUNT); + + m_phys_preset = nullptr; + m_phys_collmap = nullptr; + m_xanim_parts = nullptr; + m_xmodel_surfs = nullptr; + m_xmodel = nullptr; + m_material = nullptr; + m_material_pixel_shader = nullptr; + m_material_vertex_shader = nullptr; + m_material_vertex_decl = nullptr; + m_technique_set = nullptr; + m_image = nullptr; + m_sound = nullptr; + m_sound_curve = nullptr; + m_loaded_sound = nullptr; + m_clip_map = nullptr; + m_com_world = nullptr; + m_glass_world = nullptr; + m_path_data = nullptr; + m_vehicle_track = nullptr; + m_map_ents = nullptr; + m_fx_world = nullptr; + m_gfx_world = nullptr; + m_gfx_light_def = nullptr; + m_font = nullptr; + m_menu_list = nullptr; + m_menu_def = nullptr; + m_localize = nullptr; + m_attachment = nullptr; + m_weapon = nullptr; + m_fx = nullptr; + m_fx_impact_table = nullptr; + m_surface_fx_table = nullptr; + m_raw_file = nullptr; + m_script_file = nullptr; + m_string_table = nullptr; + m_leaderboard = nullptr; + m_structed_data_def_set = nullptr; + m_tracer = nullptr; + m_vehicle = nullptr; + m_addon_map_ents = nullptr; +} + +void GameAssetPoolIW5::InitPoolStatic(const asset_type_t type, const size_t capacity) +{ +#define CASE_INIT_POOL_STATIC(assetType, poolName, poolType) \ + case assetType: \ + { \ + if((poolName) == nullptr && capacity > 0) \ + { \ + (poolName) = std::make_unique>(capacity, m_priority, (assetType)); \ + } \ + break; \ + } + + switch (type) + { + CASE_INIT_POOL_STATIC(ASSET_TYPE_PHYSPRESET, m_phys_preset, PhysPreset); + CASE_INIT_POOL_STATIC(ASSET_TYPE_PHYSCOLLMAP, m_phys_collmap, PhysCollmap); + CASE_INIT_POOL_STATIC(ASSET_TYPE_XANIMPARTS, m_xanim_parts, XAnimParts); + CASE_INIT_POOL_STATIC(ASSET_TYPE_XMODEL_SURFS, m_xmodel_surfs, XModelSurfs); + CASE_INIT_POOL_STATIC(ASSET_TYPE_XMODEL, m_xmodel, XModel); + CASE_INIT_POOL_STATIC(ASSET_TYPE_MATERIAL, m_material, Material); + CASE_INIT_POOL_STATIC(ASSET_TYPE_PIXELSHADER, m_material_pixel_shader, MaterialPixelShader); + CASE_INIT_POOL_STATIC(ASSET_TYPE_VERTEXSHADER, m_material_vertex_shader, MaterialVertexShader); + CASE_INIT_POOL_STATIC(ASSET_TYPE_VERTEXDECL, m_material_vertex_decl, MaterialVertexDeclaration); + CASE_INIT_POOL_STATIC(ASSET_TYPE_TECHNIQUE_SET, m_technique_set, MaterialTechniqueSet); + CASE_INIT_POOL_STATIC(ASSET_TYPE_IMAGE, m_image, GfxImage); + CASE_INIT_POOL_STATIC(ASSET_TYPE_SOUND, m_sound, snd_alias_list_t); + CASE_INIT_POOL_STATIC(ASSET_TYPE_SOUND_CURVE, m_sound_curve, SndCurve); + CASE_INIT_POOL_STATIC(ASSET_TYPE_LOADED_SOUND, m_loaded_sound, LoadedSound); + CASE_INIT_POOL_STATIC(ASSET_TYPE_CLIPMAP, m_clip_map, clipMap_t); + CASE_INIT_POOL_STATIC(ASSET_TYPE_COMWORLD, m_com_world, ComWorld); + CASE_INIT_POOL_STATIC(ASSET_TYPE_GLASSWORLD, m_glass_world, GlassWorld); + CASE_INIT_POOL_STATIC(ASSET_TYPE_PATHDATA, m_path_data, PathData); + CASE_INIT_POOL_STATIC(ASSET_TYPE_VEHICLE_TRACK, m_vehicle_track, VehicleTrack); + CASE_INIT_POOL_STATIC(ASSET_TYPE_MAP_ENTS, m_map_ents, MapEnts); + CASE_INIT_POOL_STATIC(ASSET_TYPE_FXWORLD, m_fx_world, FxWorld); + CASE_INIT_POOL_STATIC(ASSET_TYPE_GFXWORLD, m_gfx_world, GfxWorld); + CASE_INIT_POOL_STATIC(ASSET_TYPE_LIGHT_DEF, m_gfx_light_def, GfxLightDef); + CASE_INIT_POOL_STATIC(ASSET_TYPE_FONT, m_font, Font_s); + CASE_INIT_POOL_STATIC(ASSET_TYPE_MENULIST, m_menu_list, MenuList); + CASE_INIT_POOL_STATIC(ASSET_TYPE_MENU, m_menu_def, menuDef_t); + CASE_INIT_POOL_STATIC(ASSET_TYPE_LOCALIZE_ENTRY, m_localize, LocalizeEntry); + CASE_INIT_POOL_STATIC(ASSET_TYPE_ATTACHMENT, m_attachment, WeaponAttachment); + CASE_INIT_POOL_STATIC(ASSET_TYPE_WEAPON, m_weapon, WeaponCompleteDef); + CASE_INIT_POOL_STATIC(ASSET_TYPE_FX, m_fx, FxEffectDef); + CASE_INIT_POOL_STATIC(ASSET_TYPE_IMPACT_FX, m_fx_impact_table, FxImpactTable); + CASE_INIT_POOL_STATIC(ASSET_TYPE_SURFACE_FX, m_surface_fx_table, SurfaceFxTable); + CASE_INIT_POOL_STATIC(ASSET_TYPE_RAWFILE, m_raw_file, RawFile); + CASE_INIT_POOL_STATIC(ASSET_TYPE_SCRIPTFILE, m_script_file, ScriptFile); + CASE_INIT_POOL_STATIC(ASSET_TYPE_STRINGTABLE, m_string_table, StringTable); + CASE_INIT_POOL_STATIC(ASSET_TYPE_LEADERBOARD, m_leaderboard, LeaderboardDef); + CASE_INIT_POOL_STATIC(ASSET_TYPE_STRUCTURED_DATA_DEF, m_structed_data_def_set, StructuredDataDefSet); + CASE_INIT_POOL_STATIC(ASSET_TYPE_TRACER, m_tracer, TracerDef); + CASE_INIT_POOL_STATIC(ASSET_TYPE_VEHICLE, m_vehicle, VehicleDef); + CASE_INIT_POOL_STATIC(ASSET_TYPE_ADDON_MAP_ENTS, m_addon_map_ents, AddonMapEnts); + + default: + assert(type >= 0 && type < ASSET_TYPE_COUNT); + break; + } + +#undef CASE_INIT_POOL_STATIC +} + +void GameAssetPoolIW5::InitPoolDynamic(const asset_type_t type) +{ +#define CASE_INIT_POOL_DYNAMIC(assetType, poolName, poolType) \ + case assetType: \ + { \ + if((poolName) == nullptr) \ + { \ + (poolName) = std::make_unique>(m_priority, (assetType)); \ + } \ + break; \ + } + + switch (type) + { + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_PHYSPRESET, m_phys_preset, PhysPreset); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_PHYSCOLLMAP, m_phys_collmap, PhysCollmap); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_XANIMPARTS, m_xanim_parts, XAnimParts); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_XMODEL_SURFS, m_xmodel_surfs, XModelSurfs); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_XMODEL, m_xmodel, XModel); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_MATERIAL, m_material, Material); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_PIXELSHADER, m_material_pixel_shader, MaterialPixelShader); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_VERTEXSHADER, m_material_vertex_shader, MaterialVertexShader); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_VERTEXDECL, m_material_vertex_decl, MaterialVertexDeclaration); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_TECHNIQUE_SET, m_technique_set, MaterialTechniqueSet); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_IMAGE, m_image, GfxImage); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_SOUND, m_sound, snd_alias_list_t); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_SOUND_CURVE, m_sound_curve, SndCurve); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_LOADED_SOUND, m_loaded_sound, LoadedSound); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_CLIPMAP, m_clip_map, clipMap_t); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_COMWORLD, m_com_world, ComWorld); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_GLASSWORLD, m_glass_world, GlassWorld); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_PATHDATA, m_path_data, PathData); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_VEHICLE_TRACK, m_vehicle_track, VehicleTrack); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_MAP_ENTS, m_map_ents, MapEnts); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_FXWORLD, m_fx_world, FxWorld); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_GFXWORLD, m_gfx_world, GfxWorld); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_LIGHT_DEF, m_gfx_light_def, GfxLightDef); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_FONT, m_font, Font_s); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_MENULIST, m_menu_list, MenuList); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_MENU, m_menu_def, menuDef_t); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_LOCALIZE_ENTRY, m_localize, LocalizeEntry); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_ATTACHMENT, m_attachment, WeaponAttachment); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_WEAPON, m_weapon, WeaponCompleteDef); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_FX, m_fx, FxEffectDef); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_IMPACT_FX, m_fx_impact_table, FxImpactTable); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_SURFACE_FX, m_surface_fx_table, SurfaceFxTable); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_RAWFILE, m_raw_file, RawFile); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_SCRIPTFILE, m_script_file, ScriptFile); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_STRINGTABLE, m_string_table, StringTable); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_LEADERBOARD, m_leaderboard, LeaderboardDef); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_STRUCTURED_DATA_DEF, m_structed_data_def_set, StructuredDataDefSet); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_TRACER, m_tracer, TracerDef); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_VEHICLE, m_vehicle, VehicleDef); + CASE_INIT_POOL_DYNAMIC(ASSET_TYPE_ADDON_MAP_ENTS, m_addon_map_ents, AddonMapEnts); + + default: + assert(type >= 0 && type < ASSET_TYPE_COUNT); + break; + } + +#undef CASE_INIT_POOL_STATIC +} + +XAssetInfoGeneric* GameAssetPoolIW5::AddAssetToPool(asset_type_t type, std::string name, void* asset, std::vector dependencies, std::vector usedScriptStrings, Zone* zone) +{ + XAsset xAsset{}; + + xAsset.type = static_cast(type); + xAsset.header.data = asset; + +#define CASE_ADD_TO_POOL(assetType, poolName, headerName) \ + case assetType: \ + { \ + assert((poolName) != nullptr); \ + return (poolName)->AddAsset(std::move(name), xAsset.header.headerName, zone, std::move(dependencies), std::move(usedScriptStrings)); \ + } + + switch (xAsset.type) + { + CASE_ADD_TO_POOL(ASSET_TYPE_PHYSPRESET, m_phys_preset, physPreset); + CASE_ADD_TO_POOL(ASSET_TYPE_PHYSCOLLMAP, m_phys_collmap, physCollmap); + CASE_ADD_TO_POOL(ASSET_TYPE_XANIMPARTS, m_xanim_parts, parts); + CASE_ADD_TO_POOL(ASSET_TYPE_XMODEL_SURFS, m_xmodel_surfs, modelSurfs); + CASE_ADD_TO_POOL(ASSET_TYPE_XMODEL, m_xmodel, model); + CASE_ADD_TO_POOL(ASSET_TYPE_MATERIAL, m_material, material); + CASE_ADD_TO_POOL(ASSET_TYPE_PIXELSHADER, m_material_pixel_shader, pixelShader); + CASE_ADD_TO_POOL(ASSET_TYPE_VERTEXSHADER, m_material_vertex_shader, vertexShader); + CASE_ADD_TO_POOL(ASSET_TYPE_VERTEXDECL, m_material_vertex_decl, vertexDecl); + CASE_ADD_TO_POOL(ASSET_TYPE_TECHNIQUE_SET, m_technique_set, techniqueSet); + CASE_ADD_TO_POOL(ASSET_TYPE_IMAGE, m_image, image); + CASE_ADD_TO_POOL(ASSET_TYPE_SOUND, m_sound, sound); + CASE_ADD_TO_POOL(ASSET_TYPE_SOUND_CURVE, m_sound_curve, sndCurve); + CASE_ADD_TO_POOL(ASSET_TYPE_LOADED_SOUND, m_loaded_sound, loadSnd); + CASE_ADD_TO_POOL(ASSET_TYPE_CLIPMAP, m_clip_map, clipMap); + CASE_ADD_TO_POOL(ASSET_TYPE_COMWORLD, m_com_world, comWorld); + CASE_ADD_TO_POOL(ASSET_TYPE_GLASSWORLD, m_glass_world, glassWorld); + CASE_ADD_TO_POOL(ASSET_TYPE_PATHDATA, m_path_data, pathData); + CASE_ADD_TO_POOL(ASSET_TYPE_VEHICLE_TRACK, m_vehicle_track, vehicleTrack); + CASE_ADD_TO_POOL(ASSET_TYPE_MAP_ENTS, m_map_ents, mapEnts); + CASE_ADD_TO_POOL(ASSET_TYPE_FXWORLD, m_fx_world, fxWorld); + CASE_ADD_TO_POOL(ASSET_TYPE_GFXWORLD, m_gfx_world, gfxWorld); + CASE_ADD_TO_POOL(ASSET_TYPE_LIGHT_DEF, m_gfx_light_def, lightDef); + CASE_ADD_TO_POOL(ASSET_TYPE_FONT, m_font, font); + CASE_ADD_TO_POOL(ASSET_TYPE_MENULIST, m_menu_list, menuList); + CASE_ADD_TO_POOL(ASSET_TYPE_MENU, m_menu_def, menu); + CASE_ADD_TO_POOL(ASSET_TYPE_LOCALIZE_ENTRY, m_localize, localize); + CASE_ADD_TO_POOL(ASSET_TYPE_ATTACHMENT, m_attachment, attachment); + CASE_ADD_TO_POOL(ASSET_TYPE_WEAPON, m_weapon, weapon); + CASE_ADD_TO_POOL(ASSET_TYPE_FX, m_fx, fx); + CASE_ADD_TO_POOL(ASSET_TYPE_IMPACT_FX, m_fx_impact_table, impactFx); + CASE_ADD_TO_POOL(ASSET_TYPE_SURFACE_FX, m_surface_fx_table, surfaceFx); + CASE_ADD_TO_POOL(ASSET_TYPE_RAWFILE, m_raw_file, rawfile); + CASE_ADD_TO_POOL(ASSET_TYPE_SCRIPTFILE, m_script_file, scriptfile); + CASE_ADD_TO_POOL(ASSET_TYPE_STRINGTABLE, m_string_table, stringTable); + CASE_ADD_TO_POOL(ASSET_TYPE_LEADERBOARD, m_leaderboard, leaderboardDef); + CASE_ADD_TO_POOL(ASSET_TYPE_STRUCTURED_DATA_DEF, m_structed_data_def_set, structuredDataDefSet); + CASE_ADD_TO_POOL(ASSET_TYPE_TRACER, m_tracer, tracerDef); + CASE_ADD_TO_POOL(ASSET_TYPE_VEHICLE, m_vehicle, vehDef); + CASE_ADD_TO_POOL(ASSET_TYPE_ADDON_MAP_ENTS, m_addon_map_ents, addonMapEnts); + + default: + assert(false); + break; + } + + return nullptr; + +#undef CASE_ADD_TO_POOL +} + +XAssetInfoGeneric* GameAssetPoolIW5::GetAsset(const asset_type_t type, std::string name) const +{ +#define CASE_GET_ASSET(assetType, poolName) \ + case assetType: \ + { \ + if((poolName) != nullptr) \ + return (poolName)->GetAsset(std::move(name)); \ + break; \ + } + + switch (type) + { + CASE_GET_ASSET(ASSET_TYPE_PHYSPRESET, m_phys_preset); + CASE_GET_ASSET(ASSET_TYPE_PHYSCOLLMAP, m_phys_collmap); + CASE_GET_ASSET(ASSET_TYPE_XANIMPARTS, m_xanim_parts); + CASE_GET_ASSET(ASSET_TYPE_XMODEL_SURFS, m_xmodel_surfs); + CASE_GET_ASSET(ASSET_TYPE_XMODEL, m_xmodel); + CASE_GET_ASSET(ASSET_TYPE_MATERIAL, m_material); + CASE_GET_ASSET(ASSET_TYPE_PIXELSHADER, m_material_pixel_shader); + CASE_GET_ASSET(ASSET_TYPE_VERTEXSHADER, m_material_vertex_shader); + CASE_GET_ASSET(ASSET_TYPE_VERTEXDECL, m_material_vertex_decl); + CASE_GET_ASSET(ASSET_TYPE_TECHNIQUE_SET, m_technique_set); + CASE_GET_ASSET(ASSET_TYPE_IMAGE, m_image); + CASE_GET_ASSET(ASSET_TYPE_SOUND, m_sound); + CASE_GET_ASSET(ASSET_TYPE_SOUND_CURVE, m_sound_curve); + CASE_GET_ASSET(ASSET_TYPE_LOADED_SOUND, m_loaded_sound); + CASE_GET_ASSET(ASSET_TYPE_CLIPMAP, m_clip_map); + CASE_GET_ASSET(ASSET_TYPE_COMWORLD, m_com_world); + CASE_GET_ASSET(ASSET_TYPE_GLASSWORLD, m_glass_world); + CASE_GET_ASSET(ASSET_TYPE_PATHDATA, m_path_data); + CASE_GET_ASSET(ASSET_TYPE_VEHICLE_TRACK, m_vehicle_track); + CASE_GET_ASSET(ASSET_TYPE_MAP_ENTS, m_map_ents); + CASE_GET_ASSET(ASSET_TYPE_FXWORLD, m_fx_world); + CASE_GET_ASSET(ASSET_TYPE_GFXWORLD, m_gfx_world); + CASE_GET_ASSET(ASSET_TYPE_LIGHT_DEF, m_gfx_light_def); + CASE_GET_ASSET(ASSET_TYPE_FONT, m_font); + CASE_GET_ASSET(ASSET_TYPE_MENULIST, m_menu_list); + CASE_GET_ASSET(ASSET_TYPE_MENU, m_menu_def); + CASE_GET_ASSET(ASSET_TYPE_LOCALIZE_ENTRY, m_localize); + CASE_GET_ASSET(ASSET_TYPE_ATTACHMENT, m_attachment); + CASE_GET_ASSET(ASSET_TYPE_WEAPON, m_weapon); + CASE_GET_ASSET(ASSET_TYPE_FX, m_fx); + CASE_GET_ASSET(ASSET_TYPE_IMPACT_FX, m_fx_impact_table); + CASE_GET_ASSET(ASSET_TYPE_SURFACE_FX, m_surface_fx_table); + CASE_GET_ASSET(ASSET_TYPE_RAWFILE, m_raw_file); + CASE_GET_ASSET(ASSET_TYPE_SCRIPTFILE, m_script_file); + CASE_GET_ASSET(ASSET_TYPE_STRINGTABLE, m_string_table); + CASE_GET_ASSET(ASSET_TYPE_LEADERBOARD, m_leaderboard); + CASE_GET_ASSET(ASSET_TYPE_STRUCTURED_DATA_DEF, m_structed_data_def_set); + CASE_GET_ASSET(ASSET_TYPE_TRACER, m_tracer); + CASE_GET_ASSET(ASSET_TYPE_VEHICLE, m_vehicle); + CASE_GET_ASSET(ASSET_TYPE_ADDON_MAP_ENTS, m_addon_map_ents); + + default: + assert(false); + break; + } + + return nullptr; + +#undef CASE_GET_ASSET +} + +const char* GameAssetPoolIW5::AssetTypeNameByType(asset_type_t assetType) +{ + if (assetType >= 0 && assetType < static_cast(std::extent::value)) + return ASSET_TYPE_NAMES[assetType]; + + return ASSET_TYPE_INVALID; +} + +const char* GameAssetPoolIW5::GetAssetTypeName(const asset_type_t assetType) const +{ + return AssetTypeNameByType(assetType); +} diff --git a/src/ZoneCommon/Game/IW5/GameAssetPoolIW5.h b/src/ZoneCommon/Game/IW5/GameAssetPoolIW5.h new file mode 100644 index 00000000..6f76e806 --- /dev/null +++ b/src/ZoneCommon/Game/IW5/GameAssetPoolIW5.h @@ -0,0 +1,70 @@ +#pragma once + +#include + +#include "Pool/ZoneAssetPools.h" +#include "Pool/AssetPool.h" +#include "Game/IW5/IW5.h" + +class GameAssetPoolIW5 final : public ZoneAssetPools +{ + int m_priority; + + static constexpr const char* ASSET_TYPE_INVALID = "invalid_asset_type"; + static const char* ASSET_TYPE_NAMES[]; + +protected: + XAssetInfoGeneric* AddAssetToPool(asset_type_t type, std::string name, void* asset, std::vector dependencies, std::vector usedScriptStrings, Zone* zone) override; + +public: + std::unique_ptr> m_phys_preset; + std::unique_ptr> m_phys_collmap; + std::unique_ptr> m_xanim_parts; + std::unique_ptr> m_xmodel_surfs; + std::unique_ptr> m_xmodel; + std::unique_ptr> m_material; + std::unique_ptr> m_material_pixel_shader; + std::unique_ptr> m_material_vertex_shader; + std::unique_ptr> m_material_vertex_decl; + std::unique_ptr> m_technique_set; + std::unique_ptr> m_image; + std::unique_ptr> m_sound; + std::unique_ptr> m_sound_curve; + std::unique_ptr> m_loaded_sound; + std::unique_ptr> m_clip_map; + std::unique_ptr> m_com_world; + std::unique_ptr> m_glass_world; + std::unique_ptr> m_path_data; + std::unique_ptr> m_vehicle_track; + std::unique_ptr> m_map_ents; + std::unique_ptr> m_fx_world; + std::unique_ptr> m_gfx_world; + std::unique_ptr> m_gfx_light_def; + std::unique_ptr> m_font; + std::unique_ptr> m_menu_list; + std::unique_ptr> m_menu_def; + std::unique_ptr> m_localize; + std::unique_ptr> m_attachment; + std::unique_ptr> m_weapon; + std::unique_ptr> m_fx; + std::unique_ptr> m_fx_impact_table; + std::unique_ptr> m_surface_fx_table; + std::unique_ptr> m_raw_file; + std::unique_ptr> m_script_file; + std::unique_ptr> m_string_table; + std::unique_ptr> m_leaderboard; + std::unique_ptr> m_structed_data_def_set; + std::unique_ptr> m_tracer; + std::unique_ptr> m_vehicle; + std::unique_ptr> m_addon_map_ents; + + GameAssetPoolIW5(Zone* zone, int priority); + ~GameAssetPoolIW5() override = default; + + void InitPoolStatic(asset_type_t type, size_t capacity) override; + void InitPoolDynamic(asset_type_t type) override; + + XAssetInfoGeneric* GetAsset(asset_type_t type, std::string name) const override; + static const char* AssetTypeNameByType(asset_type_t assetType); + const char* GetAssetTypeName(asset_type_t assetType) const override; +}; diff --git a/src/ZoneCommon/Game/IW5/ZoneConstantsIW5.h b/src/ZoneCommon/Game/IW5/ZoneConstantsIW5.h new file mode 100644 index 00000000..a62fe2c5 --- /dev/null +++ b/src/ZoneCommon/Game/IW5/ZoneConstantsIW5.h @@ -0,0 +1,69 @@ +#pragma once +#include +#include + +#include "Zone/ZoneTypes.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class ZoneConstants final + { + ZoneConstants() = default; + + public: + static constexpr const char* MAGIC_SIGNED_INFINITY_WARD = "IWff0100"; + static constexpr const char* MAGIC_SIGNED_OAT = "ABff0100"; + static constexpr const char* MAGIC_UNSIGNED = "IWffu100"; + static constexpr int ZONE_VERSION = 1; + + static_assert(std::char_traits::length(MAGIC_SIGNED_INFINITY_WARD) == sizeof(ZoneHeader::m_magic)); + static_assert(std::char_traits::length(MAGIC_SIGNED_OAT) == sizeof(ZoneHeader::m_magic)); + static_assert(std::char_traits::length(MAGIC_UNSIGNED) == sizeof(ZoneHeader::m_magic)); + + static constexpr const char* MAGIC_AUTH_HEADER = "IWffs100"; + inline static const uint8_t RSA_PUBLIC_KEY_INFINITY_WARD[] + { + 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, + 0x00, 0xA5, 0x86, 0xCC, 0x18, 0xA9, 0x12, 0x17, + 0x4F, 0x3A, 0xC9, 0x0C, 0xD2, 0x38, 0x5D, 0xDB, + 0x67, 0x62, 0xA4, 0xE3, 0xD4, 0x42, 0x05, 0x8A, + 0x57, 0x0C, 0x31, 0x4E, 0x19, 0xE4, 0xBA, 0x89, + 0x73, 0x13, 0xDB, 0x72, 0x25, 0x63, 0xB1, 0x2F, + 0xD7, 0xF1, 0x08, 0x48, 0x34, 0x06, 0xD7, 0x84, + 0x5F, 0xC8, 0xCF, 0x2F, 0xB6, 0xA3, 0x5A, 0x8F, + 0x7E, 0xAA, 0x9D, 0x51, 0xE7, 0x0F, 0xB9, 0x07, + 0xB7, 0x30, 0x91, 0x04, 0x39, 0x9C, 0xDC, 0x1C, + 0xF1, 0x16, 0xCB, 0x96, 0x10, 0xEB, 0x38, 0xB1, + 0x3B, 0xBA, 0x42, 0xE3, 0xE2, 0x78, 0xBD, 0x77, + 0x82, 0x1A, 0x2B, 0x54, 0x27, 0x0A, 0xF7, 0x66, + 0x06, 0xAD, 0x46, 0x39, 0xC0, 0xEB, 0xB5, 0xC2, + 0x27, 0xDD, 0x2C, 0x08, 0x62, 0x2C, 0x0B, 0xC4, + 0x00, 0x0D, 0xCB, 0xAD, 0x22, 0x67, 0x01, 0xA6, + 0x92, 0x9C, 0x00, 0xAF, 0x9D, 0x55, 0xCC, 0x68, + 0xEC, 0x39, 0x49, 0x85, 0x7E, 0x2C, 0x98, 0xCF, + 0x4C, 0x12, 0x8D, 0xED, 0xC7, 0x1D, 0x21, 0x54, + 0x9C, 0x2F, 0xC9, 0x54, 0x36, 0x08, 0xA9, 0x67, + 0xEE, 0x91, 0xE6, 0xD9, 0xB1, 0xFA, 0xA9, 0x2B, + 0x88, 0xAD, 0x2A, 0xD0, 0xAA, 0x28, 0xF9, 0x47, + 0xA6, 0x0F, 0xCF, 0x55, 0x4C, 0x9B, 0x26, 0x41, + 0x89, 0x76, 0x11, 0xFD, 0x1B, 0x83, 0xE4, 0xE8, + 0x8E, 0x7E, 0xB4, 0x03, 0xA3, 0x29, 0xDD, 0x4F, + 0xAC, 0x99, 0xBE, 0x7C, 0xD3, 0xFD, 0x14, 0x28, + 0x1C, 0x59, 0x69, 0xE0, 0x79, 0x5F, 0x4B, 0xDA, + 0x6B, 0xAB, 0x48, 0x4E, 0x28, 0x39, 0x84, 0xC6, + 0x2B, 0xC6, 0x20, 0x05, 0xDB, 0x05, 0x21, 0xC3, + 0xE1, 0xD4, 0x20, 0x28, 0xDD, 0x3A, 0x4D, 0x51, + 0xE7, 0x49, 0x8A, 0x49, 0xEF, 0xF5, 0xDA, 0xDA, + 0x7D, 0x5D, 0xA8, 0x0B, 0xA1, 0x77, 0xCD, 0x62, + 0x7D, 0x9D, 0x40, 0x26, 0x44, 0x4B, 0x3B, 0x0A, + 0x89, 0x02, 0x03, 0x01, 0x00, 0x01 + }; + + static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000; + static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256; + + static constexpr int OFFSET_BLOCK_BIT_COUNT = 4; + static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL; + }; +} diff --git a/src/ZoneLoading/Game/IW5/ContentLoaderIW5.cpp b/src/ZoneLoading/Game/IW5/ContentLoaderIW5.cpp new file mode 100644 index 00000000..f0b2ab2e --- /dev/null +++ b/src/ZoneLoading/Game/IW5/ContentLoaderIW5.cpp @@ -0,0 +1,203 @@ +#include "ContentLoaderIW5.h" +#include "Game/IW5/IW5.h" +#include "Loading/Exception/UnsupportedAssetTypeException.h" + +#include + +#include "Game/IW5/XAssets/addonmapents/addonmapents_load_db.h" +#include "Game/IW5/XAssets/clipmap_t/clipmap_t_load_db.h" +#include "Game/IW5/XAssets/comworld/comworld_load_db.h" +#include "Game/IW5/XAssets/font_s/font_s_load_db.h" +#include "Game/IW5/XAssets/fxeffectdef/fxeffectdef_load_db.h" +#include "Game/IW5/XAssets/fximpacttable/fximpacttable_load_db.h" +#include "Game/IW5/XAssets/fxworld/fxworld_load_db.h" +#include "Game/IW5/XAssets/gfximage/gfximage_load_db.h" +#include "Game/IW5/XAssets/gfxlightdef/gfxlightdef_load_db.h" +#include "Game/IW5/XAssets/gfxworld/gfxworld_load_db.h" +#include "Game/IW5/XAssets/glassworld/glassworld_load_db.h" +#include "Game/IW5/XAssets/leaderboarddef/leaderboarddef_load_db.h" +#include "Game/IW5/XAssets/loadedsound/loadedsound_load_db.h" +#include "Game/IW5/XAssets/localizeentry/localizeentry_load_db.h" +#include "Game/IW5/XAssets/mapents/mapents_load_db.h" +#include "Game/IW5/XAssets/material/material_load_db.h" +#include "Game/IW5/XAssets/materialpixelshader/materialpixelshader_load_db.h" +#include "Game/IW5/XAssets/materialtechniqueset/materialtechniqueset_load_db.h" +#include "Game/IW5/XAssets/materialvertexdeclaration/materialvertexdeclaration_load_db.h" +#include "Game/IW5/XAssets/materialvertexshader/materialvertexshader_load_db.h" +#include "Game/IW5/XAssets/menudef_t/menudef_t_load_db.h" +#include "Game/IW5/XAssets/menulist/menulist_load_db.h" +#include "Game/IW5/XAssets/pathdata/pathdata_load_db.h" +#include "Game/IW5/XAssets/physcollmap/physcollmap_load_db.h" +#include "Game/IW5/XAssets/physpreset/physpreset_load_db.h" +#include "Game/IW5/XAssets/rawfile/rawfile_load_db.h" +#include "Game/IW5/XAssets/scriptfile/scriptfile_load_db.h" +#include "Game/IW5/XAssets/snd_alias_list_t/snd_alias_list_t_load_db.h" +#include "Game/IW5/XAssets/sndcurve/sndcurve_load_db.h" +#include "Game/IW5/XAssets/stringtable/stringtable_load_db.h" +#include "Game/IW5/XAssets/structureddatadefset/structureddatadefset_load_db.h" +#include "Game/IW5/XAssets/surfacefxtable/surfacefxtable_load_db.h" +#include "Game/IW5/XAssets/tracerdef/tracerdef_load_db.h" +#include "Game/IW5/XAssets/vehicledef/vehicledef_load_db.h" +#include "Game/IW5/XAssets/vehicletrack/vehicletrack_load_db.h" +#include "Game/IW5/XAssets/weaponattachment/weaponattachment_load_db.h" +#include "Game/IW5/XAssets/weaponcompletedef/weaponcompletedef_load_db.h" +#include "Game/IW5/XAssets/xanimparts/xanimparts_load_db.h" +#include "Game/IW5/XAssets/xmodel/xmodel_load_db.h" +#include "Game/IW5/XAssets/xmodelsurfs/xmodelsurfs_load_db.h" + +using namespace IW5; + +ContentLoader::ContentLoader() +{ + varXAsset = nullptr; + varScriptStringList = nullptr; +} + +void ContentLoader::LoadScriptStringList(const bool atStreamStart) +{ + assert(m_zone->m_script_strings.Empty()); + + m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); + + if (atStreamStart) + m_stream->Load(varScriptStringList); + + if (varScriptStringList->strings != nullptr) + { + assert(varScriptStringList->strings == PTR_FOLLOWING); + + varScriptStringList->strings = m_stream->Alloc(alignof(const char*)); + varXString = varScriptStringList->strings; + LoadXStringArray(true, varScriptStringList->count); + + for (int i = 0; i < varScriptStringList->count; i++) + { + if (varScriptStringList->strings[i]) + { + m_zone->m_script_strings.AddScriptString(varScriptStringList->strings[i]); + } + else + { + m_zone->m_script_strings.AddScriptString(""); + } + } + } + + m_stream->PopBlock(); + + assert(m_zone->m_script_strings.Count() <= SCR_STRING_MAX + 1); +} + +void ContentLoader::LoadXAsset(const bool atStreamStart) +{ +#define LOAD_ASSET(type_index, typeName, headerEntry) \ + case type_index: \ + { \ + Loader_##typeName loader(m_zone, m_stream); \ + loader.Load(&varXAsset->header.headerEntry); \ + break; \ + } +#define SKIP_ASSET(type_index, typeName, headerEntry) \ + case type_index: \ + break; + + assert(varXAsset != nullptr); + + if (atStreamStart) + m_stream->Load(varXAsset); + + switch (varXAsset->type) + { + LOAD_ASSET(ASSET_TYPE_PHYSPRESET, PhysPreset, physPreset) + LOAD_ASSET(ASSET_TYPE_PHYSCOLLMAP, PhysCollmap, physCollmap) + LOAD_ASSET(ASSET_TYPE_XANIMPARTS, XAnimParts, parts) + LOAD_ASSET(ASSET_TYPE_XMODEL_SURFS, XModelSurfs, modelSurfs) + LOAD_ASSET(ASSET_TYPE_XMODEL, XModel, model) + LOAD_ASSET(ASSET_TYPE_MATERIAL, Material, material) + LOAD_ASSET(ASSET_TYPE_PIXELSHADER, MaterialPixelShader, pixelShader) + LOAD_ASSET(ASSET_TYPE_VERTEXSHADER, MaterialVertexShader, vertexShader) + LOAD_ASSET(ASSET_TYPE_VERTEXDECL, MaterialVertexDeclaration, vertexDecl) + LOAD_ASSET(ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet, techniqueSet) + LOAD_ASSET(ASSET_TYPE_IMAGE, GfxImage, image) + LOAD_ASSET(ASSET_TYPE_SOUND, snd_alias_list_t, sound) + LOAD_ASSET(ASSET_TYPE_SOUND_CURVE, SndCurve, sndCurve) + LOAD_ASSET(ASSET_TYPE_LOADED_SOUND, LoadedSound, loadSnd) + LOAD_ASSET(ASSET_TYPE_CLIPMAP, clipMap_t, clipMap) + LOAD_ASSET(ASSET_TYPE_COMWORLD, ComWorld, comWorld) + LOAD_ASSET(ASSET_TYPE_GLASSWORLD, GlassWorld, glassWorld) + LOAD_ASSET(ASSET_TYPE_PATHDATA, PathData, pathData) + LOAD_ASSET(ASSET_TYPE_VEHICLE_TRACK, VehicleTrack, vehicleTrack) + LOAD_ASSET(ASSET_TYPE_MAP_ENTS, MapEnts, mapEnts) + LOAD_ASSET(ASSET_TYPE_FXWORLD, FxWorld, fxWorld) + LOAD_ASSET(ASSET_TYPE_GFXWORLD, GfxWorld, gfxWorld) + LOAD_ASSET(ASSET_TYPE_LIGHT_DEF, GfxLightDef, lightDef) + LOAD_ASSET(ASSET_TYPE_FONT, Font_s, font) + LOAD_ASSET(ASSET_TYPE_MENULIST, MenuList, menuList) + LOAD_ASSET(ASSET_TYPE_MENU, menuDef_t, menu) + LOAD_ASSET(ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry, localize) + LOAD_ASSET(ASSET_TYPE_ATTACHMENT, WeaponAttachment, attachment) + LOAD_ASSET(ASSET_TYPE_WEAPON, WeaponCompleteDef, weapon) + LOAD_ASSET(ASSET_TYPE_FX, FxEffectDef, fx) + LOAD_ASSET(ASSET_TYPE_IMPACT_FX, FxImpactTable, impactFx) + LOAD_ASSET(ASSET_TYPE_SURFACE_FX, SurfaceFxTable, surfaceFx) + LOAD_ASSET(ASSET_TYPE_RAWFILE, RawFile, rawfile) + LOAD_ASSET(ASSET_TYPE_SCRIPTFILE, ScriptFile, scriptfile) + LOAD_ASSET(ASSET_TYPE_STRINGTABLE, StringTable, stringTable) + LOAD_ASSET(ASSET_TYPE_LEADERBOARD, LeaderboardDef, leaderboardDef) + LOAD_ASSET(ASSET_TYPE_STRUCTURED_DATA_DEF, StructuredDataDefSet, structuredDataDefSet) + LOAD_ASSET(ASSET_TYPE_TRACER, TracerDef, tracerDef) + LOAD_ASSET(ASSET_TYPE_VEHICLE, VehicleDef, vehDef) + LOAD_ASSET(ASSET_TYPE_ADDON_MAP_ENTS, AddonMapEnts, addonMapEnts) + + default: + { + throw UnsupportedAssetTypeException(varXAsset->type); + } + } + +#undef LOAD_ASSET +} + +void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count) +{ + assert(varXAsset != nullptr); + + if (atStreamStart) + m_stream->Load(varXAsset, count); + + for (asset_type_t assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++) + { + m_zone->m_pools->InitPoolDynamic(assetType); + } + + for (size_t index = 0; index < count; index++) + { + LoadXAsset(false); + varXAsset++; + } +} + +void ContentLoader::Load(Zone* zone, IZoneInputStream* stream) +{ + m_zone = zone; + m_stream = stream; + + m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); + + XAssetList assetList{}; + m_stream->LoadDataRaw(&assetList, sizeof assetList); + + varScriptStringList = &assetList.stringList; + LoadScriptStringList(false); + + if (assetList.assets != nullptr) + { + assert(assetList.assets == PTR_FOLLOWING); + + assetList.assets = m_stream->Alloc(alignof(XAsset)); + varXAsset = assetList.assets; + LoadXAssetArray(true, assetList.assetCount); + } + + m_stream->PopBlock(); +} diff --git a/src/ZoneLoading/Game/IW5/ContentLoaderIW5.h b/src/ZoneLoading/Game/IW5/ContentLoaderIW5.h new file mode 100644 index 00000000..2bcc7451 --- /dev/null +++ b/src/ZoneLoading/Game/IW5/ContentLoaderIW5.h @@ -0,0 +1,23 @@ +#pragma once +#include "Loading/ContentLoaderBase.h" +#include "Loading/IContentLoadingEntryPoint.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint + { + XAsset* varXAsset; + ScriptStringList* varScriptStringList; + + void LoadScriptStringList(bool atStreamStart); + + void LoadXAsset(bool atStreamStart); + void LoadXAssetArray(bool atStreamStart, size_t count); + + public: + ContentLoader(); + + void Load(Zone* zone, IZoneInputStream* stream) override; + }; +} diff --git a/src/ZoneLoading/Game/IW5/XAssets/gfximage/gfximage_actions.cpp b/src/ZoneLoading/Game/IW5/XAssets/gfximage/gfximage_actions.cpp new file mode 100644 index 00000000..a6e71c00 --- /dev/null +++ b/src/ZoneLoading/Game/IW5/XAssets/gfximage/gfximage_actions.cpp @@ -0,0 +1,24 @@ +#include "gfximage_actions.h" + +#include +#include + +using namespace IW5; + +Actions_GfxImage::Actions_GfxImage(Zone* zone) + : AssetLoadingActions(zone) +{ +} + +void Actions_GfxImage::OnImageLoaded(GfxImage* image) const +{ + image->cardMemory.platform[0] = 0; +} + +void Actions_GfxImage::LoadImageData(GfxImageLoadDef* loadDef, GfxImage* image) const +{ + const size_t loadDefSize = offsetof(IW5::GfxImageLoadDef, data) + loadDef->resourceSize; + + image->texture.loadDef = static_cast(m_zone->GetMemory()->Alloc(loadDefSize)); + memcpy(image->texture.loadDef, loadDef, loadDefSize); +} diff --git a/src/ZoneLoading/Game/IW5/XAssets/gfximage/gfximage_actions.h b/src/ZoneLoading/Game/IW5/XAssets/gfximage/gfximage_actions.h new file mode 100644 index 00000000..ca2e6dcb --- /dev/null +++ b/src/ZoneLoading/Game/IW5/XAssets/gfximage/gfximage_actions.h @@ -0,0 +1,16 @@ +#pragma once + +#include "Loading/AssetLoadingActions.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class Actions_GfxImage final : public AssetLoadingActions + { + public: + explicit Actions_GfxImage(Zone* zone); + + void OnImageLoaded(GfxImage* image) const; + void LoadImageData(GfxImageLoadDef* loadDef, GfxImage* image) const; + }; +} diff --git a/src/ZoneLoading/Game/IW5/XAssets/loadedsound/loadedsound_actions.cpp b/src/ZoneLoading/Game/IW5/XAssets/loadedsound/loadedsound_actions.cpp new file mode 100644 index 00000000..1d446387 --- /dev/null +++ b/src/ZoneLoading/Game/IW5/XAssets/loadedsound/loadedsound_actions.cpp @@ -0,0 +1,24 @@ +#include "loadedsound_actions.h" + +#include + +using namespace IW5; + +Actions_LoadedSound::Actions_LoadedSound(Zone* zone) + : AssetLoadingActions(zone) +{ +} + +void Actions_LoadedSound::SetSoundData(MssSound* sound) const +{ + if (sound->info.data_len > 0) + { + char* tempData = sound->data; + sound->data = static_cast(m_zone->GetMemory()->Alloc(sound->info.data_len)); + memcpy(sound->data, tempData, sound->info.data_len); + } + else + { + sound->data = nullptr; + } +} diff --git a/src/ZoneLoading/Game/IW5/XAssets/loadedsound/loadedsound_actions.h b/src/ZoneLoading/Game/IW5/XAssets/loadedsound/loadedsound_actions.h new file mode 100644 index 00000000..a6bbfc1a --- /dev/null +++ b/src/ZoneLoading/Game/IW5/XAssets/loadedsound/loadedsound_actions.h @@ -0,0 +1,15 @@ +#pragma once + +#include "Loading/AssetLoadingActions.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class Actions_LoadedSound final : public AssetLoadingActions + { + public: + explicit Actions_LoadedSound(Zone* zone); + + void SetSoundData(MssSound* sound) const; + }; +} diff --git a/src/ZoneLoading/Game/IW5/XAssets/xmodel/xmodel_actions.cpp b/src/ZoneLoading/Game/IW5/XAssets/xmodel/xmodel_actions.cpp new file mode 100644 index 00000000..49955781 --- /dev/null +++ b/src/ZoneLoading/Game/IW5/XAssets/xmodel/xmodel_actions.cpp @@ -0,0 +1,19 @@ +#include "xmodel_actions.h" + +#include + +using namespace IW5; + +Actions_XModel::Actions_XModel(Zone* zone) + : AssetLoadingActions(zone) +{ +} + +void Actions_XModel::SetModelSurfs(XModelLodInfo* lodInfo, XModelSurfs* modelSurfs) const +{ + if(modelSurfs) + { + lodInfo->modelSurfs = m_zone->GetMemory()->Create(); + memcpy(lodInfo->modelSurfs, modelSurfs, sizeof(XModelSurfs)); + } +} diff --git a/src/ZoneLoading/Game/IW5/XAssets/xmodel/xmodel_actions.h b/src/ZoneLoading/Game/IW5/XAssets/xmodel/xmodel_actions.h new file mode 100644 index 00000000..60cb637e --- /dev/null +++ b/src/ZoneLoading/Game/IW5/XAssets/xmodel/xmodel_actions.h @@ -0,0 +1,15 @@ +#pragma once + +#include "Loading/AssetLoadingActions.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class Actions_XModel final : public AssetLoadingActions + { + public: + explicit Actions_XModel(Zone* zone); + + void SetModelSurfs(XModelLodInfo* lodInfo, XModelSurfs* modelSurfs) const; + }; +} diff --git a/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.cpp b/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.cpp new file mode 100644 index 00000000..10a41a0b --- /dev/null +++ b/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.cpp @@ -0,0 +1,198 @@ +#include "ZoneLoaderFactoryIW5.h" + +#include +#include +#include + +#include "Game/IW5/IW5.h" + +#include "Utils/ClassUtils.h" +#include "ContentLoaderIW5.h" +#include "Game/IW5/GameAssetPoolIW5.h" +#include "Game/IW5/GameIW5.h" +#include "Game/GameLanguage.h" +#include "Game/IW5/ZoneConstantsIW5.h" +#include "Loading/Processor/ProcessorAuthedBlocks.h" +#include "Loading/Processor/ProcessorCaptureData.h" +#include "Loading/Processor/ProcessorInflate.h" +#include "Loading/Steps/StepVerifyMagic.h" +#include "Loading/Steps/StepSkipBytes.h" +#include "Loading/Steps/StepVerifyFileName.h" +#include "Loading/Steps/StepLoadSignature.h" +#include "Loading/Steps/StepVerifySignature.h" +#include "Loading/Steps/StepAddProcessor.h" +#include "Loading/Steps/StepAllocXBlocks.h" +#include "Loading/Steps/StepLoadZoneContent.h" +#include "Loading/Steps/StepLoadHash.h" +#include "Loading/Steps/StepRemoveProcessor.h" +#include "Loading/Steps/StepVerifyHash.h" + +using namespace IW5; + +class ZoneLoaderFactory::Impl +{ + static GameLanguage GetZoneLanguage(std::string& zoneName) + { + return GameLanguage::LANGUAGE_NONE; + } + + static bool CanLoad(ZoneHeader& header, bool* isSecure, bool* isOfficial) + { + assert(isSecure != nullptr); + assert(isOfficial != nullptr); + + if (header.m_version != ZoneConstants::ZONE_VERSION) + { + return false; + } + + if (!memcmp(header.m_magic, ZoneConstants::MAGIC_SIGNED_INFINITY_WARD, std::char_traits::length(ZoneConstants::MAGIC_SIGNED_INFINITY_WARD))) + { + *isSecure = true; + *isOfficial = true; + return true; + } + + if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, std::char_traits::length(ZoneConstants::MAGIC_UNSIGNED))) + { + *isSecure = false; + *isOfficial = true; + return true; + } + + return false; + } + + static void SetupBlock(ZoneLoader* zoneLoader) + { +#define XBLOCK_DEF(name, type) std::make_unique(STR(name), name, type) + + zoneLoader->AddXBlock(XBLOCK_DEF(IW5::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); + zoneLoader->AddXBlock(XBLOCK_DEF(IW5::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader->AddXBlock(XBLOCK_DEF(IW5::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + zoneLoader->AddXBlock(XBLOCK_DEF(IW5::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader->AddXBlock(XBLOCK_DEF(IW5::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader->AddXBlock(XBLOCK_DEF(IW5::XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL)); + zoneLoader->AddXBlock(XBLOCK_DEF(IW5::XFILE_BLOCK_SCRIPT, XBlock::Type::BLOCK_TYPE_NORMAL)); + +#undef XBLOCK_DEF + } + + static std::unique_ptr SetupRSA(const bool isOfficial) + { + if (isOfficial) + { + auto rsa = Crypto::CreateRSA(IPublicKeyAlgorithm::HashingAlgorithm::RSA_HASH_SHA256, + Crypto::RSAPaddingMode::RSA_PADDING_PSS); + + if (!rsa->SetKey(ZoneConstants::RSA_PUBLIC_KEY_INFINITY_WARD, sizeof(ZoneConstants::RSA_PUBLIC_KEY_INFINITY_WARD))) + { + printf("Invalid public key for signature checking\n"); + return nullptr; + } + + return rsa; + } + else + { + assert(false); + + // TODO: Load custom RSA key here + return nullptr; + } + } + + static void AddAuthHeaderSteps(const bool isSecure, const bool isOfficial, ZoneLoader* zoneLoader, + std::string& fileName) + { + // Unsigned zones do not have an auth header + if (!isSecure) + return; + + // If file is signed setup a RSA instance. + auto rsa = SetupRSA(isOfficial); + + zoneLoader->AddLoadingStep(std::make_unique(ZoneConstants::MAGIC_AUTH_HEADER)); + zoneLoader->AddLoadingStep(std::make_unique(4)); // Skip reserved + + auto subHeaderHash = std::make_unique(sizeof DB_AuthHash::bytes, 1); + auto* subHeaderHashPtr = subHeaderHash.get(); + zoneLoader->AddLoadingStep(std::move(subHeaderHash)); + + auto subHeaderHashSignature = std::make_unique(sizeof DB_AuthSignature::bytes); + auto* subHeaderHashSignaturePtr = subHeaderHashSignature.get(); + zoneLoader->AddLoadingStep(std::move(subHeaderHashSignature)); + + zoneLoader->AddLoadingStep(std::make_unique(std::move(rsa), subHeaderHashSignaturePtr, subHeaderHashPtr)); + + auto subHeaderCapture = std::make_unique(sizeof(DB_AuthSubHeader)); + auto* subHeaderCapturePtr = subHeaderCapture.get(); + zoneLoader->AddLoadingStep(std::make_unique(std::move(subHeaderCapture))); + + zoneLoader->AddLoadingStep(std::make_unique(fileName, sizeof(DB_AuthSubHeader::fastfileName))); + zoneLoader->AddLoadingStep(std::make_unique(4)); // Skip reserved + + auto masterBlockHashes = std::make_unique(sizeof DB_AuthHash::bytes, std::extent::value); + auto* masterBlockHashesPtr = masterBlockHashes.get(); + zoneLoader->AddLoadingStep(std::move(masterBlockHashes)); + + zoneLoader->AddLoadingStep(std::make_unique(std::unique_ptr(Crypto::CreateSHA256()), 0, subHeaderHashPtr, subHeaderCapturePtr)); + zoneLoader->AddLoadingStep(std::make_unique(subHeaderCapturePtr)); + + // Skip the rest of the first chunk + zoneLoader->AddLoadingStep(std::make_unique(ZoneConstants::AUTHED_CHUNK_SIZE - sizeof(DB_AuthHeader))); + + zoneLoader->AddLoadingStep(std::make_unique(std::make_unique( + ZoneConstants::AUTHED_CHUNK_COUNT_PER_GROUP, ZoneConstants::AUTHED_CHUNK_SIZE, std::extent::value, + std::unique_ptr(Crypto::CreateSHA256()), masterBlockHashesPtr))); + } + +public: + static ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) + { + bool isSecure; + bool isOfficial; + + // Check if this file is a supported IW4 zone. + if (!CanLoad(header, &isSecure, &isOfficial)) + return nullptr; + + // Create new zone + auto zone = std::make_unique(fileName, 0, &g_GameIW5); + auto* zonePtr = zone.get(); + zone->m_pools = std::make_unique(zonePtr, 0); + zone->m_language = GetZoneLanguage(fileName); + + // File is supported. Now setup all required steps for loading this file. + auto* zoneLoader = new ZoneLoader(std::move(zone)); + + SetupBlock(zoneLoader); + + // Skip unknown 1 byte field that the game ignores as well + zoneLoader->AddLoadingStep(std::make_unique(1)); + + // Skip timestamp + zoneLoader->AddLoadingStep(std::make_unique(8)); + + // Add steps for loading the auth header which also contain the signature of the zone if it is signed. + AddAuthHeaderSteps(isSecure, isOfficial, zoneLoader, fileName); + + zoneLoader->AddLoadingStep(std::make_unique(std::make_unique(ZoneConstants::AUTHED_CHUNK_SIZE))); + + // Start of the XFile struct + zoneLoader->AddLoadingStep(std::make_unique(8)); + // Skip size and externalSize fields since they are not interesting for us + zoneLoader->AddLoadingStep(std::make_unique()); + + // Start of the zone content + zoneLoader->AddLoadingStep(std::make_unique(std::make_unique(), zonePtr, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK)); + + // Return the fully setup zoneloader + return zoneLoader; + } +}; + +ZoneLoader* ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) +{ + return Impl::CreateLoaderForHeader(header, fileName); +} diff --git a/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.h b/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.h new file mode 100644 index 00000000..cecef300 --- /dev/null +++ b/src/ZoneLoading/Game/IW5/ZoneLoaderFactoryIW5.h @@ -0,0 +1,15 @@ +#pragma once + +#include "Loading/IZoneLoaderFactory.h" +#include + +namespace IW5 +{ + class ZoneLoaderFactory final : public IZoneLoaderFactory + { + class Impl; + + public: + ZoneLoader* CreateLoaderForHeader(ZoneHeader& header, std::string& fileName) override; + }; +} diff --git a/src/ZoneLoading/ZoneLoading.cpp b/src/ZoneLoading/ZoneLoading.cpp index afa8dfcf..995c011c 100644 --- a/src/ZoneLoading/ZoneLoading.cpp +++ b/src/ZoneLoading/ZoneLoading.cpp @@ -6,6 +6,7 @@ #include "Game/IW3/ZoneLoaderFactoryIW3.h" #include "Game/IW4/ZoneLoaderFactoryIW4.h" +#include "Game/IW5/ZoneLoaderFactoryIW5.h" #include "Game/T5/ZoneLoaderFactoryT5.h" #include "Game/T6/ZoneLoaderFactoryT6.h" #include "Utils/ObjFileStream.h" @@ -16,6 +17,7 @@ IZoneLoaderFactory* ZoneLoaderFactories[] { new IW3::ZoneLoaderFactory(), new IW4::ZoneLoaderFactory(), + new IW5::ZoneLoaderFactory(), new T5::ZoneLoaderFactory(), new T6::ZoneLoaderFactory() }; diff --git a/src/ZoneWriting/Game/IW5/ContentWriterIW5.cpp b/src/ZoneWriting/Game/IW5/ContentWriterIW5.cpp new file mode 100644 index 00000000..418a24db --- /dev/null +++ b/src/ZoneWriting/Game/IW5/ContentWriterIW5.cpp @@ -0,0 +1,231 @@ +#include "ContentWriterIW5.h" + +#include +#include + +#include "Game/IW5/XAssets/addonmapents/addonmapents_write_db.h" +#include "Game/IW5/XAssets/clipmap_t/clipmap_t_write_db.h" +#include "Game/IW5/XAssets/comworld/comworld_write_db.h" +#include "Game/IW5/XAssets/font_s/font_s_write_db.h" +#include "Game/IW5/XAssets/fxeffectdef/fxeffectdef_write_db.h" +#include "Game/IW5/XAssets/fximpacttable/fximpacttable_write_db.h" +#include "Game/IW5/XAssets/fxworld/fxworld_write_db.h" +#include "Game/IW5/XAssets/gfximage/gfximage_write_db.h" +#include "Game/IW5/XAssets/gfxlightdef/gfxlightdef_write_db.h" +#include "Game/IW5/XAssets/gfxworld/gfxworld_write_db.h" +#include "Game/IW5/XAssets/glassworld/glassworld_write_db.h" +#include "Game/IW5/XAssets/leaderboarddef/leaderboarddef_write_db.h" +#include "Game/IW5/XAssets/loadedsound/loadedsound_write_db.h" +#include "Game/IW5/XAssets/localizeentry/localizeentry_write_db.h" +#include "Game/IW5/XAssets/mapents/mapents_write_db.h" +#include "Game/IW5/XAssets/material/material_write_db.h" +#include "Game/IW5/XAssets/materialpixelshader/materialpixelshader_write_db.h" +#include "Game/IW5/XAssets/materialtechniqueset/materialtechniqueset_write_db.h" +#include "Game/IW5/XAssets/materialvertexdeclaration/materialvertexdeclaration_write_db.h" +#include "Game/IW5/XAssets/materialvertexshader/materialvertexshader_write_db.h" +#include "Game/IW5/XAssets/menudef_t/menudef_t_write_db.h" +#include "Game/IW5/XAssets/menulist/menulist_write_db.h" +#include "Game/IW5/XAssets/pathdata/pathdata_write_db.h" +#include "Game/IW5/XAssets/physcollmap/physcollmap_write_db.h" +#include "Game/IW5/XAssets/physpreset/physpreset_write_db.h" +#include "Game/IW5/XAssets/rawfile/rawfile_write_db.h" +#include "Game/IW5/XAssets/scriptfile/scriptfile_write_db.h" +#include "Game/IW5/XAssets/snd_alias_list_t/snd_alias_list_t_write_db.h" +#include "Game/IW5/XAssets/sndcurve/sndcurve_write_db.h" +#include "Game/IW5/XAssets/stringtable/stringtable_write_db.h" +#include "Game/IW5/XAssets/structureddatadefset/structureddatadefset_write_db.h" +#include "Game/IW5/XAssets/surfacefxtable/surfacefxtable_write_db.h" +#include "Game/IW5/XAssets/tracerdef/tracerdef_write_db.h" +#include "Game/IW5/XAssets/vehicledef/vehicledef_write_db.h" +#include "Game/IW5/XAssets/vehicletrack/vehicletrack_write_db.h" +#include "Game/IW5/XAssets/weaponattachment/weaponattachment_write_db.h" +#include "Game/IW5/XAssets/weaponcompletedef/weaponcompletedef_write_db.h" +#include "Game/IW5/XAssets/xanimparts/xanimparts_write_db.h" +#include "Game/IW5/XAssets/xmodel/xmodel_write_db.h" +#include "Game/IW5/XAssets/xmodelsurfs/xmodelsurfs_write_db.h" + +#include "Writing/WritingException.h" + +using namespace IW5; + +ContentWriter::ContentWriter() + : varXAssetList(nullptr), + varXAsset(nullptr), + varScriptStringList(nullptr) +{ +} + +void ContentWriter::CreateXAssetList(XAssetList& xAssetList, MemoryManager& memory) const +{ + if (!m_zone->m_script_strings.Empty()) + { + assert(m_zone->m_script_strings.Count() <= SCR_STRING_MAX + 1); + xAssetList.stringList.count = m_zone->m_script_strings.Count(); + xAssetList.stringList.strings = static_cast(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(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((*i)->m_type); + asset.header.data = (*i)->m_ptr; + } + } + else + { + xAssetList.assetCount = 0; + xAssetList.assets = nullptr; + } +} + +void ContentWriter::WriteScriptStringList(const bool atStreamStart) +{ + m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); + + if (atStreamStart) + varScriptStringList = m_stream->Write(varScriptStringList); + + if (varScriptStringList->strings != nullptr) + { + m_stream->Align(alignof(const char*)); + varXString = varScriptStringList->strings; + WriteXStringArray(true, varScriptStringList->count); + + m_stream->MarkFollowing(varScriptStringList->strings); + } + + m_stream->PopBlock(); +} + +void ContentWriter::WriteXAsset(const bool atStreamStart) +{ +#define WRITE_ASSET(type_index, typeName, headerEntry) \ + case type_index: \ + { \ + Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, m_stream); \ + writer.Write(&varXAsset->header.headerEntry); \ + break; \ + } +#define SKIP_ASSET(type_index, typeName, headerEntry) \ + case type_index: \ + break; + + assert(varXAsset != nullptr); + + if (atStreamStart) + varXAsset = m_stream->Write(varXAsset); + + switch (varXAsset->type) + { + WRITE_ASSET(ASSET_TYPE_PHYSPRESET, PhysPreset, physPreset) + WRITE_ASSET(ASSET_TYPE_PHYSCOLLMAP, PhysCollmap, physCollmap) + WRITE_ASSET(ASSET_TYPE_XANIMPARTS, XAnimParts, parts) + WRITE_ASSET(ASSET_TYPE_XMODEL_SURFS, XModelSurfs, modelSurfs) + WRITE_ASSET(ASSET_TYPE_XMODEL, XModel, model) + WRITE_ASSET(ASSET_TYPE_MATERIAL, Material, material) + WRITE_ASSET(ASSET_TYPE_PIXELSHADER, MaterialPixelShader, pixelShader) + WRITE_ASSET(ASSET_TYPE_VERTEXSHADER, MaterialVertexShader, vertexShader) + WRITE_ASSET(ASSET_TYPE_VERTEXDECL, MaterialVertexDeclaration, vertexDecl) + WRITE_ASSET(ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet, techniqueSet) + WRITE_ASSET(ASSET_TYPE_IMAGE, GfxImage, image) + WRITE_ASSET(ASSET_TYPE_SOUND, snd_alias_list_t, sound) + WRITE_ASSET(ASSET_TYPE_SOUND_CURVE, SndCurve, sndCurve) + WRITE_ASSET(ASSET_TYPE_LOADED_SOUND, LoadedSound, loadSnd) + WRITE_ASSET(ASSET_TYPE_CLIPMAP, clipMap_t, clipMap) + WRITE_ASSET(ASSET_TYPE_COMWORLD, ComWorld, comWorld) + WRITE_ASSET(ASSET_TYPE_GLASSWORLD, GlassWorld, glassWorld) + WRITE_ASSET(ASSET_TYPE_PATHDATA, PathData, pathData) + WRITE_ASSET(ASSET_TYPE_VEHICLE_TRACK, VehicleTrack, vehicleTrack) + WRITE_ASSET(ASSET_TYPE_MAP_ENTS, MapEnts, mapEnts) + WRITE_ASSET(ASSET_TYPE_FXWORLD, FxWorld, fxWorld) + WRITE_ASSET(ASSET_TYPE_GFXWORLD, GfxWorld, gfxWorld) + WRITE_ASSET(ASSET_TYPE_LIGHT_DEF, GfxLightDef, lightDef) + WRITE_ASSET(ASSET_TYPE_FONT, Font_s, font) + WRITE_ASSET(ASSET_TYPE_MENULIST, MenuList, menuList) + WRITE_ASSET(ASSET_TYPE_MENU, menuDef_t, menu) + WRITE_ASSET(ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry, localize) + WRITE_ASSET(ASSET_TYPE_ATTACHMENT, WeaponAttachment, attachment) + WRITE_ASSET(ASSET_TYPE_WEAPON, WeaponCompleteDef, weapon) + WRITE_ASSET(ASSET_TYPE_FX, FxEffectDef, fx) + WRITE_ASSET(ASSET_TYPE_IMPACT_FX, FxImpactTable, impactFx) + WRITE_ASSET(ASSET_TYPE_SURFACE_FX, SurfaceFxTable, surfaceFx) + WRITE_ASSET(ASSET_TYPE_RAWFILE, RawFile, rawfile) + WRITE_ASSET(ASSET_TYPE_SCRIPTFILE, ScriptFile, scriptfile) + WRITE_ASSET(ASSET_TYPE_STRINGTABLE, StringTable, stringTable) + WRITE_ASSET(ASSET_TYPE_LEADERBOARD, LeaderboardDef, leaderboardDef) + WRITE_ASSET(ASSET_TYPE_STRUCTURED_DATA_DEF, StructuredDataDefSet, structuredDataDefSet) + WRITE_ASSET(ASSET_TYPE_TRACER, TracerDef, tracerDef) + WRITE_ASSET(ASSET_TYPE_VEHICLE, VehicleDef, vehDef) + WRITE_ASSET(ASSET_TYPE_ADDON_MAP_ENTS, AddonMapEnts, addonMapEnts) + + default: + { + std::ostringstream str; + str << "Unsupported asset type: " << varXAsset->type << "."; + throw WritingException(str.str()); + } + } + +#undef WRITE_ASSET +#undef SKIP_ASSET +} + +void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t count) +{ + assert(varXAsset != nullptr); + + if (atStreamStart) + varXAsset = m_stream->Write(varXAsset, count); + + for (size_t index = 0; index < count; index++) + { + WriteXAsset(false); + varXAsset++; + } +} + +void ContentWriter::WriteContent(Zone* zone, IZoneOutputStream* stream) +{ + m_zone = zone; + m_stream = stream; + + m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); + + MemoryManager memory; + XAssetList assetList{}; + + CreateXAssetList(assetList, memory); + + varXAssetList = static_cast(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(); +} diff --git a/src/ZoneWriting/Game/IW5/ContentWriterIW5.h b/src/ZoneWriting/Game/IW5/ContentWriterIW5.h new file mode 100644 index 00000000..c90384b3 --- /dev/null +++ b/src/ZoneWriting/Game/IW5/ContentWriterIW5.h @@ -0,0 +1,26 @@ +#pragma once +#include "Writing/ContentWriterBase.h" +#include "Writing/IContentWritingEntryPoint.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class ContentWriter final : public ContentWriterBase, public IContentWritingEntryPoint + { + XAssetList* varXAssetList; + XAsset* varXAsset; + ScriptStringList* varScriptStringList; + + void CreateXAssetList(XAssetList& xAssetList, MemoryManager& memory) const; + + void WriteScriptStringList(bool atStreamStart); + + void WriteXAsset(bool atStreamStart); + void WriteXAssetArray(bool atStreamStart, size_t count); + + public: + ContentWriter(); + + void WriteContent(Zone* zone, IZoneOutputStream* stream) override; + }; +} diff --git a/src/ZoneWriting/Game/IW5/ZoneWriterFactoryIW5.cpp b/src/ZoneWriting/Game/IW5/ZoneWriterFactoryIW5.cpp new file mode 100644 index 00000000..d6f6ade6 --- /dev/null +++ b/src/ZoneWriting/Game/IW5/ZoneWriterFactoryIW5.cpp @@ -0,0 +1,111 @@ +#include "ZoneWriterFactoryIW5.h" + +#include + +#include "ContentWriterIW5.h" +#include "Game/IW5/IW5.h" +#include "Game/IW5/GameIW5.h" +#include "Game/IW5/ZoneConstantsIW5.h" +#include "Writing/Processor/OutputProcessorDeflate.h" +#include "Writing/Steps/StepAddOutputProcessor.h" +#include "Writing/Steps/StepWriteTimestamp.h" +#include "Writing/Steps/StepWriteXBlockSizes.h" +#include "Writing/Steps/StepWriteZero.h" +#include "Writing/Steps/StepWriteZoneContentToFile.h" +#include "Writing/Steps/StepWriteZoneContentToMemory.h" +#include "Writing/Steps/StepWriteZoneHeader.h" +#include "Writing/Steps/StepWriteZoneSizes.h" + +using namespace IW5; + +class ZoneWriterFactory::Impl +{ + Zone* m_zone; + std::unique_ptr m_writer; + +public: + explicit Impl(Zone* zone) + : m_zone(zone), + m_writer(std::make_unique()) + { + } + + void SetupBlocks() const + { +#define XBLOCK_DEF(name, type) std::make_unique(STR(name), name, type) + + m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); + m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); + m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); + m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); + m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL)); + m_writer->AddXBlock(XBLOCK_DEF(XFILE_BLOCK_SCRIPT, XBlock::Type::BLOCK_TYPE_NORMAL)); + +#undef XBLOCK_DEF + } + + static ZoneHeader CreateHeaderForParams(const bool isSecure, const bool isOfficial) + { + ZoneHeader header{}; + header.m_version = ZoneConstants::ZONE_VERSION; + + if (isSecure) + { + if (isOfficial) + memcpy(header.m_magic, ZoneConstants::MAGIC_SIGNED_INFINITY_WARD, sizeof(ZoneHeader::m_magic)); + else + memcpy(header.m_magic, ZoneConstants::MAGIC_SIGNED_OAT, sizeof(ZoneHeader::m_magic)); + } + else + { + memcpy(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, sizeof(ZoneHeader::m_magic)); + } + + return header; + } + + std::unique_ptr CreateWriter() + { + // TODO Support signed fastfiles + bool isSecure = false; + + SetupBlocks(); + + auto contentInMemory = std::make_unique(std::make_unique(), m_zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK); + auto* contentInMemoryPtr = contentInMemory.get(); + m_writer->AddWritingStep(std::move(contentInMemory)); + + // Write zone header + m_writer->AddWritingStep(std::make_unique(CreateHeaderForParams(isSecure, false))); + + // Write dummy byte that the game ignores as well. No clue what it means. + m_writer->AddWritingStep(std::make_unique(1)); + + // Write timestamp + m_writer->AddWritingStep(std::make_unique()); + + m_writer->AddWritingStep(std::make_unique(std::make_unique())); + + // Start of the XFile struct + m_writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); + m_writer->AddWritingStep(std::make_unique(m_zone)); + + // Start of the zone content + m_writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); + + // Return the fully setup zoneloader + return std::move(m_writer); + } +}; + +bool ZoneWriterFactory::SupportsZone(Zone* zone) const +{ + return zone->m_game == &g_GameIW5; +} + +std::unique_ptr ZoneWriterFactory::CreateWriter(Zone* zone) const +{ + Impl impl(zone); + return impl.CreateWriter(); +} diff --git a/src/ZoneWriting/Game/IW5/ZoneWriterFactoryIW5.h b/src/ZoneWriting/Game/IW5/ZoneWriterFactoryIW5.h new file mode 100644 index 00000000..beb5147f --- /dev/null +++ b/src/ZoneWriting/Game/IW5/ZoneWriterFactoryIW5.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +#include "Writing/IZoneWriterFactory.h" + +namespace IW5 +{ + class ZoneWriterFactory final : public IZoneWriterFactory + { + class Impl; + + public: + _NODISCARD bool SupportsZone(Zone* zone) const override; + _NODISCARD std::unique_ptr CreateWriter(Zone* zone) const override; + }; +} diff --git a/src/ZoneWriting/ZoneWriting.cpp b/src/ZoneWriting/ZoneWriting.cpp index cb8a47e2..75e6dc11 100644 --- a/src/ZoneWriting/ZoneWriting.cpp +++ b/src/ZoneWriting/ZoneWriting.cpp @@ -2,6 +2,7 @@ #include "Game/IW3/ZoneWriterFactoryIW3.h" #include "Game/IW4/ZoneWriterFactoryIW4.h" +#include "Game/IW5/ZoneWriterFactoryIW5.h" #include "Game/T5/ZoneWriterFactoryT5.h" #include "Game/T6/ZoneWriterFactoryT6.h" #include "Writing/IZoneWriterFactory.h" @@ -10,6 +11,7 @@ IZoneWriterFactory* ZoneWriterFactories[] { new IW3::ZoneWriterFactory(), new IW4::ZoneWriterFactory(), + new IW5::ZoneWriterFactory(), new T5::ZoneWriterFactory(), new T6::ZoneWriterFactory() };