#pragma once #include "gamelib/effects/lensflaremanager.h" #include "gamelib/effects/ribbonmanager.h" #include "idlib/containers/hashindex.h" #include "idlib/containers/list.h" #include "idlib/containers/staticlist.h" #include "idlib/math/random.h" #include "idlib/math/vector.h" #include "idlib/text/atomicstring.h" #include class idDeclFX; class idDeclParticle; class idDeclRenderParm; class idDeclTable; class idFXSingleAction; class idGameLibEffects; class idMaterial; class idRenderLight; class idRenderModel; class idRenderModelParticle; class idRenderWorld; class idSerializer; class idSoundEmitter; class idSoundShader; class idTreeAnimator; class idViewCallbacks; enum fxCondition_t : int { FX_NONE = 0 }; enum fxExtraCondition_t : int { FX_EXTRA_COND_NONE = 0, FX_EXTRA_COND_MAX = 0x10000 }; enum soundChannel_t : int { SND_CHANNEL_ANY = 0 }; enum fxActionType_t : int { FX_LIGHT = 0, FX_PARTICLE, FX_DECAL2, FX_MODEL, FX_SOUND, FX_SCREEN_SHAKE, FX_CONTROLLER_SHAKE, FX_ENV_OVERRIDE, FX_ENV_CHANGE, FX_FLARE, FX_RIBBON, FX_OTHER }; struct tagData_t { idVec3 trans; idQuat rot; std::uint16_t parentJoint; }; struct fxEmitterSound_t { idSoundEmitter* emitter; soundChannel_t channel; }; // Stable PC-side view of the fields the recovered state machine reads from // each idFXSingleAction. The declaration system fills this view. struct idFXActionParameters { fxActionType_t type; fxCondition_t startCondition; fxCondition_t stopCondition; fxExtraCondition_t extraCondition; idVec2 delay; float duration; float fadeInTime; float fadeOutTime; float restart; bool looping; bool triggered; bool trackOrigin; bool bindOrigin; bool bindAxis; idVec2 randomRotationX; idVec2 randomRotationY; idVec2 randomRotationZ; const idDeclParticle* particleDecl; idAtomicString modelName; const idSoundShader* sound; soundChannel_t soundChannel; }; class idFXModelRecycler { public: struct fxPrtModel_t { idRenderModelParticle* pmodel; const idDeclParticle* pDecl; }; struct fxStaticModel_t { idRenderModel* rmodel; idAtomicString modelName; }; idFXModelRecycler(); ~idFXModelRecycler(); void Init(); void Shutdown(); idRenderModelParticle* GetParticleFxModel( const idDeclParticle* particleDecl, idRenderWorld* renderWorld); void RecycleParticleFxModel(const idDeclParticle* particleDecl, idRenderModelParticle* model); idRenderModel* GetStaticFxModel(const idAtomicString& modelName, idRenderWorld* renderWorld); void RecycleStaticFxModel(const idAtomicString& modelName, idRenderModel* model); idStaticList fxPrtModels; idHashIndex activePrtModelHash; idHashIndex inactivePrtModelHash; idStaticList fxStaticModels; idHashIndex activeStaticModelHash; idHashIndex inactiveStaticModelHash; }; struct idFXAction { idFXAction(); int tagIndex; idVec3 startOrg; idMat3 startAxis; idRenderLight* rLight; idRenderModel* rModel; idRenderModelParticle* rParticle; int screenPrtHandle; idLensFlareManager flareManager; idRibbonManager ribbonManager; idList tagData; idVec3 lastParticleDropPos; idVec4 renderParmStartValue; idAngles randomAngles; int viewCallbacksID; }; struct fxActionState_t { int startDelay; int startTime; int stopTime; bool hidden; bool started; bool shouldTrigger; bool forceStop; int fadeInStartTime; int fadeInEndTime; int fadeOutStartTime; }; class idFXManager { public: enum fxActionCallType_t : int { FXACTION_START = 0, FXACTION_STOP = 1, FXACTION_STOP_ALL = 2, FXACTION_MAX = 3 }; struct fxActionCall_t { idVec3 org; idMat3 axis; fxCondition_t condition; int time; fxExtraCondition_t extraCondition; int tagIdx; fxActionCallType_t actionType; bool immediate; int viewCallbacksID; }; idFXManager(); ~idFXManager(); void Init(const idDeclFX* declFX, idRenderWorld* renderWorld, const fxEmitterSound_t* soundInfo, idGameLibEffects* gameLibEffects, float diversity, idTreeAnimator* treeAnimator); void Shutdown(); void Update(const idVec3& parentOrigin, const idMat3& parentAxis, const idVec3& parentVelocity, int time, int gameMsPerFrame, int frameNumber, float fovScale, float depthHack); int StartFX(const idVec3& origin, const idMat3& axis, int time, fxCondition_t startCondition, int explicitTagIndex, int delay); int StartFX(const idVec3& origin, const idMat3& axis, int time, fxCondition_t startCondition, fxExtraCondition_t extraCondition); int StartFX(const idVec3& origin, const idMat3& axis, int time, fxCondition_t startCondition); void LocalStartFX(const idVec3& origin, const idMat3& axis, int time, fxCondition_t startCondition); void StopFX(int time, fxCondition_t stopCondition, bool immediate); void StopFX(int time, fxCondition_t stopCondition, fxExtraCondition_t extraCondition, bool immediate); void LocalStopFX(int time, fxCondition_t stopCondition, bool immediate); void StopAllFX(int time, bool immediate); void LocalStopAllFX(int time, bool immediate); bool IsStopped(int time) const; const char* GetName() const; void ResetTreeAnimator(idTreeAnimator* treeAnimator); void Serialize(idSerializer& serializer); bool initialized; const idDeclFX* fxDecl; idGameLibEffects* gameLibEffects; idTreeAnimator* ta; idRenderWorld* rw; idVec4 systemColor; idRandom2 random; fxEmitterSound_t soundInfo; idList actions; idList actionState; bool remote; int allowSurfaceOnlyInViewID; int suppressSurfaceInViewID; int viewCallbacksID; int declChangeId; idMat3 externalRotation; idVec3 externalPosition; bool hasExternalPositionAndRotation; fxActionCall_t actionBuffer[8]; int actionBufferPos; int serializeActionCount; private: idVec4 GetVector(const idDeclRenderParm* parameter) const; idVec4 GetTableColor(const idFXSingleAction& action, float fraction) const; bool GetWorldSpaceTagVelocity(const tagData_t& tag, int gameMsPerFrame, idVec3& velocity); int StartSound(soundChannel_t channel, const idSoundShader* shader); idList& GetViewCallbacks(); void ApplyFade(const idFXActionParameters& parameters, idFXAction& action, fxActionState_t& state, int time, float fraction); void StopAction(int index, int time, bool immediate, bool recycleResources); void RestartAction(int index, int time); void StopActions(int time, fxCondition_t stopCondition, fxExtraCondition_t extraCondition, bool stopAll, bool immediate); void InternalStopFX(const fxActionCall_t& actionCall); void StartAction(int index, const idVec3& origin, const idMat3& axis, int time, int explicitTagIndex); void EnumerateTags(); void UpdateActions(const idVec3& origin, const idMat3& axis, const idVec3& velocity, int time, int gameMsPerFrame, int frameNumber, float fovScale, float depthHack); int StartActions(const idVec3& origin, const idMat3& axis, int time, fxCondition_t startCondition, fxExtraCondition_t extraCondition, int explicitTagIndex); void CreateAction(int index, idRenderWorld* renderWorld); void FreeActions(); int InternalStartFX(const fxActionCall_t& actionCall); }; static_assert(sizeof(tagData_t) == 32, "Recovered tagData_t ABI changed"); static_assert(sizeof(fxEmitterSound_t) == 8, "Recovered FX emitter sound ABI changed"); static_assert(sizeof(fxActionState_t) == 28, "Recovered FX action-state ABI changed"); #if defined(_WIN32) && !defined(_WIN64) static_assert(sizeof(idFXAction) == 184, "Recovered idFXAction ABI changed"); static_assert(sizeof(idFXManager::fxActionCall_t) == 76, "Recovered FX action-call ABI changed"); static_assert(sizeof(idFXManager) == 768, "Recovered idFXManager ABI changed"); #endif