diff --git a/README.md b/README.md index d63b2908..a0e93bae 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,6 @@ CBoat CBulletInfo CExplosion CMenuManager - WIP -CMotionBlurStreaks CObject CPacManPickups CPad - only cheats @@ -53,7 +52,6 @@ CRecordDataForChase CRecordDataForGame CRoadBlocks CSkidmarks -CSpecialFX CStats CTrafficLights CWeapon diff --git a/src/core/config.h b/src/core/config.h index 1dc6abe9..dfc454a8 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -78,6 +78,7 @@ enum Config { NUMMONEYMESSAGES = 16, NUMPICKUPMESSAGES = 16, NUMBULLETTRACES = 16, + NUMMBLURSTREAKS = 4, NUMONSCREENTIMERENTRIES = 1, NUMRADARBLIPS = 32, diff --git a/src/core/main.cpp b/src/core/main.cpp index 674527f5..fb5beee0 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -162,17 +162,17 @@ Idle(void *arg) } else { CPointLights::InitPerFrame(); #ifdef TIMEBARS - tbStartTimer(0, "CGame::Process"); + tbStartTimer(0, "CGame::Process"); #endif CGame::Process(); #ifdef TIMEBARS tbEndTimer("CGame::Process"); - tbStartTimer(0, "DMAudio.Service"); + tbStartTimer(0, "DMAudio.Service"); #endif DMAudio.Service(); #ifdef TIMEBARS - tbEndTimer("DMAudio.Service"); + tbEndTimer("DMAudio.Service"); #endif } @@ -181,18 +181,18 @@ Idle(void *arg) #else CPointLights::InitPerFrame(); #ifdef TIMEBARS - tbStartTimer(0, "CGame::Process"); + tbStartTimer(0, "CGame::Process"); #endif CGame::Process(); #ifdef TIMEBARS tbEndTimer("CGame::Process"); - tbStartTimer(0, "DMAudio.Service"); + tbStartTimer(0, "DMAudio.Service"); #endif DMAudio.Service(); #ifdef TIMEBARS - tbEndTimer("DMAudio.Service"); + tbEndTimer("DMAudio.Service"); #endif #endif @@ -222,16 +222,16 @@ Idle(void *arg) } #endif #ifdef TIMEBARS - tbStartTimer(0, "CnstrRenderList"); + tbStartTimer(0, "CnstrRenderList"); #endif CRenderer::ConstructRenderList(); #ifdef TIMEBARS tbEndTimer("CnstrRenderList"); - tbStartTimer(0, "PreRender"); + tbStartTimer(0, "PreRender"); #endif CRenderer::PreRender(); #ifdef TIMEBARS - tbEndTimer("PreRender"); + tbEndTimer("PreRender"); #endif if(CWeather::LightningFlash && !CCullZones::CamNoRain()){ @@ -251,17 +251,17 @@ Idle(void *arg) RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart()); #ifdef TIMEBARS - tbStartTimer(0, "RenderScene"); + tbStartTimer(0, "RenderScene"); #endif RenderScene(); #ifdef TIMEBARS - tbEndTimer("RenderScene"); + tbEndTimer("RenderScene"); #endif RenderDebugShit(); RenderEffects(); -#ifdef TIMEBARS - tbStartTimer(0, "RenderMotionBlur"); +#ifdef TIMEBARS + tbStartTimer(0, "RenderMotionBlur"); #endif if((TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_NORMAL) && TheCamera.m_ScreenReductionPercentage > 0.0f) @@ -269,11 +269,11 @@ Idle(void *arg) TheCamera.RenderMotionBlur(); #ifdef TIMEBARS tbEndTimer("RenderMotionBlur"); - tbStartTimer(0, "Render2dStuff"); + tbStartTimer(0, "Render2dStuff"); #endif Render2dStuff(); #ifdef TIMEBARS - tbEndTimer("Render2dStuff"); + tbEndTimer("Render2dStuff"); #endif }else{ float viewWindow = DEFAULT_VIEWWINDOW; @@ -293,21 +293,21 @@ Idle(void *arg) DefinedState(); #endif #ifdef TIMEBARS - tbStartTimer(0, "RenderMenus"); + tbStartTimer(0, "RenderMenus"); #endif RenderMenus(); #ifdef TIMEBARS tbEndTimer("RenderMenus"); - tbStartTimer(0, "DoFade"); + tbStartTimer(0, "DoFade"); #endif DoFade(); #ifdef TIMEBARS tbEndTimer("DoFade"); - tbStartTimer(0, "Render2dStuff-Fade"); + tbStartTimer(0, "Render2dStuff-Fade"); #endif Render2dStuffAfterFade(); #ifdef TIMEBARS - tbEndTimer("Render2dStuff-Fade"); + tbEndTimer("Render2dStuff-Fade"); #endif CCredits::Render(); diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp index 8bec1ac8..7a050818 100644 --- a/src/entities/Entity.cpp +++ b/src/entities/Entity.cpp @@ -394,13 +394,13 @@ CEntity::PreRender(void) }else if(GetModelIndex() == MI_GRENADE){ CMotionBlurStreaks::RegisterStreak((uintptr)this, 100, 100, 100, - TheCamera.GetPosition() - 0.07f*TheCamera.GetRight(), - TheCamera.GetPosition() + 0.07f*TheCamera.GetRight()); + GetPosition() - 0.07f*TheCamera.GetRight(), + GetPosition() + 0.07f*TheCamera.GetRight()); }else if(GetModelIndex() == MI_MOLOTOV){ CMotionBlurStreaks::RegisterStreak((uintptr)this, 0, 100, 0, - TheCamera.GetPosition() - 0.07f*TheCamera.GetRight(), - TheCamera.GetPosition() + 0.07f*TheCamera.GetRight()); + GetPosition() - 0.07f*TheCamera.GetRight(), + GetPosition() + 0.07f*TheCamera.GetRight()); } }else if(GetModelIndex() == MI_MISSILE){ CVector pos = GetPosition(); diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp index f126e197..0d856d9c 100644 --- a/src/render/SpecialFX.cpp +++ b/src/render/SpecialFX.cpp @@ -9,9 +9,12 @@ #include "TxdStore.h" #include "FileMgr.h" #include "FileLoader.h" +#include "Timecycle.h" #include "Lights.h" +#include "ModelIndices.h" #include "VisibilityPlugins.h" #include "World.h" +#include "PlayerPed.h" #include "Particle.h" #include "Shadows.h" #include "General.h" @@ -19,17 +22,247 @@ #include "Shadows.h" #include "main.h" -WRAPPER void CSpecialFX::Render(void) { EAXJMP(0x518DC0); } -WRAPPER void CSpecialFX::Update(void) { EAXJMP(0x518D40); } -WRAPPER void CSpecialFX::Init(void) { EAXJMP(0x5189E0); } -WRAPPER void CSpecialFX::Shutdown(void) { EAXJMP(0x518BE0); } +RxObjSpace3DVertex StreakVertices[4]; +RwImVertexIndex StreakIndexList[12]; -WRAPPER void CMotionBlurStreaks::RegisterStreak(int32 id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2) { EAXJMP(0x519460); } +RxObjSpace3DVertex TraceVertices[6]; +RwImVertexIndex TraceIndexList[12]; -CBulletTrace (&CBulletTraces::aTraces)[NUMBULLETTRACES] = *(CBulletTrace(*)[NUMBULLETTRACES])*(uintptr*)0x72B1B8; -RxObjSpace3DVertex (&TraceVertices)[6] = *(RxObjSpace3DVertex(*)[6])*(uintptr*)0x649884; -RwImVertexIndex (&TraceIndexList)[12] = *(RwImVertexIndex(*)[12])*(uintptr*)0x64986C; +void +CSpecialFX::Init(void) +{ + CBulletTraces::Init(); + + RwIm3DVertexSetU(&StreakVertices[0], 0.0f); + RwIm3DVertexSetV(&StreakVertices[0], 0.0f); + RwIm3DVertexSetU(&StreakVertices[1], 1.0f); + RwIm3DVertexSetV(&StreakVertices[1], 0.0f); + RwIm3DVertexSetU(&StreakVertices[2], 0.0f); + RwIm3DVertexSetV(&StreakVertices[2], 0.0f); + RwIm3DVertexSetU(&StreakVertices[3], 1.0f); + RwIm3DVertexSetV(&StreakVertices[3], 0.0f); + + StreakIndexList[0] = 0; + StreakIndexList[1] = 1; + StreakIndexList[2] = 2; + StreakIndexList[3] = 1; + StreakIndexList[4] = 3; + StreakIndexList[5] = 2; + StreakIndexList[6] = 0; + StreakIndexList[7] = 2; + StreakIndexList[8] = 1; + StreakIndexList[9] = 1; + StreakIndexList[10] = 2; + StreakIndexList[11] = 3; + + RwIm3DVertexSetRGBA(&TraceVertices[0], 20, 20, 20, 255); + RwIm3DVertexSetRGBA(&TraceVertices[1], 20, 20, 20, 255); + RwIm3DVertexSetRGBA(&TraceVertices[2], 70, 70, 70, 255); + RwIm3DVertexSetRGBA(&TraceVertices[3], 70, 70, 70, 255); + RwIm3DVertexSetRGBA(&TraceVertices[4], 10, 10, 10, 255); + RwIm3DVertexSetRGBA(&TraceVertices[5], 10, 10, 10, 255); + RwIm3DVertexSetU(&TraceVertices[0], 0.0); + RwIm3DVertexSetV(&TraceVertices[0], 0.0); + RwIm3DVertexSetU(&TraceVertices[1], 1.0); + RwIm3DVertexSetV(&TraceVertices[1], 0.0); + RwIm3DVertexSetU(&TraceVertices[2], 0.0); + RwIm3DVertexSetV(&TraceVertices[2], 0.5); + RwIm3DVertexSetU(&TraceVertices[3], 1.0); + RwIm3DVertexSetV(&TraceVertices[3], 0.5); + RwIm3DVertexSetU(&TraceVertices[4], 0.0); + RwIm3DVertexSetV(&TraceVertices[4], 1.0); + RwIm3DVertexSetU(&TraceVertices[5], 1.0); + RwIm3DVertexSetV(&TraceVertices[5], 1.0); + + TraceIndexList[0] = 0; + TraceIndexList[1] = 2; + TraceIndexList[2] = 1; + TraceIndexList[3] = 1; + TraceIndexList[4] = 2; + TraceIndexList[5] = 3; + TraceIndexList[6] = 2; + TraceIndexList[7] = 4; + TraceIndexList[8] = 3; + TraceIndexList[9] = 3; + TraceIndexList[10] = 4; + TraceIndexList[11] = 5; + + CMotionBlurStreaks::Init(); + CBrightLights::Init(); + CShinyTexts::Init(); + CMoneyMessages::Init(); + C3dMarkers::Init(); +} + +RwObject* +LookForBatCB(RwObject *object, void *data) +{ + static CMatrix MatLTM; + + if(CVisibilityPlugins::GetAtomicModelInfo((RpAtomic*)object) == (CSimpleModelInfo*)data){ + MatLTM = CMatrix(RwFrameGetLTM(RpAtomicGetFrame((RpAtomic*)object))); + CVector p1 = MatLTM * CVector(0.02f, 0.05f, 0.07f); + CVector p2 = MatLTM * CVector(0.246f, 0.0325f, 0.796f); + CMotionBlurStreaks::RegisterStreak((uintptr)object, 100, 100, 100, p1, p2); + } + return nil; +} + +void +CSpecialFX::Update(void) +{ + CMotionBlurStreaks::Update(); + CBulletTraces::Update(); + + if(FindPlayerPed() && + FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT && + FindPlayerPed()->GetWeapon()->m_eWeaponState == WEAPONSTATE_FIRING) + RwFrameForAllObjects(FindPlayerPed()->GetNodeFrame(PED_HANDR), LookForBatCB, CModelInfo::GetModelInfo(MI_BASEBALL_BAT)); +} + +void +CSpecialFX::Shutdown(void) +{ + C3dMarkers::Shutdown(); +} + +void +CSpecialFX::Render(void) +{ + CMotionBlurStreaks::Render(); + CBulletTraces::Render(); + CBrightLights::Render(); + CShinyTexts::Render(); + CMoneyMessages::Render(); + C3dMarkers::Render(); +} + +CRegisteredMotionBlurStreak CMotionBlurStreaks::aStreaks[NUMMBLURSTREAKS]; + +void +CRegisteredMotionBlurStreak::Update(void) +{ + int i; + bool wasUpdated; + bool lastWasUpdated = false; + for(i = 2; i > 0; i--){ + m_pos1[i] = m_pos1[i-1]; + m_pos2[i] = m_pos2[i-1]; + m_isValid[i] = m_isValid[i-1]; + wasUpdated = true; + if(!lastWasUpdated && !m_isValid[i]) + wasUpdated = false; + lastWasUpdated = wasUpdated; + } + m_isValid[0] = false; + if(!wasUpdated) + m_id = 0; +} + +void +CRegisteredMotionBlurStreak::Render(void) +{ + int i; + int a1, a2; + for(i = 0; i < 2; i++) + if(m_isValid[i] && m_isValid[i+1]){ + a1 = (255/3)*(3-i)/3; + RwIm3DVertexSetRGBA(&StreakVertices[0], m_red, m_green, m_blue, a1); + RwIm3DVertexSetRGBA(&StreakVertices[1], m_red, m_green, m_blue, a1); + a2 = (255/3)*(3-(i+1))/3; + RwIm3DVertexSetRGBA(&StreakVertices[2], m_red, m_green, m_blue, a2); + RwIm3DVertexSetRGBA(&StreakVertices[3], m_red, m_green, m_blue, a2); + RwIm3DVertexSetPos(&StreakVertices[0], m_pos1[i].x, m_pos1[i].y, m_pos1[i].z); + RwIm3DVertexSetPos(&StreakVertices[1], m_pos2[i].x, m_pos2[i].y, m_pos2[i].z); + RwIm3DVertexSetPos(&StreakVertices[2], m_pos1[i+1].x, m_pos1[i+1].y, m_pos1[i+1].z); + RwIm3DVertexSetPos(&StreakVertices[3], m_pos2[i+1].x, m_pos2[i+1].y, m_pos2[i+1].z); + LittleTest(); + if(RwIm3DTransform(StreakVertices, 4, nil, rwIM3D_VERTEXUV)){ + RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, StreakIndexList, 12); + RwIm3DEnd(); + } + } +} + +void +CMotionBlurStreaks::Init(void) +{ + int i; + for(i = 0; i < NUMMBLURSTREAKS; i++) + aStreaks[i].m_id = 0; +} + +void +CMotionBlurStreaks::Update(void) +{ + int i; + for(i = 0; i < NUMMBLURSTREAKS; i++) + if(aStreaks[i].m_id) + aStreaks[i].Update(); +} + +void +CMotionBlurStreaks::RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2) +{ + int i; + for(i = 0; i < NUMMBLURSTREAKS; i++){ + if(aStreaks[i].m_id == id){ + // Found a streak from last frame, update + aStreaks[i].m_red = r; + aStreaks[i].m_green = g; + aStreaks[i].m_blue = b; + aStreaks[i].m_pos1[0] = p1; + aStreaks[i].m_pos2[0] = p2; + aStreaks[i].m_isValid[0] = true; + return; + } + } + // Find free slot + for(i = 0; aStreaks[i].m_id; i++) + if(i == NUMMBLURSTREAKS-1) + return; + // Create a new streak + aStreaks[i].m_id = id; + aStreaks[i].m_red = r; + aStreaks[i].m_green = g; + aStreaks[i].m_blue = b; + aStreaks[i].m_pos1[0] = p1; + aStreaks[i].m_pos2[0] = p2; + aStreaks[i].m_isValid[0] = true; + aStreaks[i].m_isValid[1] = false; + aStreaks[i].m_isValid[2] = false; +} + +void +CMotionBlurStreaks::Render(void) +{ + bool setRenderStates = false; + int i; + for(i = 0; i < NUMMBLURSTREAKS; i++) + if(aStreaks[i].m_id){ + if(!setRenderStates){ + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)TRUE); + RwRenderStateSet(rwRENDERSTATEFOGCOLOR, + (void*)RWRGBALONG(CTimeCycle::GetFogRed(), CTimeCycle::GetFogGreen(), CTimeCycle::GetFogBlue(), 255)); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE); + setRenderStates = true; + } + aStreaks[i].Render(); + } + if(setRenderStates){ + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)FALSE); + } +} + + +CBulletTrace CBulletTraces::aTraces[NUMBULLETTRACES]; void CBulletTraces::Init(void) { @@ -201,9 +434,9 @@ C3dMarker::Render() ReSetAmbientAndDirectionalColours(); } -C3dMarker(&C3dMarkers::m_aMarkerArray)[NUM3DMARKERS] = *(C3dMarker(*)[NUM3DMARKERS])*(uintptr*)0x72D408; -int32 &C3dMarkers::NumActiveMarkers = *(int32*)0x8F2A08; -RpClump* (&C3dMarkers::m_pRpClumpArray)[NUMMARKERTYPES] = *(RpClump*(*)[NUMMARKERTYPES])*(uintptr*)0x8E2888; +C3dMarker C3dMarkers::m_aMarkerArray[NUM3DMARKERS]; +int32 C3dMarkers::NumActiveMarkers; +RpClump* C3dMarkers::m_pRpClumpArray[NUMMARKERTYPES]; void C3dMarkers::Init() @@ -627,9 +860,7 @@ CBrightLights::RenderOutGeometryBuffer(void) TempBufferVerticesStored = 0; TempBufferIndicesStored = 0; } -} - - +} int CShinyTexts::NumShinyTexts; CShinyText CShinyTexts::aShinyTexts[NUMSHINYTEXTS]; diff --git a/src/render/SpecialFX.h b/src/render/SpecialFX.h index 1cff55b3..8519ae79 100644 --- a/src/render/SpecialFX.h +++ b/src/render/SpecialFX.h @@ -9,10 +9,29 @@ public: static void Shutdown(void); }; -class CMotionBlurStreaks +class CRegisteredMotionBlurStreak { public: - static void RegisterStreak(int32 id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2); + uintptr m_id; + uint8 m_red; + uint8 m_green; + uint8 m_blue; + CVector m_pos1[3]; + CVector m_pos2[3]; + bool m_isValid[3]; + + void Update(void); + void Render(void); +}; + +class CMotionBlurStreaks +{ + static CRegisteredMotionBlurStreak aStreaks[NUMMBLURSTREAKS]; +public: + static void Init(void); + static void Update(void); + static void RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2); + static void Render(void); }; struct CBulletTrace @@ -29,7 +48,7 @@ struct CBulletTrace class CBulletTraces { public: - static CBulletTrace (&aTraces)[NUMBULLETTRACES]; + static CBulletTrace aTraces[NUMBULLETTRACES]; static void Init(void); static void AddTrace(CVector*, CVector*); @@ -84,9 +103,9 @@ public: static void Render(); static void Update(); - static C3dMarker(&m_aMarkerArray)[NUM3DMARKERS]; - static int32 &NumActiveMarkers; - static RpClump* (&m_pRpClumpArray)[NUMMARKERTYPES]; + static C3dMarker m_aMarkerArray[NUM3DMARKERS]; + static int32 NumActiveMarkers; + static RpClump* m_pRpClumpArray[NUMMARKERTYPES]; }; enum