diff options
Diffstat (limited to 'src/render')
-rw-r--r-- | src/render/SpecialFX.cpp | 524 | ||||
-rw-r--r-- | src/render/SpecialFX.h | 44 |
2 files changed, 420 insertions, 148 deletions
diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp index fa8379f0..b614fae0 100644 --- a/src/render/SpecialFX.cpp +++ b/src/render/SpecialFX.cpp @@ -24,21 +24,44 @@ #include "ColStore.h" #include "Coronas.h" #include "Script.h" +#include "DMAudio.h" RwIm3DVertex StreakVertices[4]; RwImVertexIndex StreakIndexList[12]; -RwIm3DVertex TraceVertices[6]; -RwImVertexIndex TraceIndexList[12]; +RwIm3DVertex TraceVertices[10]; +static RwImVertexIndex TraceIndexList[48] = {0, 5, 7, 0, 7, 2, 0, 7, 5, 0, 2, 7, 0, 4, 9, 0, + 9, 5, 0, 9, 4, 0, 5, 9, 0, 1, 6, 0, 6, 5, 0, 6, + 1, 0, 5, 6, 0, 3, 8, 0, 8, 5, 0, 8, 3, 0, 5, 8 }; +bool CSpecialFX::bVideoCam; +bool CSpecialFX::bLiftCam; bool CSpecialFX::bSnapShotActive; int32 CSpecialFX::SnapShotFrames; +static RwTexture* gpSmokeTrailTexture; + void CSpecialFX::Init(void) { CBulletTraces::Init(); + RwIm3DVertexSetU(&TraceVertices[0], 0.0); + RwIm3DVertexSetV(&TraceVertices[0], 0.0); + RwIm3DVertexSetU(&TraceVertices[1], 1.0); + RwIm3DVertexSetV(&TraceVertices[1], 0.0); + RwIm3DVertexSetU(&TraceVertices[2], 1.0); + RwIm3DVertexSetV(&TraceVertices[2], 0.0); + RwIm3DVertexSetU(&TraceVertices[3], 1.0); + RwIm3DVertexSetV(&TraceVertices[3], 0.0); + RwIm3DVertexSetU(&TraceVertices[4], 1.0); + RwIm3DVertexSetV(&TraceVertices[4], 0.0); + RwIm3DVertexSetU(&TraceVertices[5], 0.0); + RwIm3DVertexSetU(&TraceVertices[6], 1.0); + RwIm3DVertexSetU(&TraceVertices[7], 1.0); + RwIm3DVertexSetU(&TraceVertices[8], 1.0); + RwIm3DVertexSetU(&TraceVertices[9], 1.0); + RwIm3DVertexSetU(&StreakVertices[0], 0.0f); RwIm3DVertexSetV(&StreakVertices[0], 0.0f); RwIm3DVertexSetU(&StreakVertices[1], 1.0f); @@ -47,7 +70,6 @@ CSpecialFX::Init(void) RwIm3DVertexSetV(&StreakVertices[2], 0.0f); RwIm3DVertexSetU(&StreakVertices[3], 1.0f); RwIm3DVertexSetV(&StreakVertices[3], 0.0f); - StreakIndexList[0] = 0; StreakIndexList[1] = 1; StreakIndexList[2] = 2; @@ -61,43 +83,51 @@ CSpecialFX::Init(void) 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(); + CBrightLights::Init(); CMoneyMessages::Init(); C3dMarkers::Init(); + CSpecialFX::bSnapShotActive = false; + CSpecialFX::bVideoCam = false; + CSpecialFX::SnapShotFrames = 0; + CSpecialFX::bLiftCam = false; + CTxdStore::PushCurrentTxd(); + CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("particle")); + if(gpSmokeTrailTexture == nil) + gpSmokeTrailTexture = RwTextureRead("smoketrail", 0); + CTxdStore::PopCurrentTxd(); +} + +void +CSpecialFX::AddWeaponStreak(int type) +{ + static CMatrix matrix; + CVector start; + CVector end; + + if (FindPlayerPed() != nil && FindPlayerPed()->m_pWeaponModel != nil) { + switch (type) { + case WEAPONTYPE_BASEBALLBAT: + matrix = RwFrameGetLTM(RpAtomicGetFrame(FindPlayerPed()->m_pWeaponModel)); + start = matrix * CVector(0.02f, 0.05f, 0.07f); + end = matrix * CVector(0.246f, 0.0325f, 0.796f); + break; + case WEAPONTYPE_GOLFCLUB: + matrix = RwFrameGetLTM(RpAtomicGetFrame(FindPlayerPed()->m_pWeaponModel)); + start = matrix * CVector(0.02f, 0.05f, 0.07f); + end = matrix * CVector(-0.054f, 0.0325f, 0.796f); + break; + case WEAPONTYPE_KATANA: + matrix = RwFrameGetLTM(RpAtomicGetFrame(FindPlayerPed()->m_pWeaponModel)); + start = matrix * CVector(0.02f, 0.05f, 0.07f); + end = matrix * CVector(0.096f, -0.0175f, 1.096f); + break; + default: + break; + } + CMotionBlurStreaks::RegisterStreak((uintptr)FindPlayerPed()->m_pWeaponModel, 100, 100, 100, start, end); + } } RwObject* @@ -119,23 +149,16 @@ CSpecialFX::Update(void) { CMotionBlurStreaks::Update(); CBulletTraces::Update(); - - if(FindPlayerPed() && - FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT && - FindPlayerPed()->GetWeapon()->m_eWeaponState == WEAPONSTATE_FIRING){ -#ifdef PED_SKIN - if(IsClumpSkinned(FindPlayerPed()->GetClump())){ - LookForBatCB((RwObject*)FindPlayerPed()->m_pWeaponModel, CModelInfo::GetModelInfo(MI_BASEBALL_BAT)); - }else -#endif - RwFrameForAllObjects(FindPlayerPed()->m_pFrames[PED_HANDR]->frame, LookForBatCB, CModelInfo::GetModelInfo(MI_BASEBALL_BAT)); - } } void CSpecialFX::Shutdown(void) { C3dMarkers::Shutdown(); + if (gpSmokeTrailTexture) { + RwTextureDestroy(gpSmokeTrailTexture); + gpSmokeTrailTexture = nil; + } } void @@ -149,6 +172,80 @@ CSpecialFX::Render(void) C3dMarkers::Render(); } +void +CSpecialFX::Render2DFXs(void) +{ + if (CSpecialFX::bVideoCam) { + CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f)); + CFont::SetJustifyOff(); + CFont::SetBackgroundOff(); + CFont::SetCentreSize(SCREEN_SCALE_FROM_RIGHT(20.0f)); + CFont::SetCentreOff(); + CFont::SetPropOn(); + CFont::SetColor(CRGBA(0, 255, 0, 200)); + FONT_LOCALE(FONT_STANDARD); + sprintf(gString, "%d", CTimer::GetFrameCounter() & 0x3F); // mb % 63 + AsciiToUnicode(gString, gUString); + CFont::PrintString(SCREEN_WIDTH * 8 / 10, SCREEN_HEIGHT * 8 / 10, gUString); + for (int32 i = 0; i < SCREEN_HEIGHT; i += 4) { + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDONE); + CSprite2d::Draw2DPolygon(0.0f, i, SCREEN_WIDTH, i, 0.0f, i+1, SCREEN_WIDTH, i+1, CRGBA(0, 100, 0, 100)); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + CSprite2d::Draw2DPolygon(0.0f, i+2, SCREEN_WIDTH, i+2, 0.0f, i+3, SCREEN_WIDTH, i+3, CRGBA(0, 0, 0, 150)); + } + int32 tmp = (CTimer::GetTimeInMilliseconds() & 0x7ff) * (SCREEN_HEIGHT + 70.0f) / 2048 - 70.0f; //mb % 2048 + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + CSprite2d::Draw2DPolygon(0.0, tmp, SCREEN_WIDTH, tmp, 0.0, tmp + 70.0f, SCREEN_WIDTH, tmp + 70.0f , CRGBA(0, 100, 0, 60)); + } + if (CSpecialFX::bLiftCam) { + CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f)); + CFont::SetJustifyOff(); + CFont::SetBackgroundOff(); + CFont::SetCentreSize(SCREEN_SCALE_FROM_RIGHT(20.0f)); + CFont::SetCentreOff(); + CFont::SetPropOn(); + CFont::SetColor(CRGBA(100, 100, 100, 200)); + FONT_LOCALE(FONT_STANDARD); + CFont::PrintString(SCREEN_WIDTH * 8 / 10, SCREEN_HEIGHT * 8 / 10, gUString); + for (int32 i = 0; i < SCREEN_HEIGHT; i += 4) { + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + CSprite2d::Draw2DPolygon(0.0f, i, SCREEN_WIDTH, i, 0.0f, i + 1, SCREEN_WIDTH, i + 1, CRGBA(100, 100, 100, 100)); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + CSprite2d::Draw2DPolygon(0.0f, i + 2, SCREEN_WIDTH, i + 2, 0.0f, i + 3, SCREEN_WIDTH, i + 3, CRGBA(0, 0, 0, 150)); + } + int32 tmp = (CTimer::GetTimeInMilliseconds() & 0x7ff) * (SCREEN_HEIGHT + 70.0f) / 2048 - 70.0f; //mb % 2048 + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + CSprite2d::Draw2DPolygon(0.0, tmp, SCREEN_WIDTH, tmp, 0.0, tmp + 70.0f, SCREEN_WIDTH, tmp + 70.0f, CRGBA(100, 100, 100, 60)); + for (int32 i = 0; i < 200; i++) { + int32 posX = CGeneral::GetRandomNumber() % (int32)SCREEN_WIDTH; + int32 posY = CGeneral::GetRandomNumber() % (int32)SCREEN_HEIGHT; + CSprite2d::DrawRect(CRect(posX, posY + 2, posX+20, posY), CRGBA(255, 255, 255, 64)); + } + } + if (CSpecialFX::bSnapShotActive) { + if (++CSpecialFX::SnapShotFrames > 20) { + CSpecialFX::bSnapShotActive = false; + CTimer::SetTimeScale(1.0f); + } else { + CTimer::SetTimeScale(0.0f); //in andro it's 0.00001 + if (CSpecialFX::SnapShotFrames < 10) { + int32 tmp = (1 - CSpecialFX::SnapShotFrames / 10) * 255 * 0.65f; + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + CSprite2d::Draw2DPolygon(0.0f, 0.0f, SCREEN_WIDTH, 0.0f, 0.0f, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, CRGBA(tmp, tmp, tmp, tmp)); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + } + } + } +} + CRegisteredMotionBlurStreak CMotionBlurStreaks::aStreaks[NUMMBLURSTREAKS]; void @@ -217,6 +314,7 @@ 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 @@ -229,10 +327,12 @@ CMotionBlurStreaks::RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVecto return; } } + // Find free slot - for(i = 0; aStreaks[i].m_id; i++) + for(i = 0; aStreaks[i].m_id != nil ; i++) if(i == NUMMBLURSTREAKS-1) return; + // Create a new streak aStreaks[i].m_id = id; aStreaks[i].m_red = r; @@ -251,7 +351,7 @@ CMotionBlurStreaks::Render(void) bool setRenderStates = false; int i; for(i = 0; i < NUMMBLURSTREAKS; i++) - if(aStreaks[i].m_id){ + if(aStreaks[i].m_id != nil){ if(!setRenderStates){ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); @@ -281,20 +381,102 @@ void CBulletTraces::Init(void) aTraces[i].m_bInUse = false; } -void CBulletTraces::AddTrace(CVector* vecStart, CVector* vecTarget) +void CBulletTraces::AddTrace(CVector* start, CVector* end, float thicknes, uint32 lifeTime, uint8 visibility) { - int index; - for (index = 0; index < NUMBULLETTRACES; index++) { - if (!aTraces[index].m_bInUse) - break; + int32 enabledCount; + uint32 modifiedLifeTime; + int32 nextSlot; + + enabledCount = 0; + for (int i = 0; i < NUMBULLETTRACES; i++) + if (aTraces[i].m_bInUse) + enabledCount++; + if (enabledCount >= 10) + modifiedLifeTime = lifeTime / 4; + else if (enabledCount >= 5) + modifiedLifeTime = lifeTime / 2; + else + modifiedLifeTime = lifeTime; + + nextSlot = 0; + for (int i = 0; nextSlot < NUMBULLETTRACES && aTraces[i].m_bInUse; i++) + nextSlot++; + if (nextSlot < 16) { + aTraces[nextSlot].m_vecCurrentPos = *start; + aTraces[nextSlot].m_vecTargetPos = *end; + aTraces[nextSlot].m_bInUse = true; + aTraces[nextSlot].m_nCreationTime = CTimer::GetTimeInMilliseconds(); + aTraces[nextSlot].m_fVisibility = visibility; + aTraces[nextSlot].m_fThicknes = thicknes; + aTraces[nextSlot].m_nLifeTime = modifiedLifeTime; + } + + float upDotProd = DotProduct(TheCamera.GetUp(), *start - TheCamera.GetPosition()); + float forwardDotProd = DotProduct(TheCamera.GetForward(), *start - TheCamera.GetPosition()); + float upDotProdEnd = DotProduct(TheCamera.GetUp(), *end - TheCamera.GetPosition()); + float forwardDotProdEnd = DotProduct(TheCamera.GetForward(), *end - TheCamera.GetPosition()); + if (forwardDotProd*forwardDotProdEnd < 0.0f) { + float tmp = Abs(forwardDotProd) / (Abs(forwardDotProd) + Abs(forwardDotProdEnd)); + float tmp2 = (upDotProdEnd - upDotProd) * tmp + upDotProd; + float dotProdEndRight = DotProduct(TheCamera.GetRight(), *end - TheCamera.GetPosition()); + float dotProdRight = DotProduct(TheCamera.GetRight(), *start - TheCamera.GetPosition()); + float tmp3 = (dotProdEndRight - dotProdRight) * tmp + dotProdRight; + float dist = Sqrt(SQR(tmp2) + SQR(tmp3)); + if (dist < 2.0f) { + if(tmp3 < 0.0f) + DMAudio.PlayFrontEndSound(SOUND_BULLETTRACE_2, 127 * (1.0f - dist * 0.5f)); + else + DMAudio.PlayFrontEndSound(SOUND_BULLETTRACE_1, 127 * (1.0f - dist * 0.5f)); + } + } +} + +void CBulletTraces::AddTrace(CVector* start, CVector* end, int32 weaponType, class CEntity* shooter) +{ + CPhysical* player; + float speed; + int16 camMode; + + if (shooter == (CEntity*)FindPlayerPed() || (FindPlayerVehicle() != nil && FindPlayerVehicle() == (CVehicle*)shooter)) { + camMode = TheCamera.Cams[TheCamera.ActiveCam].Mode; + if (camMode == CCam::MODE_M16_1STPERSON + || camMode == CCam::MODE_CAMERA + || camMode == CCam::MODE_SNIPER + || camMode == CCam::MODE_M16_1STPERSON_RUNABOUT +#ifdef MOBILE_IMPROVEMENTS + || camMode == CCam::MODE_ROCKETLAUNCHER + || camMode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT +#endif + || camMode == CCam::MODE_SNIPER_RUNABOUT + || camMode == CCam::MODE_HELICANNON_1STPERSON) { + + player = FindPlayerVehicle() ? (CPhysical*)FindPlayerVehicle() : (CPhysical*)FindPlayerPed(); + speed = player->m_vecMoveSpeed.Magnitude(); + if (speed < 0.05f) + return; + } + } + + switch (weaponType) { + case WEAPONTYPE_PYTHON: + case WEAPONTYPE_SHOTGUN: + case WEAPONTYPE_SPAS12_SHOTGUN: + case WEAPONTYPE_STUBBY_SHOTGUN: + CBulletTraces::AddTrace(start, end, 0.7f, 1000, 200); + break; + case WEAPONTYPE_M4: + case WEAPONTYPE_RUGER: + case WEAPONTYPE_SNIPERRIFLE: + case WEAPONTYPE_LASERSCOPE: + case WEAPONTYPE_M60: + case WEAPONTYPE_MINIGUN: + case WEAPONTYPE_HELICANNON: + CBulletTraces::AddTrace(start, end, 1.0f, 2000, 220); + break; + default: + CBulletTraces::AddTrace(start, end, 0.4f, 750, 150); + break; } - if (index == NUMBULLETTRACES) - 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) @@ -303,34 +485,113 @@ void CBulletTraces::Render(void) if (!aTraces[i].m_bInUse) continue; RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); -#ifdef FIX_BUGS - // Raster has no transparent pixels so it relies on the raster format having alpha - // to turn on blending. librw image conversion might get rid of it right now so let's - // just force it on. - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); -#endif - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpShadowExplosionTex)); - CVector inf = aTraces[i].m_vecCurrentPos; - CVector sup = aTraces[i].m_vecTargetPos; - CVector center = (inf + sup) / 2; - CVector width = CrossProduct(TheCamera.GetForward(), (sup - inf)); - width.Normalise(); - width /= 20; - uint8 intensity = aTraces[i].m_lifeTime; - for (int i = 0; i < ARRAY_SIZE(TraceVertices); i++) - RwIm3DVertexSetRGBA(&TraceVertices[i], intensity, intensity, intensity, 0xFF); - RwIm3DVertexSetPos(&TraceVertices[0], inf.x + width.x, inf.y + width.y, inf.z + width.z); - RwIm3DVertexSetPos(&TraceVertices[1], inf.x - width.x, inf.y - width.y, inf.z - width.z); - RwIm3DVertexSetPos(&TraceVertices[2], center.x + width.x, center.y + width.y, center.z + width.z); - RwIm3DVertexSetPos(&TraceVertices[3], center.x - width.x, center.y - width.y, center.z - width.z); - RwIm3DVertexSetPos(&TraceVertices[4], sup.x + width.x, sup.y + width.y, sup.z + width.z); - RwIm3DVertexSetPos(&TraceVertices[5], sup.x - width.x, sup.y - width.y, sup.z - width.z); - LittleTest(); - if (RwIm3DTransform(TraceVertices, ARRAY_SIZE(TraceVertices), nil, 1)) { - RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TraceIndexList, ARRAY_SIZE(TraceIndexList)); - RwIm3DEnd(); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSmokeTrailTexture)); + + float nTimeOfLiving = CTimer::GetTimeInMilliseconds() - aTraces[i].m_nCreationTime; + + float traceThicknes = aTraces[i].m_fThicknes * nTimeOfLiving / aTraces[i].m_nLifeTime; + CVector vecOffset = aTraces[i].m_vecTargetPos - aTraces[i].m_vecCurrentPos; + vecOffset.Normalise(); + vecOffset *= traceThicknes; + uint8 nAlphaValue = aTraces[i].m_fVisibility * (aTraces[i].m_nLifeTime - nTimeOfLiving) / aTraces[i].m_nLifeTime; + + CVector currentPos = aTraces[i].m_vecCurrentPos; + CVector targetPos = aTraces[i].m_vecTargetPos; + float dotProdCur = DotProduct(currentPos - TheCamera.GetPosition(), TheCamera.GetForward()) - 0.7f; + float dotProdTar = DotProduct(targetPos - TheCamera.GetPosition(), TheCamera.GetForward()) - 0.7f; + if (dotProdCur >= 0.0f || dotProdTar >= 0.0f) { + if (dotProdCur < 0.0f) { + float absDotProdCur = Abs(dotProdCur); + float absDotProdTar = Abs(dotProdTar); + currentPos = (absDotProdTar * currentPos + absDotProdCur * targetPos) / (absDotProdCur + absDotProdTar); + } else if (dotProdTar < 0.0f){ + float absDotProdCur = Abs(dotProdCur); + float absDotProdTar = Abs(dotProdTar); + targetPos = (absDotProdTar * currentPos + absDotProdCur * targetPos) / (absDotProdCur + absDotProdTar); + } + RwIm3DVertexSetV(&TraceVertices[5], 10.0f); + RwIm3DVertexSetV(&TraceVertices[6], 10.0f); + RwIm3DVertexSetV(&TraceVertices[7], 10.0f); + RwIm3DVertexSetV(&TraceVertices[8], 10.0f); + RwIm3DVertexSetV(&TraceVertices[9], 10.0f); + + RwIm3DVertexSetRGBA(&TraceVertices[0], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[1], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[2], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[3], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[4], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[5], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[6], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[7], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[8], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[9], 255, 255, 255, nAlphaValue); + + CVector currentPos2 = (7.0f * currentPos + targetPos) / 8; + CVector targetPos2 = (7.0f * targetPos + currentPos) / 8; + RwIm3DVertexSetPos(&TraceVertices[0], currentPos2.x, currentPos2.y, currentPos2.z); + RwIm3DVertexSetPos(&TraceVertices[1], currentPos2.x, currentPos2.y, currentPos2.z + traceThicknes); + RwIm3DVertexSetPos(&TraceVertices[2], currentPos2.x + vecOffset.y, currentPos2.y - vecOffset.x, currentPos2.z); + RwIm3DVertexSetPos(&TraceVertices[3], currentPos2.x, currentPos2.y, currentPos2.z - traceThicknes); + RwIm3DVertexSetPos(&TraceVertices[4], currentPos2.x - vecOffset.y, currentPos2.y - vecOffset.y, currentPos2.z); + + RwIm3DVertexSetPos(&TraceVertices[5], targetPos2.x, targetPos2.y, targetPos2.z); + RwIm3DVertexSetPos(&TraceVertices[6], targetPos2.x, targetPos2.y, targetPos2.z + traceThicknes); + RwIm3DVertexSetPos(&TraceVertices[7], targetPos2.x + vecOffset.y, targetPos2.y - vecOffset.x, targetPos2.z); + RwIm3DVertexSetPos(&TraceVertices[8], targetPos2.x, targetPos2.y, targetPos2.z - traceThicknes); + RwIm3DVertexSetPos(&TraceVertices[9], targetPos2.x - vecOffset.y, targetPos2.y - vecOffset.y, targetPos2.z); + + if (RwIm3DTransform(TraceVertices, ARRAY_SIZE(TraceVertices), nil, 1)) { + RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TraceIndexList, ARRAY_SIZE(TraceIndexList)); + RwIm3DEnd(); + } + + + RwIm3DVertexSetV(&TraceVertices[5], 2.0f); + RwIm3DVertexSetV(&TraceVertices[6], 2.0f); + RwIm3DVertexSetV(&TraceVertices[7], 2.0f); + RwIm3DVertexSetV(&TraceVertices[8], 2.0f); + RwIm3DVertexSetV(&TraceVertices[9], 2.0f); + RwIm3DVertexSetRGBA(&TraceVertices[0], 255, 255, 255, 0); + RwIm3DVertexSetRGBA(&TraceVertices[1], 255, 255, 255, 0); + RwIm3DVertexSetRGBA(&TraceVertices[2], 255, 255, 255, 0); + RwIm3DVertexSetRGBA(&TraceVertices[3], 255, 255, 255, 0); + RwIm3DVertexSetRGBA(&TraceVertices[4], 255, 255, 255, 0); + + RwIm3DVertexSetPos(&TraceVertices[0], currentPos.x, currentPos.y, currentPos.z); + RwIm3DVertexSetPos(&TraceVertices[1], currentPos.x, currentPos.y, currentPos.z + traceThicknes); + RwIm3DVertexSetPos(&TraceVertices[2], currentPos.x + vecOffset.y, currentPos.y - vecOffset.x, currentPos.z); + RwIm3DVertexSetPos(&TraceVertices[3], currentPos.x, currentPos.y, currentPos.z - traceThicknes); + RwIm3DVertexSetPos(&TraceVertices[4], currentPos.x - vecOffset.y, currentPos.y - vecOffset.y, currentPos.z); + + RwIm3DVertexSetPos(&TraceVertices[5], currentPos2.x, currentPos2.y, currentPos2.z); + RwIm3DVertexSetPos(&TraceVertices[6], currentPos2.x, currentPos2.y, currentPos2.z + traceThicknes); + RwIm3DVertexSetPos(&TraceVertices[7], currentPos2.x + vecOffset.y, currentPos2.y - vecOffset.x, currentPos2.z); + RwIm3DVertexSetPos(&TraceVertices[8], currentPos2.x, currentPos2.y, currentPos2.z - traceThicknes); + RwIm3DVertexSetPos(&TraceVertices[9], currentPos2.x - vecOffset.y, currentPos2.y - vecOffset.y, currentPos2.z); + + if (RwIm3DTransform(TraceVertices, ARRAY_SIZE(TraceVertices), nil, 1)) { + RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TraceIndexList, ARRAY_SIZE(TraceIndexList)); + RwIm3DEnd(); + } + + RwIm3DVertexSetPos(&TraceVertices[1], targetPos.x, targetPos.y, targetPos.z); + RwIm3DVertexSetPos(&TraceVertices[2], targetPos.x, targetPos.y, targetPos.z + traceThicknes); + RwIm3DVertexSetPos(&TraceVertices[3], targetPos.x + vecOffset.y, targetPos.y - vecOffset.x, targetPos.z); + RwIm3DVertexSetPos(&TraceVertices[4], targetPos.x, targetPos.y, targetPos.z - traceThicknes); + RwIm3DVertexSetPos(&TraceVertices[5], targetPos.x - vecOffset.y, targetPos.y - vecOffset.y, targetPos.z); + + RwIm3DVertexSetPos(&TraceVertices[5], targetPos2.x, targetPos2.y, targetPos2.z); + RwIm3DVertexSetPos(&TraceVertices[6], targetPos2.x, targetPos2.y, targetPos2.z + traceThicknes); + RwIm3DVertexSetPos(&TraceVertices[7], targetPos2.x + vecOffset.y, targetPos2.y - vecOffset.x, targetPos2.z); + RwIm3DVertexSetPos(&TraceVertices[8], targetPos2.x, targetPos2.y, targetPos2.z - traceThicknes); + RwIm3DVertexSetPos(&TraceVertices[9], targetPos2.x - vecOffset.y, targetPos2.y - vecOffset.y, targetPos2.z); + + if (RwIm3DTransform(TraceVertices, ARRAY_SIZE(TraceVertices), nil, 1)) { + RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TraceIndexList, ARRAY_SIZE(TraceIndexList)); + RwIm3DEnd(); + } } } RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); @@ -348,23 +609,8 @@ void CBulletTraces::Update(void) 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) + if (CTimer::GetTimeInMilliseconds() - m_nCreationTime >= m_nLifeTime) m_bInUse = false; - m_framesInUse++; } RpAtomic * @@ -516,7 +762,7 @@ C3dMarkers::Render() CCoronas::RegisterCorona((uintptr)&m_aMarkerArray[i], SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, 192, m_aMarkerArray[i].m_Matrix.GetPosition(), 1.2f * m_aMarkerArray[i].m_fSize, 50.0f * TheCamera.LODDistMultiplier, - CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f, false); + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f, false, 1.5f); } } NumActiveMarkers++; @@ -578,7 +824,7 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size } else { pMarker->m_fStdSize = size; } - } else if (type == MARKERTYPE_CYLINDER) { + } else { if (dist < size + 12.0f) { if (dist > size + 1.0f) pMarker->m_Color.alpha = (1.0f - (size + 12.0f - dist) * 0.7f / 11.0f) * (float)a; @@ -591,15 +837,9 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size float someSin = Sin(TWOPI * (float)((pMarker->m_nPulsePeriod - 1) & (CTimer::GetTimeInMilliseconds() - pMarker->m_nStartTime)) / (float)pMarker->m_nPulsePeriod); pMarker->m_fSize = pMarker->m_fStdSize - pulseFraction * pMarker->m_fStdSize * someSin; - if (type == MARKERTYPE_ARROW) { + if (type == MARKERTYPE_ARROW) pos.z += 0.25f * pMarker->m_fStdSize * someSin; - } else if (type == MARKERTYPE_0) { - if (someSin > 0.0f) - pMarker->m_Color.alpha = (float)a * 0.7f * someSin + a; - else - pMarker->m_Color.alpha = (float)a * 0.4f * someSin + a; - } - if (pMarker->m_nRotateRate) { + if (pMarker->m_nRotateRate != 0) { RwV3d pos = pMarker->m_Matrix.m_matrix.pos; pMarker->m_Matrix.RotateZ(DEGTORAD(pMarker->m_nRotateRate * CTimer::GetTimeStep())); pMarker->m_Matrix.GetPosition() = pos; @@ -623,7 +863,7 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size pMarker->DeleteMarkerObject(); pMarker->AddMarker(identifier, type, size, r, g, b, a, pulsePeriod, pulseFraction, rotateRate); - if (type == MARKERTYPE_CYLINDER || type == MARKERTYPE_0 || type == MARKERTYPE_2) { + if (type == MARKERTYPE_CYLINDER) { if ((playerPos - pos).MagnitudeSqr() < sq(100.f) && CColStore::HasCollisionLoaded(CVector2D(pos))) { float z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 1.0f, nil); if (z != 0.0f) @@ -634,10 +874,6 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size } } pMarker->m_Matrix.SetTranslate(pos.x, pos.y, pos.z); - if (type == MARKERTYPE_2) { - pMarker->m_Matrix.RotateX(PI); - pMarker->m_Matrix.GetPosition() = pos; - } pMarker->m_Matrix.UpdateRW(); if (type == MARKERTYPE_ARROW) { if (dist < 25.0f) { @@ -648,7 +884,7 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size } else { pMarker->m_fStdSize = size; } - } else if (type == MARKERTYPE_CYLINDER) { + } else { if (dist < size + 12.0f) { if (dist > size + 1.0f) pMarker->m_Color.alpha = (1.0f - (size + 12.0f - dist) * 0.7f / 11.0f) * (float)a; @@ -752,6 +988,9 @@ CBrightLights::Render(void) RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil); + TempBufferVerticesStored = 0; + TempBufferIndicesStored = 0; + for(i = 0; i < NumBrightLights; i++){ if(TempBufferIndicesStored > TEMPBUFFERINDEXSIZE-40 || TempBufferVerticesStored > TEMPBUFFERVERTSIZE-40) RenderOutGeometryBuffer(); @@ -788,6 +1027,13 @@ CBrightLights::Render(void) g = aBrightLights[i].m_green; b = aBrightLights[i].m_blue; break; + default: +#ifdef FIX_BUGS //just to make sure that color never will be undefined + r = 0; + g = 0; + b = 0; +#endif + break; } if(aBrightLights[i].m_camDist < BRIGHTLIGHTS_FADE_DIST) @@ -851,6 +1097,22 @@ CBrightLights::Render(void) TempBufferIndicesStored += 12*3; break; + case BRIGHTLIGHT_FRONT_BIG: + case BRIGHTLIGHT_REAR_BIG: + for (j = 0; j < 8; j++) { + pos = BigCarHeadLightsSide[j] * aBrightLights[i].m_side + + BigCarHeadLightsUp[j] * aBrightLights[i].m_up + + BigCarHeadLightsFront[j] * aBrightLights[i].m_front + + aBrightLights[i].m_pos; + RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + j], r, g, b, a); + RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + j], pos.x, pos.y, pos.z); + } + for (j = 0; j < 12 * 3; j++) + TempBufferRenderIndexList[TempBufferIndicesStored + j] = CubeIndices[j] + TempBufferVerticesStored; + TempBufferVerticesStored += 8; + TempBufferIndicesStored += 12 * 3; + break; + case BRIGHTLIGHT_FRONT_TALL: case BRIGHTLIGHT_REAR_TALL: for(j = 0; j < 8; j++){ @@ -869,8 +1131,8 @@ CBrightLights::Render(void) case BRIGHTLIGHT_SIREN: for(j = 0; j < 6; j++){ - pos = SirenLightsSide[j]*aBrightLights[i].m_side + - SirenLightsUp[j]*aBrightLights[i].m_up + + pos = SirenLightsSide[j]*TheCamera.GetRight() + + SirenLightsUp[j]* TheCamera.GetUp() + aBrightLights[i].m_pos; RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+j], r, g, b, a); RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+j], pos.x, pos.y, pos.z); @@ -1056,8 +1318,9 @@ CMoneyMessage::Render() { const float MAX_SCALE = 4.0f; uint32 nLifeTime = CTimer::GetTimeInMilliseconds() - m_nTimeRegistered; - if (nLifeTime >= MONEY_MESSAGE_LIFETIME_MS) m_nTimeRegistered = 0; - else { + if (nLifeTime >= MONEY_MESSAGE_LIFETIME_MS) { + m_nTimeRegistered = 0; + } else { float fLifeTime = (float)nLifeTime / MONEY_MESSAGE_LIFETIME_MS; RwV3d vecOut; float fDistX, fDistY; @@ -1066,20 +1329,15 @@ CMoneyMessage::Render() fDistY *= (0.7 * fLifeTime + 2.0) * m_fSize; CFont::SetPropOn(); CFont::SetBackgroundOff(); - - float fScaleY = fDistY / 100.0f; - if (fScaleY > MAX_SCALE) fScaleY = MAX_SCALE; - - float fScaleX = fDistX / 100.0f; - if (fScaleX > MAX_SCALE) fScaleX = MAX_SCALE; - + float fScaleY = Min(fDistY / 100.0f, MAX_SCALE); + float fScaleX = Min(fDistX / 100.0f, MAX_SCALE); CFont::SetScale(fScaleX, fScaleY); // maybe use SCREEN_SCALE_X and SCREEN_SCALE_Y here? CFont::SetCentreOn(); CFont::SetCentreSize(SCREEN_WIDTH); CFont::SetJustifyOff(); CFont::SetColor(CRGBA(m_Colour.r, m_Colour.g, m_Colour.b, (255.0f - 255.0f * fLifeTime) * m_fOpacity)); CFont::SetBackGroundOnlyTextOff(); - CFont::SetFontStyle(FONT_STANDARD); + FONT_LOCALE(FONT_STANDARD); CFont::PrintString(vecOut.x, vecOut.y, m_aText); } } diff --git a/src/render/SpecialFX.h b/src/render/SpecialFX.h index 8bd0d5e1..e09d840f 100644 --- a/src/render/SpecialFX.h +++ b/src/render/SpecialFX.h @@ -1,8 +1,12 @@ #pragma once +//file done + class CSpecialFX { public: + static bool bVideoCam; + static bool bLiftCam; static bool bSnapShotActive; static int32 SnapShotFrames; @@ -10,8 +14,11 @@ public: static void Update(void); static void Init(void); static void Shutdown(void); + static void AddWeaponStreak(int type); + static void Render2DFXs(); }; + class CRegisteredMotionBlurStreak { public: @@ -27,6 +34,7 @@ public: void Render(void); }; + class CMotionBlurStreaks { static CRegisteredMotionBlurStreak aStreaks[NUMMBLURSTREAKS]; @@ -37,33 +45,31 @@ public: static void Render(void); }; + struct CBulletTrace { CVector m_vecCurrentPos; CVector m_vecTargetPos; bool m_bInUse; - uint8 m_framesInUse; - uint8 m_lifeTime; + uint32 m_nCreationTime; + uint32 m_nLifeTime; + float m_fThicknes; + uint8 m_fVisibility; void Update(void); }; + class CBulletTraces { public: static CBulletTrace aTraces[NUMBULLETTRACES]; static void Init(void); - static void AddTrace(CVector*, CVector*); static void Render(void); static void Update(void); - -//TODO(MIAMI) - static void AddTrace(CVector *, CVector *, float, unsigned int, unsigned char) {} - static void AddTrace(CVector *a, CVector *b, int32 weapontype, class CEntity *shooter) - { - AddTrace(a, b); //TODO: temp - } + static void AddTrace(CVector* start, CVector* end, float thickness, uint32 lifeTime, uint8 visibility); + static void AddTrace(CVector* start, CVector* end, int32 weaponType, class CEntity* shooter); }; enum @@ -104,6 +110,7 @@ public: void Render(); }; + class C3dMarkers { public: @@ -144,6 +151,7 @@ enum BRIGHTLIGHT_REAR = BRIGHTLIGHT_REAR_LONG, }; + class CBrightLight { public: @@ -158,6 +166,7 @@ public: uint8 m_blue; }; + class CBrightLights { static int NumBrightLights; @@ -177,6 +186,7 @@ enum SHINYTEXT_FLAT }; + class CShinyText { public: @@ -189,7 +199,8 @@ public: uint8 m_blue; }; -class CShinyTexts + +class CShinyTexts { static int NumShinyTexts; static CShinyText aShinyTexts[NUMSHINYTEXTS]; @@ -197,11 +208,12 @@ public: static void Init(void); static void RegisterOne(CVector p0, CVector p1, CVector p2, CVector p3, float u0, float v0, float u1, float v1, float u2, float v2, float u3, float v3, - uint8 type, uint8 red, uint8 green, uint8 blue, float maxDist); + uint8 type, uint8 red, uint8 green, uint8 blue, float maxDist); //not used static void Render(void); static void RenderOutGeometryBuffer(void); }; + class CMoneyMessage { friend class CMoneyMessages; @@ -216,6 +228,7 @@ public: void Render(); }; + class CMoneyMessages { static CMoneyMessage aMoneyMessages[NUMMONEYMESSAGES]; @@ -225,11 +238,12 @@ public: static void RegisterOne(CVector vecPos, const char *pText, uint8 bRed, uint8 bGreen, uint8 bBlue, float fSize, float fOpacity); }; + class CSpecialParticleStuff { static uint32 BoatFromStart; public: - static void CreateFoamAroundObject(CMatrix*, float, float, float, int32); - static void StartBoatFoamAnimation(); - static void UpdateBoatFoamAnimation(CMatrix*); + static void CreateFoamAroundObject(CMatrix*, float, float, float, int32); //not used + static void StartBoatFoamAnimation(); //not used + static void UpdateBoatFoamAnimation(CMatrix*); //not used }; |