summaryrefslogtreecommitdiffstats
path: root/src/render/WaterLevel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/WaterLevel.cpp')
-rw-r--r--src/render/WaterLevel.cpp1554
1 files changed, 0 insertions, 1554 deletions
diff --git a/src/render/WaterLevel.cpp b/src/render/WaterLevel.cpp
deleted file mode 100644
index 7001c0cf..00000000
--- a/src/render/WaterLevel.cpp
+++ /dev/null
@@ -1,1554 +0,0 @@
-#include "common.h"
-#include "main.h"
-#include "FileMgr.h"
-#include "FileLoader.h"
-#include "TxdStore.h"
-#include "Timer.h"
-#include "Weather.h"
-#include "Camera.h"
-#include "Vehicle.h"
-#include "Boat.h"
-#include "World.h"
-#include "General.h"
-#include "Timecycle.h"
-#include "ZoneCull.h"
-#include "Clock.h"
-#include "Particle.h"
-#include "ParticleMgr.h"
-#include "RwHelper.h"
-#include "Streaming.h"
-#include "CdStream.h"
-#include "Pad.h"
-#include "RenderBuffer.h"
-#include <rpworld.h>
-#include "WaterLevel.h"
-#include "MemoryHeap.h"
-
-
-float TEXTURE_ADDU;
-float TEXTURE_ADDV;
-
-int32 CWaterLevel::ms_nNoOfWaterLevels;
-float CWaterLevel::ms_aWaterZs[48];
-CRect CWaterLevel::ms_aWaterRects[48];
-int8 CWaterLevel::aWaterBlockList[MAX_LARGE_SECTORS][MAX_LARGE_SECTORS];
-int8 CWaterLevel::aWaterFineBlockList[MAX_SMALL_SECTORS][MAX_SMALL_SECTORS];
-bool CWaterLevel::WavesCalculatedThisFrame;
-RpAtomic *CWaterLevel::ms_pWavyAtomic;
-RpGeometry *CWaterLevel::apGeomArray[8];
-int16 CWaterLevel::nGeomUsed;
-//"Custom" Don't Render Water Toggle
-bool gbDontRenderWater;
-
-//RwTexture *gpWaterTex;
-//RwRaster *gpWaterRaster;
-
-RwTexture *gpWaterTex;
-RwRaster *gpWaterRaster;
-
-
-const float fAdd1 = 180.0f;
-const float fAdd2 = 80.0f;
-const float fRedMult = 0.6f;
-const float fGreenMult = 1.0f;
-const float fBlueMult = 1.4f;
-
-
-void
-CWaterLevel::Initialise(Const char *pWaterDat)
-{
- ms_nNoOfWaterLevels = 0;
-
-#ifdef MASTER
- int32 hFile = -1;
-
- do
- {
- hFile = CFileMgr::OpenFile("DATA\\waterpro.dat", "rb");
- }
- while ( hFile < 0 );
-#else
- int32 hFile = CFileMgr::OpenFile("DATA\\waterpro.dat", "rb");
-#endif
-
- if (hFile > 0)
- {
- CFileMgr::Read(hFile, (char *)&ms_nNoOfWaterLevels, sizeof(ms_nNoOfWaterLevels));
- CFileMgr::Read(hFile, (char *)ms_aWaterZs, sizeof(ms_aWaterZs));
- CFileMgr::Read(hFile, (char *)ms_aWaterRects, sizeof(ms_aWaterRects));
- CFileMgr::Read(hFile, (char *)aWaterBlockList, sizeof(aWaterBlockList));
- CFileMgr::Read(hFile, (char *)aWaterFineBlockList, sizeof(aWaterFineBlockList));
-
- CFileMgr::CloseFile(hFile);
- }
-#ifndef MASTER
- else
- {
- printf("Init waterlevels\n");
-
- CFileMgr::SetDir("");
- hFile = CFileMgr::OpenFile(pWaterDat, "r");
-
- char *line;
-
- while ((line = CFileLoader::LoadLine(hFile)))
- {
-#ifdef FIX_BUGS
- if (*line && *line != ';' && !strstr(line, "* ;end of file"))
-#else
- if (*line && *line != ';')
-#endif
- {
- float z, l, b, r, t;
- sscanf(line, "%f %f %f %f %f", &z, &l, &b, &r, &t);
- AddWaterLevel(l, b, r, t, z);
- }
- }
-
- CFileMgr::CloseFile(hFile);
-
- for (int32 x = 0; x < MAX_SMALL_SECTORS; x++)
- {
- for (int32 y = 0; y < MAX_SMALL_SECTORS; y++)
- {
- aWaterFineBlockList[x][y] = NO_WATER;
- }
- }
-
- // rasterize water rects read from file
- for (int32 i = 0; i < ms_nNoOfWaterLevels; i++)
- {
- int32 l = WATER_HUGE_X(ms_aWaterRects[i].left);
- int32 r = WATER_HUGE_X(ms_aWaterRects[i].right) + 1.0f;
- int32 t = WATER_HUGE_Y(ms_aWaterRects[i].top);
- int32 b = WATER_HUGE_Y(ms_aWaterRects[i].bottom) + 1.0f;
-
-#ifdef FIX_BUGS
- // water.dat has rects that go out of bounds
- // which causes memory corruption
- l = Clamp(l, 0, MAX_SMALL_SECTORS - 1);
- r = Clamp(r, 0, MAX_SMALL_SECTORS - 1);
- t = Clamp(t, 0, MAX_SMALL_SECTORS - 1);
- b = Clamp(b, 0, MAX_SMALL_SECTORS - 1);
-#endif
-
- for (int32 x = l; x <= r; x++)
- {
- for (int32 y = t; y <= b; y++)
- {
- aWaterFineBlockList[x][y] = i;
- }
- }
- }
-
- // remove tiles that are obscured by land
- for (int32 x = 0; x < MAX_SMALL_SECTORS; x++)
- {
- float worldX = WATER_START_X + x * SMALL_SECTOR_SIZE;
-
- for (int32 y = 0; y < MAX_SMALL_SECTORS; y++)
- {
- if (aWaterFineBlockList[x][y] >= 0)
- {
- float worldY = WATER_START_Y + y * SMALL_SECTOR_SIZE;
-
- int32 i;
- for (i = 0; i <= 8; i++)
- {
- for (int32 j = 0; j <= 8; j++)
- {
- CVector worldPos = CVector(worldX + i * (SMALL_SECTOR_SIZE / 8), worldY + j * (SMALL_SECTOR_SIZE / 8), ms_aWaterZs[aWaterFineBlockList[x][y]]);
-
- if ((worldPos.x > WORLD_MIN_X && worldPos.x < WORLD_MAX_X) && (worldPos.y > WORLD_MIN_Y && worldPos.y < WORLD_MAX_Y) &&
- (!WaterLevelAccordingToRectangles(worldPos.x, worldPos.y) || TestVisibilityForFineWaterBlocks(worldPos)))
- continue;
-
- // at least one point in the tile wasn't blocked, so don't remove water
- i = 1000;
- break;
- }
- }
-
- if (i < 1000)
- aWaterFineBlockList[x][y] = NO_WATER;
- }
- }
- }
-
- RemoveIsolatedWater();
-
- // calculate coarse tiles from fine tiles
- for (int32 x = 0; x < MAX_LARGE_SECTORS; x++)
- {
- for (int32 y = 0; y < MAX_LARGE_SECTORS; y++)
- {
- if (aWaterFineBlockList[x * 2][y * 2] >= 0)
- {
- aWaterBlockList[x][y] = aWaterFineBlockList[x * 2][y * 2];
- }
- else if (aWaterFineBlockList[x * 2 + 1][y * 2] >= 0)
- {
- aWaterBlockList[x][y] = aWaterFineBlockList[x * 2 + 1][y * 2];
- }
- else if (aWaterFineBlockList[x * 2][y * 2 + 1] >= 0)
- {
- aWaterBlockList[x][y] = aWaterFineBlockList[x * 2][y * 2 + 1];
- }
- else if (aWaterFineBlockList[x * 2 + 1][y * 2 + 1] >= 0)
- {
- aWaterBlockList[x][y] = aWaterFineBlockList[x * 2 + 1][y * 2 + 1];
- }
- else
- {
- aWaterBlockList[x][y] = NO_WATER;
- }
- }
- }
-
- hFile = CFileMgr::OpenFileForWriting("data\\waterpro.dat");
-
- if (hFile > 0)
- {
- CFileMgr::Write(hFile, (char *)&ms_nNoOfWaterLevels, sizeof(ms_nNoOfWaterLevels));
- CFileMgr::Write(hFile, (char *)ms_aWaterZs, sizeof(ms_aWaterZs));
- CFileMgr::Write(hFile, (char *)ms_aWaterRects, sizeof(ms_aWaterRects));
- CFileMgr::Write(hFile, (char *)aWaterBlockList, sizeof(aWaterBlockList));
- CFileMgr::Write(hFile, (char *)aWaterFineBlockList, sizeof(aWaterFineBlockList));
-
- CFileMgr::CloseFile(hFile);
- }
- }
-#endif
-
- CTxdStore::PushCurrentTxd();
-
- int32 slot = CTxdStore::FindTxdSlot("particle");
- CTxdStore::SetCurrentTxd(slot);
-
- if ( gpWaterTex == nil )
- gpWaterTex = RwTextureRead("water_old", nil);
- gpWaterRaster = RwTextureGetRaster(gpWaterTex);
-
- CTxdStore::PopCurrentTxd();
-
- CreateWavyAtomic();
- FreeBoatWakeArray();
-
- printf("Done Initing waterlevels\n");
-}
-
-void
-CWaterLevel::Shutdown()
-{
- FreeBoatWakeArray();
- DestroyWavyAtomic();
-
- if ( gpWaterTex != nil )
- {
- RwTextureDestroy(gpWaterTex);
- gpWaterTex = nil;
- }
-}
-
-void
-CWaterLevel::CreateWavyAtomic()
-{
- RpGeometry *wavyGeometry;
- RpMaterial *wavyMaterial;
- RpTriangle *wavyTriangles;
- RpMorphTarget *wavyMorphTarget;
- RwSphere boundingSphere;
- RwV3d *wavyVert;
-
- RwFrame *wavyFrame;
-
- {
- wavyGeometry = RpGeometryCreate(9*9, 8*8*2, rpGEOMETRYTRISTRIP
- |rpGEOMETRYTEXTURED
- |rpGEOMETRYPRELIT
- |rpGEOMETRYMODULATEMATERIALCOLOR);
-
- ASSERT(wavyGeometry != nil);
-
- }
-
- {
- wavyMaterial = RpMaterialCreate();
-
- ASSERT(wavyMaterial != nil);
- ASSERT(gpWaterTex != nil);
-
- RpMaterialSetTexture(wavyMaterial, gpWaterTex);
- }
-
- {
- wavyTriangles = RpGeometryGetTriangles(wavyGeometry);
-
- ASSERT(wavyTriangles != nil);
- /*
- [B] [C]
- ***********
- * * *
- * * *
- * * *
- * * *
- ***********
- [A] [D]
- */
-
- for ( int32 i = 0; i < 8; i++ )
- {
- for ( int32 j = 0; j < 8; j++ )
- {
- RpGeometryTriangleSetVertexIndices(wavyGeometry,
- &wavyTriangles[2 * 8*i + 2*j + 0], /*A*/9*i+j+0, /*B*/9*i+j+1, /*C*/9*i+j+9+1);
-
- RpGeometryTriangleSetVertexIndices(wavyGeometry,
- &wavyTriangles[2 * 8*i + 2*j + 1], /*A*/9*i+j+0, /*C*/9*i+j+9+1, /*D*/9*i+j+9 );
-
- RpGeometryTriangleSetMaterial(wavyGeometry, &wavyTriangles[2 * 8*i + 2*j + 0], wavyMaterial);
- RpGeometryTriangleSetMaterial(wavyGeometry, &wavyTriangles[2 * 8*i + 2*j + 1], wavyMaterial);
- }
- }
- }
-
-
- {
- wavyMorphTarget = RpGeometryGetMorphTarget(wavyGeometry, 0);
- ASSERT(wavyMorphTarget != nil);
- wavyVert = RpMorphTargetGetVertices(wavyMorphTarget);
- ASSERT(wavyVert != nil);
-
- for ( int32 i = 0; i < 9; i++ )
- {
- for ( int32 j = 0; j < 9; j++ )
- {
- wavyVert[9*i+j].x = (float)i * 4.0f;
- wavyVert[9*i+j].y = (float)j * 4.0f;
- wavyVert[9*i+j].z = 0.0f;
- }
- }
-
- RpMorphTargetCalcBoundingSphere(wavyMorphTarget, &boundingSphere);
- RpMorphTargetSetBoundingSphere(wavyMorphTarget, &boundingSphere);
- RpGeometryUnlock(wavyGeometry);
- }
-
-
- {
- wavyFrame = RwFrameCreate();
- ASSERT( wavyFrame != nil );
-
- ms_pWavyAtomic = RpAtomicCreate();
- ASSERT( ms_pWavyAtomic != nil );
-
- RpAtomicSetGeometry(ms_pWavyAtomic, wavyGeometry, 0);
- RpAtomicSetFrame(ms_pWavyAtomic, wavyFrame);
- RpMaterialDestroy(wavyMaterial);
- RpGeometryDestroy(wavyGeometry);
- }
-}
-
-void
-CWaterLevel::DestroyWavyAtomic()
-{
- RwFrame *frame;
-
- frame = RpAtomicGetFrame(ms_pWavyAtomic);
-
- RpAtomicDestroy(ms_pWavyAtomic);
-
- RwFrameDestroy(frame);
-}
-
-#ifndef MASTER
-void
-CWaterLevel::AddWaterLevel(float fXLeft, float fYBottom, float fXRight, float fYTop, float fLevel)
-{
- ms_aWaterRects[ms_nNoOfWaterLevels] = CRect(fXLeft, fYBottom, fXRight, fYTop);
- ms_aWaterZs[ms_nNoOfWaterLevels] = fLevel;
- ms_nNoOfWaterLevels++;
-}
-
-bool
-CWaterLevel::WaterLevelAccordingToRectangles(float fX, float fY, float *pfOutLevel)
-{
- if (ms_nNoOfWaterLevels <= 0) return false;
-
- for (int32 i = 0; i < ms_nNoOfWaterLevels; i++)
- {
- if (fX >= ms_aWaterRects[i].left && fX <= ms_aWaterRects[i].right
- && fY >= ms_aWaterRects[i].top && fY <= ms_aWaterRects[i].bottom)
- {
- if (pfOutLevel) *pfOutLevel = ms_aWaterZs[i];
-
- return true;
- }
- }
-
- return false;
-}
-
-bool
-CWaterLevel::TestVisibilityForFineWaterBlocks(const CVector &worldPos)
-{
- static CVector2D tab[] =
- {
- { 50.0f, 50.0f },
- { -50.0f, 50.0f },
- { -50.0f, -50.0f },
- { 50.0f, -50.0f },
- { 50.0f, 0.0f },
- { -50.0f, 0.0f },
- { 0.0f, -50.0f },
- { 0.0f, 50.0f },
- };
-
- CEntity *entity;
- CColPoint col;
- CVector lineStart, lineEnd;
-
- lineStart = worldPos;
-
- if (!CWorld::ProcessVerticalLine(lineStart, lineStart.z + 100.0f, col, entity, true, false, false, false, true, false, nil))
- {
- lineStart.x += 0.4f;
- lineStart.y += 0.4f;
-
- if (!CWorld::ProcessVerticalLine(lineStart, lineStart.z + 100.0f, col, entity, true, false, false, false, true, false, nil))
- {
- return false;
- }
- }
-
- for (int32 i = 0; i < ARRAY_SIZE(tab); i++)
- {
- lineStart = worldPos;
- lineEnd = worldPos;
-
- lineEnd.x += tab[i].x;
- lineEnd.y += tab[i].y;
- lineEnd.z += 100.0f;
-
- if ((lineEnd.x > WORLD_MIN_X && lineEnd.x < WORLD_MAX_X) && (lineEnd.y > WORLD_MIN_Y && lineEnd.y < WORLD_MAX_Y))
- {
- if (!CWorld::ProcessLineOfSight(lineStart, lineEnd, col, entity, true, false, false, false, true, false))
- {
- lineStart.x += 0.4f;
- lineStart.y += 0.4f;
- lineEnd.x += 0.4f;
- lineEnd.y += 0.4f;
-
- if (!CWorld::ProcessLineOfSight(lineStart, lineEnd, col, entity, true, false, false, false, true, false))
- {
- return false;
- }
- }
- }
- }
-
- return true;
-}
-
-void
-CWaterLevel::RemoveIsolatedWater()
-{
- bool (*isConnected)[MAX_SMALL_SECTORS] = new bool[MAX_SMALL_SECTORS][MAX_SMALL_SECTORS];
-
- for (int32 x = 0; x < MAX_SMALL_SECTORS; x++)
- {
- for (int32 y = 0; y < MAX_SMALL_SECTORS; y++)
- {
- isConnected[x][y] = false;
- }
- }
-
- isConnected[0][0] = true;
- bool keepGoing;
-
- do
- {
- keepGoing = false;
-
- for (int32 x = 0; x < MAX_SMALL_SECTORS; x++)
- {
- for (int32 y = 0; y < MAX_SMALL_SECTORS; y++)
- {
- if (aWaterFineBlockList[x][y] < 0 || isConnected[x][y])
- continue;
-
- if (x > 0 && isConnected[x - 1][y])
- {
- isConnected[x][y] = true;
- keepGoing = true;
- }
-
- if (y > 0 && isConnected[x][y - 1])
- {
- isConnected[x][y] = true;
- keepGoing = true;
- }
-
- if (x + 1 < MAX_SMALL_SECTORS && isConnected[x + 1][y])
- {
- isConnected[x][y] = true;
- keepGoing = true;
- }
-
- if (y + 1 < MAX_SMALL_SECTORS && isConnected[x][y + 1])
- {
- isConnected[x][y] = true;
- keepGoing = true;
- }
- }
- }
- }
- while (keepGoing);
-
- int32 numRemoved = 0;
-
- for (int32 x = 0; x < MAX_SMALL_SECTORS; x++)
- {
- for (int32 y = 0; y < MAX_SMALL_SECTORS; y++)
- {
- if (aWaterFineBlockList[x][y] >= 0 && !isConnected[x][y] && ms_aWaterZs[aWaterFineBlockList[x][y]] == 0.0f)
- {
- numRemoved++;
- aWaterFineBlockList[x][y] = NO_WATER;
- }
- }
- }
-
- printf("Removed %d isolated patches of water\n", numRemoved);
-
- delete[] isConnected;
-}
-#endif
-
-bool
-CWaterLevel::GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool bDontCheckZ)
-{
- int32 x = WATER_HUGE_X(fX);
- int32 y = WATER_HUGE_Y(fY);
-
- ASSERT( x >= 0 && x < HUGE_SECTOR_SIZE );
- ASSERT( y >= 0 && y < HUGE_SECTOR_SIZE );
-
- int8 nBlock = aWaterFineBlockList[x][y];
-
- if ( nBlock == NO_WATER )
- return false;
-
- ASSERT( pfOutLevel != nil );
- *pfOutLevel = ms_aWaterZs[nBlock];
-
- float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f);
-
- float fWave = Sin
- (
- /*( WATER_UNSIGN_Y(fY) - float(y) * MAX_HUGE_SECTORS + WATER_UNSIGN_X(fX) - float(x) * MAX_HUGE_SECTORS )*/ // VC
- (float)( ((int32)fX & (MAX_HUGE_SECTORS-1)) + ((int32)fY & (MAX_HUGE_SECTORS-1)) )
- * (TWOPI / MAX_HUGE_SECTORS ) + fAngle
- );
-
- float fWindFactor = CWeather::Wind * 0.7f + 0.3f;
-
- *pfOutLevel += fWave * fWindFactor;
-
- if ( bDontCheckZ == false && (*pfOutLevel - fZ) > 3.0f )
- {
- *pfOutLevel = 0.0f;
- return false;
- }
-
- return true;
-}
-
-bool
-CWaterLevel::GetWaterLevelNoWaves(float fX, float fY, float fZ, float *pfOutLevel)
-{
- int32 x = WATER_HUGE_X(fX);
- int32 y = WATER_HUGE_Y(fY);
-
- ASSERT( x >= 0 && x < HUGE_SECTOR_SIZE );
- ASSERT( y >= 0 && y < HUGE_SECTOR_SIZE );
-
- int8 nBlock = aWaterFineBlockList[x][y];
-
- if ( nBlock == NO_WATER )
- return false;
-
- ASSERT( pfOutLevel != nil );
- *pfOutLevel = ms_aWaterZs[nBlock];
-
- return true;
-}
-
-inline float
-_GetWaterDrawDist()
-{
- // if z less then 15.0f return 1200.0f
- if ( TheCamera.GetPosition().z < 15.0f )
- return 1200.0f;
-
- // if z greater then 60.0f return 2000.0f;
- if ( TheCamera.GetPosition().z > 60.0f )
- return 2000.0f;
-
- return (TheCamera.GetPosition().z + -15.0f) * 800.0f / 45.0f + 1200.0f;
-}
-
-inline float
-_GetWavyDrawDist()
-{
- if ( FindPlayerVehicle() && FindPlayerVehicle()->IsBoat() )
- return 120.0f;
- else
- return 70.0f;
-}
-
-inline void
-_GetCamBounds(bool *bUseCamStartY, bool *bUseCamEndY, bool *bUseCamStartX, bool *bUseCamEndX)
-{
- if ( TheCamera.GetForward().z > -0.8f )
- {
- if ( Abs(TheCamera.GetForward().x) > Abs(TheCamera.GetForward().y) )
- {
- if ( TheCamera.GetForward().x > 0.0f )
- *bUseCamStartX = true;
- else
- *bUseCamEndX = true;
- }
- else
- {
- if ( TheCamera.GetForward().y > 0.0f )
- *bUseCamStartY = true;
- else
- *bUseCamEndY = true;
- }
- }
-}
-
-inline float
-SectorRadius(float fSize)
-{
- return Sqrt(Pow(fSize, 2) + Pow(fSize, 2));
-}
-
-void
-CWaterLevel::RenderWater()
-{
-//"Custom" Don't Render Water Toggle
-#ifndef MASTER
- if (gbDontRenderWater)
- return;
-#endif
- PUSH_RENDERGROUP("CWaterLevel::RenderWater");
- bool bUseCamEndX = false;
- bool bUseCamStartY = false;
-
- bool bUseCamStartX = false;
- bool bUseCamEndY = false;
-
- float fWavySectorMaxRenderDist = _GetWavyDrawDist();
- float fWavySectorMaxRenderDistSqr = SQR(fWavySectorMaxRenderDist);
-
- _GetCamBounds(&bUseCamStartY, &bUseCamEndY, &bUseCamStartX, &bUseCamEndX);
-
- float fHugeSectorMaxRenderDist = _GetWaterDrawDist();
- float fHugeSectorMaxRenderDistSqr = SQR(fHugeSectorMaxRenderDist);
-
- float windAddUV = CWeather::Wind * 0.0015f + 0.0005f;
-
-
- if ( !CTimer::GetIsPaused() )
- {
-#ifdef FIX_BUGS
- TEXTURE_ADDU += (CGeneral::GetRandomNumberInRange(-0.0005f, 0.0005f) + windAddUV) * CTimer::GetTimeStepFix();
- TEXTURE_ADDV += (CGeneral::GetRandomNumberInRange(-0.0005f, 0.0005f) + windAddUV) * CTimer::GetTimeStepFix();
-#else
- TEXTURE_ADDU += CGeneral::GetRandomNumberInRange(-0.0005f, 0.0005f) + windAddUV;
- TEXTURE_ADDV += CGeneral::GetRandomNumberInRange(-0.0005f, 0.0005f) + windAddUV;
-#endif
- }
-
- if ( TEXTURE_ADDU >= 1.0f )
- TEXTURE_ADDU = 0.0f;
- if ( TEXTURE_ADDV >= 1.0f )
- TEXTURE_ADDV = 0.0f;
-
- WavesCalculatedThisFrame = false;
-
- RwRGBA color = { 0, 0, 0, 255 };
-
- color.red = uint32((CTimeCycle::GetDirectionalRed() * 0.5f + CTimeCycle::GetAmbientRed() ) * 255.0f);
- color.green = uint32((CTimeCycle::GetDirectionalGreen() * 0.5f + CTimeCycle::GetAmbientGreen()) * 255.0f);
- color.blue = uint32((CTimeCycle::GetDirectionalBlue() * 0.5f + CTimeCycle::GetAmbientBlue() ) * 255.0f);
-
- TempBufferVerticesStored = 0;
- TempBufferIndicesStored = 0;
-
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpWaterRaster);
- RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)TRUE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
-
- CVector2D camPos
- (
- TheCamera.GetPosition().x,
- TheCamera.GetPosition().y
- );
-
- int32 nStartX = WATER_TO_HUGE_SECTOR_X(camPos.x - fHugeSectorMaxRenderDist);
- int32 nEndX = WATER_TO_HUGE_SECTOR_X(camPos.x + fHugeSectorMaxRenderDist) + 1;
- int32 nStartY = WATER_TO_HUGE_SECTOR_Y(camPos.y - fHugeSectorMaxRenderDist);
- int32 nEndY = WATER_TO_HUGE_SECTOR_Y(camPos.y + fHugeSectorMaxRenderDist) + 1;
-
- if ( bUseCamStartX )
- nStartX = WATER_TO_HUGE_SECTOR_X(camPos.x);
- if ( bUseCamEndX )
- nEndX = WATER_TO_HUGE_SECTOR_X(camPos.x);
- if ( bUseCamStartY )
- nStartY = WATER_TO_HUGE_SECTOR_Y(camPos.y);
- if ( bUseCamEndY )
- nEndY = WATER_TO_HUGE_SECTOR_Y(camPos.y);
-
- nStartX = Clamp(nStartX, 0, MAX_HUGE_SECTORS - 1);
- nEndX = Clamp(nEndX, 0, MAX_HUGE_SECTORS - 1);
- nStartY = Clamp(nStartY, 0, MAX_HUGE_SECTORS - 1);
- nEndY = Clamp(nEndY, 0, MAX_HUGE_SECTORS - 1);
-
- for ( int32 x = nStartX; x <= nEndX; x++ )
- {
- for ( int32 y = nStartY; y <= nEndY; y++ )
- {
- if ( aWaterBlockList[2*x+0][2*y+0] >= 0
- || aWaterBlockList[2*x+1][2*y+0] >= 0
- || aWaterBlockList[2*x+0][2*y+1] >= 0
- || aWaterBlockList[2*x+1][2*y+1] >= 0 )
- {
- float fX = WATER_FROM_HUGE_SECTOR_X(x);
- float fY = WATER_FROM_HUGE_SECTOR_Y(y);
-
- CVector2D vecHugeSectorCentre
- (
- fX + HUGE_SECTOR_SIZE/2,
- fY + HUGE_SECTOR_SIZE/2
- );
-
- float fHugeSectorDistToCamSqr = (camPos - vecHugeSectorCentre).MagnitudeSqr();
-
- if ( fHugeSectorMaxRenderDistSqr > fHugeSectorDistToCamSqr )
- {
- if ( TheCamera.IsSphereVisible(CVector(vecHugeSectorCentre.x, vecHugeSectorCentre.y, 0.0f), SectorRadius(HUGE_SECTOR_SIZE)) )
- {
- if ( fHugeSectorDistToCamSqr >= SQR(500.0f) /*fHugeSectorNearDist*/ )
- {
- float fZ;
-
- if ( aWaterBlockList[2*x+0][2*y+0] >= 0 )
- fZ = ms_aWaterZs[ aWaterBlockList[2*x+0][2*y+0] ];
-
- if ( aWaterBlockList[2*x+1][2*y+0] >= 0 )
- fZ = ms_aWaterZs[ aWaterBlockList[2*x+1][2*y+0] ];
-
- if ( aWaterBlockList[2*x+0][2*y+1] >= 0 )
- fZ = ms_aWaterZs[ aWaterBlockList[2*x+0][2*y+1] ];
-
- if ( aWaterBlockList[2*x+1][2*y+1] >= 0 )
- fZ = ms_aWaterZs[ aWaterBlockList[2*x+1][2*y+1] ];
-
- RenderOneFlatHugeWaterPoly(fX, fY, fZ, color);
- }
- else
- {
- for ( int32 x2 = 2*x; x2 <= 2*x+1; x2++ )
- {
- for ( int32 y2 = 2*y; y2 <= 2*y+1; y2++ )
- {
- if ( aWaterBlockList[x2][y2] >= 0 )
- {
- float fLargeX = WATER_FROM_LARGE_SECTOR_X(x2);
- float fLargeY = WATER_FROM_LARGE_SECTOR_Y(y2);
-
- CVector2D vecLargeSectorCentre
- (
- fLargeX + LARGE_SECTOR_SIZE/2,
- fLargeY + LARGE_SECTOR_SIZE/2
- );
-
- float fLargeSectorDistToCamSqr = (camPos - vecLargeSectorCentre).MagnitudeSqr();
-
- if ( fLargeSectorDistToCamSqr < fHugeSectorMaxRenderDistSqr )
- {
- if ( TheCamera.IsSphereVisible(CVector(vecLargeSectorCentre.x, vecLargeSectorCentre.y, 0.0f), SectorRadius(LARGE_SECTOR_SIZE)) ) //90.879997f,
- {
- // Render four small(32x32) sectors, or one large(64x64).
-
- //
- // [N]
- // ---------
- // |0x1|1x1|
- // [W] --------- [E]
- // |0x0|1x0|
- // ---------
- // [S]
- //
-
- if ( fLargeSectorDistToCamSqr < SQR(176.0f) )
- {
- float fZ;
-
- // WS
- if ( aWaterFineBlockList[2*x2+0][2*y2+0] >= 0 )
- {
- float fSmallX = fLargeX;
- float fSmallY = fLargeY;
-
- CVector2D vecSmallSectorCentre
- (
- fSmallX + SMALL_SECTOR_SIZE/2,
- fSmallY + SMALL_SECTOR_SIZE/2
- );
-
- float fSmallSectorDistToCamSqr = (camPos - vecSmallSectorCentre).MagnitudeSqr();
- fZ = ms_aWaterZs[ aWaterFineBlockList[2*x2+0][2*y2+0] ];
-
- if ( fSmallSectorDistToCamSqr < fWavySectorMaxRenderDistSqr )
- RenderOneWavySector(fSmallX, fSmallY, fZ, color);
- else
- RenderOneFlatSmallWaterPoly(fSmallX, fSmallY, fZ, color);
- }
-
- // SE
- if ( aWaterFineBlockList[2*x2+1][2*y2+0] >= 0 )
- {
- float fSmallX = fLargeX + (LARGE_SECTOR_SIZE/2);
- float fSmallY = fLargeY;
-
- CVector2D vecSmallSectorCentre
- (
- fSmallX + SMALL_SECTOR_SIZE/2,
- fSmallY + SMALL_SECTOR_SIZE/2
- );
-
- float fSmallSectorDistToCamSqr = (camPos - vecSmallSectorCentre).MagnitudeSqr();
- fZ = ms_aWaterZs[ aWaterFineBlockList[2*x2+1][2*y2+0] ];
-
- if ( fSmallSectorDistToCamSqr < fWavySectorMaxRenderDistSqr )
- RenderOneWavySector(fSmallX, fSmallY, fZ, color);
- else
- RenderOneFlatSmallWaterPoly(fSmallX, fSmallY, fZ, color);
- }
-
- // WN
- if ( aWaterFineBlockList[2*x2+0][2*y2+1] >= 0 )
- {
- float fSmallX = fLargeX;
- float fSmallY = fLargeY + (LARGE_SECTOR_SIZE/2);
-
- CVector2D vecSmallSectorCentre
- (
- fSmallX + SMALL_SECTOR_SIZE/2,
- fSmallY + SMALL_SECTOR_SIZE/2
- );
-
- float fSmallSectorDistToCamSqr = (camPos - vecSmallSectorCentre).MagnitudeSqr();
- fZ = ms_aWaterZs[ aWaterFineBlockList[2*x2+0][2*y2+1] ];
-
- if ( fSmallSectorDistToCamSqr < fWavySectorMaxRenderDistSqr )
- RenderOneWavySector(fSmallX, fSmallY, fZ, color);
- else
- RenderOneFlatSmallWaterPoly(fSmallX, fSmallY, fZ, color);
- }
-
- //NE
- if ( aWaterFineBlockList[2*x2+1][2*y2+1] >= 0 )
- {
- float fSmallX = fLargeX + (LARGE_SECTOR_SIZE/2);
- float fSmallY = fLargeY + (LARGE_SECTOR_SIZE/2);
-
- CVector2D vecSmallSectorCentre
- (
- fSmallX + SMALL_SECTOR_SIZE/2,
- fSmallY + SMALL_SECTOR_SIZE/2
- );
-
- float fSmallSectorDistToCamSqr = (camPos - vecSmallSectorCentre).MagnitudeSqr();
- fZ = ms_aWaterZs[ aWaterFineBlockList[2*x2+1][2*y2+1] ];
-
- if ( fSmallSectorDistToCamSqr < fWavySectorMaxRenderDistSqr )
- RenderOneWavySector(fSmallX, fSmallY, fZ, color);
- else
- RenderOneFlatSmallWaterPoly(fSmallX, fSmallY, fZ, color);
- }
- }
- else
- {
- float fZ;
-
- fZ = ms_aWaterZs[ aWaterBlockList[x2][y2] ];
-
- RenderOneFlatLargeWaterPoly(fLargeX, fLargeY, fZ, color);
- }
- } // if ( TheCamera.IsSphereVisible
- } // if ( fLargeSectorDistToCamSqr < fHugeSectorMaxRenderDistSqr )
- } // if ( aWaterBlockList[x2][y2] >= 0 )
- } // for ( int32 y2 = 2*y; y2 <= 2*y+1; y2++ )
- } // for ( int32 x2 = 2*x; x2 <= 2*x+1; x2++ )
- //
-
- }
- }
- }
- }
- }
- }
-
- /*
- ----------- ---------------------- ----------------------
- | [N] | | [ EndY ] | | [ top ] |
- | | | | | |
- |[W] [0] [E]| |[StartX] [] [ EndX ]| |[ left ] [] [ right]|
- | | | | | |
- | [S] | | [StartY] | | [bottom] |
- ----------- ---------------------- ----------------------
-
-
- [S] [StartY] [bottom]
- [N] [EndY] [top]
- [W] [StartX] [left]
- [E] [EndX] [right]
-
- [S] -> [N] && [W] -> [E]
- bottom -> top && left -> right
- */
-
- if ( !bUseCamStartY )
- {
- for ( int32 x = 0; x < 26; x++ )
- {
- for ( int32 y = 0; y < 5; y++ )
- {
- float fX = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f;
- float fY = WATER_SIGN_Y(float(y) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f;
-
- CVector2D vecExtraHugeSectorCentre
- (
- fX + EXTRAHUGE_SECTOR_SIZE/2,
- fY + EXTRAHUGE_SECTOR_SIZE/2
- );
-
- float fCamDistToSector = (vecExtraHugeSectorCentre - camPos).Magnitude();
-
- if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr )
- {
- if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE)) )
- {
- RenderOneFlatExtraHugeWaterPoly(
- vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2,
- vecExtraHugeSectorCentre.y - EXTRAHUGE_SECTOR_SIZE/2,
- 0.0f,
- color);
- }
- }
- }
- }
- }
-
- for ( int32 y = 5; y < 21; y++ )
- {
- for ( int32 x = 0; x < 5; x++ )
- {
- float fX = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f;
- float fX2 = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f;
- float fY = WATER_SIGN_Y(float(y) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f;
-
- if ( !bUseCamStartX )
- {
- CVector2D vecExtraHugeSectorCentre
- (
- fX + EXTRAHUGE_SECTOR_SIZE/2,
- fY + EXTRAHUGE_SECTOR_SIZE/2
- );
-
- float fCamDistToSector = (vecExtraHugeSectorCentre - camPos).Magnitude();
-
- if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr )
- {
- if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE)) )
- {
- RenderOneFlatExtraHugeWaterPoly(
- vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2,
- vecExtraHugeSectorCentre.y - EXTRAHUGE_SECTOR_SIZE/2,
- 0.0f,
- color);
- }
- }
- }
-
- if ( !bUseCamEndX )
- {
- CVector2D vecExtraHugeSectorCentre
- (
- -(fX2 + EXTRAHUGE_SECTOR_SIZE/2),
- fY + EXTRAHUGE_SECTOR_SIZE/2
- );
-
- float fCamDistToSector = (vecExtraHugeSectorCentre - camPos).Magnitude();
-
- if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr )
- {
- if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE)) )
- {
- RenderOneFlatExtraHugeWaterPoly(
- vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2,
- vecExtraHugeSectorCentre.y - EXTRAHUGE_SECTOR_SIZE/2,
- 0.0f,
- color);
- }
- }
- }
- }
- }
-
- RenderAndEmptyRenderBuffer();
-
- CVector cur_pos = TheCamera.GetPosition();
-
- if ( !CCullZones::CamNoRain()
- && !CCullZones::PlayerNoRain()
- && CWeather::NewWeatherType == WEATHER_SUNNY
- && CClock::GetHours() > 6 && CClock::GetHours() < 20
- && WavesCalculatedThisFrame)
- {
- static CVector prev_pos(0.0f, 0.0f, 0.0f);
- static CVector prev_front(0.0f, 0.0f, 0.0f);
- static int32 timecounter;
-
- if ( Abs(prev_pos.x - cur_pos.x) + Abs(prev_pos.y - cur_pos.y) + Abs(prev_pos.z - cur_pos.z) > 1.5f )
- {
- prev_pos = cur_pos;
- timecounter = CTimer::GetTimeInMilliseconds();
- }
- else if ( CTimer::GetTimeInMilliseconds() - timecounter > 5000 )
- {
- static int32 birdgenTime = 0;
-
- if ( CTimer::GetTimeInMilliseconds() - birdgenTime > 1000 )
- {
- birdgenTime = CTimer::GetTimeInMilliseconds();
-
- CVector vecPos = cur_pos;
-
- float fAngle = CGeneral::GetRandomNumberInRange(90.0f, 150.0f);
-
- int32 nRot = CGeneral::GetRandomNumber() % CParticle::SIN_COS_TABLE_SIZE-1;
-
- float fCos = CParticle::Cos(nRot);
- float fSin = CParticle::Sin(nRot);
-
- vecPos.x += (fCos - fSin) * fAngle;
- vecPos.y += (fSin + fCos) * fAngle;
- vecPos.z += CGeneral::GetRandomNumberInRange(10.0f, 30.0f);
-
- CVector vecDir(CGeneral::GetRandomNumberInRange(-1.0f, 1.0f),
- CGeneral::GetRandomNumberInRange(-1.0f, 1.0f),
- 0.0f);
-
- CParticle::AddParticle(PARTICLE_BIRD_FRONT, vecPos, vecDir);
- }
- }
- }
-
- DefinedState();
-
- POP_RENDERGROUP();
-}
-
-void
-CWaterLevel::RenderOneFlatSmallWaterPoly(float fX, float fY, float fZ, RwRGBA const &color)
-{
- if ( TempBufferIndicesStored >= TEMPBUFFERINDEXSIZE-6 || TempBufferVerticesStored >= TEMPBUFFERVERTSIZE-4 )
- RenderAndEmptyRenderBuffer();
-
- int32 vidx = TempBufferVerticesStored;
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - WATER_Z_OFFSET);
- RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDU);
- RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDV);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 0], color.red, color.green, color.blue, color.alpha);
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + SMALL_SECTOR_SIZE, fZ - WATER_Z_OFFSET);
- RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDU);
- RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDV + 1.0f);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 1], color.red, color.green, color.blue, color.alpha);
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + SMALL_SECTOR_SIZE, fY + SMALL_SECTOR_SIZE, fZ - WATER_Z_OFFSET);
- RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDU + 1.0f);
- RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDV + 1.0f);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 2], color.red, color.green, color.blue, color.alpha);
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + SMALL_SECTOR_SIZE, fY, fZ - WATER_Z_OFFSET);
- RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDU + 1.0f);
- RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDV);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 3], color.red, color.green, color.blue, color.alpha);
-
-
- int32 iidx = TempBufferIndicesStored;
-
- TempBufferRenderIndexList[iidx + 0] = TempBufferVerticesStored + 0;
- TempBufferRenderIndexList[iidx + 1] = TempBufferVerticesStored + 2;
- TempBufferRenderIndexList[iidx + 2] = TempBufferVerticesStored + 1;
- TempBufferRenderIndexList[iidx + 3] = TempBufferVerticesStored + 0;
- TempBufferRenderIndexList[iidx + 4] = TempBufferVerticesStored + 3;
- TempBufferRenderIndexList[iidx + 5] = TempBufferVerticesStored + 2;
-
- TempBufferVerticesStored += 4;
- TempBufferIndicesStored += 6;
-}
-
-void
-CWaterLevel::RenderOneFlatLargeWaterPoly(float fX, float fY, float fZ, RwRGBA const &color)
-{
- if ( TempBufferIndicesStored >= TEMPBUFFERINDEXSIZE-6 || TempBufferVerticesStored >= TEMPBUFFERVERTSIZE-4 )
- RenderAndEmptyRenderBuffer();
-
- int32 vidx = TempBufferVerticesStored;
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - WATER_Z_OFFSET);
- RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDU);
- RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDV);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 0], color.red, color.green, color.blue, color.alpha);
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + LARGE_SECTOR_SIZE, fZ - WATER_Z_OFFSET);
- RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDU);
- RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDV + 2.0f);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 1], color.red, color.green, color.blue, color.alpha);
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + LARGE_SECTOR_SIZE, fY + LARGE_SECTOR_SIZE, fZ - WATER_Z_OFFSET);
- RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDU + 2.0f);
- RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDV + 2.0f);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 2], color.red, color.green, color.blue, color.alpha);
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + LARGE_SECTOR_SIZE, fY, fZ - WATER_Z_OFFSET);
- RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDU + 2.0f);
- RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDV);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 3], color.red, color.green, color.blue, color.alpha);
-
-
- int32 iidx = TempBufferIndicesStored;
-
- TempBufferRenderIndexList[iidx + 0] = TempBufferVerticesStored + 0;
- TempBufferRenderIndexList[iidx + 1] = TempBufferVerticesStored + 2;
- TempBufferRenderIndexList[iidx + 2] = TempBufferVerticesStored + 1;
- TempBufferRenderIndexList[iidx + 3] = TempBufferVerticesStored + 0;
- TempBufferRenderIndexList[iidx + 4] = TempBufferVerticesStored + 3;
- TempBufferRenderIndexList[iidx + 5] = TempBufferVerticesStored + 2;
-
- TempBufferVerticesStored += 4;
- TempBufferIndicesStored += 6;
-}
-
-void
-CWaterLevel::RenderOneFlatHugeWaterPoly(float fX, float fY, float fZ, RwRGBA const &color)
-{
- if ( TempBufferIndicesStored >= TEMPBUFFERINDEXSIZE-6 || TempBufferVerticesStored >= TEMPBUFFERVERTSIZE-4 )
- RenderAndEmptyRenderBuffer();
-
- int32 vidx = TempBufferVerticesStored;
-
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - WATER_Z_OFFSET);
- RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDU);
- RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDV);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 0], color.red, color.green, color.blue, 255);
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + HUGE_SECTOR_SIZE, fZ - WATER_Z_OFFSET);
- RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDU);
- RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDV + 4.0f);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 1], color.red, color.green, color.blue, 255);
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + HUGE_SECTOR_SIZE, fY + HUGE_SECTOR_SIZE, fZ - WATER_Z_OFFSET);
- RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDU + 4.0f);
- RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDV + 4.0f);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 2], color.red, color.green, color.blue, 255);
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + HUGE_SECTOR_SIZE, fY, fZ - WATER_Z_OFFSET);
- RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDU + 4.0f);
- RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDV);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 3], color.red, color.green, color.blue, 255);
-
-
- int32 iidx = TempBufferIndicesStored;
-
- TempBufferRenderIndexList[iidx + 0] = TempBufferVerticesStored + 0;
- TempBufferRenderIndexList[iidx + 1] = TempBufferVerticesStored + 2;
- TempBufferRenderIndexList[iidx + 2] = TempBufferVerticesStored + 1;
- TempBufferRenderIndexList[iidx + 3] = TempBufferVerticesStored + 0;
- TempBufferRenderIndexList[iidx + 4] = TempBufferVerticesStored + 3;
- TempBufferRenderIndexList[iidx + 5] = TempBufferVerticesStored + 2;
-
- TempBufferVerticesStored += 4;
- TempBufferIndicesStored += 6;
-}
-
-void
-CWaterLevel::RenderOneFlatExtraHugeWaterPoly(float fX, float fY, float fZ, RwRGBA const &color)
-{
- if ( TempBufferIndicesStored >= TEMPBUFFERINDEXSIZE-6 || TempBufferVerticesStored >= TEMPBUFFERVERTSIZE-4 )
- RenderAndEmptyRenderBuffer();
-
- int32 vidx = TempBufferVerticesStored;
-
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 0], fX, fY, fZ - WATER_Z_OFFSET);
- RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDU);
- RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 0], TEXTURE_ADDV);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 0], color.red, color.green, color.blue, 255);
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 1], fX, fY + EXTRAHUGE_SECTOR_SIZE, fZ - WATER_Z_OFFSET);
- RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDU);
- RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 1], TEXTURE_ADDV + 8.0f);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 1], color.red, color.green, color.blue, 255);
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 2], fX + EXTRAHUGE_SECTOR_SIZE, fY + EXTRAHUGE_SECTOR_SIZE, fZ - WATER_Z_OFFSET);
- RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDU + 8.0f);
- RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 2], TEXTURE_ADDV + 8.0f);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 2], color.red, color.green, color.blue, 255);
-
- RwIm3DVertexSetPos (&TempBufferRenderVertices[vidx + 3], fX + EXTRAHUGE_SECTOR_SIZE, fY, fZ - WATER_Z_OFFSET);
- RwIm3DVertexSetU (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDU + 8.0f);
- RwIm3DVertexSetV (&TempBufferRenderVertices[vidx + 3], TEXTURE_ADDV);
- RwIm3DVertexSetRGBA (&TempBufferRenderVertices[vidx + 3], color.red, color.green, color.blue, 255);
-
-
- int32 iidx = TempBufferIndicesStored;
-
- TempBufferRenderIndexList[iidx + 0] = TempBufferVerticesStored + 0;
- TempBufferRenderIndexList[iidx + 1] = TempBufferVerticesStored + 2;
- TempBufferRenderIndexList[iidx + 2] = TempBufferVerticesStored + 1;
- TempBufferRenderIndexList[iidx + 3] = TempBufferVerticesStored + 0;
- TempBufferRenderIndexList[iidx + 4] = TempBufferVerticesStored + 3;
- TempBufferRenderIndexList[iidx + 5] = TempBufferVerticesStored + 2;
-
- TempBufferVerticesStored += 4;
- TempBufferIndicesStored += 6;
-}
-
-void
-CWaterLevel::RenderOneWavySector(float fX, float fY, float fZ, RwRGBA const &color, bool bUnk)
-{
- float fAngle = (CTimer::GetTimeInMilliseconds() & 4095) * (TWOPI / 4096.0f);
-
- if ( !WavesCalculatedThisFrame )
- {
- nGeomUsed = 0;
-
- WavesCalculatedThisFrame = true;
-
- CBoat::FillBoatList();
-
- ASSERT( ms_pWavyAtomic != nil );
-
- RpGeometry *geometry = RpAtomicGetGeometry(ms_pWavyAtomic);
-
- ASSERT( geometry != nil );
-
- RwRGBA *wavyPreLights = RpGeometryGetPreLightColors(geometry);
- RwTexCoords *wavyTexCoords = RpGeometryGetVertexTexCoords(geometry, rwTEXTURECOORDINATEINDEX0);
- RwV3d *wavyVertices = RpMorphTargetGetVertices(RpGeometryGetMorphTarget(geometry, 0));
-
- ASSERT( wavyPreLights != nil );
- ASSERT( wavyTexCoords != nil );
- ASSERT( wavyVertices != nil );
-
- RpGeometryLock(geometry, rpGEOMETRYLOCKVERTICES
- | rpGEOMETRYLOCKPRELIGHT
- | rpGEOMETRYLOCKTEXCOORDS);
-
- for ( int32 i = 0; i < 9; i++ )
- {
- for ( int32 j = 0; j < 9; j++ )
- {
- wavyTexCoords[9*i+j].u = float(i) / 8 + TEXTURE_ADDV;
- wavyTexCoords[9*i+j].v = float(j) / 8 + TEXTURE_ADDU;
- RwRGBAAssign(&wavyPreLights[9*i+j], &color);
-
- wavyVertices[9*i+j].z = ( CWeather::Wind * 0.7f + 0.3f )
- * ( Sin(float(i + j) * DEGTORAD(45.0f) + fAngle) )
- + ( CWeather::Wind * 0.2f * Sin(float(j - i) * PI + (2.0f * fAngle)) );
- }
- }
-
- RpGeometryUnlock(geometry);
- }
-
- static CBoat *apBoatList[4] = { nil };
-
- if ( apGeomArray[0]
- && nGeomUsed < MAX_BOAT_WAKES
- && CBoat::IsSectorAffectedByWake(
- CVector2D(fX + (SMALL_SECTOR_SIZE / 2), fY + (SMALL_SECTOR_SIZE / 2)),
- SMALL_SECTOR_SIZE / 2,
- apBoatList) )
- {
- float fWakeColor = fAdd1 - Max(255.0f - float(color.blue + color.red + color.green) / 3, fAdd2);
-
- RpGeometry *wavyGeometry = RpAtomicGetGeometry(ms_pWavyAtomic);
- RpGeometry *geom = apGeomArray[nGeomUsed++];
-
- ASSERT( wavyGeometry != nil );
- ASSERT( geom != nil );
-
- RpAtomic *atomic = RpAtomicCreate();
- ASSERT( atomic != nil );
-
- RpAtomicSetGeometry(atomic, geom, 0);
-
- RwFrame *frame = RwFrameCreate();
- ASSERT( frame != nil );
-
- RwMatrixCopy(RwFrameGetMatrix(frame), RwFrameGetMatrix(RpAtomicGetFrame(ms_pWavyAtomic)));
- RpAtomicSetFrame(atomic, frame);
-
- RwTexCoords *geomTexCoords = RpGeometryGetVertexTexCoords(geom, rwTEXTURECOORDINATEINDEX0);
- RwTexCoords *wavyTexCoord = RpGeometryGetVertexTexCoords(wavyGeometry, rwTEXTURECOORDINATEINDEX0);
- RwRGBA *geomPreLights = RpGeometryGetPreLightColors(geom);
- RwV3d *geomVertices = RpMorphTargetGetVertices(RpGeometryGetMorphTarget(geom, 0));
- RwV3d *wavyVertices = RpMorphTargetGetVertices(RpGeometryGetMorphTarget(wavyGeometry, 0));
-
- ASSERT( geomTexCoords != nil );
- ASSERT( wavyTexCoord != nil );
- ASSERT( geomPreLights != nil );
- ASSERT( geomVertices != nil );
- ASSERT( wavyVertices != nil );
-
- RpGeometryLock(geom, rpGEOMETRYLOCKVERTICES | rpGEOMETRYLOCKPRELIGHT | rpGEOMETRYLOCKTEXCOORDS);
-
- for ( int32 i = 0; i < 9; i++ )
- {
- for ( int32 j = 0; j < 9; j++ )
- {
- geomTexCoords[9*i+j] = wavyTexCoord[9*i+j];
-
- float fVertexX = (float)i * 4.0f + fX;
- float fVertexY = (float)j * 4.0f + fY;
-
- float fDistMult = 0.0f;
-
- for ( int32 k = 0; k < 4; k++ )
- {
- if ( apBoatList[k] != nil )
- fDistMult += CBoat::IsVertexAffectedByWake(CVector(fVertexX, fVertexY, 0.0f), apBoatList[k]);
- }
-
- if ( fDistMult > 0.0f )
- {
- RwRGBA wakeColor;
-
- RwRGBAAssign(&wakeColor, &color);
-
- wakeColor.red = Min(color.red + int32(fWakeColor * fRedMult * fDistMult), 255);
- wakeColor.green = Min(color.green + int32(fWakeColor * fGreenMult * fDistMult), 255);
- wakeColor.blue = Min(color.blue + int32(fWakeColor * fBlueMult * fDistMult), 255);
-
- RwRGBAAssign(&geomPreLights[9*i+j], &wakeColor);
-
- }
- else
- RwRGBAAssign(&geomPreLights[9*i+j], &color);
-
-
- geomVertices[9*i+j].z = wavyVertices[9*i+j].z;
- }
- }
-
- RpGeometryUnlock(geom);
-
-
- RwV3d pos = {0.0f, 0.0f, 0.0f};
-
- pos.x = fX;
- pos.z = fZ;
- pos.y = fY;
-
- RwFrameTranslate(RpAtomicGetFrame(atomic), &pos, rwCOMBINEREPLACE);
-
- RpAtomicRender(atomic);
-
- RpAtomicDestroy(atomic);
- RwFrameDestroy(frame);
- }
- else
- {
- RwV3d pos = { 0.0f, 0.0f, 0.0f };
-
- pos.x = fX;
- pos.y = fY;
- pos.z = fZ;
-
- ASSERT( ms_pWavyAtomic != nil );
-
- RwFrameTranslate(RpAtomicGetFrame(ms_pWavyAtomic), &pos, rwCOMBINEREPLACE);
-
- RpAtomicRender(ms_pWavyAtomic);
- }
-}
-
-float
-CWaterLevel::CalcDistanceToWater(float fX, float fY)
-{
- const float fSectorMaxRenderDist = 75.0f;
-
- int32 nStartX = WATER_TO_SMALL_SECTOR_X(fX - fSectorMaxRenderDist) - 1;
- int32 nEndX = WATER_TO_SMALL_SECTOR_X(fX + fSectorMaxRenderDist) + 1;
- int32 nStartY = WATER_TO_SMALL_SECTOR_Y(fY - fSectorMaxRenderDist) - 1;
- int32 nEndY = WATER_TO_SMALL_SECTOR_Y(fY + fSectorMaxRenderDist) + 1;
-
- nStartX = Clamp(nStartX, 0, MAX_SMALL_SECTORS - 1);
- nEndX = Clamp(nEndX, 0, MAX_SMALL_SECTORS - 1);
- nStartY = Clamp(nStartY, 0, MAX_SMALL_SECTORS - 1);
- nEndY = Clamp(nEndY, 0, MAX_SMALL_SECTORS - 1);
-
- float fDistSqr = 1.0e10f;
-
- for ( int32 x = nStartX; x <= nEndX; x++ )
- {
- for ( int32 y = nStartY; y <= nEndY; y++ )
- {
- if ( aWaterFineBlockList[x][y] >= 0 )
- {
- float fSectorX = WATER_FROM_SMALL_SECTOR_X(x);
- float fSectorY = WATER_FROM_SMALL_SECTOR_Y(y);
-
- CVector2D vecDist
- (
- fSectorX + SMALL_SECTOR_SIZE - fX,
- fSectorY + SMALL_SECTOR_SIZE - fY
- );
-
- fDistSqr = Min(vecDist.MagnitudeSqr(), fDistSqr);
- }
- }
- }
-
- return Clamp(Sqrt(fDistSqr) - 23.0f, 0.0f, fSectorMaxRenderDist);
-}
-
-void
-CWaterLevel::RenderAndEmptyRenderBuffer()
-{
- if ( TempBufferVerticesStored )
- {
- LittleTest();
-
- if ( RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXUV) )
- {
- RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
- RwIm3DEnd();
- }
- }
-
- TempBufferIndicesStored = 0;
- TempBufferVerticesStored = 0;
-}
-
-void
-CWaterLevel::AllocateBoatWakeArray()
-{
- CStreaming::MakeSpaceFor(14 * CDSTREAM_SECTOR_SIZE);
-
- PUSH_MEMID(MEMID_STREAM);
-
- ASSERT(ms_pWavyAtomic != nil );
-
- RpGeometry *wavyGeometry = RpAtomicGetGeometry(ms_pWavyAtomic);
- ASSERT(wavyGeometry != nil );
- RpMorphTarget *wavyMorphTarget = RpGeometryGetMorphTarget(wavyGeometry, 0);
- RpMaterial *wavyMaterial = RpGeometryGetMaterial(wavyGeometry, 0);
-
- ASSERT(wavyMorphTarget != nil );
- ASSERT(wavyMaterial != nil );
-
- for ( int32 geom = 0; geom < MAX_BOAT_WAKES; geom++ )
- {
- if ( apGeomArray[geom] == nil )
- {
- apGeomArray[geom] = RpGeometryCreate(9*9, 8*8*2, rpGEOMETRYTRISTRIP
- | rpGEOMETRYPRELIT
- | rpGEOMETRYMODULATEMATERIALCOLOR
- | rpGEOMETRYTEXTURED);
- ASSERT(apGeomArray[geom] != nil);
-
- RpTriangle *geomTriangles = RpGeometryGetTriangles(apGeomArray[geom]);
-
- ASSERT( geomTriangles != nil );
-
- for ( int32 i = 0; i < 8; i++ )
- {
- for ( int32 j = 0; j < 8; j++ )
- {
-
- /*
- [B] [C]
- ***********
- * * *
- * * *
- * * *
- * * *
- ***********
- [A] [D]
- */
-
-
- RpGeometryTriangleSetVertexIndices(apGeomArray[geom],
- &geomTriangles[2 * 8*i + 2*j + 0], /*A*/i*9+j+0, /*B*/i*9+j+1, /*C*/i*9+j+9+1);
-
- RpGeometryTriangleSetVertexIndices(apGeomArray[geom],
- &geomTriangles[2 * 8*i + 2*j + 1], /*A*/i*9+j+0, /*C*/i*9+j+9+1, /*D*/i*9+j+9 );
-
- RpGeometryTriangleSetMaterial(apGeomArray[geom], &geomTriangles[2 * 8*i + 2*j + 0], wavyMaterial);
-
- RpGeometryTriangleSetMaterial(apGeomArray[geom], &geomTriangles[2 * 8*i + 2*j + 1], wavyMaterial);
- }
- }
-
- RpMorphTarget *geomMorphTarget = RpGeometryGetMorphTarget(apGeomArray[geom], 0);
- RwV3d *geomVertices = RpMorphTargetGetVertices(geomMorphTarget);
-
- ASSERT( geomMorphTarget != nil );
- ASSERT( geomVertices != nil );
-
- for ( int32 i = 0; i < 9; i++ )
- {
- for ( int32 j = 0; j < 9; j++ )
- {
- geomVertices[9*i+j].x = (float)i * 4.0f;
- geomVertices[9*i+j].y = (float)j * 4.0f;
- geomVertices[9*i+j].z = 0.0f;
- }
- }
-
- RpMorphTargetSetBoundingSphere(geomMorphTarget, RpMorphTargetGetBoundingSphere(wavyMorphTarget));
- RpGeometryUnlock(apGeomArray[geom]);
- }
- }
-
- POP_MEMID();
-}
-
-void
-CWaterLevel::FreeBoatWakeArray()
-{
- for ( int32 i = 0; i < MAX_BOAT_WAKES; i++ )
- {
- if ( apGeomArray[i] != nil )
- {
- RpGeometryDestroy(apGeomArray[i]);
- apGeomArray[i] = nil;
- }
- }
-
- nGeomUsed = 0;
-}