diff --git a/src/Components/Modules/Renderer.cpp b/src/Components/Modules/Renderer.cpp index 498b075b..cd0a75de 100644 --- a/src/Components/Modules/Renderer.cpp +++ b/src/Components/Modules/Renderer.cpp @@ -12,6 +12,7 @@ namespace Components Dvar::Var Renderer::r_drawSceneModelCollisions; Dvar::Var Renderer::r_drawModelBoundingBoxes; Dvar::Var Renderer::r_drawModelNames; + Dvar::Var Renderer::r_drawRunners; Dvar::Var Renderer::r_drawAABBTrees; Dvar::Var Renderer::r_playerDrawDebugDistance; Dvar::Var Renderer::r_forceTechnique; @@ -118,30 +119,34 @@ namespace Components } } - void Renderer::R_TextureFromCodeError(const char* sampler, Game::GfxCmdBufState* state) + void Renderer::R_TextureFromCodeError(const char* sampler, Game::GfxCmdBufState* state, int samplerCode) { - Logger::Error(Game::ERR_FATAL, "Tried to use sampler '{}' when it isn't valid for material '{}' and technique '{}'", - sampler, state->material->info.name, state->technique->name); + Logger::Error(Game::ERR_FATAL, "Tried to use sampler '{}' ({}) at the wrong time! Additional info:\nMaterial: '{}'\nTechnique '{}'\nTechnique slot: {}\nTechnique flags: {}\nPass: {}\nPixel shader: '{}'\n", + samplerCode, sampler, state->material->info.name, state->technique->name, static_cast(state->techType), state->technique->flags, state->passIndex, state->pixelShader->name + ); } __declspec(naked) void Renderer::StoreGfxBufContextPtrStub1() { __asm { - // original code + // Game's code mov eax, dword ptr [eax * 4 + 0x66E600C] - // show error + // Show error pushad - push [esp + 0x24 + 0x20] + + push eax + push [esp + 0x20 + 0x24] push eax call R_TextureFromCodeError - add esp, 8 + add esp, 0xC + popad - // go back + // Jump back in push 0x54CAC1 - retn + ret } } @@ -354,14 +359,13 @@ namespace Components for (size_t i = 0; i < world->dpvs.smodelCount; i++) { auto staticModel = &world->dpvs.smodelDrawInsts[i]; - Game::Bounds* b = &world->dpvs.smodelInsts[i].bounds; + auto* b = &world->dpvs.smodelInsts[i].bounds; if (Utils::Maths::Vec3SqrDistance(playerPosition, staticModel->placement.origin) < sqrDist) { if (staticModel->model) { - - Game::R_AddDebugBounds(staticModelsColor, b); + Game::R_AddDebugBounds(staticModelsColor, b); } } } @@ -458,6 +462,44 @@ namespace Components } } + void Renderer::DebugDrawRunners() + { + if (!Game::CL_IsCgameInitialized()) + { + return; + } + + if (!r_drawRunners.get()) + { + return; + } + + auto* fxSystem = reinterpret_cast(0x173F200); + + if (fxSystem) + { + for (auto i = 0; i < fxSystem->activeElemCount; i++) + { + auto* elem = &fxSystem->effects[i]; + if (elem->def) + { + Game::R_AddDebugString(sceneModelsColor, elem->frameNow.origin, 1.0f, elem->def->name); + } + } + } + + auto soundCount = *reinterpret_cast(0x7C5C90); + auto* sounds = reinterpret_cast(0x7C5CA0); + + for (auto i = 0; i < soundCount; i++) + { + if (sounds[i].aliasList) + { + Game::R_AddDebugString(staticModelsColor, sounds[i].origin, 1.0f, sounds[i].aliasList->aliasName); + } + } + } + void Renderer::DebugDrawAABBTrees() { if (!r_drawAABBTrees.get()) return; @@ -507,6 +549,7 @@ namespace Components { if (Game::CL_IsCgameInitialized()) { + DebugDrawRunners(); DebugDrawAABBTrees(); DebugDrawModelNames(); DebugDrawModelBoundingBoxes(); @@ -565,6 +608,7 @@ namespace Components Renderer::r_drawSceneModelCollisions = Game::Dvar_RegisterBool("r_drawSceneModelCollisions", false, Game::DVAR_CHEAT, "Draw scene model collisions"); Renderer::r_drawTriggers = Game::Dvar_RegisterBool("r_drawTriggers", false, Game::DVAR_CHEAT, "Draw triggers"); Renderer::r_drawModelNames = Game::Dvar_RegisterEnum("r_drawModelNames", values, 0, Game::DVAR_CHEAT, "Draw all model names"); + Renderer::r_drawRunners = Game::Dvar_RegisterBool("r_drawRunners", false, Game::DVAR_NONE, "Draw active sound & fx runners"); Renderer::r_drawAABBTrees = Game::Dvar_RegisterBool("r_drawAabbTrees", false, Game::DVAR_CHEAT, "Draw aabb trees"); Renderer::r_playerDrawDebugDistance = Game::Dvar_RegisterInt("r_drawDebugDistance", 1000, 0, 50000, Game::DVAR_ARCHIVE, "r_draw debug functions draw distance relative to the player"); Renderer::r_forceTechnique = Game::Dvar_RegisterInt("r_forceTechnique", 0, 0, 14, Game::DVAR_NONE, "Force a base technique on the renderer"); diff --git a/src/Components/Modules/Renderer.hpp b/src/Components/Modules/Renderer.hpp index c856376e..7c619af3 100644 --- a/src/Components/Modules/Renderer.hpp +++ b/src/Components/Modules/Renderer.hpp @@ -28,7 +28,7 @@ namespace Components static void PostVidRestart(); static void PostVidRestartStub(); - static void R_TextureFromCodeError(const char* sampler, Game::GfxCmdBufState* state); + static void R_TextureFromCodeError(const char* sampler, Game::GfxCmdBufState* state, int samplerCode); static void StoreGfxBufContextPtrStub1(); static void StoreGfxBufContextPtrStub2(); @@ -38,6 +38,7 @@ namespace Components static void DebugDrawSceneModelCollisions(); static void DebugDrawModelBoundingBoxes(); static void DebugDrawModelNames(); + static void DebugDrawRunners(); static void DebugDrawAABBTrees(); static void ForceTechnique(); @@ -53,6 +54,7 @@ namespace Components static Dvar::Var r_drawSceneModelCollisions; static Dvar::Var r_drawModelBoundingBoxes; static Dvar::Var r_drawModelNames; + static Dvar::Var r_drawRunners; static Dvar::Var r_drawAABBTrees; static Dvar::Var r_playerDrawDebugDistance; static Dvar::Var r_forceTechnique; diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 04840947..4ba05281 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -10852,6 +10852,130 @@ namespace Game HANDLE handle; }; + struct FxCamera + { + float origin[3]; + volatile int isValid; + float frustum[6][4]; + float axis[3][3]; + unsigned int frustumPlaneCount; + float viewOffset[3]; + bool thermal; + unsigned int pad[2]; + }; + + struct r_double_index_t + { + unsigned __int16 value[2]; + }; + + struct FxSpriteInfo + { + r_double_index_t* indices; + unsigned int indexCount; + Material* material; + const char* name; + }; + + struct FxVisBlocker + { + float origin[3]; + unsigned __int16 radius; + unsigned __int16 visibility; + }; + + struct FxVisState + { + FxVisBlocker blocker[256]; + volatile int blockerCount; + unsigned int pad[3]; + }; + + struct FxElem + { + char defIndex; + char sequence; + char atRestFraction; + char emitResidual; + unsigned __int16 nextElemHandleInEffect; + unsigned __int16 prevElemHandleInEffect; + int msecBegin; + float baseVel[3]; + union + { + int physObjId; + float origin[3]; + } ___u8; + union + { + unsigned __int16 lightingHandle; + unsigned __int16 sparkCloudHandle; + unsigned __int16 sparkFountainHandle; + } u; + }; + + struct FxSystem + { + FxCamera camera; + FxCamera cameraPrev; + FxSpriteInfo sprite; + FxEffect* effects; + FxElem* elems; + void* trails; + void* trailElems; + void* bolts; + void* sparkClouds; + void* sparkFountains; + void* sparkFountainClusters; + unsigned __int16* deferredElems; + volatile int firstFreeElem; + volatile int firstFreeTrailElem; + volatile int firstFreeTrail; + volatile int firstFreeBolt; + volatile int firstFreeSparkCloud; + volatile int firstFreeSparkFountain; + volatile int firstFreeSparkFountainCluster; + volatile int deferredElemCount; + volatile int activeElemCount; + volatile int activeTrailElemCount; + volatile int activeTrailCount; + volatile int activeBoltCount; + volatile int activeSparkCloudCount; + volatile int activeSparkFountainCount; + volatile int activeSparkFountainClusterCount; + volatile int gfxCloudCount; + FxVisState* visState; + FxVisState* visStateBufferRead; + FxVisState* visStateBufferWrite; + volatile int firstActiveEffect; + volatile int firstNewEffect; + volatile int firstFreeEffect; + unsigned __int16 allEffectHandles[1024]; + volatile int activeSpotLightEffectCount; + volatile int activeSpotLightElemCount; + unsigned __int16 activeSpotLightEffectHandle; + unsigned __int16 activeSpotLightElemHandle; + __int16 activeSpotLightBoltDobj; + volatile int iteratorCount; + int msecNow; + volatile int msecDraw; + int frameCount; + bool isInitialized; + bool needsGarbageCollection; + bool isArchiving; + char localClientNum; + unsigned int restartList[32]; + FxEffect** restartEffectsList; + unsigned int restartCount; + unsigned int pad1[14]; + }; + + struct ClientEntSound + { + float origin[3]; + snd_alias_list_t* aliasList; + }; + #pragma endregion #ifndef IDA