From c2f5dfdb1e7f46c94c80fa7d4aeb3c59acb348e7 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Sat, 21 Mar 2020 20:14:29 +0300 Subject: bullet traces --- src/control/Replay.cpp | 12 +++--- src/render/SpecialFX.cpp | 103 ++++++++++++++++++++++++++++++++++++++++++++++- src/render/SpecialFX.h | 14 +++++-- 3 files changed, 118 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index 2b7c6b62..5d651748 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -280,7 +280,7 @@ void CReplay::RecordThisFrame(void) } memory_required += sizeof(tPedUpdatePacket); } - for (uint8 i = 0; i < 16; i++) { + for (uint8 i = 0; i < CBulletTraces::NUM_BULLET_TRACES; i++) { if (!CBulletTraces::aTraces[i].m_bInUse) continue; memory_required += sizeof(tBulletTracePacket); @@ -340,7 +340,7 @@ void CReplay::RecordThisFrame(void) } StorePedUpdate(p, i); } - for (uint8 i = 0; i < 16; i++){ + for (uint8 i = 0; i < CBulletTraces::NUM_BULLET_TRACES; i++){ if (!CBulletTraces::aTraces[i].m_bInUse) continue; tBulletTracePacket* bt = (tBulletTracePacket*)&Record.m_pBase[Record.m_nOffset]; @@ -348,8 +348,8 @@ void CReplay::RecordThisFrame(void) bt->index = i; bt->frames = CBulletTraces::aTraces[i].m_framesInUse; bt->lifetime = CBulletTraces::aTraces[i].m_lifeTime; - bt->inf = CBulletTraces::aTraces[i].m_vecInf; - bt->sup = CBulletTraces::aTraces[i].m_vecSup; + bt->inf = CBulletTraces::aTraces[i].m_vecCurrentPos; + bt->sup = CBulletTraces::aTraces[i].m_vecTargetPos; Record.m_nOffset += sizeof(*bt); } tEndOfFramePacket* eof = (tEndOfFramePacket*)&Record.m_pBase[Record.m_nOffset]; @@ -995,8 +995,8 @@ bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, flo CBulletTraces::aTraces[pb->index].m_bInUse = true; CBulletTraces::aTraces[pb->index].m_framesInUse = pb->frames; CBulletTraces::aTraces[pb->index].m_lifeTime = pb->lifetime; - CBulletTraces::aTraces[pb->index].m_vecInf = pb->inf; - CBulletTraces::aTraces[pb->index].m_vecSup = pb->sup; + CBulletTraces::aTraces[pb->index].m_vecCurrentPos = pb->inf; + CBulletTraces::aTraces[pb->index].m_vecTargetPos = pb->sup; buffer->m_nOffset += sizeof(tBulletTracePacket); } default: diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp index 76abcd5b..a14da60c 100644 --- a/src/render/SpecialFX.cpp +++ b/src/render/SpecialFX.cpp @@ -14,6 +14,8 @@ #include "Particle.h" #include "General.h" #include "Camera.h" +#include "Shadows.h" +#include "main.h" WRAPPER void CSpecialFX::Render(void) { EAXJMP(0x518DC0); } WRAPPER void CSpecialFX::Update(void) { EAXJMP(0x518D40); } @@ -21,9 +23,101 @@ WRAPPER void CSpecialFX::Update(void) { EAXJMP(0x518D40); } WRAPPER void CMotionBlurStreaks::RegisterStreak(int32 id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2) { EAXJMP(0x519460); } -CBulletTrace (&CBulletTraces::aTraces)[16] = *(CBulletTrace(*)[16])*(uintptr*)0x72B1B8; +CBulletTrace (&CBulletTraces::aTraces)[NUM_BULLET_TRACES] = *(CBulletTrace(*)[NUM_BULLET_TRACES])*(uintptr*)0x72B1B8; +RxObjSpace3DVertex (&TraceVertices)[6] = *(RxObjSpace3DVertex(*)[6])*(uintptr*)0x649884; +RwImVertexIndex (&TraceIndexList)[12] = *(RwImVertexIndex(*)[12])*(uintptr*)0x64986C; -WRAPPER void CBulletTraces::Init(void) { EAXJMP(0x518DE0); } +void CBulletTraces::Init(void) +{ + for (int i = 0; i < NUM_BULLET_TRACES; i++) + aTraces[i].m_bInUse = false; +} + +void CBulletTraces::AddTrace(CVector* vecStart, CVector* vecTarget) +{ + int index; + for (index = 0; index < NUM_BULLET_TRACES; index++) { + if (!aTraces[index].m_bInUse) + break; + } + if (index == NUM_BULLET_TRACES) + return; + aTraces[index].m_vecCurrentPos = *vecStart; + aTraces[index].m_vecTargetPos = *vecTarget; + aTraces[index].m_bInUse = true; + aTraces[index].m_framesInUse = 0; + aTraces[index].m_lifeTime = 25 + CGeneral::GetRandomNumber() % 32; +} + +void CBulletTraces::Render(void) +{ + for (int i = 0; i < NUM_BULLET_TRACES; i++) { + if (!aTraces[i].m_bInUse) + continue; + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)0); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)2); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)2); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpShadowExplosionTex->raster); + CVector inf = aTraces[i].m_vecCurrentPos; + CVector sup = aTraces[i].m_vecTargetPos; + CVector center = (inf + sup) / 2; + CVector screenPos = CrossProduct(TheCamera.GetForward(), (sup - inf)); + screenPos.Normalise(); + screenPos /= 20; + uint8 intensity = aTraces[i].m_lifeTime; + uint32 color = 0xFF << 24 | intensity << 16 | intensity << 8 | intensity; + TraceVertices[0].color = color; + TraceVertices[1].color = color; + TraceVertices[2].color = color; + TraceVertices[3].color = color; + TraceVertices[4].color = color; + TraceVertices[5].color = color; + // cast to satisfy compiler + TraceVertices[0].objVertex = (const CVector&)(inf + screenPos); + TraceVertices[1].objVertex = (const CVector&)(inf - screenPos); + TraceVertices[2].objVertex = (const CVector&)(center + screenPos); + TraceVertices[3].objVertex = (const CVector&)(center - screenPos); + TraceVertices[4].objVertex = (const CVector&)(sup + screenPos); + TraceVertices[5].objVertex = (const CVector&)(sup - screenPos); + LittleTest(); + if (RwIm3DTransform(TraceVertices, ARRAY_SIZE(TraceVertices), nil, 1)) { + RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TraceIndexList, ARRAY_SIZE(TraceIndexList)); + RwIm3DEnd(); + } + } + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)1); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)5); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)6); +} + +void CBulletTraces::Update(void) +{ + for (int i = 0; i < NUM_BULLET_TRACES; i++) { + if (aTraces[i].m_bInUse) + aTraces[i].Update(); + } +} + +void CBulletTrace::Update(void) +{ + if (m_framesInUse == 0) { + m_framesInUse++; + return; + } + if (m_framesInUse > 60) { + m_bInUse = false; + return; + } + CVector diff = m_vecCurrentPos - m_vecTargetPos; + float remaining = diff.Magnitude(); + if (remaining > 0.8f) + m_vecCurrentPos = m_vecTargetPos + (remaining - 0.8f) / remaining * diff; + else + m_bInUse = false; + if (--m_lifeTime == 0) + m_bInUse = false; + m_framesInUse++; +} WRAPPER void CBrightLights::RegisterOne(CVector pos, CVector up, CVector right, CVector fwd, uint8 type, uint8 unk1, uint8 unk2, uint8 unk3) { EAXJMP(0x51A410); } @@ -460,6 +554,11 @@ CSpecialParticleStuff::UpdateBoatFoamAnimation(CMatrix* pMatrix) } STARTPATCHES + InjectHook(0x518DE0, &CBulletTraces::Init, PATCH_JUMP); + InjectHook(0x518E90, &CBulletTraces::AddTrace, PATCH_JUMP); + InjectHook(0x518F20, &CBulletTraces::Render, PATCH_JUMP); + InjectHook(0x519240, &CBulletTraces::Update, PATCH_JUMP); + InjectHook(0x51B070, &C3dMarker::AddMarker, PATCH_JUMP); InjectHook(0x51B170, &C3dMarker::DeleteMarkerObject, PATCH_JUMP); InjectHook(0x51B1B0, &C3dMarker::Render, PATCH_JUMP); diff --git a/src/render/SpecialFX.h b/src/render/SpecialFX.h index 7c0e3436..2d758fdd 100644 --- a/src/render/SpecialFX.h +++ b/src/render/SpecialFX.h @@ -15,19 +15,27 @@ public: struct CBulletTrace { - CVector m_vecInf; - CVector m_vecSup; + CVector m_vecCurrentPos; + CVector m_vecTargetPos; bool m_bInUse; uint8 m_framesInUse; uint8 m_lifeTime; + + void Update(void); }; class CBulletTraces { public: - static CBulletTrace (&aTraces)[16]; + enum { + NUM_BULLET_TRACES = 16 + }; + static CBulletTrace (&aTraces)[NUM_BULLET_TRACES]; static void Init(void); + static void AddTrace(CVector*, CVector*); + static void Render(void); + static void Update(void); }; class CBrightLights -- cgit v1.2.3