diff options
Diffstat (limited to 'src/render')
-rw-r--r-- | src/render/Clouds.cpp | 14 | ||||
-rw-r--r-- | src/render/Fluff.cpp | 4 | ||||
-rw-r--r-- | src/render/MBlur.cpp | 3 | ||||
-rw-r--r-- | src/render/Skidmarks.cpp | 247 | ||||
-rw-r--r-- | src/render/Skidmarks.h | 26 | ||||
-rw-r--r-- | src/render/SpecialFX.cpp | 465 | ||||
-rw-r--r-- | src/render/Sprite.cpp | 2 | ||||
-rw-r--r-- | src/render/Sprite2d.cpp | 30 | ||||
-rw-r--r-- | src/render/TexList.cpp | 41 | ||||
-rw-r--r-- | src/render/TexList.h | 14 | ||||
-rw-r--r-- | src/render/Timecycle.h | 1 | ||||
-rw-r--r-- | src/render/VisibilityPlugins.cpp | 2 | ||||
-rw-r--r-- | src/render/Weather.cpp | 470 | ||||
-rw-r--r-- | src/render/Weather.h | 22 |
14 files changed, 1069 insertions, 272 deletions
diff --git a/src/render/Clouds.cpp b/src/render/Clouds.cpp index 2884894c..39866294 100644 --- a/src/render/Clouds.cpp +++ b/src/render/Clouds.cpp @@ -87,7 +87,7 @@ CClouds::Render(void) RwV3d pos = { 0.0f, -100.0f, 15.0f }; RwV3dAdd(&worldpos, &campos, &pos); if(CSprite::CalcScreenCoors(worldpos, &screenpos, &szx, &szy, false)){ - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[2]->raster); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[2])); if(CCoronas::bSmallMoon){ szx *= 4.0f; szy *= 4.0f; @@ -116,7 +116,7 @@ CClouds::Render(void) static float StarCoorsY[9] = { 0.0f, 0.45f, 0.9f, 1.0f, 0.85f, 0.52f, 0.48f, 0.35f, 0.2f }; static float StarSizes[9] = { 1.0f, 1.4f, 0.9f, 1.0f, 0.6f, 1.5f, 1.3f, 1.0f, 0.8f }; int brightness = (1.0f - coverage) * starintens; - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0])); for(i = 0; i < 11; i++){ RwV3d pos = { 100.0f, 0.0f, 10.0f }; if(i >= 9) pos.x = -pos.x; @@ -132,7 +132,7 @@ CClouds::Render(void) CSprite::FlushSpriteBuffer(); // * - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0])); RwV3d pos = { 100.0f, 0.0f, 10.0f }; RwV3dAdd(&worldpos, &campos, &pos); worldpos.y -= 90.0f; @@ -156,7 +156,7 @@ CClouds::Render(void) int b = CTimeCycle::GetLowCloudsBlue() * lowcloudintensity; for(int cloudtype = 0; cloudtype < 3; cloudtype++){ for(i = cloudtype; i < 12; i += 3){ - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[cloudtype]->raster); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[cloudtype])); RwV3d pos = { 800.0f*LowCloudsX[i], 800.0f*LowCloudsY[i], 60.0f*LowCloudsZ[i] }; worldpos.x = campos.x + pos.x; worldpos.y = campos.y + pos.y; @@ -202,7 +202,7 @@ CClouds::Render(void) RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[4]->raster); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[4])); for(i = 0; i < 37; i++){ RwV3d pos = { 2.0f*CoorsOffsetX[i], 2.0f*CoorsOffsetY[i], 40.0f*CoorsOffsetZ[i] + 40.0f }; worldpos.x = pos.x*rot_cos + pos.y*rot_sin + campos.x; @@ -244,7 +244,7 @@ CClouds::Render(void) // Highlights RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[3]->raster); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[3])); for(i = 0; i < 37; i++){ RwV3d pos = { 2.0f*CoorsOffsetX[i], 2.0f*CoorsOffsetY[i], 40.0f*CoorsOffsetZ[i] + 40.0f }; @@ -269,7 +269,7 @@ CClouds::Render(void) static uint8 BowRed[6] = { 30, 30, 30, 10, 0, 15 }; static uint8 BowGreen[6] = { 0, 15, 30, 30, 0, 0 }; static uint8 BowBlue[6] = { 0, 0, 0, 10, 30, 30 }; - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0])); for(i = 0; i < 6; i++){ RwV3d pos = { i*1.5f, 100.0f, 5.0f }; RwV3dAdd(&worldpos, &campos, &pos); diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp index 8d7fad92..e2899532 100644 --- a/src/render/Fluff.cpp +++ b/src/render/Fluff.cpp @@ -755,14 +755,14 @@ void CTowerClock::Render() &TempV[1], m_Position.x + Sin(angleMinute) * m_fScale * m_Size.x, m_Position.y + Sin(angleMinute) * m_fScale * m_Size.y, - m_Position.z + Cos(angleMinute) * m_fScale; + m_Position.z + Cos(angleMinute) * m_fScale ); RwIm3DVertexSetPos(&TempV[2], m_Position.x, m_Position.y, m_Position.z); RwIm3DVertexSetPos( &TempV[3], m_Position.x + Sin(angleHour) * 0.75f * m_fScale * m_Size.x, m_Position.y + Sin(angleHour) * 0.75f * m_fScale * m_Size.y, - m_Position.z + Cos(angleHour) * 0.75f * m_fScale; + m_Position.z + Cos(angleHour) * 0.75f * m_fScale ); LittleTest(); diff --git a/src/render/MBlur.cpp b/src/render/MBlur.cpp index 1cf27ee0..d28671fa 100644 --- a/src/render/MBlur.cpp +++ b/src/render/MBlur.cpp @@ -4,12 +4,13 @@ #include "Camera.h" #include "MBlur.h" +// Originally taken from RW example 'mblur' + RwRaster *&CMBlur::pFrontBuffer = *(RwRaster**)0x8E2C48; bool &CMBlur::ms_bJustInitialised = *(bool*)0x95CDAB; bool &CMBlur::BlurOn = *(bool*)0x95CDAD; static RwIm2DVertex Vertex[4]; -//static RwIm2DVertex *Vertex = (RwIm2DVertex*)0x62F780; static RwImVertexIndex Index[6] = { 0, 1, 2, 0, 2, 3 }; void diff --git a/src/render/Skidmarks.cpp b/src/render/Skidmarks.cpp index c2725ed6..41ee5d1d 100644 --- a/src/render/Skidmarks.cpp +++ b/src/render/Skidmarks.cpp @@ -1,12 +1,247 @@ #include "common.h" #include "patcher.h" +#include "main.h" +#include "TxdStore.h" +#include "Timer.h" +#include "Replay.h" #include "Skidmarks.h" -WRAPPER void CSkidmarks::Clear(void) { EAXJMP(0x518130); } -WRAPPER void CSkidmarks::Update() { EAXJMP(0x518200); } +CSkidmark CSkidmarks::aSkidmarks[NUMSKIDMARKS]; -WRAPPER void CSkidmarks::Render(void) { EAXJMP(0x5182E0); } -WRAPPER void CSkidmarks::RegisterOne(uint32 id, CVector pos, float fwdx, float fwdY, bool *isMuddy, bool *isBloddy) { EAXJMP(0x5185C0); } +RwImVertexIndex SkidmarkIndexList[SKIDMARK_LENGTH * 6]; +RwIm3DVertex SkidmarkVertices[SKIDMARK_LENGTH * 2]; +RwTexture *gpSkidTex; +RwTexture *gpSkidBloodTex; +RwTexture *gpSkidMudTex; -WRAPPER void CSkidmarks::Init(void) { EAXJMP(0x517D70); } -WRAPPER void CSkidmarks::Shutdown(void) { EAXJMP(0x518100); } +void +CSkidmarks::Init(void) +{ + int i, ix, slot; + CTxdStore::PushCurrentTxd(); + slot = CTxdStore::FindTxdSlot("particle"); + CTxdStore::SetCurrentTxd(slot); + gpSkidTex = RwTextureRead("particleskid", nil); + gpSkidBloodTex = RwTextureRead("particleskidblood", nil); + gpSkidMudTex = RwTextureRead("particleskidmud", nil); + CTxdStore::PopCurrentTxd(); + + for(i = 0; i < NUMSKIDMARKS; i++){ + aSkidmarks[i].m_state = 0; + aSkidmarks[i].m_wasUpdated = false; + } + + ix = 0; + for(i = 0; i < SKIDMARK_LENGTH; i++){ + SkidmarkIndexList[i*6+0] = ix+0; + SkidmarkIndexList[i*6+1] = ix+2; + SkidmarkIndexList[i*6+2] = ix+1; + SkidmarkIndexList[i*6+3] = ix+1; + SkidmarkIndexList[i*6+4] = ix+2; + SkidmarkIndexList[i*6+5] = ix+3; + ix += 2; + } + + for(i = 0; i < SKIDMARK_LENGTH; i++){ + RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 0], 0.0f); + RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 0], i*5.01f); + RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 1], 1.0f); + RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 1], i*5.01f); + } +} + +void +CSkidmarks::Shutdown(void) +{ + RwTextureDestroy(gpSkidTex); + RwTextureDestroy(gpSkidBloodTex); + RwTextureDestroy(gpSkidMudTex); +} + +void +CSkidmarks::Clear(void) +{ + int i; + for(i = 0; i < NUMSKIDMARKS; i++){ + aSkidmarks[i].m_state = 0; + aSkidmarks[i].m_wasUpdated = false; + } +} + +void +CSkidmarks::Update(void) +{ + int i; + uint32 t1 = CTimer::GetTimeInMilliseconds() + 2500; + uint32 t2 = CTimer::GetTimeInMilliseconds() + 5000; + uint32 t3 = CTimer::GetTimeInMilliseconds() + 10000; + uint32 t4 = CTimer::GetTimeInMilliseconds() + 20000; + for(i = 0; i < NUMSKIDMARKS; i++){ + switch(aSkidmarks[i].m_state){ + case 1: + if(!aSkidmarks[i].m_wasUpdated){ + // Didn't continue this one last time, so finish it and set fade times + aSkidmarks[i].m_state = 2; + if(aSkidmarks[i].m_last < 4){ + aSkidmarks[i].m_fadeStart = t1; + aSkidmarks[i].m_fadeEnd = t2; + }else if(aSkidmarks[i].m_last < 9){ + aSkidmarks[i].m_fadeStart = t2; + aSkidmarks[i].m_fadeEnd = t3; + }else{ + aSkidmarks[i].m_fadeStart = t3; + aSkidmarks[i].m_fadeEnd = t4; + } + } + break; + case 2: + if(CTimer::GetTimeInMilliseconds() > aSkidmarks[i].m_fadeEnd) + aSkidmarks[i].m_state = 0; + break; + } + aSkidmarks[i].m_wasUpdated = false; + } +} + +void +CSkidmarks::Render(void) +{ + int i, j; + RwTexture *lastTex = nil; + + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + + for(i = 0; i < NUMSKIDMARKS; i++){ + if(aSkidmarks[i].m_state == 0 || aSkidmarks[i].m_last < 1) + continue; + + if(aSkidmarks[i].m_isBloody){ + if(lastTex != gpSkidBloodTex){ + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidBloodTex)); + lastTex = gpSkidBloodTex; + } + }else if(aSkidmarks[i].m_isMuddy){ + if(lastTex != gpSkidMudTex){ + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidMudTex)); + lastTex = gpSkidMudTex; + } + }else{ + if(lastTex != gpSkidTex){ + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidTex)); + lastTex = gpSkidTex; + } + } + + uint32 fade, alpha; + if(aSkidmarks[i].m_state == 1 || CTimer::GetTimeInMilliseconds() < aSkidmarks[i].m_fadeStart) + fade = 255; + else + fade = 255*(aSkidmarks[i].m_fadeEnd - CTimer::GetTimeInMilliseconds()) / (aSkidmarks[i].m_fadeEnd - aSkidmarks[i].m_fadeStart); + + for(j = 0; j <= aSkidmarks[i].m_last; j++){ + alpha = 128; + if(j == 0 || j == aSkidmarks[i].m_last && aSkidmarks[i].m_state == 2) + alpha = 0; + alpha = alpha*fade/256; + + CVector p1 = aSkidmarks[i].m_pos[j] + aSkidmarks[i].m_side[j]; + CVector p2 = aSkidmarks[i].m_pos[j] - aSkidmarks[i].m_side[j]; + RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+0], 255, 255, 255, alpha); + RwIm3DVertexSetPos(&SkidmarkVertices[j*2+0], p1.x, p1.y, p1.z+0.1f); + RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+1], 255, 255, 255, alpha); + RwIm3DVertexSetPos(&SkidmarkVertices[j*2+1], p2.x, p2.y, p2.z+0.1f); + } + + LittleTest(); + if(RwIm3DTransform(SkidmarkVertices, 2*(aSkidmarks[i].m_last+1), nil, rwIM3D_VERTEXUV)){ + RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, SkidmarkIndexList, 6*aSkidmarks[i].m_last); + RwIm3DEnd(); + } + } + + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); +} + +void +CSkidmarks::RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *isMuddy, bool *isBloody) +{ + int i; + CVector2D fwd(fwdX, fwdY); + + if(CReplay::IsPlayingBack()) + return; + + // Find a skidmark to continue + for(i = 0; i < NUMSKIDMARKS; i++) + if(aSkidmarks[i].m_state == 1 && aSkidmarks[i].m_id == id) + break; + + if(i < NUMSKIDMARKS){ + // Continue this one + + if(aSkidmarks[i].m_isBloody != *isBloody){ + // Blood-status changed, end this one + aSkidmarks[i].m_state = 2; + aSkidmarks[i].m_fadeStart = CTimer::GetTimeInMilliseconds() + 10000; + aSkidmarks[i].m_fadeEnd = CTimer::GetTimeInMilliseconds() + 20000; + return; + } + + aSkidmarks[i].m_wasUpdated = true; + + if(CTimer::GetTimeInMilliseconds() - aSkidmarks[i].m_lastUpdate <= 100){ + // Last update was recently, just change last coords + aSkidmarks[i].m_pos[aSkidmarks[i].m_last] = pos; + return; + } + aSkidmarks[i].m_lastUpdate = CTimer::GetTimeInMilliseconds(); + + if(aSkidmarks[i].m_last >= SKIDMARK_LENGTH-1){ + // No space to continue, end it + aSkidmarks[i].m_state = 2; + aSkidmarks[i].m_fadeStart = CTimer::GetTimeInMilliseconds() + 10000; + aSkidmarks[i].m_fadeEnd = CTimer::GetTimeInMilliseconds() + 20000; + *isBloody = false; // stpo blood marks at end + return; + } + aSkidmarks[i].m_last++; + + aSkidmarks[i].m_pos[aSkidmarks[i].m_last] = pos; + + CVector2D dist = aSkidmarks[i].m_pos[aSkidmarks[i].m_last] - aSkidmarks[i].m_pos[aSkidmarks[i].m_last-1]; + dist.Normalise(); + CVector2D right(dist.y, -dist.x); + float turn = DotProduct2D(fwd, right); + turn = Abs(turn) + 1.0f; + aSkidmarks[i].m_side[aSkidmarks[i].m_last] = CVector(right.x, right.y, 0.0f) * turn * 0.125f; + if(aSkidmarks[i].m_last == 1) + aSkidmarks[i].m_side[0] = aSkidmarks[i].m_side[1]; + + if(aSkidmarks[i].m_last > 8) + *isBloody = false; // stop blood marks after 8 + return; + } + + // Start a new one + for(i = 0; i < NUMSKIDMARKS; i++) + if(aSkidmarks[i].m_state == 0) + break; + if(i < NUMSKIDMARKS){ + // Found a free slot + aSkidmarks[i].m_state = 1; + aSkidmarks[i].m_id = id; + aSkidmarks[i].m_pos[0] = pos; + aSkidmarks[i].m_side[0] = CVector(0.0f, 0.0f, 0.0f); + aSkidmarks[i].m_wasUpdated = true; + aSkidmarks[i].m_last = 0; + aSkidmarks[i].m_lastUpdate = CTimer::GetTimeInMilliseconds() - 1000; + aSkidmarks[i].m_isBloody = *isBloody; + aSkidmarks[i].m_isMuddy = *isMuddy; + }else + *isBloody = false; // stop blood marks if no space +} diff --git a/src/render/Skidmarks.h b/src/render/Skidmarks.h index bf2da7e4..085b4c6d 100644 --- a/src/render/Skidmarks.h +++ b/src/render/Skidmarks.h @@ -1,12 +1,32 @@ #pragma once +enum { SKIDMARK_LENGTH = 16 }; + +class CSkidmark +{ +public: + uint8 m_state; + bool m_wasUpdated; + bool m_isBloody; + bool m_isMuddy; + uintptr m_id; + int16 m_last; + uint32 m_lastUpdate;; + uint32 m_fadeStart; + uint32 m_fadeEnd; + CVector m_pos[SKIDMARK_LENGTH]; + CVector m_side[SKIDMARK_LENGTH]; +}; + class CSkidmarks { + static CSkidmark aSkidmarks[NUMSKIDMARKS]; public: + + static void Init(void); + static void Shutdown(void); static void Clear(void); static void Update(void); static void Render(void); - static void RegisterOne(uint32 id, CVector pos, float fwdx, float fwdY, bool *isMuddy, bool *isBloddy); - static void Init(void); - static void Shutdown(void); + static void RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *isMuddy, bool *isBloody); }; diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp index 0d856d9c..9189a7c2 100644 --- a/src/render/SpecialFX.cpp +++ b/src/render/SpecialFX.cpp @@ -22,10 +22,10 @@ #include "Shadows.h" #include "main.h" -RxObjSpace3DVertex StreakVertices[4]; +RwIm3DVertex StreakVertices[4]; RwImVertexIndex StreakIndexList[12]; -RxObjSpace3DVertex TraceVertices[6]; +RwIm3DVertex TraceVertices[6]; RwImVertexIndex TraceIndexList[12]; @@ -34,60 +34,60 @@ 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;
-
+ 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(); @@ -112,13 +112,13 @@ LookForBatCB(RwObject *object, void *data) 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));
+ 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 @@ -130,78 +130,78 @@ CSpecialFX::Shutdown(void) void CSpecialFX::Render(void) { - CMotionBlurStreaks::Render();
- CBulletTraces::Render();
- CBrightLights::Render();
- CShinyTexts::Render();
- CMoneyMessages::Render();
- C3dMarkers::Render();
+ 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);
+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::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) { @@ -234,32 +234,32 @@ CMotionBlurStreaks::RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVecto aStreaks[i].m_isValid[2] = false; } -void
-CMotionBlurStreaks::Render(void)
-{
+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);
+ 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);
- }
-}
+ 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]; @@ -291,10 +291,10 @@ void CBulletTraces::Render(void) for (int i = 0; i < NUMBULLETTRACES; i++) { if (!aTraces[i].m_bInUse) continue; - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)0); - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)2); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)2); - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpShadowExplosionTex->raster); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); + 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; @@ -316,9 +316,9 @@ void CBulletTraces::Render(void) RwIm3DEnd(); } } - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)1); - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)5); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)6); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); } void CBulletTraces::Update(void) @@ -414,8 +414,7 @@ C3dMarker::Render() { if (m_pAtomic == nil) return; - RwRGBA *color = RpMaterialGetColor(m_pMaterial); - *color = m_Color; + RpMaterialSetColor(m_pMaterial, &m_Color); m_Matrix.UpdateRW(); @@ -643,13 +642,13 @@ C3dMarkers::Update() int CBrightLights::NumBrightLights; CBrightLight CBrightLights::aBrightLights[NUMBRIGHTLIGHTS]; -
-void
-CBrightLights::Init(void)
-{
- NumBrightLights = 0;
-}
-
+ +void +CBrightLights::Init(void) +{ + NumBrightLights = 0; +} + void CBrightLights::RegisterOne(CVector pos, CVector up, CVector side, CVector front, uint8 type, uint8 red, uint8 green, uint8 blue) @@ -661,13 +660,13 @@ CBrightLights::RegisterOne(CVector pos, CVector up, CVector side, CVector front, if(aBrightLights[NumBrightLights].m_camDist > BRIGHTLIGHTS_MAX_DIST) return; - aBrightLights[NumBrightLights].m_pos = pos;
- aBrightLights[NumBrightLights].m_up = up;
- aBrightLights[NumBrightLights].m_side = side;
- aBrightLights[NumBrightLights].m_front = front;
- aBrightLights[NumBrightLights].m_type = type;
- aBrightLights[NumBrightLights].m_red = red;
- aBrightLights[NumBrightLights].m_green = green;
+ aBrightLights[NumBrightLights].m_pos = pos; + aBrightLights[NumBrightLights].m_up = up; + aBrightLights[NumBrightLights].m_side = side; + aBrightLights[NumBrightLights].m_front = front; + aBrightLights[NumBrightLights].m_type = type; + aBrightLights[NumBrightLights].m_red = red; + aBrightLights[NumBrightLights].m_green = green; aBrightLights[NumBrightLights].m_blue = blue; NumBrightLights++; @@ -696,22 +695,22 @@ static RwImVertexIndex CubeIndices[12*3] = { 6, 0, 4, 6, 2, 0, 6, 5, 7, 6, 4, 5 }; -void
-CBrightLights::Render(void)
-{
+void +CBrightLights::Render(void) +{ int i, j; CVector pos; - if(NumBrightLights == 0)
- return;
-
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
-
- for(i = 0; i < NumBrightLights; i++){
+ if(NumBrightLights == 0) + return; + + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil); + + for(i = 0; i < NumBrightLights; i++){ if(TempBufferIndicesStored > TEMPBUFFERINDEXSIZE-40 || TempBufferVerticesStored > TEMPBUFFERVERTSIZE-40) RenderOutGeometryBuffer(); @@ -753,14 +752,14 @@ CBrightLights::Render(void) a = 255; else a = 255*(1.0f - (aBrightLights[i].m_camDist-BRIGHTLIGHTS_FADE_DIST)/(BRIGHTLIGHTS_MAX_DIST-BRIGHTLIGHTS_FADE_DIST)); - // fade car lights down to 31 as they come near
- if(aBrightLights[i].m_type >= BRIGHTLIGHT_FRONT_LONG && aBrightLights[i].m_type <= BRIGHTLIGHT_REAR_TALL){
+ // fade car lights down to 31 as they come near + if(aBrightLights[i].m_type >= BRIGHTLIGHT_FRONT_LONG && aBrightLights[i].m_type <= BRIGHTLIGHT_REAR_TALL){ if(aBrightLights[i].m_camDist < CARLIGHTS_FADE_DIST) a = 31; else if(aBrightLights[i].m_camDist < CARLIGHTS_MAX_DIST) a = 31 + (255-31)*((aBrightLights[i].m_camDist-CARLIGHTS_FADE_DIST)/(CARLIGHTS_MAX_DIST-CARLIGHTS_FADE_DIST)); - }
-
+ } + switch(aBrightLights[i].m_type){ case BRIGHTLIGHT_TRAFFIC_GREEN: case BRIGHTLIGHT_TRAFFIC_YELLOW: @@ -793,7 +792,7 @@ CBrightLights::Render(void) TempBufferVerticesStored += 8; TempBufferIndicesStored += 12*3; break; -
+ case BRIGHTLIGHT_FRONT_SMALL: case BRIGHTLIGHT_REAR_SMALL: for(j = 0; j < 8; j++){ @@ -809,7 +808,7 @@ CBrightLights::Render(void) TempBufferVerticesStored += 8; TempBufferIndicesStored += 12*3; break; -
+ case BRIGHTLIGHT_FRONT_TALL: case BRIGHTLIGHT_REAR_TALL: for(j = 0; j < 8; j++){ @@ -840,17 +839,17 @@ CBrightLights::Render(void) TempBufferIndicesStored += 4*3; break; - }
- }
-
- RenderOutGeometryBuffer();
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
- NumBrightLights = 0;
-}
-
-void
-CBrightLights::RenderOutGeometryBuffer(void)
-{
+ } + } + + RenderOutGeometryBuffer(); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); + NumBrightLights = 0; +} + +void +CBrightLights::RenderOutGeometryBuffer(void) +{ if(TempBufferIndicesStored != 0){ LittleTest(); if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXUV)){ @@ -864,13 +863,13 @@ CBrightLights::RenderOutGeometryBuffer(void) int CShinyTexts::NumShinyTexts; CShinyText CShinyTexts::aShinyTexts[NUMSHINYTEXTS]; -
-void
-CShinyTexts::Init(void)
-{
- NumShinyTexts = 0;
-}
-
+ +void +CShinyTexts::Init(void) +{ + NumShinyTexts = 0; +} + void CShinyTexts::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, @@ -910,20 +909,20 @@ CShinyTexts::RegisterOne(CVector p0, CVector p1, CVector p2, CVector p3, NumShinyTexts++; } -void
-CShinyTexts::Render(void)
-{
- int i, ix, v;
- RwTexture *lastTex = nil;
-
- if(NumShinyTexts == 0)
- return;
-
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
-
+void +CShinyTexts::Render(void) +{ + int i, ix, v; + RwTexture *lastTex = nil; + + if(NumShinyTexts == 0) + return; + + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + TempBufferVerticesStored = 0; TempBufferIndicesStored = 0; @@ -984,15 +983,15 @@ CShinyTexts::Render(void) RenderOutGeometryBuffer(); NumShinyTexts = 0; - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); -}
-
-void
-CShinyTexts::RenderOutGeometryBuffer(void)
-{
+} + +void +CShinyTexts::RenderOutGeometryBuffer(void) +{ if(TempBufferIndicesStored != 0){ LittleTest(); if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXUV)){ @@ -1002,8 +1001,8 @@ CShinyTexts::RenderOutGeometryBuffer(void) TempBufferVerticesStored = 0; TempBufferIndicesStored = 0; } -}
-
+} + #define MONEY_MESSAGE_LIFETIME_MS 2000 diff --git a/src/render/Sprite.cpp b/src/render/Sprite.cpp index 24577f41..fec50c7e 100644 --- a/src/render/Sprite.cpp +++ b/src/render/Sprite.cpp @@ -432,6 +432,7 @@ void CSprite::Set6Vertices2D(RwIm2DVertex *verts, const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3) { float screenz, recipz; + float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game screenz = m_f2DNearScreenZ; recipz = m_fRecipNearClipPlane; @@ -496,6 +497,7 @@ CSprite::Set6Vertices2D(RwIm2DVertex *verts, float x1, float y1, float x2, float const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3) { float screenz, recipz; + float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game screenz = m_f2DNearScreenZ; recipz = m_fRecipNearClipPlane; diff --git a/src/render/Sprite2d.cpp b/src/render/Sprite2d.cpp index c4dbcdaa..3f21516a 100644 --- a/src/render/Sprite2d.cpp +++ b/src/render/Sprite2d.cpp @@ -267,6 +267,7 @@ CSprite2d::SetVertices(float x1, float y1, float x2, float y2, float x3, float y const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3) { float screenz, recipz; + float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game screenz = RwIm2DGetNearScreenZ(); recipz = RecipNearClip; @@ -312,10 +313,11 @@ void CSprite2d::SetVertices(int n, float *positions, float *uvs, const CRGBA &col) { int i; - float screenz, recipz; + float screenz, recipz, z; screenz = RwIm2DGetNearScreenZ(); recipz = RecipNearClip; + z = RwCameraGetNearClipPlane(Scene.camera); // not done by game for(i = 0; i < n; i++){ @@ -334,10 +336,11 @@ void CSprite2d::SetMaskVertices(int n, float *positions) { int i; - float screenz, recipz; + float screenz, recipz, z; screenz = RwIm2DGetNearScreenZ(); recipz = RecipNearClip; + z = RwCameraGetNearClipPlane(Scene.camera); // not done by game for(i = 0; i < n; i++){ RwIm2DVertexSetScreenX(&maVertices[i], positions[i*2 + 0]); @@ -345,7 +348,7 @@ CSprite2d::SetMaskVertices(int n, float *positions) RwIm2DVertexSetScreenZ(&maVertices[i], screenz); RwIm2DVertexSetCameraZ(&maVertices[i], z); RwIm2DVertexSetRecipCameraZ(&maVertices[i], recipz); - RwIm2DVertexSetIntRGBA(&maVertices[i], 0, 0, 0, 0); + RwIm2DVertexSetIntRGBA(&maVertices[i], 255, 255, 255, 255); // 0, 0, 0, 0 on PC } } @@ -353,10 +356,11 @@ void CSprite2d::SetVertices(RwIm2DVertex *verts, const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3, float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2) { - float screenz, recipz; + float screenz, recipz, z; screenz = RwIm2DGetNearScreenZ(); recipz = RecipNearClip; + z = RwCameraGetNearClipPlane(Scene.camera); // not done by game RwIm2DVertexSetScreenX(&verts[0], r.left); RwIm2DVertexSetScreenY(&verts[0], r.top); @@ -459,15 +463,15 @@ CSprite2d::DrawRectXLU(const CRect &r, const CRGBA &c0, const CRGBA &c1, const C void CSprite2d::Draw2DPolygon(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, const CRGBA &color) { - SetVertices(x1, y1, x2, y2, x3, y3, x4, y4, color, color, color, color);
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, 0);
- RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
- RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)(color.a != 255));
- RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
- RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ SetVertices(x1, y1, x2, y2, x3, y3, x4, y4, color, color, color, color); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, 0); + RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)(color.a != 255)); + RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEGOURAUD); } diff --git a/src/render/TexList.cpp b/src/render/TexList.cpp new file mode 100644 index 00000000..daed620a --- /dev/null +++ b/src/render/TexList.cpp @@ -0,0 +1,41 @@ +#include "common.h"
+#include "TexList.h"
+#include "rtbmp.h"
+#include "FileMgr.h"
+
+bool CTexList::ms_nTexUsed[MAX_TEXUSED];
+
+void
+CTexList::Initialise()
+{}
+
+void
+CTexList::Shutdown()
+{}
+
+RwTexture *
+CTexList::SetTexture(int32 slot, char *name)
+{
+ return nil;
+}
+
+int32
+CTexList::GetFirstFreeTexture()
+{
+ for (int32 i = 0; i < MAX_TEXUSED; i++)
+ if (!ms_nTexUsed[i])
+ return i;
+ return -1;
+}
+
+RwTexture *
+CTexList::LoadFileNameTexture(char *name)
+{
+ return SetTexture(GetFirstFreeTexture(), name);
+}
+
+void
+CTexList::LoadGlobalTextureList()
+{
+ CFileMgr::SetDir("TEXTURES");
+}
\ No newline at end of file diff --git a/src/render/TexList.h b/src/render/TexList.h new file mode 100644 index 00000000..c6618fba --- /dev/null +++ b/src/render/TexList.h @@ -0,0 +1,14 @@ +#pragma once
+
+class CTexList
+{
+ enum { MAX_TEXUSED = 400, };
+ static bool ms_nTexUsed[MAX_TEXUSED];
+public:
+ static void Initialise();
+ static void Shutdown();
+ static RwTexture *SetTexture(int32 slot, char *name);
+ static int32 GetFirstFreeTexture();
+ static RwTexture *LoadFileNameTexture(char *name);
+ static void LoadGlobalTextureList();
+};
\ No newline at end of file diff --git a/src/render/Timecycle.h b/src/render/Timecycle.h index 235d559c..f126dca6 100644 --- a/src/render/Timecycle.h +++ b/src/render/Timecycle.h @@ -136,6 +136,7 @@ public: static int GetFogRed(void) { return m_nCurrentFogColourRed; } static int GetFogGreen(void) { return m_nCurrentFogColourGreen; } static int GetFogBlue(void) { return m_nCurrentFogColourBlue; } + static int GetFogReduction(void) { return m_FogReduction; } static void Initialise(void); static void Update(void); diff --git a/src/render/VisibilityPlugins.cpp b/src/render/VisibilityPlugins.cpp index 74cd2590..f8b1f6b2 100644 --- a/src/render/VisibilityPlugins.cpp +++ b/src/render/VisibilityPlugins.cpp @@ -117,7 +117,7 @@ CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera) RpMaterial* SetAlphaCB(RpMaterial *material, void *data) { - material->color.alpha = (uint8)(uint32)data; + ((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uint32)data; return material; } diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp index c1988ab4..d132ffdb 100644 --- a/src/render/Weather.cpp +++ b/src/render/Weather.cpp @@ -2,6 +2,22 @@ #include "patcher.h" #include "Weather.h" +#include "Camera.h" +#include "Clock.h" +#include "CutsceneMgr.h" +#include "DMAudio.h" +#include "General.h" +#include "Pad.h" +#include "Particle.h" +#include "RenderBuffer.h" +#include "Stats.h" +#include "Shadows.h" +#include "Timecycle.h" +#include "Timer.h" +#include "Vehicle.h" +#include "World.h" +#include "ZoneCull.h" + int32 &CWeather::SoundHandle = *(int32*)0x5FFBC4; int32 &CWeather::WeatherTypeInList = *(int32*)0x8F626C; @@ -32,13 +48,203 @@ int16 &CWeather::Stored_OldWeatherType = *(int16*)0x95CC68; int16 &CWeather::Stored_NewWeatherType = *(int16*)0x95CCAE; float &CWeather::Stored_Rain = *(float*)0x885B4C; -WRAPPER void CWeather::RenderRainStreaks(void) { EAXJMP(0x524550); } -WRAPPER void CWeather::Update(void) { EAXJMP(0x522C10); } -WRAPPER void CWeather::Init(void) { EAXJMP(0x522BA0); } +tRainStreak Streaks[NUM_RAIN_STREAKS]; -void CWeather::ReleaseWeather() +const int16 WeatherTypesList[] = { + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_CLOUDY, WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_RAINY, + WEATHER_CLOUDY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_CLOUDY, WEATHER_FOGGY, WEATHER_FOGGY, WEATHER_CLOUDY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_CLOUDY, WEATHER_CLOUDY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_CLOUDY, WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_RAINY, + WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_CLOUDY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_FOGGY, WEATHER_FOGGY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_RAINY, WEATHER_CLOUDY, +}; + +const float Windiness[] = { + 0.0f, // WEATHER_SUNNY + 0.7f, // WEATHER_RAINY + 1.0f, // WEATHER_CLOUDY + 0.5f // WEATHER_FOGGY +}; + +#define MIN_TIME_BETWEEN_LIGHTNING_FLASH_CHANGES (50) + +#define RAIN_CHANGE_SPEED (0.003f) + +#define DROPLETS_LEFT_OFFSET (10.0f) +#define DROPLETS_RIGHT_OFFSET (10.0f) +#define DROPLETS_TOP_OFFSET (10.0f) +#define DROPLETS_BOTTOM_OFFSET (10.0f) + +#define STREAK_U (10.0f) +#define STREAK_V (18.0f) +#define LARGE_STREAK_COEFFICIENT (1.23f) +#define STREAK_MIN_DISTANCE (8.0f) +#define STREAK_MAX_DISTANCE (16.0f) + +#define SPLASH_CHECK_RADIUS (7.0f) +#define SPLASH_OFFSET_RADIUS (2.0f) + +#define STREAK_LIFETIME (4.0f) +#define STREAK_INTEROLATION_TIME (0.3f) + +#define RAIN_COLOUR_R (200) +#define RAIN_COLOUR_G (200) +#define RAIN_COLOUR_B (256) +#define RAIN_ALPHA (255) + +void CWeather::Init(void) { - ForcedWeatherType = -1; + NewWeatherType = WEATHER_SUNNY; + bScriptsForceRain = false; + OldWeatherType = WEATHER_RAINY; + Stored_StateStored = false; + InterpolationValue = 0.0f; + WhenToPlayLightningSound = 0; + WeatherTypeInList = 0; + ForcedWeatherType = WEATHER_RANDOM; + SoundHandle = DMAudio.CreateEntity(AUDIOTYPE_WEATHER, (void*)1); + if (SoundHandle >= 0) + DMAudio.SetEntityStatus(SoundHandle, 1); +} + +void CWeather::Update(void) +{ + float fNewInterpolation = CClock::GetMinutes() * 1.0f / 60; + if (fNewInterpolation < InterpolationValue) { + // new hour + OldWeatherType = NewWeatherType; + if (ForcedWeatherType >= 0) + NewWeatherType = ForcedWeatherType; + else { + WeatherTypeInList = (WeatherTypeInList + 1) % ARRAYSIZE(WeatherTypesList); + NewWeatherType = WeatherTypesList[WeatherTypeInList]; +#ifdef FIX_BUGS + } + if (NewWeatherType == WEATHER_RAINY) + CStats::mmRain += CGeneral::GetRandomNumber() & 7; +#else + if (NewWeatherType == WEATHER_RAINY) + CStats::mmRain += CGeneral::GetRandomNumber() & 7; + } +#endif + } + InterpolationValue = fNewInterpolation; + if (CPad::GetPad(1)->GetRightShockJustDown()) { + NewWeatherType = (NewWeatherType + 1) % WEATHER_TOTAL; + OldWeatherType = NewWeatherType; + } + + // Lightning + if (NewWeatherType != WEATHER_RAINY || OldWeatherType != WEATHER_RAINY) { + LightningFlash = false; + LightningBurst = false; + } + else{ + if (LightningBurst) { + if ((CGeneral::GetRandomNumber() & 255) >= 32) { + // 0.875 probability + if (CTimer::GetTimeInMilliseconds() - LightningFlashLastChange > MIN_TIME_BETWEEN_LIGHTNING_FLASH_CHANGES) { + bool bOldLightningFlash = LightningFlash; + LightningFlash = CGeneral::GetRandomTrueFalse(); + if (LightningFlash != bOldLightningFlash) + LightningFlashLastChange = CTimer::GetTimeInMilliseconds(); + } + } + else { + // 0.125 probability + LightningBurst = false; + LightningDuration = min(CTimer::GetFrameCounter() - LightningStart, 20); + LightningFlash = false; + WhenToPlayLightningSound = CTimer::GetTimeInMilliseconds() + 150 * (20 - LightningDuration); + } + } + else { + if (CGeneral::GetRandomNumber() >= 200) { + // lower probability on PC due to randomness bug + LightningFlash = false; + } + else { + LightningBurst = true; + LightningStart = CTimer::GetFrameCounter(); + LightningFlashLastChange = CTimer::GetTimeInMilliseconds(); + LightningFlash = true; + } + } + } + if (WhenToPlayLightningSound && CTimer::GetTimeInMilliseconds() > WhenToPlayLightningSound) { + DMAudio.PlayOneShot(SoundHandle, SOUND_LIGHTNING, LightningDuration); + CPad::GetPad(0)->StartShake(40 * LightningDuration + 100, 2 * LightningDuration + 80); + WhenToPlayLightningSound = 0; + } + + // Wet roads + if (OldWeatherType == WEATHER_RAINY) { + if (NewWeatherType == WEATHER_RAINY) + WetRoads = 1.0f; + else + WetRoads = 1.0f - InterpolationValue; + } + else { + if (NewWeatherType == WEATHER_RAINY) + WetRoads = InterpolationValue; + else + WetRoads = 0.0f; + } + + // Rain + float fNewRain; + if (NewWeatherType == WEATHER_RAINY) { + // if raining for >1 hour, values: 0, 0.33, 0.66, 0.99, switching every ~16.5s + fNewRain = ((uint16)CTimer::GetTimeInMilliseconds() >> 14) * 0.33f; + if (OldWeatherType != WEATHER_RAINY) { + if (InterpolationValue < 0.4f) + // if rain has just started (<24 minutes), always 0.5 + fNewRain = 0.5f; + else + // if rain is ongoing for >24 minutes, values: 0.25, 0.5, 0.75, 1.0, switching every ~16.5s + fNewRain = 0.25f + ((uint16)CTimer::GetTimeInMilliseconds() >> 14) * 0.25f; + } + } + else + fNewRain = 0.0f; + if (Rain != fNewRain) { // ok to use comparasion + if (Rain < fNewRain) + Rain = min(fNewRain, Rain + RAIN_CHANGE_SPEED * CTimer::GetTimeStep()); + else + Rain = max(fNewRain, Rain - RAIN_CHANGE_SPEED * CTimer::GetTimeStep()); + } + + // Clouds + if (OldWeatherType != WEATHER_SUNNY) + CloudCoverage = 1.0f - InterpolationValue; + else + CloudCoverage = 0.0f; + if (NewWeatherType != WEATHER_SUNNY) + CloudCoverage += InterpolationValue; + + // Fog + if (OldWeatherType == WEATHER_FOGGY) + Foggyness = 1.0f - InterpolationValue; + else + Foggyness = 0.0f; + if (NewWeatherType == WEATHER_FOGGY) + Foggyness += InterpolationValue; + if (OldWeatherType == WEATHER_RAINY && NewWeatherType == WEATHER_SUNNY && InterpolationValue < 0.5f && CClock::GetHours() > 6 && CClock::GetHours() < 21) + Rainbow = 1.0f - 4.0f * Abs(InterpolationValue - 0.25f) / 4.0f; + else + Rainbow = 0.0f; + Wind = InterpolationValue * Windiness[NewWeatherType] + (1.0f - InterpolationValue) * Windiness[OldWeatherType]; + AddRain(); } void CWeather::ForceWeather(int16 weather) @@ -53,6 +259,258 @@ void CWeather::ForceWeatherNow(int16 weather) ForcedWeatherType = weather; } +void CWeather::ReleaseWeather() +{ + ForcedWeatherType = -1; +} + +void CWeather::AddRain() +{ + if (CCullZones::CamNoRain() || CCullZones::PlayerNoRain()) + return; + if (TheCamera.GetLookingLRBFirstPerson()) { + CVehicle* pVehicle = FindPlayerVehicle(); + if (pVehicle && pVehicle->CarHasRoof()) { + CParticle::RemovePSystem(PARTICLE_RAINDROP_2D); + return; + } + } + if (Rain <= 0.1f) + return; + static RwRGBA colour; + float screen_width = RsGlobal.width; + float screen_height = RsGlobal.height; + int cur_frame = (int)(3 * Rain) & 3; + int num_drops = (int)(2 * Rain) + 2; + static int STATIC_RAIN_ANGLE = -45; + static int count = 1500; + static int add_angle = 1; + if (--count == 0) { + count = 1; + if (add_angle) { + STATIC_RAIN_ANGLE += 12; + if (STATIC_RAIN_ANGLE > 45) { + count = 1500; + add_angle = !add_angle; + } + } + else { + STATIC_RAIN_ANGLE -= 12; + if (STATIC_RAIN_ANGLE < -45) { + count = 1500; + add_angle = !add_angle; + } + } + } + float rain_angle = DEGTORAD(STATIC_RAIN_ANGLE + ((STATIC_RAIN_ANGLE < 0) ? 360 : 0)); + float sin_angle = Sin(rain_angle); + float cos_angle = Cos(rain_angle); + float base_x = 0.0f * cos_angle - 1.0f * sin_angle; + float base_y = 1.0f * cos_angle + 0.0f * sin_angle; + CVector xpos(0.0f, 0.0f, 0.0f); + for (int i = 0; i < 2 * num_drops; i++) { + CVector dir; + dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f); + dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f); + dir.z = 0; + CParticle::AddParticle(PARTICLE_RAINDROP_2D, xpos, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f), + colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame); + xpos.x += screen_width / (2 * num_drops); + xpos.x += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f); + } + CVector ypos(0.0f, 0.0f, 0.0f); + for (int i = 0; i < num_drops; i++) { + CVector dir; + dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f); + dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f); + dir.z = 0; + CParticle::AddParticle(PARTICLE_RAINDROP_2D, ypos, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f), + colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame); + ypos.y += screen_width / num_drops; + ypos.y += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f); + } + CVector ypos2(0.0f, 0.0f, 0.0f); + for (int i = 0; i < num_drops; i++) { + CVector dir; + dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f); + dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f); + dir.z = 0; + CParticle::AddParticle(PARTICLE_RAINDROP_2D, ypos2, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f), + colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame); + ypos2.y += screen_width / num_drops; + ypos2.y += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f); + } + for (int i = 0; i < num_drops; i++) { + CVector pos; + pos.x = CGeneral::GetRandomNumberInRange(DROPLETS_LEFT_OFFSET, screen_width - DROPLETS_RIGHT_OFFSET); + pos.y = CGeneral::GetRandomNumberInRange(DROPLETS_TOP_OFFSET, screen_height - DROPLETS_TOP_OFFSET); + pos.z = 0.0f; + CParticle::AddParticle(PARTICLE_RAINDROP_2D, pos, CVector(0.0f, 0.0f, 0.0f), nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f), + colour, CGeneral::GetRandomNumberInRange(-10, 10), 360 - rain_angle + CGeneral::GetRandomNumberInRange(-30, 30), cur_frame, 0); + } + int num_splash_attempts = (int)(3 * Rain) + 1; + int num_splashes = (int)(3 * Rain) + 4; + CVector splash_points[4]; + splash_points[0] = CVector(-RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) * + RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude(); + splash_points[1] = CVector(RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) * + RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude(); + splash_points[2] = 4.0f * CVector(-RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) * + RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude(); + splash_points[3] = 4.0f * CVector(RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) * + RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude(); + RwV3dTransformPoints((RwV3d*)splash_points, (RwV3d*)splash_points, 4, RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera))); + CVector fp = (splash_points[0] + splash_points[1] + splash_points[2] + splash_points[3]) / 4; + for (int i = 0; i < num_splash_attempts; i++) { + CColPoint point; + CEntity* entity; + CVector np = fp + CVector(CGeneral::GetRandomNumberInRange(-SPLASH_CHECK_RADIUS, SPLASH_CHECK_RADIUS), CGeneral::GetRandomNumberInRange(-SPLASH_CHECK_RADIUS, SPLASH_CHECK_RADIUS), 0.0f); + if (CWorld::ProcessVerticalLine(np + CVector(0.0f, 0.0f, 40.0f), -40.0f, point, entity, true, false, false, false, true, false, nil)) { + for (int j = 0; j < num_splashes; j++) + CParticle::AddParticle((CGeneral::GetRandomTrueFalse() ? PARTICLE_RAIN_SPLASH : PARTICLE_RAIN_SPLASHUP), + CVector( + np.x + CGeneral::GetRandomNumberInRange(-SPLASH_OFFSET_RADIUS, SPLASH_OFFSET_RADIUS), + np.y + CGeneral::GetRandomNumberInRange(-SPLASH_OFFSET_RADIUS, SPLASH_OFFSET_RADIUS), + point.point.z + 0.1f), + CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, colour); + } + } +} + +void RenderOneRainStreak(CVector pos, CVector unused, int intensity, bool scale, float distance) +{ + static float RandomTex; + static float RandomTexX; + static float RandomTexY; + TempBufferRenderIndexList[TempBufferIndicesStored + 0] = TempBufferVerticesStored + 0; + TempBufferRenderIndexList[TempBufferIndicesStored + 1] = TempBufferVerticesStored + 2; + TempBufferRenderIndexList[TempBufferIndicesStored + 2] = TempBufferVerticesStored + 1; + TempBufferRenderIndexList[TempBufferIndicesStored + 3] = TempBufferVerticesStored + 0; + TempBufferRenderIndexList[TempBufferIndicesStored + 4] = TempBufferVerticesStored + 3; + TempBufferRenderIndexList[TempBufferIndicesStored + 5] = TempBufferVerticesStored + 2; + TempBufferRenderIndexList[TempBufferIndicesStored + 6] = TempBufferVerticesStored + 1; + TempBufferRenderIndexList[TempBufferIndicesStored + 7] = TempBufferVerticesStored + 2; + TempBufferRenderIndexList[TempBufferIndicesStored + 8] = TempBufferVerticesStored + 4; + TempBufferRenderIndexList[TempBufferIndicesStored + 9] = TempBufferVerticesStored + 2; + TempBufferRenderIndexList[TempBufferIndicesStored + 10] = TempBufferVerticesStored + 3; + TempBufferRenderIndexList[TempBufferIndicesStored + 11] = TempBufferVerticesStored + 4; + RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 0], 0, 0, 0, 0); + RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 0], pos.x + 11.0f * TheCamera.GetUp().x, pos.y + 11.0f * TheCamera.GetUp().y, pos.z + 11.0f * TheCamera.GetUp().z); + RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 1], 0, 0, 0, 0); + RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 1], pos.x - 9.0f * TheCamera.GetRight().x, pos.y - 9.0f * TheCamera.GetRight().y, pos.z - 9.0f * TheCamera.GetUp().z); + RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 2], RAIN_COLOUR_R * intensity / 256, RAIN_COLOUR_G * intensity / 256, RAIN_COLOUR_B * intensity / 256, RAIN_ALPHA); + RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 2], pos.x, pos.y, pos.z); + RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 3], 0, 0, 0, 0); + RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 3], pos.x + 9.0f * TheCamera.GetRight().x, pos.y + 9.0f * TheCamera.GetRight().y, pos.z + 9.0f * TheCamera.GetUp().z); + RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 4], 0, 0, 0, 0); + RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 4], pos.x - 11.0f * TheCamera.GetUp().x, pos.y - 11.0f * TheCamera.GetUp().y, pos.z - 11.0f * TheCamera.GetUp().z); + float u = STREAK_U; + float v = STREAK_V; + if (scale) { + u *= LARGE_STREAK_COEFFICIENT; + v *= LARGE_STREAK_COEFFICIENT; + } + float distance_coefficient; + if (distance < STREAK_MIN_DISTANCE) + distance_coefficient = 1.0f; + else if (distance > STREAK_MAX_DISTANCE) + distance_coefficient = 0.5f; + else + distance_coefficient = 1.0f - 0.5f * (distance - STREAK_MIN_DISTANCE) / (STREAK_MAX_DISTANCE - STREAK_MIN_DISTANCE); + u *= distance_coefficient; + v *= distance_coefficient; + if (!CTimer::GetIsPaused()) { + RandomTex = ((CGeneral::GetRandomNumber() & 255) - 128) * 0.01f; + RandomTexX = (CGeneral::GetRandomNumber() & 127) * 0.01f; + RandomTexY = (CGeneral::GetRandomNumber() & 127) * 0.01f; + } + RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 0], 0.5f * u - RandomTex + RandomTexX); + RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 0], -v * 0.5f + RandomTexY); + RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 1], RandomTexX); + RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 1], RandomTexY); + RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 2], 0.5f * u + RandomTexX); + RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 2], RandomTexY); + RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 3], u + RandomTexX); + RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 3], RandomTexY); + RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 4], 0.5f * u + RandomTex + RandomTexX); + RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 5], 0.5f * v + RandomTexY); + TempBufferIndicesStored += 12; + TempBufferVerticesStored += 5; +} + +void CWeather::RenderRainStreaks(void) +{ + if (CTimer::GetIsCodePaused()) + return; + int base_intensity = (64.0f - CTimeCycle::GetFogReduction()) / 64.0f * int(255 * Rain); + if (base_intensity == 0) + return; + TempBufferIndicesStored = 0; + TempBufferVerticesStored = 0; + for (int i = 0; i < NUM_RAIN_STREAKS; i++) { + if (Streaks[i].timer) { + float secondsElapsed = (CTimer::GetTimeInMilliseconds() - Streaks[i].timer) / 1024.0f; + if (secondsElapsed > STREAK_LIFETIME) + Streaks[i].timer = 0; + else{ + int intensity; + if (secondsElapsed < STREAK_INTEROLATION_TIME) + intensity = base_intensity * 0.5f * secondsElapsed / STREAK_INTEROLATION_TIME; + else if (secondsElapsed > (STREAK_LIFETIME - STREAK_INTEROLATION_TIME)) + intensity = (STREAK_LIFETIME - secondsElapsed) * 0.5f * base_intensity / STREAK_INTEROLATION_TIME; + else + intensity = base_intensity * 0.5f; + CVector dir = Streaks[i].direction; + dir.Normalise(); + CVector pos = Streaks[i].position + secondsElapsed * Streaks[i].direction; + RenderOneRainStreak(pos, dir, intensity, false, (pos - TheCamera.GetPosition()).Magnitude()); +#ifndef FIX_BUGS // remove useless code + if (secondsElapsed > 1.0f && secondsElapsed < STREAK_LIFETIME - 1.0f) { + CGeneral::GetRandomNumber(), CGeneral::GetRandomNumber(); + } +#endif + } + } + else if ((CGeneral::GetRandomNumber() & 0xF00) == 0){ + // 1/16 probability + Streaks[i].direction = CVector(4.0f, 4.0f, -4.0f); + Streaks[i].position = 6.0f * TheCamera.GetForward() + TheCamera.GetPosition() + CVector(-1.8f * Streaks[i].direction.x, -1.8f * Streaks[i].direction.y, 8.0f); + if (!CCutsceneMgr::IsCutsceneProcessing()) { + Streaks[i].position.x += 2.0f * FindPlayerSpeed().x * 60.0f; + Streaks[i].position.y += 2.0f * FindPlayerSpeed().y * 60.0f; + } + else + Streaks[i].position += (TheCamera.GetPosition() - TheCamera.m_RealPreviousCameraPosition) * 20.0f; + Streaks[i].position.x += ((CGeneral::GetRandomNumber() & 255) - 128) * 0.08f; + Streaks[i].position.y += ((CGeneral::GetRandomNumber() & 255) - 128) * 0.08f; + Streaks[i].timer = CTimer::GetTimeInMilliseconds(); + } + } + if (TempBufferIndicesStored){ + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEFOGTYPE, (void*)rwFOGTYPELINEAR); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRainDropTex[3])); + if (RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, 1)) + { + RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored); + RwIm3DEnd(); + } + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); + } + TempBufferVerticesStored = 0; + TempBufferIndicesStored = 0; +} + void CWeather::StoreWeatherState() { Stored_StateStored = true; @@ -71,4 +529,4 @@ void CWeather::RestoreWeatherState() Rain = Stored_Rain; NewWeatherType = Stored_NewWeatherType; OldWeatherType = Stored_OldWeatherType; -}
\ No newline at end of file +} diff --git a/src/render/Weather.h b/src/render/Weather.h index 63def9b9..9e4ea378 100644 --- a/src/render/Weather.h +++ b/src/render/Weather.h @@ -8,6 +8,14 @@ enum { class CWeather { public: + enum { + WEATHER_RANDOM = -1, + WEATHER_SUNNY = 0, + WEATHER_CLOUDY = 1, + WEATHER_RAINY = 2, + WEATHER_FOGGY = 3, + WEATHER_TOTAL = 4 + }; static int32 &SoundHandle; static int32 &WeatherTypeInList; @@ -46,4 +54,18 @@ public: static void ForceWeatherNow(int16); static void StoreWeatherState(); static void RestoreWeatherState(); + static void AddRain(); }; + +enum { + NUM_RAIN_STREAKS = 35 +}; + +struct tRainStreak +{ + CVector position; + CVector direction; + uint32 timer; +}; + +extern RwTexture* (&gpRainDropTex)[4];
\ No newline at end of file |