summaryrefslogtreecommitdiffstats
path: root/src/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/render')
-rw-r--r--src/render/2dEffect.h12
-rw-r--r--src/render/Clouds.cpp225
-rw-r--r--src/render/Clouds.h2
-rw-r--r--src/render/Coronas.cpp13
-rw-r--r--src/render/Coronas.h8
-rw-r--r--src/render/Fluff.cpp4
-rw-r--r--src/render/Hud.cpp395
-rw-r--r--src/render/Hud.h39
-rw-r--r--src/render/MBlur.cpp147
-rw-r--r--src/render/MBlur.h6
-rw-r--r--src/render/Occlusion.cpp44
-rw-r--r--src/render/Occlusion.h26
-rw-r--r--src/render/Particle.cpp8
-rw-r--r--src/render/Renderer.cpp436
-rw-r--r--src/render/Renderer.h9
-rw-r--r--src/render/Skidmarks.cpp42
-rw-r--r--src/render/Sprite.cpp8
-rw-r--r--src/render/Sprite2d.cpp17
-rw-r--r--src/render/Sprite2d.h2
-rw-r--r--src/render/Timecycle.cpp131
-rw-r--r--src/render/Timecycle.h46
-rw-r--r--src/render/WaterLevel.cpp89
-rw-r--r--src/render/WaterLevel.h4
-rw-r--r--src/render/Weather.cpp183
-rw-r--r--src/render/Weather.h29
-rw-r--r--src/render/WindModifiers.cpp8
-rw-r--r--src/render/WindModifiers.h7
27 files changed, 1303 insertions, 637 deletions
diff --git a/src/render/2dEffect.h b/src/render/2dEffect.h
index 2a71a8d5..504824c5 100644
--- a/src/render/2dEffect.h
+++ b/src/render/2dEffect.h
@@ -3,7 +3,9 @@
enum {
EFFECT_LIGHT,
EFFECT_PARTICLE,
- EFFECT_ATTRACTOR
+ EFFECT_ATTRACTOR,
+ EFFECT_PED_ATTRACTOR,
+ EFFECT_SUNGLARE
};
enum {
@@ -34,6 +36,8 @@ enum {
// same order as CPointLights flags, must start at 2
LIGHTFLAG_FOG_NORMAL = 2, // can have light and fog
LIGHTFLAG_FOG_ALWAYS = 4, // fog only
+ LIGHTFLAG_HIDE_OBJECT = 8, // hide the object instead of rendering light (???)
+ LIGHTFLAG_LONG_DIST = 16,
LIGHTFLAG_FOG = (LIGHTFLAG_FOG_NORMAL|LIGHTFLAG_FOG_ALWAYS)
};
@@ -63,6 +67,11 @@ public:
uint8 flags;
uint8 probability;
};
+ struct PedAttractor {
+ CVector queueDir;
+ CVector useDir;
+ int8 type;
+ };
CVector pos;
CRGBA col;
@@ -71,6 +80,7 @@ public:
Light light;
Particle particle;
Attractor attractor;
+ PedAttractor pedattr;
};
C2dEffect(void) {}
diff --git a/src/render/Clouds.cpp b/src/render/Clouds.cpp
index 60450213..c6ba0f10 100644
--- a/src/render/Clouds.cpp
+++ b/src/render/Clouds.cpp
@@ -3,6 +3,7 @@
#include "Sprite.h"
#include "Sprite2d.h"
#include "General.h"
+#include "Game.h"
#include "Coronas.h"
#include "Camera.h"
#include "TxdStore.h"
@@ -23,8 +24,10 @@ uint32 CClouds::IndividualRotation;
float CClouds::ms_cameraRoll;
float CClouds::ms_horizonZ;
+float CClouds::ms_HorizonTilt;
CRGBA CClouds::ms_colourTop;
CRGBA CClouds::ms_colourBottom;
+CRGBA CClouds::ms_colourBkGrd;
void
CClouds::Init(void)
@@ -44,25 +47,15 @@ void
CClouds::Shutdown(void)
{
RwTextureDestroy(gpCloudTex[0]);
-#ifdef GTA3_1_1_PATCH
gpCloudTex[0] = nil;
-#endif
RwTextureDestroy(gpCloudTex[1]);
-#ifdef GTA3_1_1_PATCH
gpCloudTex[1] = nil;
-#endif
RwTextureDestroy(gpCloudTex[2]);
-#ifdef GTA3_1_1_PATCH
gpCloudTex[2] = nil;
-#endif
RwTextureDestroy(gpCloudTex[3]);
-#ifdef GTA3_1_1_PATCH
gpCloudTex[3] = nil;
-#endif
RwTextureDestroy(gpCloudTex[4]);
-#ifdef GTA3_1_1_PATCH
gpCloudTex[4] = nil;
-#endif
}
void
@@ -70,11 +63,11 @@ CClouds::Update(void)
{
float s = Sin(TheCamera.Orientation - 0.85f);
#ifdef FIX_BUGS
- CloudRotation += CWeather::Wind*s*0.0025f*CTimer::GetTimeStepFix();
- IndividualRotation += (CWeather::Wind*CTimer::GetTimeStep() + 0.3f*CTimer::GetTimeStepFix()) * 60.0f;
+ CloudRotation += CWeather::Wind*s*0.001f*CTimer::GetTimeStepFix();
+ IndividualRotation += (CWeather::Wind*CTimer::GetTimeStep()*0.5f + 0.3f*CTimer::GetTimeStepFix()) * 60.0f;
#else
- CloudRotation += CWeather::Wind*s*0.0025f;
- IndividualRotation += (CWeather::Wind*CTimer::GetTimeStep() + 0.3f) * 60.0f;
+ CloudRotation += CWeather::Wind*s*0.001f;
+ IndividualRotation += (CWeather::Wind*CTimer::GetTimeStep()*0.5f + 0.3f) * 60.0f;
#endif
}
@@ -86,6 +79,9 @@ CClouds::Render(void)
RwV3d screenpos;
RwV3d worldpos;
+ if(!CGame::CanSeeOutSideFromCurrArea())
+ return;
+
CCoronas::SunBlockedByClouds = false;
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
@@ -95,26 +91,21 @@ CClouds::Render(void)
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
CSprite::InitSpriteBuffer();
- int minute = CClock::GetHours()*60 + CClock::GetMinutes();
+ float minute = CClock::GetHours()*60 + CClock::GetMinutes() + CClock::GetSeconds()/60.0f;
RwV3d campos = *(RwV3d*)&TheCamera.GetPosition();
float coverage = Max(CWeather::Foggyness, CWeather::Foggyness);
// Moon
- int moonfadeout = Abs(minute - 180); // fully visible at 3AM
- if(moonfadeout < 180){ // fade in/out 3 hours
- int brightness = (1.0f - coverage) * (180 - moonfadeout);
+ float moonfadeout = Abs(minute - 180.0f); // fully visible at 3AM
+ if((int)moonfadeout < 180){ // fade in/out 3 hours
+ int brightness = (1.0f - coverage) * (180 - (int)moonfadeout);
RwV3d pos = { 0.0f, -100.0f, 15.0f };
RwV3dAdd(&worldpos, &campos, &pos);
if(CSprite::CalcScreenCoors(worldpos, &screenpos, &szx, &szy, false)){
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[2]));
- if(CCoronas::bSmallMoon){
- szx *= 4.0f;
- szy *= 4.0f;
- }else{
- szx *= 10.0f;
- szy *= 10.0f;
- }
+ szx *= CCoronas::MoonSize*2.0f + 4.0f;
+ szy *= CCoronas::MoonSize*2.0f + 4.0f;
CSprite::RenderOneXLUSprite(screenpos.x, screenpos.y, screenpos.z,
szx, szy, brightness, brightness, brightness, 255, 1.0f/screenpos.z, 255);
}
@@ -132,7 +123,7 @@ CClouds::Render(void)
starintens = 255 * (60 - CClock::GetMinutes())/60.0f;
if(starintens != 0){
// R
- static float StarCoorsX[9] = { 0.0f, 0.05f, 0.12f, 0.5f, 0.8f, 0.6f, 0.27f, 0.55f, 0.75f };
+ static float StarCoorsX[9] = { 0.0f, 0.05f, 0.13f, 0.4f, 0.7f, 0.6f, 0.27f, 0.55f, 0.75f };
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;
@@ -170,7 +161,7 @@ CClouds::Render(void)
1.0f, 0.7f, 0.4f, 0.4f, -0.8f, -0.8f };
static float LowCloudsZ[12] = { 0.0f, 1.0f, 0.5f, 0.0f, 1.0f, 0.3f,
0.9f, 0.4f, 1.3f, 1.4f, 1.2f, 1.7f };
- float lowcloudintensity = 1.0f - coverage;
+ float lowcloudintensity = 1.0f - Max(coverage, CWeather::ExtraSunnyness);
int r = CTimeCycle::GetLowCloudsRed() * lowcloudintensity;
int g = CTimeCycle::GetLowCloudsGreen() * lowcloudintensity;
int b = CTimeCycle::GetLowCloudsBlue() * lowcloudintensity;
@@ -191,7 +182,7 @@ CClouds::Render(void)
// Fluffy clouds
float rot_sin = Sin(CloudRotation);
float rot_cos = Cos(CloudRotation);
- int fluffyalpha = 160 * (1.0f - CWeather::Foggyness);
+ int fluffyalpha = 160 * (1.0f - Max(CWeather::Foggyness, CWeather::ExtraSunnyness));
if(fluffyalpha != 0){
static float CoorsOffsetX[37] = {
0.0f, 60.0f, 72.0f, 48.0f, 21.0f, 12.0f,
@@ -218,7 +209,7 @@ CClouds::Render(void)
2.0f, 2.0f, 1.5f, 1.2f, 1.7f, 1.5f, 2.1f
};
static bool bCloudOnScreen[37];
- float hilight;
+ float sundist, hilight;
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
@@ -230,15 +221,16 @@ CClouds::Render(void)
worldpos.z = pos.z;
if(CSprite::CalcScreenCoors(worldpos, &screenpos, &szx, &szy, false)){
- float sundist = Sqrt(sq(screenpos.x-CCoronas::SunScreenX) + sq(screenpos.y-CCoronas::SunScreenY));
+ sundist = Sqrt(sq(screenpos.x-CCoronas::SunScreenX) + sq(screenpos.y-CCoronas::SunScreenY));
int tr = CTimeCycle::GetFluffyCloudsTopRed();
int tg = CTimeCycle::GetFluffyCloudsTopGreen();
int tb = CTimeCycle::GetFluffyCloudsTopBlue();
int br = CTimeCycle::GetFluffyCloudsBottomRed();
int bg = CTimeCycle::GetFluffyCloudsBottomGreen();
int bb = CTimeCycle::GetFluffyCloudsBottomBlue();
- if(sundist < SCREEN_WIDTH/2){
- hilight = (1.0f - coverage) * (1.0f - sundist/(SCREEN_WIDTH/2));
+ int distLimit = (3*SCREEN_WIDTH)/4;
+ if(sundist < distLimit){
+ hilight = (1.0f - coverage) * (1.0f - sundist/(float)distLimit);
tr = tr*(1.0f-hilight) + 255*hilight;
tg = tg*(1.0f-hilight) + 190*hilight;
tb = tb*(1.0f-hilight) + 190*hilight;
@@ -272,8 +264,7 @@ CClouds::Render(void)
worldpos.y = campos.x*rot_sin + campos.y*rot_cos + pos.y;
worldpos.z = pos.z;
if(bCloudOnScreen[i] && CSprite::CalcScreenCoors(worldpos, &screenpos, &szx, &szy, false)){
- // BUG: this is stupid....would have to do this for each cloud individually
- if(hilight > 0.0f){
+ if(sundist < SCREEN_WIDTH/3){
CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect(screenpos.x, screenpos.y, screenpos.z,
szx*30.0f, szy*30.0f,
200*hilight, 0, 0, 255, 1.0f/screenpos.z,
@@ -320,14 +311,17 @@ void
CClouds::RenderBackground(int16 topred, int16 topgreen, int16 topblue,
int16 botred, int16 botgreen, int16 botblue, int16 alpha)
{
- CVector left = TheCamera.GetRight();
- float c = left.Magnitude2D();
+ CVector right = CrossProduct(TheCamera.GetUp(), TheCamera.GetForward());
+ right.Normalise();
+ float c = right.Magnitude2D();
if(c > 1.0f)
c = 1.0f;
ms_cameraRoll = Acos(c);
- if(left.z < 0.0f)
+ if(right.z < 0.0f)
ms_cameraRoll = -ms_cameraRoll;
+ ms_HorizonTilt = SCREEN_WIDTH/2.0f * Tan(ms_cameraRoll);
+
if(UseDarkBackground()){
ms_colourTop.r = 50;
ms_colourTop.g = 50;
@@ -350,75 +344,74 @@ CClouds::RenderBackground(int16 topred, int16 topgreen, int16 topblue,
}else{
ms_horizonZ = CSprite::CalcHorizonCoors();
+ int fogr = (topred + 2 * botred) / 3;
+ int fogg = (topgreen + 2 * botgreen) / 3;
+ int fogb = (topblue + 2 * botblue) / 3;
+
// Draw top/bottom gradient
float gradheight = SCREEN_HEIGHT/2.0f;
- float topedge = ms_horizonZ - gradheight;
- float botpos, toppos;
- if(ms_horizonZ > 0.0f && topedge < SCREEN_HEIGHT){
- ms_colourTop.r = topred;
- ms_colourTop.g = topgreen;
- ms_colourTop.b = topblue;
- ms_colourTop.a = alpha;
- ms_colourBottom.r = botred;
- ms_colourBottom.g = botgreen;
- ms_colourBottom.b = botblue;
- ms_colourBottom.a = alpha;
-
- if(ms_horizonZ < SCREEN_HEIGHT)
- botpos = ms_horizonZ;
- else{
- float f = (ms_horizonZ - SCREEN_HEIGHT)/gradheight;
- ms_colourBottom.r = topred*f + (1.0f-f)*botred;
- ms_colourBottom.g = topgreen*f + (1.0f-f)*botgreen;
- ms_colourBottom.b = topblue*f + (1.0f-f)*botblue;
- botpos = SCREEN_HEIGHT;
- }
- if(topedge >= 0.0f)
- toppos = topedge;
- else{
- float f = (0.0f - topedge)/gradheight;
- ms_colourTop.r = botred*f + (1.0f-f)*topred;
- ms_colourTop.g = botgreen*f + (1.0f-f)*topgreen;
- ms_colourTop.b = botblue*f + (1.0f-f)*topblue;
- toppos = 0.0f;
- }
- CSprite2d::DrawRect(CRect(0, toppos, SCREEN_WIDTH, botpos),
- ms_colourBottom, ms_colourBottom, ms_colourTop, ms_colourTop);
- }
+
+ ms_colourTop.r = topred;
+ ms_colourTop.g = topgreen;
+ ms_colourTop.b = topblue;
+ ms_colourTop.a = alpha;
+ ms_colourBottom.r = botred;
+ ms_colourBottom.g = botgreen;
+ ms_colourBottom.b = botblue;
+ ms_colourBottom.a = alpha;
+
+ float botright = ms_horizonZ - ms_HorizonTilt;
+ float botleft = ms_horizonZ + ms_HorizonTilt;
+ float topright = botright - gradheight;
+ float topleft = botleft - gradheight;
+
+ CSprite2d::DrawAnyRect(0.0f, topleft, SCREEN_WIDTH, topright, 0.0f, botleft, SCREEN_WIDTH, botright,
+ ms_colourTop, ms_colourTop, ms_colourBottom, ms_colourBottom);
// draw the small stripe (whatever it's supposed to be)
- if(ms_horizonZ > -SMALLSTRIPHEIGHT && ms_horizonZ < SCREEN_HEIGHT){
- // Same colour as fog
- ms_colourTop.r = (topred + 2 * botred) / 3;
- ms_colourTop.g = (topgreen + 2 * botgreen) / 3;
- ms_colourTop.b = (topblue + 2 * botblue) / 3;
- CSprite2d::DrawRect(CRect(0, ms_horizonZ, SCREEN_WIDTH, ms_horizonZ+SMALLSTRIPHEIGHT),
- ms_colourTop, ms_colourTop, ms_colourTop, ms_colourTop);
- }
+ ms_colourTop.r = fogr;
+ ms_colourTop.g = fogg;
+ ms_colourTop.b = fogb;
+ ms_colourTop.a = alpha;
+ topright = ms_horizonZ - ms_HorizonTilt;
+ topleft = ms_horizonZ + ms_HorizonTilt;
+ botright = topright + SMALLSTRIPHEIGHT;
+ botleft = topleft + SMALLSTRIPHEIGHT;
+ CSprite2d::DrawAnyRect(0.0f, topleft, SCREEN_WIDTH, topright, 0.0f, botleft, SCREEN_WIDTH, botright,
+ ms_colourTop, ms_colourTop, ms_colourTop, ms_colourTop);
// Only top
- if(topedge > 0.0f){
+ if(ms_horizonZ + ms_HorizonTilt - gradheight > 0.0f ||
+ ms_horizonZ - ms_HorizonTilt - gradheight > 0.0f){
ms_colourTop.r = topred;
ms_colourTop.g = topgreen;
ms_colourTop.b = topblue;
ms_colourTop.a = alpha;
- ms_colourBottom.r = topred;
- ms_colourBottom.g = topgreen;
- ms_colourBottom.b = topblue;
- ms_colourBottom.a = alpha;
-
- botpos = Min(SCREEN_HEIGHT, topedge);
- CSprite2d::DrawRect(CRect(0, 0, SCREEN_WIDTH, botpos),
- ms_colourBottom, ms_colourBottom, ms_colourTop, ms_colourTop);
+
+ if(ms_horizonZ - Abs(ms_HorizonTilt) - gradheight > SCREEN_HEIGHT){
+ // only top is visible
+ topleft = 0.0f;
+ topright = 0.0f;
+ botleft = SCREEN_HEIGHT;
+ botright = SCREEN_HEIGHT;
+ }else{
+ botright = ms_horizonZ - ms_HorizonTilt - gradheight;
+ botleft = ms_horizonZ + ms_HorizonTilt - gradheight;
+ topright = Min(ms_horizonZ - ms_HorizonTilt - 2*SCREEN_HEIGHT, 0.0f);
+ topleft = Min(ms_horizonZ + ms_HorizonTilt - 2*SCREEN_HEIGHT, 0.0f);
+ }
+
+ CSprite2d::DrawAnyRect(0.0f, topleft, SCREEN_WIDTH, topright, 0.0f, botleft, SCREEN_WIDTH, botright,
+ ms_colourTop, ms_colourTop, ms_colourTop, ms_colourTop);
}
// Set both to fog colour for RenderHorizon
- ms_colourTop.r = (topred + 2 * botred) / 3;
- ms_colourTop.g = (topgreen + 2 * botgreen) / 3;
- ms_colourTop.b = (topblue + 2 * botblue) / 3;
- ms_colourBottom.r = (topred + 2 * botred) / 3;
- ms_colourBottom.g = (topgreen + 2 * botgreen) / 3;
- ms_colourBottom.b = (topblue + 2 * botblue) / 3;
+ ms_colourTop.r = fogr;
+ ms_colourTop.g = fogg;
+ ms_colourTop.b = fogb;
+ ms_colourBottom.r = fogr;
+ ms_colourBottom.g = fogg;
+ ms_colourBottom.b = fogb;
}
}
@@ -431,21 +424,35 @@ CClouds::RenderHorizon(void)
ms_colourBottom.a = 230;
ms_colourTop.a = 80;
- if(ms_horizonZ > SCREEN_HEIGHT)
- return;
+ float topright = ms_horizonZ - ms_HorizonTilt;
+ float topleft = ms_horizonZ + ms_HorizonTilt;
+ float botright = topright + SMALLSTRIPHEIGHT;
+ float botleft = topleft + SMALLSTRIPHEIGHT;
+
+ CSprite2d::DrawAnyRect(0.0f, topleft, SCREEN_WIDTH, topright, 0.0f, botleft, SCREEN_WIDTH, botright,
+ ms_colourTop, ms_colourTop, ms_colourBottom, ms_colourBottom);
+
+
+ ms_colourBkGrd.r = 128.0f*CTimeCycle::GetAmbientRed();
+ ms_colourBkGrd.g = 128.0f*CTimeCycle::GetAmbientGreen();
+ ms_colourBkGrd.b = 128.0f*CTimeCycle::GetAmbientBlue();
+ ms_colourBkGrd.a = 255;
+
+ float horzstrip = SCREEN_STRETCH_Y(HORIZSTRIPHEIGHT);
+ topright = botright;
+ topleft = botleft;
+ botright = topright + horzstrip;
+ botleft = topleft + horzstrip;
+
+ CSprite2d::DrawAnyRect(0.0f, topleft, SCREEN_WIDTH, topright, 0.0f, botleft, SCREEN_WIDTH, botright,
+ ms_colourBottom, ms_colourBottom, ms_colourBkGrd, ms_colourBkGrd);
+
+
+ topright = botright;
+ topleft = botleft;
+ botright = Max(topright, SCREEN_HEIGHT);
+ botleft = Max(topleft, SCREEN_HEIGHT);
- float z1 = Min(ms_horizonZ + SMALLSTRIPHEIGHT, SCREEN_HEIGHT);
- CSprite2d::DrawRectXLU(CRect(0, ms_horizonZ, SCREEN_WIDTH, z1),
- ms_colourBottom, ms_colourBottom, ms_colourTop, ms_colourTop);
-
- // This is just weird
- float a = SCREEN_HEIGHT/400.0f * HORIZSTRIPHEIGHT +
- SCREEN_HEIGHT/300.0f * Max(TheCamera.GetPosition().z, 0.0f);
- float b = TheCamera.GetUp().z < 0.0f ?
- SCREEN_HEIGHT :
- SCREEN_HEIGHT * Abs(TheCamera.GetRight().z);
- float z2 = z1 + (a + b)*TheCamera.LODDistMultiplier;
- z2 = Min(z2, SCREEN_HEIGHT);
- CSprite2d::DrawRect(CRect(0, z1, SCREEN_WIDTH, z2),
- ms_colourBottom, ms_colourBottom, ms_colourTop, ms_colourTop);
+ CSprite2d::DrawAnyRect(0.0f, topleft, SCREEN_WIDTH, topright, 0.0f, botleft, SCREEN_WIDTH, botright,
+ ms_colourBkGrd, ms_colourBkGrd, ms_colourBkGrd, ms_colourBkGrd);
}
diff --git a/src/render/Clouds.h b/src/render/Clouds.h
index 4d8cd2c8..ef33030b 100644
--- a/src/render/Clouds.h
+++ b/src/render/Clouds.h
@@ -8,8 +8,10 @@ public:
static float ms_cameraRoll;
static float ms_horizonZ;
+ static float ms_HorizonTilt;
static CRGBA ms_colourTop;
static CRGBA ms_colourBottom;
+ static CRGBA ms_colourBkGrd;
static void Init(void);
static void Shutdown(void);
diff --git a/src/render/Coronas.cpp b/src/render/Coronas.cpp
index de3b5c78..8e832ab1 100644
--- a/src/render/Coronas.cpp
+++ b/src/render/Coronas.cpp
@@ -53,7 +53,7 @@ RwTexture *gpCoronaTexture[9] = { nil, nil, nil, nil, nil, nil, nil, nil, nil };
float CCoronas::LightsMult = 1.0f;
float CCoronas::SunScreenX;
float CCoronas::SunScreenY;
-bool CCoronas::bSmallMoon;
+int CCoronas::MoonSize;
bool CCoronas::SunBlockedByClouds;
int CCoronas::bChangeBrightnessImmediately;
@@ -129,7 +129,8 @@ CCoronas::Update(void)
void
CCoronas::RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha,
const CVector &coors, float size, float drawDist, RwTexture *tex,
- int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle)
+ int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle,
+ bool longDist, float nearDist)
{
int i;
@@ -192,11 +193,13 @@ CCoronas::RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 al
void
CCoronas::RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha,
- const CVector &coors, float size, float drawDist, uint8 type,
- int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle)
+ const CVector &coors, float size, float drawDist, uint8 type,
+ int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle,
+ bool longDist, float nearDist)
{
RegisterCorona(id, red, green, blue, alpha, coors, size, drawDist,
- gpCoronaTexture[type], flareType, reflection, LOScheck, drawStreak, someAngle);
+ gpCoronaTexture[type], flareType, reflection, LOScheck, drawStreak, someAngle,
+ longDist, nearDist);
}
void
diff --git a/src/render/Coronas.h b/src/render/Coronas.h
index 46eb4315..cb4e8583 100644
--- a/src/render/Coronas.h
+++ b/src/render/Coronas.h
@@ -81,7 +81,7 @@ public:
static float LightsMult;
static float SunScreenY;
static float SunScreenX;
- static bool bSmallMoon;
+ static int MoonSize;
static bool SunBlockedByClouds;
static int bChangeBrightnessImmediately;
@@ -90,10 +90,12 @@ public:
static void Update(void);
static void RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha,
const CVector &coors, float size, float drawDist, RwTexture *tex,
- int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle);
+ int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle,
+ bool longDist = false, float nearClip = 1.5f);
static void RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha,
const CVector &coors, float size, float drawDist, uint8 type,
- int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle);
+ int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle,
+ bool longDist = false, float nearClip = 1.5f);
static void UpdateCoronaCoors(uint32 id, const CVector &coors, float drawDist, float someAngle);
static void Render(void);
static void RenderReflections(void);
diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp
index 9f3f6929..59ac1652 100644
--- a/src/render/Fluff.cpp
+++ b/src/render/Fluff.cpp
@@ -104,7 +104,8 @@ void CMovingThings::Init()
EndCloseList.m_pNext = nil;
EndCloseList.m_pPrev = &CMovingThings::StartCloseList;
Num = 0;
-
+
+#ifndef MIAMI // something is still used here actually
// Initialize scroll bars
aScrollBars[0].Init(CVector( 228.3f, -669.0f, 39.0f ), SCROLL_BUSINESS, 0.0f, 0.5f, 0.5f, 255, 128, 0, 0.3f);
aScrollBars[1].Init(CVector( 772.0f, 164.0f, -9.5f ), SCROLL_TRAFFIC, 0.0f, 0.5f, 0.25f, 128, 255, 0, 0.3f);
@@ -137,6 +138,7 @@ void CMovingThings::Init()
CVector(58.145f - sz.y * 0.05f - sz.x * 0.3f, -1079.268f + sz.x * 0.05f - sz.y * 0.3f, 32.803f),
-sz.x, -sz.y, 0, 255, 0, 100.0f, 0.8f
);
+#endif
}
void CMovingThings::Shutdown()
diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp
index 8c7904ef..7289d70c 100644
--- a/src/render/Hud.cpp
+++ b/src/render/Hud.cpp
@@ -23,18 +23,20 @@
// Game has colors inlined in code.
// For easier modification we collect them here:
-CRGBA MONEY_COLOR(89, 115, 150, 255);
-CRGBA AMMO_COLOR(0, 0, 0, 255);
-CRGBA HEALTH_COLOR(186, 101, 50, 255);
-CRGBA ARMOUR_COLOR(124, 140, 95, 255);
-CRGBA WANTED_COLOR(193, 164, 120, 255);
-CRGBA ZONE_COLOR(152, 154, 82, 255);
-CRGBA VEHICLE_COLOR(194, 165, 120, 255);
-CRGBA CLOCK_COLOR(194, 165, 120, 255);
-CRGBA TIMER_COLOR(186, 101, 50, 255);
-CRGBA COUNTER_COLOR(0, 106, 164, 255);
+CRGBA MONEY_COLOR(0, 207, 133, 255);
+CRGBA AMMO_COLOR(255, 150, 225, 255);
+CRGBA HEALTH_COLOR(255, 150, 225, 255);
+CRGBA ARMOUR_COLOR(185, 185, 185, 255);
+CRGBA NOTWANTED_COLOR(27, 89, 130, 255);
+CRGBA WANTED_COLOR_FLASH(62, 141, 181, 255);
+CRGBA WANTED_COLOR(97, 194, 247, 255);
+CRGBA ZONE_COLOR(45, 155, 90, 255);
+CRGBA VEHICLE_COLOR(97, 194, 247, 255);
+CRGBA CLOCK_COLOR(97, 194, 247, 255);
+CRGBA TIMER_COLOR(97, 194, 247, 255);
+CRGBA COUNTER_COLOR(97, 194, 247, 255);
CRGBA PAGER_COLOR(32, 162, 66, 205);
-CRGBA RADARDISC_COLOR(0, 0, 0, 255);
+CRGBA RADARDISC_COLOR(255, 255, 255, 255);
CRGBA BIGMESSAGE_COLOR(85, 119, 133, 255);
CRGBA WASTEDBUSTED_COLOR(170, 123, 87, 255);
CRGBA ODDJOB_COLOR(89, 115, 150, 255);
@@ -86,6 +88,21 @@ float CHud::PagerXOffset;
int16 CHud::PagerTimer;
int16 CHud::PagerOn;
+uint32 CHud::m_WantedFadeTimer;
+uint32 CHud::m_WantedState;
+uint32 CHud::m_WantedTimer;
+uint32 CHud::m_EnergyLostFadeTimer;
+uint32 CHud::m_EnergyLostState;
+uint32 CHud::m_EnergyLostTimer;
+uint32 CHud::m_DisplayScoreFadeTimer;
+uint32 CHud::m_DisplayScoreState;
+uint32 CHud::m_DisplayScoreTimer;
+uint32 CHud::m_WeaponFadeTimer;
+uint32 CHud::m_WeaponState;
+uint32 CHud::m_WeaponTimer;
+
+uint32 CHud::m_LastDisplayScore;
+
CSprite2d CHud::Sprites[NUM_HUD_SPRITES];
struct
@@ -123,6 +140,10 @@ RwTexture *gpRocketSightTex;
void CHud::Draw()
{
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST);
+ RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+
// disable hud via second controller
if (CPad::GetPad(1)->GetStartJustDown())
m_Wants_To_Draw_Hud = !m_Wants_To_Draw_Hud;
@@ -134,22 +155,29 @@ void CHud::Draw()
bool DrawCrossHair = 0;
bool DrawCrossHairPC = 0;
- int32 WeaponType = FindPlayerPed()->m_weapons[FindPlayerPed()->m_currentWeapon].m_eWeaponType;
+ CPlayerPed *playerPed = FindPlayerPed();
+ eWeaponType WeaponType = playerPed->GetWeapon()->m_eWeaponType;
int32 Mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
- if (Mode == CCam::MODE_SNIPER || Mode == CCam::MODE_ROCKETLAUNCHER || Mode == CCam::MODE_M16_1STPERSON || Mode == CCam::MODE_HELICANNON_1STPERSON)
- DrawCrossHair = 1;
- if (Mode == CCam::MODE_M16_1STPERSON_RUNABOUT || Mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT || Mode == CCam::MODE_SNIPER_RUNABOUT)
- DrawCrossHairPC = 1;
+ // TODO(Miami): New cam mode
+ if ((Mode == CCam::MODE_SNIPER || Mode == CCam::MODE_ROCKETLAUNCHER || Mode == CCam::MODE_M16_1STPERSON || Mode == CCam::MODE_HELICANNON_1STPERSON/* || Mode == 46*/)
+ && playerPed && !playerPed->GetWeapon()->IsTypeMelee())
+ DrawCrossHair = true;
- /*
- Draw Crosshairs
- */
- if (TheCamera.Cams[TheCamera.ActiveCam].Using3rdPersonMouseCam() &&
- (!CPad::GetPad(0)->GetLookBehindForPed() || TheCamera.m_bPlayerIsInGarage) || Mode == CCam::MODE_1STPERSON_RUNABOUT) {
- if (FindPlayerPed() && !FindPlayerPed()->EnteringCar()) {
- if ((WeaponType >= WEAPONTYPE_COLT45 && WeaponType <= WEAPONTYPE_M16) || WeaponType == WEAPONTYPE_FLAMETHROWER)
- DrawCrossHairPC = 1;
+ if (Mode == CCam::MODE_M16_1STPERSON_RUNABOUT || Mode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT || Mode == CCam::MODE_SNIPER_RUNABOUT)
+ DrawCrossHairPC = true;
+ if (TheCamera.Cams[TheCamera.ActiveCam].Using3rdPersonMouseCam() && (!CPad::GetPad(0)->GetLookBehindForPed() || TheCamera.m_bPlayerIsInGarage)
+ || Mode == CCam::MODE_1STPERSON_RUNABOUT) {
+ if (playerPed) {
+ if (playerPed->m_nPedState != PED_ENTER_CAR && playerPed->m_nPedState != PED_CARJACK) {
+
+ // TODO(Miami): Uncomment
+ if (WeaponType >= WEAPONTYPE_COLT45 && WeaponType <= WEAPONTYPE_AK47
+ /*|| WeaponType == WEAPONTYPE_M60 || || WeaponType == WEAPONTYPE_MINIGUN */
+ || WeaponType == WEAPONTYPE_FLAMETHROWER) {
+ DrawCrossHairPC = 1;
+ }
+ }
}
}
@@ -169,7 +197,8 @@ void CHud::Draw()
#ifdef ASPECT_RATIO_SCALE
f3rdY -= SCREEN_SCALE_Y(2.0f);
#endif
- if (FindPlayerPed() && WeaponType == WEAPONTYPE_M16) {
+ // TODO(Miami): M60
+ if (playerPed && (WeaponType == WEAPONTYPE_M16 || WeaponType == WEAPONTYPE_AK47/* || WeaponType == WEAPONTYPE_M60*/)) {
rect.left = f3rdX - SCREEN_SCALE_X(32.0f * 0.6f);
rect.top = f3rdY - SCREEN_SCALE_Y(32.0f * 0.6f);
rect.right = f3rdX + SCREEN_SCALE_X(32.0f * 0.6f);
@@ -185,8 +214,7 @@ void CHud::Draw()
Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255));
}
- }
- else {
+ } else {
if (Mode == CCam::MODE_M16_1STPERSON ||
Mode == CCam::MODE_M16_1STPERSON_RUNABOUT ||
Mode == CCam::MODE_HELICANNON_1STPERSON) {
@@ -213,8 +241,11 @@ void CHud::Draw()
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRocketSightTex));
CSprite::RenderOneXLUSprite(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 1.0f, SCREEN_SCALE_X(40.0f), SCREEN_SCALE_Y(40.0f), (100.0f * fMultBright), (200.0f * fMultBright), (100.0f * fMultBright), 255, 1.0f, 255);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
}
else {
+
+ // TODO(Miami)
// Sniper
rect.left = (SCREEN_WIDTH / 2) - SCREEN_SCALE_X(210.0f);
rect.top = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(210.0f);
@@ -241,9 +272,9 @@ void CHud::Draw()
Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255));
}
}
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
}
else {
SpriteBrightness = 0;
@@ -252,35 +283,51 @@ void CHud::Draw()
/*
DrawMoneyCounter
*/
+
wchar sPrint[16];
wchar sPrintIcon[16];
char sTemp[16];
+ float alpha;
- sprintf(sTemp, "$%08d", CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
- AsciiToUnicode(sTemp, sPrint);
-
- CFont::SetPropOff();
- CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
- CFont::SetCentreOff();
- CFont::SetRightJustifyOn();
- CFont::SetRightJustifyWrap(0.0f);
- CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_HEADING);
- CFont::SetPropOff();
- CFont::SetColor(CRGBA(0, 0, 0, 255));
-
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f - 2.0f), SCREEN_SCALE_Y(43.0f + 2.0f), sPrint);
+ if (m_LastDisplayScore == CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney) {
+ alpha = CHud::DrawFadeState(HUD_SCORE_FADING, 0);
+ } else {
+ alpha = CHud::DrawFadeState(HUD_SCORE_FADING, 1);
+ m_LastDisplayScore = CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney;
+ }
+ if (m_DisplayScoreState != FADED_OUT) {
+ sprintf(sTemp, "$%08d", CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
+ AsciiToUnicode(sTemp, sPrint);
- CFont::SetColor(MONEY_COLOR);
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(43.0f), sPrint);
+ CFont::SetPropOff();
+ CFont::SetBackgroundOff();
+ CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y));
+ CFont::SetCentreOff();
+ CFont::SetRightJustifyOn();
+ CFont::SetRightJustifyWrap(0.0f);
+ CFont::SetBackGroundOnlyTextOff();
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetPropOff();
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, alpha));
+ MONEY_COLOR.a = alpha;
+ CFont::SetColor(MONEY_COLOR);
+
+ // TODO(Miami): m_nHudMode
+ //if (CMenuManager.m_nHudMode)
+ {
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(43.0f), sPrint);
+ }
+ }
/*
DrawAmmo
*/
- uint32 AmmoAmount = CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition;
- uint32 AmmoInClip = FindPlayerPed()->m_weapons[FindPlayerPed()->m_currentWeapon].m_nAmmoInClip;
- uint32 TotalAmmo = FindPlayerPed()->m_weapons[FindPlayerPed()->m_currentWeapon].m_nAmmoTotal;
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo((eWeaponType)WeaponType);
+ CWeapon *weapon = playerPed->GetWeapon();
+ uint32 AmmoAmount = weaponInfo->m_nAmountofAmmunition;
+ uint32 AmmoInClip = weapon->m_nAmmoInClip;
+ uint32 TotalAmmo = weapon->m_nAmmoTotal;
uint32 Ammo, Clip;
if (AmmoAmount <= 1 || AmmoAmount >= 1000)
@@ -311,36 +358,59 @@ void CHud::Draw()
/*
DrawWeaponIcon
*/
- Sprites[WeaponType].Draw(
- CRect(SCREEN_SCALE_FROM_RIGHT(99.0f), SCREEN_SCALE_Y(27.0f), SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(91.0f)),
- CRGBA(255, 255, 255, 255),
- 0.015f,
- 0.015f,
- 1.0f,
- 0.0f,
- 0.015f,
- 1.0f,
- 1.0f,
- 1.0f);
+
+ if (weaponInfo->m_nModelId <= 0) {
+ Sprites[WeaponType].Draw(
+ CRect(SCREEN_SCALE_FROM_RIGHT(99.0f), SCREEN_SCALE_Y(27.0f), SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(91.0f)),
+ CRGBA(255, 255, 255, 255),
+ 0.015f,
+ 0.015f,
+ 1.0f,
+ 0.0f,
+ 0.015f,
+ 1.0f,
+ 1.0f,
+ 1.0f);
+ } else {
+ CBaseModelInfo *weaponModel = CModelInfo::GetModelInfo(weaponInfo->m_nModelId);
+ RwTexDictionary *weaponTxd = CTxdStore::GetSlot(weaponModel->GetTxdSlot())->texDict;
+ if (weaponTxd) {
+ RwTexture *weaponIcon = RwTexDictionaryFindNamedTexture(weaponTxd, weaponModel->GetName());
+ if (weaponIcon) {
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(weaponIcon));
+ const float xSize = SCREEN_SCALE_X(64.0f / 2.0f);
+ const float ySize = SCREEN_SCALE_X(64.0f / 2.0f);
+ CSprite::RenderOneXLUSprite(SCREEN_SCALE_FROM_RIGHT(99.0f) + xSize, SCREEN_SCALE_Y(25.0f) + ySize, 1.0f, xSize, ySize,
+ 255, 255, 255, 255, 1.0f, 255);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ }
+ }
+ }
CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.4f), SCREEN_SCALE_Y(0.6f));
+ CFont::SetScale(SCREEN_SCALE_X(0.5f), SCREEN_SCALE_Y(0.8f));
CFont::SetJustifyOff();
CFont::SetCentreOn();
CFont::SetCentreSize(SCREEN_SCALE_X(640.0f));
CFont::SetPropOn();
+ CFont::SetDropShadowPosition(0);
CFont::SetFontStyle(FONT_BANK);
- if (!CDarkel::FrenzyOnGoing() && WeaponType != WEAPONTYPE_UNARMED && WeaponType != WEAPONTYPE_BASEBALLBAT) {
+ if (Min(9999, TotalAmmo - AmmoInClip) != 9999 && !CDarkel::FrenzyOnGoing() && weaponInfo->m_nWeaponSlot > 1 && weapon->m_eWeaponType != WEAPONTYPE_DETONATOR) {
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
CFont::SetColor(AMMO_COLOR);
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(66.0f), SCREEN_SCALE_Y(73.0f), sPrint);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(66.0f), SCREEN_SCALE_Y(90.0f), sPrint);
+ CFont::SetDropShadowPosition(0);
}
/*
DrawHealth
*/
CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
+ CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y));
CFont::SetJustifyOff();
CFont::SetCentreOff();
CFont::SetRightJustifyWrap(0.0f);
@@ -350,16 +420,16 @@ void CHud::Draw()
if (m_ItemToFlash == ITEM_HEALTH && CTimer::GetFrameCounter() & 8
|| m_ItemToFlash != ITEM_HEALTH
- || FindPlayerPed()->m_fHealth < 10
+ || playerPed->m_fHealth < 10
&& CTimer::GetFrameCounter() & 8) {
- if (FindPlayerPed()->m_fHealth >= 10
- || FindPlayerPed()->m_fHealth < 10 && CTimer::GetFrameCounter() & 8) {
+ if (playerPed->m_fHealth >= 10
+ || playerPed->m_fHealth < 10 && CTimer::GetFrameCounter() & 8) {
AsciiToUnicode("{", sPrintIcon);
#ifdef FIX_BUGS
- sprintf(sTemp, "%03d", int32(FindPlayerPed()->m_fHealth + 0.5f));
+ sprintf(sTemp, "%03d", int32(playerPed->m_fHealth + 0.5f));
#else
- sprintf(sTemp, "%03d", (int32)FindPlayerPed()->m_fHealth);
+ sprintf(sTemp, "%03d", (int32)playerPed->m_fHealth);
#endif
AsciiToUnicode(sTemp, sPrint);
@@ -383,13 +453,13 @@ void CHud::Draw()
DrawArmour
*/
if (m_ItemToFlash == ITEM_ARMOUR && CTimer::GetFrameCounter() & 8 || m_ItemToFlash != ITEM_ARMOUR) {
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
- if (FindPlayerPed()->m_fArmour > 1.0f) {
+ CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y));
+ if (playerPed->m_fArmour > 1.0f) {
AsciiToUnicode("[", sPrintIcon);
#ifdef FIX_BUGS
- sprintf(sTemp, "%03d", int32(FindPlayerPed()->m_fArmour + 0.5f));
+ sprintf(sTemp, "%03d", int32(playerPed->m_fArmour + 0.5f));
#else
- sprintf(sTemp, "%03d", (int32)FindPlayerPed()->m_fArmour);
+ sprintf(sTemp, "%03d", (int32)playerPed->m_fArmour);
#endif
AsciiToUnicode(sTemp, sPrint);
@@ -414,27 +484,33 @@ void CHud::Draw()
DrawWantedLevel
*/
CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
+ CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y));
CFont::SetJustifyOff();
CFont::SetCentreOff();
- CFont::SetRightJustifyOff();
+ CFont::SetRightJustifyOn();
CFont::SetPropOn();
CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetDropShadowPosition(2); // TODO(Miami): Remove that, VC keeps that open above
AsciiToUnicode("]", sPrintIcon);
for (int i = 0; i < 6; i++) {
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::PrintString(2.0f + SCREEN_SCALE_FROM_RIGHT(60.0f - 2.0f + 24.0f * i), SCREEN_SCALE_Y(87.0f + 2.0f), sPrintIcon);
- if (FindPlayerPed()->m_pWanted->m_nWantedLevel > i
- && (CTimer::GetTimeInMilliseconds() > FindPlayerPed()->m_pWanted->m_nLastWantedLevelChange
+ if (playerPed->m_pWanted->m_nWantedLevel > i
+ && (CTimer::GetTimeInMilliseconds() > playerPed->m_pWanted->m_nLastWantedLevelChange
+ 2000 || CTimer::GetFrameCounter() & 4)) {
CFont::SetColor(WANTED_COLOR);
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(60.0f + 24.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon);
+
+ // TODO(Miami): There is one more condition in here
+ }else if (playerPed->m_pWanted->m_nWantedLevel <= i) {
+ CFont::SetColor(NOTWANTED_COLOR);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon);
}
}
+ CFont::SetDropShadowPosition(0); // TODO(Miami): Remove that, VC keeps that open
+
/*
DrawZoneName
*/
@@ -517,15 +593,20 @@ void CHud::Draw()
else
CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f));
+ CFont::SetSlantRefPoint(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(128.0f));
+ CFont::SetSlant(0.15f);
+
CFont::SetRightJustifyOn();
CFont::SetRightJustifyWrap(0.0f);
CFont::SetBackGroundOnlyTextOff();
CFont::SetFontStyle(FONT_BANK);
CFont::SetColor(CRGBA(0, 0, 0, fZoneAlpha));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f) + SCREEN_SCALE_X(1.0f), SCREEN_SCALE_FROM_BOTTOM(30.0f) + SCREEN_SCALE_Y(1.0f), m_ZoneToPrint);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f) + SCREEN_SCALE_X(1.0f), SCREEN_SCALE_FROM_BOTTOM(128.0f) + SCREEN_SCALE_Y(1.0f), m_ZoneToPrint);
CFont::SetColor(CRGBA(ZONE_COLOR.r, ZONE_COLOR.g, ZONE_COLOR.b, fZoneAlpha));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(30.0f), m_ZoneToPrint);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(128.0f), m_ZoneToPrint);
+
+ CFont::SetSlant(0.f);
}
}
}
@@ -611,15 +692,20 @@ void CHud::Draw()
else
CFont::SetScale(SCREEN_SCALE_X(1.2f * 0.85f), SCREEN_SCALE_Y(1.2f));
+ CFont::SetSlantRefPoint(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(105.0f));
+ CFont::SetSlant(0.15f);
+
CFont::SetRightJustifyOn();
CFont::SetRightJustifyWrap(0.0f);
CFont::SetBackGroundOnlyTextOff();
CFont::SetFontStyle(FONT_BANK);
CFont::SetColor(CRGBA(0, 0, 0, fVehicleAlpha));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f) + SCREEN_SCALE_X(1.0f), SCREEN_SCALE_FROM_BOTTOM(55.0f) + SCREEN_SCALE_Y(1.0f), m_pVehicleNameToPrint);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f) + SCREEN_SCALE_X(1.0f), SCREEN_SCALE_FROM_BOTTOM(105.f) + SCREEN_SCALE_Y(1.0f), m_pVehicleNameToPrint);
CFont::SetColor(CRGBA(VEHICLE_COLOR.r, VEHICLE_COLOR.g, VEHICLE_COLOR.b, fVehicleAlpha));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(55.0f), m_pVehicleNameToPrint);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(105.0f), m_pVehicleNameToPrint);
+
+ CFont::SetSlant(0.f);
}
}
}
@@ -636,7 +722,7 @@ void CHud::Draw()
CFont::SetJustifyOff();
CFont::SetCentreOff();
CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
+ CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y));
CFont::SetBackGroundOnlyTextOff();
CFont::SetPropOff();
CFont::SetFontStyle(FONT_HEADING);
@@ -685,7 +771,7 @@ void CHud::Draw()
AsciiToUnicode(CUserDisplay::OnscnTimer.m_sEntries[0].m_bTimerBuffer, sTimer);
CFont::SetPropOn();
CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
+ CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y));
CFont::SetRightJustifyOn();
CFont::SetRightJustifyWrap(0.0f);
CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
@@ -693,7 +779,7 @@ void CHud::Draw()
CFont::SetBackGroundOnlyTextOn();
CFont::SetColor(CRGBA(0, 0, 0, 255));
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(110.0f) + SCREEN_SCALE_Y(2.0f), sTimer);
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
+ CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y));
CFont::SetColor(TIMER_COLOR);
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET), SCREEN_SCALE_Y(110.0f), sTimer);
@@ -725,7 +811,7 @@ void CHud::Draw()
CFont::SetPropOn();
CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
+ CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y));
CFont::SetCentreOff();
CFont::SetRightJustifyOn();
CFont::SetRightJustifyWrap(0.0f);
@@ -751,7 +837,7 @@ void CHud::Draw()
if (CUserDisplay::OnscnTimer.m_sEntries[0].m_aCounterText[0]) {
CFont::SetPropOn();
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
+ CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y));
CFont::SetColor(CRGBA(0, 0, 0, 255));
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) - SCREEN_SCALE_X(61.0f) + SCREEN_SCALE_Y(2.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(2.0f), TheText.Get(CUserDisplay::OnscnTimer.m_sEntries[0].m_aCounterText));
@@ -1417,6 +1503,21 @@ void CHud::Initialise()
PagerSoundPlayed = 0;
PagerXOffset = 150.0f;
+ m_WantedFadeTimer = 0;
+ m_WantedState = FADE_DISABLED;
+ m_WantedTimer = 0;
+ m_EnergyLostFadeTimer = 0;
+ m_EnergyLostState = FADE_DISABLED;
+ m_EnergyLostTimer = 0;
+ m_DisplayScoreFadeTimer = 0;
+ m_DisplayScoreState = FADE_DISABLED;
+ m_DisplayScoreTimer = 0;
+ m_WeaponFadeTimer = 0;
+ m_WeaponState = FADE_DISABLED;
+ m_WeaponTimer = 0;
+
+ m_LastDisplayScore = CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney;
+
CTxdStore::PopCurrentTxd();
}
@@ -1440,6 +1541,21 @@ void CHud::ReInitialise() {
PagerTimer = 0;
PagerSoundPlayed = 0;
PagerXOffset = 150.0f;
+
+ m_WantedFadeTimer = 0;
+ m_WantedState = FADE_DISABLED;
+ m_WantedTimer = 0;
+ m_EnergyLostFadeTimer = 0;
+ m_EnergyLostState = FADE_DISABLED;
+ m_EnergyLostTimer = 0;
+ m_DisplayScoreFadeTimer = 0;
+ m_DisplayScoreState = FADE_DISABLED;
+ m_DisplayScoreTimer = 0;
+ m_WeaponFadeTimer = 0;
+ m_WeaponState = FADE_DISABLED;
+ m_WeaponTimer = 0;
+
+ m_LastDisplayScore = CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney;
}
wchar LastBigMessage[6][128];
@@ -1536,3 +1652,106 @@ void CHud::Shutdown()
int HudTXD = CTxdStore::FindTxdSlot("hud");
CTxdStore::RemoveTxdSlot(HudTXD);
}
+
+float CHud::DrawFadeState(DRAW_FADE_STATE fadingElement, int forceFadingIn)
+{
+ float alpha = 255.0f;
+ uint32 operation, timer;
+ int32 fadeTimer;
+
+ switch (fadingElement) {
+ case HUD_WANTED_FADING:
+ fadeTimer = m_WantedFadeTimer;
+ operation = m_WantedState;
+ timer = m_WantedTimer;
+ break;
+ case HUD_ENERGY_FADING:
+ fadeTimer = m_EnergyLostFadeTimer;
+ operation = m_EnergyLostState;
+ timer = m_EnergyLostTimer;
+ break;
+ case HUD_SCORE_FADING:
+ fadeTimer = m_DisplayScoreFadeTimer;
+ operation = m_DisplayScoreState;
+ timer = m_DisplayScoreTimer;
+ break;
+ case HUD_WEAPON_FADING:
+ fadeTimer = m_WeaponFadeTimer;
+ operation = m_WeaponState;
+ timer = m_WeaponTimer;
+ break;
+ default:
+ break;
+ }
+ if (forceFadingIn) {
+ switch (operation) {
+ case FADED_OUT:
+ fadeTimer = 0;
+ case START_FADE_OUT:
+ case FADING_OUT:
+ timer = 5;
+ operation = FADING_IN;
+ break;
+ default:
+ break;
+ }
+ }
+ if (operation != FADED_OUT && operation != FADE_DISABLED) {
+ switch (operation) {
+ case START_FADE_OUT:
+ fadeTimer = 1000;
+ alpha = 255.0f;
+ if (timer > 10000) {
+ fadeTimer = 3000;
+ operation = FADING_OUT;
+ }
+ break;
+ case FADING_IN:
+ fadeTimer += CTimer::GetTimeStepInMilliseconds();
+ if (fadeTimer > 1000.0f) {
+ operation = START_FADE_OUT;
+ fadeTimer = 1000;
+ }
+ alpha = fadeTimer / 1000.0f * 255.0f;
+ break;
+ case FADING_OUT:
+ fadeTimer -= CTimer::GetTimeStepInMilliseconds();
+ if (fadeTimer < 0.0f) {
+ fadeTimer = 0;
+ operation = FADED_OUT;
+ }
+ alpha = fadeTimer / 1000.0f * 255.0f;
+ break;
+ default:
+ break;
+ }
+ timer += CTimer::GetTimeStepInMilliseconds();
+ }
+
+ switch (fadingElement) {
+ case HUD_WANTED_FADING:
+ m_WantedFadeTimer = fadeTimer;
+ m_WantedState = operation;
+ m_WantedTimer = timer;
+ break;
+ case HUD_ENERGY_FADING:
+ m_EnergyLostFadeTimer = fadeTimer;
+ m_EnergyLostState = operation;
+ m_EnergyLostTimer = timer;
+ break;
+ case HUD_SCORE_FADING:
+ m_DisplayScoreFadeTimer = fadeTimer;
+ m_DisplayScoreState = operation;
+ m_DisplayScoreTimer = timer;
+ break;
+ case HUD_WEAPON_FADING:
+ m_WeaponFadeTimer = fadeTimer;
+ m_WeaponState = operation;
+ m_WeaponTimer = timer;
+ break;
+ default:
+ break;
+ }
+
+ return clamp(alpha, 0.0f, 255.0f);
+}
diff --git a/src/render/Hud.h b/src/render/Hud.h
index 701e47e2..bae19ee4 100644
--- a/src/render/Hud.h
+++ b/src/render/Hud.h
@@ -9,6 +9,25 @@ enum eItems
ITEM_RADAR = 8
};
+// Thanks for vague name, R*
+enum DRAW_FADE_STATE
+{
+ HUD_WANTED_FADING = 0,
+ HUD_ENERGY_FADING,
+ HUD_SCORE_FADING,
+ HUD_WEAPON_FADING,
+};
+
+// My name
+enum eFadeOperation
+{
+ FADED_OUT = 0,
+ START_FADE_OUT,
+ FADING_IN,
+ FADING_OUT,
+ FADE_DISABLED = 5,
+};
+
enum eSprites
{
HUD_FIST,
@@ -32,6 +51,10 @@ enum eSprites
NUM_HUD_SPRITES,
};
+// TODO(Miami): Make those 0.7f - 1.25f once fonts have been ported
+#define HUD_TEXT_SCALE_X 0.8f
+#define HUD_TEXT_SCALE_Y 1.35f
+
class CHud
{
public:
@@ -82,6 +105,21 @@ public:
static int16 PagerTimer;
static int16 PagerOn;
+ static uint32 m_WantedFadeTimer;
+ static uint32 m_WantedState;
+ static uint32 m_WantedTimer;
+ static uint32 m_EnergyLostFadeTimer;
+ static uint32 m_EnergyLostState;
+ static uint32 m_EnergyLostTimer;
+ static uint32 m_DisplayScoreFadeTimer;
+ static uint32 m_DisplayScoreState;
+ static uint32 m_DisplayScoreTimer;
+ static uint32 m_WeaponFadeTimer;
+ static uint32 m_WeaponState;
+ static uint32 m_WeaponTimer;
+
+ static uint32 m_LastDisplayScore;
+
public:
static void Draw();
static void DrawAfterFade();
@@ -95,4 +133,5 @@ public:
static void SetVehicleName(wchar *name);
static void SetZoneName(wchar *name);
static void Shutdown();
+ static float DrawFadeState(DRAW_FADE_STATE, int);
};
diff --git a/src/render/MBlur.cpp b/src/render/MBlur.cpp
index 68ec1194..9934ae18 100644
--- a/src/render/MBlur.cpp
+++ b/src/render/MBlur.cpp
@@ -3,14 +3,17 @@
#include "RwHelper.h"
#include "Camera.h"
#include "MBlur.h"
+#include "Timer.h"
// Originally taken from RW example 'mblur'
RwRaster *CMBlur::pFrontBuffer;
bool CMBlur::ms_bJustInitialised;
bool CMBlur::BlurOn;
+float CMBlur::Drunkness;
static RwIm2DVertex Vertex[4];
+static RwIm2DVertex Vertex2[4];
static RwImVertexIndex Index[6] = { 0, 1, 2, 0, 2, 3 };
void
@@ -103,29 +106,62 @@ CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect)
RwIm2DVertexSetV(&Vertex[3], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex2[0], zero);
+ RwIm2DVertexSetScreenY(&Vertex2[0], zero);
+ RwIm2DVertexSetScreenZ(&Vertex2[0], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex2[0], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex2[0], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex2[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex2[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex2[1], zero);
+ RwIm2DVertexSetScreenY(&Vertex2[1], ymax);
+ RwIm2DVertexSetScreenZ(&Vertex2[1], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex2[1], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex2[1], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex2[1], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex2[1], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex2[2], xmax);
+ RwIm2DVertexSetScreenY(&Vertex2[2], ymax);
+ RwIm2DVertexSetScreenZ(&Vertex2[2], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex2[2], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex2[2], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex2[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex2[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], 255, 255, 255, 255);
+
+ RwIm2DVertexSetScreenX(&Vertex2[3], xmax);
+ RwIm2DVertexSetScreenY(&Vertex2[3], zero);
+ RwIm2DVertexSetScreenZ(&Vertex2[3], RwIm2DGetNearScreenZ());
+ RwIm2DVertexSetCameraZ(&Vertex2[3], RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetRecipCameraZ(&Vertex2[3], 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetU(&Vertex2[3], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetV(&Vertex2[3], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam));
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], 255, 255, 255, 255);
+
}
void
-CMBlur::MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 addalpha)
+CMBlur::MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type)
{
RwRGBA color = { (RwUInt8)red, (RwUInt8)green, (RwUInt8)blue, (RwUInt8)blur };
+ if(ms_bJustInitialised)
+ ms_bJustInitialised = false;
+ else
+ OverlayRender(cam, pFrontBuffer, color, type);
if(BlurOn){
- if(pFrontBuffer){
- if(ms_bJustInitialised)
- ms_bJustInitialised = false;
- else
- OverlayRender(cam, pFrontBuffer, color, type, addalpha);
- }
RwRasterPushContext(pFrontBuffer);
RwRasterRenderFast(RwCameraGetRaster(cam), 0, 0);
RwRasterPopContext();
- }else{
- OverlayRender(cam, nil, color, type, addalpha);
}
}
void
-CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, uint32 addalpha)
+CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type)
{
int r, g, b, a;
@@ -170,41 +206,75 @@ CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type,
}
if(!BlurOn){
- r *= 0.6f;
- g *= 0.6f;
- b *= 0.6f;
- if(type != 1)
- a *= 0.6f;
- // game clamps to 255 here, but why?
+ // gta clamps these to 255 (probably a macro or inlined function)
+ int ovR = r * 0.6f;
+ int ovG = g * 0.6f;
+ int ovB = b * 0.6f;
+ int ovA = type == MBLUR_SNIPER ? a : a*0.6f;
+ RwIm2DVertexSetIntRGBA(&Vertex[0], ovR, ovG, ovB, ovA);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], ovR, ovG, ovB, ovA);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], ovR, ovG, ovB, ovA);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], ovR, ovG, ovB, ovA);
+ }else{
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[0], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], r, g, b, a);
}
- RwIm2DVertexSetIntRGBA(&Vertex[0], r, g, b, a);
- RwIm2DVertexSetIntRGBA(&Vertex[1], r, g, b, a);
- RwIm2DVertexSetIntRGBA(&Vertex[2], r, g, b, a);
- RwIm2DVertexSetIntRGBA(&Vertex[3], r, g, b, a);
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, BlurOn ? raster : nil);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, raster);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
-
- a = addalpha/2;
- if(a < 30)
- a = 30;
-
- if(BlurOn && a != 0){ // the second condition should always be true
- RwIm2DVertexSetIntRGBA(&Vertex[0], 255, 255, 255, a);
- RwIm2DVertexSetIntRGBA(&Vertex[1], 255, 255, 255, a);
- RwIm2DVertexSetIntRGBA(&Vertex[2], 255, 255, 255, a);
- RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, a);
- RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+
+ if(BlurOn){
+ if(type == MBLUR_SNIPER){
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], r, g, b, 80);
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], r, g, b, 80);
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], r, g, b, 80);
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], r, g, b, 80);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ // TODO(MIAMI): pBufVertCount = 0;
+ }else{
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], r*2, g*2, b*2, 30);
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], r*2, g*2, b*2, 30);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex2, 4, Index, 6);
+
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+
+ RwIm2DVertexSetIntRGBA(&Vertex2[0], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[0], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[1], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[1], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[2], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[2], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex2[3], r, g, b, a);
+ RwIm2DVertexSetIntRGBA(&Vertex[3], r, g, b, a);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex2, 4, Index, 6);
+ }
}
+ // TODO(MIAMI): drunkness
+
+ // TODO(MIAMI): OverlayRenderFx
+
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
@@ -213,3 +283,10 @@ CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type,
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
}
+
+void
+CMBlur::ClearDrunkBlur()
+{
+ Drunkness = 0.0f;
+ CTimer::SetTimeScale(1.0f);
+} \ No newline at end of file
diff --git a/src/render/MBlur.h b/src/render/MBlur.h
index e8a5bef8..3129c070 100644
--- a/src/render/MBlur.h
+++ b/src/render/MBlur.h
@@ -6,11 +6,13 @@ public:
static RwRaster *pFrontBuffer;
static bool ms_bJustInitialised;
static bool BlurOn;
+ static float Drunkness;
public:
static void MotionBlurOpen(RwCamera *cam);
static void MotionBlurClose(void);
static void CreateImmediateModeData(RwCamera *cam, RwRect *rect);
- static void MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 addalpha);
- static void OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, uint32 bluralpha);
+ static void MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type);
+ static void OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type);
+ static void ClearDrunkBlur();
};
diff --git a/src/render/Occlusion.cpp b/src/render/Occlusion.cpp
new file mode 100644
index 00000000..1c4e4266
--- /dev/null
+++ b/src/render/Occlusion.cpp
@@ -0,0 +1,44 @@
+#include "common.h"
+
+#include "Occlusion.h"
+
+int32 COcclusion::NumOccludersOnMap;
+int16 COcclusion::FarAwayList;
+int16 COcclusion::NearbyList;
+int16 COcclusion::ListWalkThroughFA;
+int16 COcclusion::PreviousListWalkThroughFA;
+COccluder COcclusion::aOccluders[NUMOCCLUSIONVOLUMES];
+
+void
+COcclusion::Init(void)
+{
+ NumOccludersOnMap = 0;
+ FarAwayList = -1;
+ NearbyList = -1;
+ ListWalkThroughFA = -1;
+ PreviousListWalkThroughFA = -1;
+}
+
+void
+COcclusion::AddOne(float x, float y, float z, float width, float length, float height, float angle)
+{
+ if(NumOccludersOnMap >= NUMOCCLUSIONVOLUMES)
+ return;
+
+ aOccluders[NumOccludersOnMap].x = x;
+ aOccluders[NumOccludersOnMap].y = y;
+ aOccluders[NumOccludersOnMap].z = z;
+ aOccluders[NumOccludersOnMap].width = width;
+ aOccluders[NumOccludersOnMap].length = length;
+ aOccluders[NumOccludersOnMap].height = height;
+ while(angle < 0.0f) angle += 360.0f;
+ while(angle > 360.0f) angle -= 360.0f;
+ aOccluders[NumOccludersOnMap].angle = angle * UINT16_MAX/360.0f;
+ aOccluders[NumOccludersOnMap].listIndex = FarAwayList;
+ FarAwayList = NumOccludersOnMap++;
+}
+
+void
+COcclusion::ProcessBeforeRendering(void)
+{
+}
diff --git a/src/render/Occlusion.h b/src/render/Occlusion.h
new file mode 100644
index 00000000..ac0ede5e
--- /dev/null
+++ b/src/render/Occlusion.h
@@ -0,0 +1,26 @@
+#pragma once
+
+class COccluder
+{
+public:
+ int16 width, length, height;
+ int16 x, y, z;
+ uint16 angle;
+ int16 listIndex;
+};
+
+class COcclusion
+{
+public:
+ static int32 NumOccludersOnMap;
+ static int16 FarAwayList;
+ static int16 NearbyList;
+ static int16 ListWalkThroughFA;
+ static int16 PreviousListWalkThroughFA;
+
+ static COccluder aOccluders[NUMOCCLUSIONVOLUMES];
+
+ static void Init(void);
+ static void AddOne(float x, float y, float z, float width, float length, float height, float angle);
+ static void ProcessBeforeRendering(void);
+};
diff --git a/src/render/Particle.cpp b/src/render/Particle.cpp
index a867ae13..5f37bdc6 100644
--- a/src/render/Particle.cpp
+++ b/src/render/Particle.cpp
@@ -1546,7 +1546,7 @@ void CParticle::Render()
particle->m_fSize * 63.0f,
particle->m_Color,
particle->m_nColorIntensity,
- (float)particle->m_nRotation, //DEGTORAD((float)particle->m_nRotation) ps2
+ DEGTORAD(particle->m_nRotation),
particle->m_nAlpha);
}
else
@@ -1586,7 +1586,7 @@ void CParticle::Render()
particle->m_Color.blue,
particle->m_nColorIntensity,
1.0f / coors.z,
- float(particle->m_nRotation), // DEGTORAD((float)particle->m_nRotation) ps2
+ DEGTORAD(particle->m_nRotation),
particle->m_nAlpha);
}
else if ( psystem->Flags & SCREEN_TRAIL )
@@ -1639,7 +1639,7 @@ void CParticle::Render()
particle->m_Color.blue,
particle->m_nColorIntensity,
1.0f / coors.z,
- fRotation,
+ DEGTORAD(fRotation),
particle->m_nAlpha);
particle->m_vecScreenPosition = coors;
@@ -1688,7 +1688,7 @@ void CParticle::Render()
particle->m_Color.blue,
particle->m_nColorIntensity,
1.0f / coors.z,
- fRotation,
+ DEGTORAD(fRotation),
particle->m_nAlpha);
}
else if ( psystem->Flags & VERT_TRAIL )
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index 8a48eb11..f149c6fb 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -18,13 +18,13 @@
#include "Streaming.h"
#include "Shadows.h"
#include "PointLights.h"
+#include "Occlusion.h"
#include "Renderer.h"
-bool gbShowPedRoadGroups;
-bool gbShowCarRoadGroups;
+//--MIAMI: file almost done, just one bike flag left
+
bool gbShowCollisionPolys;
bool gbShowCollisionLines;
-bool gbShowCullZoneDebugStuff;
bool gbBigWhiteDebugLightSwitchedOn;
bool gbDontRenderBuildings;
@@ -142,8 +142,11 @@ CRenderer::RenderOneNonRoad(CEntity *e)
resetLights = e->SetupLighting();
- if(e->IsVehicle())
+ if(e->IsVehicle()){
+ // unfortunately can't use GetClump here
+ CVisibilityPlugins::SetupVehicleVariables((RpClump*)e->m_rwObject);
CVisibilityPlugins::InitAlphaAtomicList();
+ }
// Render Peds in vehicle before vehicle itself
if(e->IsVehicle()){
@@ -153,6 +156,7 @@ CRenderer::RenderOneNonRoad(CEntity *e)
for(i = 0; i < 8; i++)
if(veh->pPassengers[i] && veh->pPassengers[i]->m_nPedState == PED_DRIVING)
veh->pPassengers[i]->Render();
+ SetCullMode(rwCULLMODECULLNONE);
}
e->Render();
@@ -160,6 +164,7 @@ CRenderer::RenderOneNonRoad(CEntity *e)
e->bImBeingRendered = true;
CVisibilityPlugins::RenderAlphaAtomics();
e->bImBeingRendered = false;
+ SetCullMode(rwCULLMODECULLBACK);
}
e->RemoveLighting(resetLights);
@@ -180,38 +185,40 @@ CRenderer::RenderFirstPersonVehicle(void)
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
}
+inline bool IsRoad(CEntity *e) { return e->IsBuilding() && ((CSimpleModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex()))->m_wetRoadReflection; }
+
void
CRenderer::RenderRoads(void)
{
int i;
- CTreadable *t;
+ CEntity *e;
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ SetCullMode(rwCULLMODECULLBACK);
DeActivateDirectional();
SetAmbientColours();
for(i = 0; i < ms_nNoOfVisibleEntities; i++){
- t = (CTreadable*)ms_aVisibleEntityPtrs[i];
- if(t->IsBuilding() && t->GetIsATreadable()){
-#ifndef MASTER
- if(gbShowCarRoadGroups || gbShowPedRoadGroups){
- int ind = 0;
- if(gbShowCarRoadGroups)
- ind += ThePaths.m_pathNodes[t->m_nodeIndices[PATH_CAR][0]].group;
- if(gbShowPedRoadGroups)
- ind += ThePaths.m_pathNodes[t->m_nodeIndices[PATH_PED][0]].group;
- SetAmbientColoursToIndicateRoadGroup(ind);
- }
-#endif
- RenderOneRoad(t);
-#ifndef MASTER
- if(gbShowCarRoadGroups || gbShowPedRoadGroups)
- ReSetAmbientAndDirectionalColours();
-#endif
- }
+ e = ms_aVisibleEntityPtrs[i];
+ if(IsRoad(e))
+ RenderOneRoad(e);
}
}
+inline bool PutIntoSortedVehicleList(CVehicle *veh)
+{
+ if(veh->IsBoat()){
+ int mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
+ if(mode == CCam::MODE_WHEELCAM ||
+ mode == CCam::MODE_1STPERSON && TheCamera.GetLookDirection() != LOOKING_FORWARD && TheCamera.GetLookDirection() != LOOKING_BEHIND ||
+ CVisibilityPlugins::GetClumpAlpha(veh->GetClump()) != 255)
+ return false;
+ return true;
+ }else
+ return veh->bTouchingWater;
+}
+
void
CRenderer::RenderEverythingBarRoads(void)
{
@@ -220,17 +227,20 @@ CRenderer::RenderEverythingBarRoads(void)
CVector dist;
EntityInfo ei;
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ SetCullMode(rwCULLMODECULLBACK);
gSortedVehiclesAndPeds.Clear();
for(i = 0; i < ms_nNoOfVisibleEntities; i++){
e = ms_aVisibleEntityPtrs[i];
- if(e->IsBuilding() && ((CBuilding*)e)->GetIsATreadable())
+ if(IsRoad(e))
continue;
if(e->IsVehicle() ||
e->IsPed() && CVisibilityPlugins::GetClumpAlpha((RpClump*)e->m_rwObject) != 255){
- if(e->IsVehicle() && ((CVehicle*)e)->IsBoat()){
+ if(e->IsVehicle() && PutIntoSortedVehicleList((CVehicle*)e)){
ei.ent = e;
dist = ms_vecCameraPosition - e->GetPosition();
ei.sort = dist.MagnitudeSqr();
@@ -248,27 +258,14 @@ CRenderer::RenderEverythingBarRoads(void)
}
void
-CRenderer::RenderVehiclesButNotBoats(void)
-{
- // This function doesn't do anything
- // because only boats are inserted into the list
- CLink<EntityInfo> *node;
-
- for(node = gSortedVehiclesAndPeds.tail.prev;
- node != &gSortedVehiclesAndPeds.head;
- node = node->prev){
- // only boats in this list
- CVehicle *v = (CVehicle*)node->item.ent;
- if(!v->IsBoat())
- RenderOneNonRoad(v);
- }
-}
-
-void
CRenderer::RenderBoats(void)
{
CLink<EntityInfo> *node;
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ SetCullMode(rwCULLMODECULLBACK);
+
for(node = gSortedVehiclesAndPeds.tail.prev;
node != &gSortedVehiclesAndPeds.head;
node = node->prev){
@@ -283,12 +280,22 @@ void
CRenderer::RenderFadingInEntities(void)
{
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ SetCullMode(rwCULLMODECULLBACK);
DeActivateDirectional();
SetAmbientColours();
CVisibilityPlugins::RenderFadingEntities();
}
void
+CRenderer::RenderFadingInUnderwaterEntities(void)
+{
+ DeActivateDirectional();
+ SetAmbientColours();
+ CVisibilityPlugins::RenderFadingUnderwaterEntities();
+}
+
+void
CRenderer::RenderCollisionLines(void)
{
int i;
@@ -332,7 +339,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
float dist;
bool request = true;
- if (mi->GetModelType() == MITYPE_TIME) {
+ if(mi->GetModelType() == MITYPE_TIME){
ti = (CTimeModelInfo*)mi;
other = ti->GetOtherTimeModel();
if(CClock::GetIsTimeInRange(ti->GetTimeOn(), ti->GetTimeOff())){
@@ -348,25 +355,36 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
request = false;
}
}else{
- if (mi->GetModelType() != MITYPE_SIMPLE) {
+ if(mi->GetModelType() != MITYPE_SIMPLE && mi->GetModelType() != MITYPE_WEAPON){
if(FindPlayerVehicle() == ent &&
- TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON){
+ TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON &&
+//TODO(MIAMI): that bike flag
+ (!FindPlayerVehicle()->IsBike() || true)){
// Player's vehicle in first person mode
- if(TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_FORWARD ||
+ CVehicle *veh = (CVehicle*)ent;
+ int model = veh->GetModelIndex();
+ int direction = TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking;
+ if(direction == LOOKING_FORWARD ||
ent->GetModelIndex() == MI_RHINO ||
ent->GetModelIndex() == MI_COACH ||
- TheCamera.m_bInATunnelAndABigVehicle){
+ TheCamera.m_bInATunnelAndABigVehicle ||
+ direction == LOOKING_BEHIND && veh->pHandling->Flags & HANDLING_UNKNOWN){
ent->bNoBrightHeadLights = true;
- }else{
+ return VIS_OFFSCREEN;
+ }
+
+ if(direction != LOOKING_BEHIND ||
+ !veh->IsBoat() || model == MI_REEFER || model == MI_TROPIC || model == MI_PREDATOR || model == MI_SKIMMER){
m_pFirstPersonVehicle = (CVehicle*)ent;
ent->bNoBrightHeadLights = false;
+ return VIS_OFFSCREEN;
}
- return VIS_OFFSCREEN;
}
+
// All sorts of Clumps
if(ent->m_rwObject == nil || !ent->bIsVisible)
return VIS_INVISIBLE;
- if(!ent->GetIsOnScreen())
+ if(!ent->GetIsOnScreen() || ent->IsEntityOccluded())
return VIS_OFFSCREEN;
if(ent->bDrawLast){
dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude();
@@ -376,22 +394,36 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
}
return VIS_VISIBLE;
}
- if(ent->IsObject() &&
- ((CObject*)ent)->ObjectCreatedBy == TEMP_OBJECT){
+ if(ent->m_flagE10){
if(ent->m_rwObject == nil || !ent->bIsVisible)
return VIS_INVISIBLE;
- return ent->GetIsOnScreen() ? VIS_VISIBLE : VIS_OFFSCREEN;
+ if(!ent->GetIsOnScreen() || ent->IsEntityOccluded())
+ return VIS_OFFSCREEN;
+ if(ent->bDrawLast){
+ dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude();
+ CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist);
+ ent->bDistanceFade = false;
+ return VIS_INVISIBLE;
+ }
+ return VIS_VISIBLE;
}
}
// Simple ModelInfo
+ if(!IsAreaVisible(ent->m_area))
+ return VIS_INVISIBLE;
+
dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude();
- // This can only happen with multi-atomic models (e.g. railtracks)
- // but why do we bump up the distance? can only be fading...
- if(LOD_DISTANCE + STREAM_DISTANCE < dist && dist < mi->GetLargestLodDistance())
- dist = mi->GetLargestLodDistance();
+#ifndef FIX_BUGS
+ // Whatever this is supposed to do, it breaks fading for objects
+ // whose draw dist is > LOD_DISTANCE-FADE_DISTANCE, i.e. 280
+ // because decreasing dist here makes the object visible above LOD_DISTANCE
+ // before fading normally once below LOD_DISTANCE.
+ if(LOD_DISTANCE < dist && dist < mi->GetLargestLodDistance() + FADE_DISTANCE)
+ dist += mi->GetLargestLodDistance() - LOD_DISTANCE;
+#endif
if(ent->IsObject() && ent->bRenderDamaged)
mi->m_isDamaged = true;
@@ -411,7 +443,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
if(ent->m_rwObject == nil || !ent->bIsVisible)
return VIS_INVISIBLE;
- if(!ent->GetIsOnScreen()){
+ if(!ent->GetIsOnScreen() || ent->IsEntityOccluded()){
mi->m_alpha = 255;
return VIS_OFFSCREEN;
}
@@ -423,9 +455,10 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
}
if(mi->m_drawLast || ent->bDrawLast){
- CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist);
- ent->bDistanceFade = false;
- return VIS_INVISIBLE;
+ if(CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist)){
+ ent->bDistanceFade = false;
+ return VIS_INVISIBLE;
+ }
}
return VIS_VISIBLE;
}
@@ -461,7 +494,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
if(ent->m_rwObject == nil || !ent->bIsVisible)
return VIS_INVISIBLE;
- if(!ent->GetIsOnScreen()){
+ if(!ent->GetIsOnScreen() || ent->IsEntityOccluded()){
mi->m_alpha = 255;
return VIS_OFFSCREEN;
}else{
@@ -474,19 +507,32 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
int32
CRenderer::SetupBigBuildingVisibility(CEntity *ent)
{
- CSimpleModelInfo *mi = (CSimpleModelInfo *)CModelInfo::GetModelInfo(ent->GetModelIndex());
+ CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(ent->m_modelIndex);
CTimeModelInfo *ti;
int32 other;
- if (mi->GetModelType() == MITYPE_TIME) {
- ti = (CTimeModelInfo*)mi;
+ if(!IsAreaVisible(ent->m_area))
+ return VIS_INVISIBLE;
+
+ bool request = true;
+ if(mi->GetModelType() == MITYPE_TIME){
+ ti = (CTimeModelInfo*)mi;
other = ti->GetOtherTimeModel();
- // Hide objects not in time range if possible
- if(CANTIMECULL)
- if(!CClock::GetIsTimeInRange(ti->GetTimeOn(), ti->GetTimeOff()))
+ if(CClock::GetIsTimeInRange(ti->GetTimeOn(), ti->GetTimeOff())){
+ // don't fade in, or between time objects
+ if(CANTIMECULL)
+ ti->m_alpha = 255;
+ }else{
+ // Hide if possible
+ if(CANTIMECULL){
+ ent->DeleteRwObject();
return VIS_INVISIBLE;
- // Draw like normal
- } else if (mi->GetModelType() == MITYPE_VEHICLE)
+ }
+ // can't cull, so we'll try to draw this one, but don't request
+ // it since what we really want is the other one.
+ request = false;
+ }
+ }else if(mi->GetModelType() == MITYPE_VEHICLE)
return ent->IsVisible() ? VIS_VISIBLE : VIS_INVISIBLE;
float dist = (ms_vecCameraPosition-ent->GetPosition()).Magnitude();
@@ -495,7 +541,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent)
// Find out whether to draw below near distance.
// This is only the case if there is a non-LOD which is either not
// loaded or not completely faded in yet.
- if(dist < mi->GetNearDistance() && dist < LOD_DISTANCE + STREAM_DISTANCE){
+ if(dist < mi->GetNearDistance() && dist < LOD_DISTANCE){
// No non-LOD or non-LOD is completely visible.
if(nonLOD == nil ||
nonLOD->GetRwObject() && nonLOD->m_alpha == 255)
@@ -503,7 +549,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent)
// But if it is a time object, we'd rather draw the wrong
// non-LOD than the right LOD.
- if (nonLOD->GetModelType() == MITYPE_TIME) {
+ if(nonLOD->GetModelType() == MITYPE_TIME){
ti = (CTimeModelInfo*)nonLOD;
other = ti->GetOtherTimeModel();
if(other != -1 && CModelInfo::GetModelInfo(other)->GetRwObject())
@@ -511,7 +557,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent)
}
}
- RpAtomic *a = mi->GetAtomicFromDistance(dist);
+ RpAtomic *a = mi->GetFirstAtomicFromDistance(dist);
if(a){
if(ent->m_rwObject == nil)
ent->CreateRwObject();
@@ -522,8 +568,18 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent)
// that of an atomic for another draw distance.
if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj))
RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?)
- if(!ent->IsVisibleComplex())
+ mi->IncreaseAlpha();
+ if(!ent->IsVisibleComplex() || ent->IsEntityOccluded()){
+ mi->m_alpha = 255;
return VIS_INVISIBLE;
+ }
+
+ if(mi->m_alpha != 255){
+ CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist);
+ ent->bDistanceFade = true;
+ return VIS_INVISIBLE;
+ }
+
if(mi->m_drawLast){
CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist);
ent->bDistanceFade = false;
@@ -539,10 +595,14 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent)
// get faded atomic
- a = mi->GetAtomicFromDistance(dist - FADE_DISTANCE);
+ a = mi->GetFirstAtomicFromDistance(dist - FADE_DISTANCE);
if(a == nil){
- ent->DeleteRwObject();
- return VIS_INVISIBLE;
+ if(ent->bStreamBIGBuilding && dist-STREAM_DISTANCE < mi->GetLodDistance(0) && request){
+ return ent->GetIsOnScreen() ? VIS_STREAMME : VIS_INVISIBLE;
+ }else{
+ ent->DeleteRwObject();
+ return VIS_INVISIBLE;
+ }
}
// Fade...
@@ -552,14 +612,21 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent)
RpAtomic *rwobj = (RpAtomic*)ent->m_rwObject;
if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj))
RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?)
- if(ent->IsVisibleComplex())
- CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist);
+ mi->IncreaseAlpha();
+ if(!ent->IsVisibleComplex() || ent->IsEntityOccluded()){
+ mi->m_alpha = 255;
+ return VIS_INVISIBLE;
+ }
+ CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist);
+ ent->bDistanceFade = true;
return VIS_INVISIBLE;
}
void
CRenderer::ConstructRenderList(void)
{
+ COcclusion::ProcessBeforeRendering();
+
ms_nNoOfVisibleEntities = 0;
ms_nNoOfInVisibleEntities = 0;
ms_vecCameraPosition = TheCamera.GetPosition();
@@ -619,6 +686,15 @@ CRenderer::ScanWorld(void)
CVisibilityPlugins::InitAlphaEntityList();
CWorld::AdvanceCurrentScanCode();
+ // unused
+ static CVector prevPos;
+ static CVector prevFwd;
+ static bool smallMovement;
+ smallMovement = (TheCamera.GetPosition() - prevPos).MagnitudeSqr() < SQR(4.0f) &&
+ DotProduct(TheCamera.GetForward(), prevFwd) > 0.98f;
+ prevPos = TheCamera.GetPosition();
+ prevFwd = TheCamera.GetForward();
+
if(cammatrix->at.z > 0.0f){
// looking up, bottom corners are further away
vectors[CORNER_LOD_LEFT] = vectors[CORNER_FAR_BOTLEFT] * LOD_DISTANCE/f;
@@ -664,6 +740,7 @@ CRenderer::ScanWorld(void)
for(int y = y1; y <= y2; y++)
ScanSectorList(CWorld::GetSector(x1, y)->m_lists);
}else{
+#ifdef GTA_TRAIN
CVehicle *train = FindPlayerTrain();
if(train && train->GetPosition().z < 0.0f){
poly[0].x = CWorld::GetSectorX(vectors[CORNER_CAM].x);
@@ -673,7 +750,9 @@ CRenderer::ScanWorld(void)
poly[2].x = CWorld::GetSectorX(vectors[CORNER_LOD_RIGHT].x);
poly[2].y = CWorld::GetSectorY(vectors[CORNER_LOD_RIGHT].y);
ScanSectorPoly(poly, 3, ScanSectorList_Subway);
- }else{
+ }else
+#endif
+ {
if(f <= LOD_DISTANCE){
poly[0].x = CWorld::GetSectorX(vectors[CORNER_CAM].x);
poly[0].y = CWorld::GetSectorY(vectors[CORNER_CAM].y);
@@ -701,7 +780,7 @@ CRenderer::ScanWorld(void)
}
ScanSectorPoly(poly, 3, ScanSectorList);
- ScanBigBuildingList(CWorld::GetBigBuildingList(CCollision::ms_collisionInMemory));
+ ScanBigBuildingList(CWorld::GetBigBuildingList(CGame::currLevel));
ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_NONE));
}
}
@@ -733,6 +812,7 @@ CRenderer::RequestObjectsInFrustum(void)
cammatrix = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera));
CWorld::AdvanceCurrentScanCode();
+ ms_vecCameraPosition = TheCamera.GetPosition();
if(cammatrix->at.z > 0.0f){
// looking up, bottom corners are further away
@@ -945,11 +1025,26 @@ CRenderer::ScanBigBuildingList(CPtrList &list)
{
CPtrNode *node;
CEntity *ent;
+ int vis;
+ int f = CTimer::GetFrameCounter() & 3;
for(node = list.first; node; node = node->next){
ent = (CEntity*)node->item;
- if(!ent->bZoneCulled && SetupBigBuildingVisibility(ent) == VIS_VISIBLE)
+ if(ent->bOffscreen || (ent->m_randomSeed&3) != f){
+ ent->bOffscreen = true;
+ vis = SetupBigBuildingVisibility(ent);
+ }else
+ vis = VIS_VISIBLE;
+ switch(vis){
+ case VIS_VISIBLE:
ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent;
+ ent->bOffscreen = false;
+ break;
+ case VIS_STREAMME:
+ if(!CStreaming::ms_disableStreaming)
+ CStreaming::RequestModel(ent->GetModelIndex(), 0);
+ break;
+ }
}
}
@@ -969,35 +1064,30 @@ CRenderer::ScanSectorList(CPtrList *lists)
if(ent->m_scanCode == CWorld::GetCurrentScanCode())
continue; // already seen
ent->m_scanCode = CWorld::GetCurrentScanCode();
+ ent->bOffscreen = false;
- if(IsEntityCullZoneVisible(ent))
- switch(SetupEntityVisibility(ent)){
- case VIS_VISIBLE:
- ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent;
- break;
- case VIS_INVISIBLE:
- if(!IsGlass(ent->GetModelIndex()))
- break;
- // fall through
- case VIS_OFFSCREEN:
- dx = ms_vecCameraPosition.x - ent->GetPosition().x;
- dy = ms_vecCameraPosition.y - ent->GetPosition().y;
- if(dx > -65.0f && dx < 65.0f &&
- dy > -65.0f && dy < 65.0f &&
- ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1)
- ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent;
- break;
- case VIS_STREAMME:
- if(!CStreaming::ms_disableStreaming)
- if(!m_loadingPriority || CStreaming::ms_numModelsRequested < 10)
- CStreaming::RequestModel(ent->GetModelIndex(), 0);
+ switch(SetupEntityVisibility(ent)){
+ case VIS_VISIBLE:
+ ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent;
+ break;
+ case VIS_INVISIBLE:
+ if(!IsGlass(ent->GetModelIndex()))
break;
- }
- else if(ent->IsBuilding() && ((CBuilding*)ent)->GetIsATreadable()){
+ // fall through
+ case VIS_OFFSCREEN:
+ ent->bOffscreen = true;
+ dx = ms_vecCameraPosition.x - ent->GetPosition().x;
+ dy = ms_vecCameraPosition.y - ent->GetPosition().y;
+ if(dx > -30.0f && dx < 30.0f &&
+ dy > -30.0f && dy < 30.0f &&
+ ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1)
+ ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent;
+ break;
+ case VIS_STREAMME:
if(!CStreaming::ms_disableStreaming)
- if(SetupEntityVisibility(ent) == VIS_STREAMME)
- if(!m_loadingPriority || CStreaming::ms_numModelsRequested < 10)
- CStreaming::RequestModel(ent->GetModelIndex(), 0);
+ if(!m_loadingPriority || CStreaming::ms_numModelsRequested < 10)
+ CStreaming::RequestModel(ent->GetModelIndex(), 0);
+ break;
}
}
}
@@ -1019,41 +1109,38 @@ CRenderer::ScanSectorList_Priority(CPtrList *lists)
if(ent->m_scanCode == CWorld::GetCurrentScanCode())
continue; // already seen
ent->m_scanCode = CWorld::GetCurrentScanCode();
+ ent->bOffscreen = false;
- if(IsEntityCullZoneVisible(ent))
- switch(SetupEntityVisibility(ent)){
- case VIS_VISIBLE:
- ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent;
- break;
- case VIS_INVISIBLE:
- if(!IsGlass(ent->GetModelIndex()))
- break;
- // fall through
- case VIS_OFFSCREEN:
- dx = ms_vecCameraPosition.x - ent->GetPosition().x;
- dy = ms_vecCameraPosition.y - ent->GetPosition().y;
- if(dx > -65.0f && dx < 65.0f &&
- dy > -65.0f && dy < 65.0f &&
- ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1)
- ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent;
- break;
- case VIS_STREAMME:
- if(!CStreaming::ms_disableStreaming){
- CStreaming::RequestModel(ent->GetModelIndex(), 0);
- if(CStreaming::ms_aInfoForModel[ent->GetModelIndex()].m_loadState != STREAMSTATE_LOADED)
- m_loadingPriority = true;
- }
+ switch(SetupEntityVisibility(ent)){
+ case VIS_VISIBLE:
+ ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent;
+ break;
+ case VIS_INVISIBLE:
+ if(!IsGlass(ent->GetModelIndex()))
break;
+ // fall through
+ case VIS_OFFSCREEN:
+ ent->bOffscreen = true;
+ dx = ms_vecCameraPosition.x - ent->GetPosition().x;
+ dy = ms_vecCameraPosition.y - ent->GetPosition().y;
+ if(dx > -30.0f && dx < 30.0f &&
+ dy > -30.0f && dy < 30.0f &&
+ ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1)
+ ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent;
+ break;
+ case VIS_STREAMME:
+ if(!CStreaming::ms_disableStreaming){
+ CStreaming::RequestModel(ent->GetModelIndex(), 0);
+ if(CStreaming::ms_aInfoForModel[ent->GetModelIndex()].m_loadState != STREAMSTATE_LOADED)
+ m_loadingPriority = true;
}
- else if(ent->IsBuilding() && ((CBuilding*)ent)->GetIsATreadable()){
- if(!CStreaming::ms_disableStreaming)
- if(SetupEntityVisibility(ent) == VIS_STREAMME)
- CStreaming::RequestModel(ent->GetModelIndex(), 0);
+ break;
}
}
}
}
+#ifdef GTA_TRAIN
void
CRenderer::ScanSectorList_Subway(CPtrList *lists)
{
@@ -1070,15 +1157,17 @@ CRenderer::ScanSectorList_Subway(CPtrList *lists)
if(ent->m_scanCode == CWorld::GetCurrentScanCode())
continue; // already seen
ent->m_scanCode = CWorld::GetCurrentScanCode();
+ ent->bOffscreen = false;
switch(SetupEntityVisibility(ent)){
case VIS_VISIBLE:
ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent;
break;
case VIS_OFFSCREEN:
+ ent->bOffscreen = true;
dx = ms_vecCameraPosition.x - ent->GetPosition().x;
dy = ms_vecCameraPosition.y - ent->GetPosition().y;
- if(dx > -65.0f && dx < 65.0f &&
- dy > -65.0f && dy < 65.0f &&
+ if(dx > -30.0f && dx < 30.0f &&
+ dy > -30.0f && dy < 30.0f &&
ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1)
ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent;
break;
@@ -1086,6 +1175,7 @@ CRenderer::ScanSectorList_Subway(CPtrList *lists)
}
}
}
+#endif
void
CRenderer::ScanSectorList_RequestModels(CPtrList *lists)
@@ -1102,8 +1192,7 @@ CRenderer::ScanSectorList_RequestModels(CPtrList *lists)
if(ent->m_scanCode == CWorld::GetCurrentScanCode())
continue; // already seen
ent->m_scanCode = CWorld::GetCurrentScanCode();
- if(IsEntityCullZoneVisible(ent))
- if(ShouldModelBeStreamed(ent))
+ if(ShouldModelBeStreamed(ent, ms_vecCameraPosition))
CStreaming::RequestModel(ent->GetModelIndex(), 0);
}
}
@@ -1138,70 +1227,29 @@ CRenderer::SortBIGBuildingsForSectorList(CPtrList *list)
}
bool
-CRenderer::ShouldModelBeStreamed(CEntity *ent)
+CRenderer::ShouldModelBeStreamed(CEntity *ent, const CVector &campos)
{
- CSimpleModelInfo *mi = (CSimpleModelInfo *)CModelInfo::GetModelInfo(ent->GetModelIndex());
- float dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude();
+ if(!IsAreaVisible(ent->m_area))
+ return false;
+ CTimeModelInfo *mi = (CTimeModelInfo *)CModelInfo::GetModelInfo(ent->GetModelIndex());
+ if(mi->GetModelType() == MITYPE_TIME)
+ if(!CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff()))
+ return false;
+ float dist = (ent->GetPosition() - campos).Magnitude();
if(mi->m_noFade)
return dist - STREAM_DISTANCE < mi->GetLargestLodDistance();
else
return dist - FADE_DISTANCE - STREAM_DISTANCE < mi->GetLargestLodDistance();
}
-bool
-CRenderer::IsEntityCullZoneVisible(CEntity *ent)
-{
- CPed *ped;
- CObject *obj;
-
- if(ent->bZoneCulled)
- return false;
-
- switch(ent->GetType()){
- case ENTITY_TYPE_VEHICLE:
- return IsVehicleCullZoneVisible(ent);
- case ENTITY_TYPE_PED:
- ped = (CPed*)ent;
- if (ped->bInVehicle) {
- if (ped->m_pMyVehicle)
- return IsVehicleCullZoneVisible(ped->m_pMyVehicle);
- else
- return true;
- }
- return !(ped->m_pCurSurface && ped->m_pCurSurface->bZoneCulled2);
- case ENTITY_TYPE_OBJECT:
- obj = (CObject*)ent;
- if(!obj->IsStatic())
- return true;
- return !(obj->m_pCurSurface && obj->m_pCurSurface->bZoneCulled2);
- default: break;
- }
- return true;
-}
-
-bool
-CRenderer::IsVehicleCullZoneVisible(CEntity *ent)
-{
- CVehicle *v = (CVehicle*)ent;
- switch(v->GetStatus()) {
- case STATUS_SIMPLE:
- case STATUS_PHYSICS:
- case STATUS_ABANDONED:
- case STATUS_WRECKED:
- return !(v->m_pCurGroundEntity && v->m_pCurGroundEntity->bZoneCulled2);
- default: break;
- }
- return true;
-}
-
void
CRenderer::RemoveVehiclePedLights(CEntity *ent, bool reset)
{
- if(ent->bRenderScorched){
- WorldReplaceScorchedLightsWithNormal(Scene.world);
- return;
+ if(!ent->bRenderScorched){
+ CPointLights::RemoveLightsAffectingObject();
+ if(reset)
+ ReSetAmbientAndDirectionalColours();
}
- CPointLights::RemoveLightsAffectingObject();
- if(reset)
- ReSetAmbientAndDirectionalColours();
+ SetAmbientColours();
+ DeActivateDirectional();
}
diff --git a/src/render/Renderer.h b/src/render/Renderer.h
index 362741e3..e9f82078 100644
--- a/src/render/Renderer.h
+++ b/src/render/Renderer.h
@@ -2,11 +2,8 @@
class CEntity;
-extern bool gbShowPedRoadGroups;
-extern bool gbShowCarRoadGroups;
extern bool gbShowCollisionPolys;
extern bool gbShowCollisionLines;
-extern bool gbShowCullZoneDebugStuff;
extern bool gbBigWhiteDebugLightSwitchedOn;
extern bool gbDontRenderBuildings;
@@ -38,8 +35,8 @@ public:
static void RenderRoads(void);
static void RenderFadingInEntities(void);
+ static void RenderFadingInUnderwaterEntities(void);
static void RenderEverythingBarRoads(void);
- static void RenderVehiclesButNotBoats(void);
static void RenderBoats(void);
static void RenderOneRoad(CEntity *);
static void RenderOneNonRoad(CEntity *);
@@ -63,9 +60,7 @@ public:
static void SortBIGBuildings(void);
static void SortBIGBuildingsForSectorList(CPtrList *list);
- static bool ShouldModelBeStreamed(CEntity *ent);
- static bool IsEntityCullZoneVisible(CEntity *ent);
- static bool IsVehicleCullZoneVisible(CEntity *ent);
+ static bool ShouldModelBeStreamed(CEntity *ent, const CVector &campos);
static void RemoveVehiclePedLights(CEntity *ent, bool reset);
};
diff --git a/src/render/Skidmarks.cpp b/src/render/Skidmarks.cpp
index 5d521041..7f057319 100644
--- a/src/render/Skidmarks.cpp
+++ b/src/render/Skidmarks.cpp
@@ -11,8 +11,6 @@ CSkidmark CSkidmarks::aSkidmarks[NUMSKIDMARKS];
RwImVertexIndex SkidmarkIndexList[SKIDMARK_LENGTH * 6];
RwIm3DVertex SkidmarkVertices[SKIDMARK_LENGTH * 2];
RwTexture *gpSkidTex;
-RwTexture *gpSkidBloodTex;
-RwTexture *gpSkidMudTex;
void
CSkidmarks::Init(void)
@@ -22,8 +20,6 @@ CSkidmarks::Init(void)
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++){
@@ -54,17 +50,7 @@ void
CSkidmarks::Shutdown(void)
{
RwTextureDestroy(gpSkidTex);
-#ifdef GTA3_1_1_PATCH
gpSkidTex = nil;
-#endif
- RwTextureDestroy(gpSkidBloodTex);
-#ifdef GTA3_1_1_PATCH
- gpSkidBloodTex = nil;
-#endif
- RwTextureDestroy(gpSkidMudTex);
-#ifdef GTA3_1_1_PATCH
- gpSkidMudTex = nil;
-#endif
}
void
@@ -116,33 +102,23 @@ 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);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidTex));
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;
- }
- }
+ CRGBA color(0, 0, 0, 255);
+ // TODO(MIAMI): we have a type field here actually (0-3)
+ if(aSkidmarks[i].m_isBloody) // TODO: type 3
+ color = CRGBA(132, 34, 11, 255);
+ else if(aSkidmarks[i].m_isMuddy) // TODO: type 1
+ color = CRGBA(90, 62, 9, 255);
uint32 fade, alpha;
if(aSkidmarks[i].m_state == 1 || CTimer::GetTimeInMilliseconds() < aSkidmarks[i].m_fadeStart)
@@ -158,9 +134,9 @@ CSkidmarks::Render(void)
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);
+ RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+0], color.red, color.green, color.blue, alpha);
RwIm3DVertexSetPos(&SkidmarkVertices[j*2+0], p1.x, p1.y, p1.z+0.1f);
- RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+1], 255, 255, 255, alpha);
+ RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+1], color.red, color.green, color.blue, alpha);
RwIm3DVertexSetPos(&SkidmarkVertices[j*2+1], p2.x, p2.y, p2.z+0.1f);
}
diff --git a/src/render/Sprite.cpp b/src/render/Sprite.cpp
index 1dd1aaab..9631aced 100644
--- a/src/render/Sprite.cpp
+++ b/src/render/Sprite.cpp
@@ -267,8 +267,8 @@ CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension(float x, float y, float z,
{
m_bFlushSpriteBufferSwitchZTest = 0;
// TODO: replace with lookup
- float c = Cos(DEGTORAD(rotation));
- float s = Sin(DEGTORAD(rotation));
+ float c = Cos(rotation);
+ float s = Sin(rotation);
float xs[4];
float ys[4];
@@ -580,8 +580,8 @@ CSprite::RenderBufferedOneXLUSprite2D_Rotate_Dimension(float x, float y, float w
{
m_bFlushSpriteBufferSwitchZTest = 1;
CRGBA col(intens * colour.red >> 8, intens * colour.green >> 8, intens * colour.blue >> 8, alpha);
- float c = Cos(DEGTORAD(rotation));
- float s = Sin(DEGTORAD(rotation));
+ float c = Cos(rotation);
+ float s = Sin(rotation);
Set6Vertices2D(&SpriteBufferVerts[6 * nSpriteBufferIndex],
x + c*w - s*h,
diff --git a/src/render/Sprite2d.cpp b/src/render/Sprite2d.cpp
index 52b85018..189c9797 100644
--- a/src/render/Sprite2d.cpp
+++ b/src/render/Sprite2d.cpp
@@ -151,7 +151,6 @@ CSprite2d::Draw(float x1, float y1, float x2, float y2, float x3, float y3, floa
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
}
-
// Arguments:
// 2---3
// | |
@@ -461,6 +460,22 @@ CSprite2d::DrawRectXLU(const CRect &r, const CRGBA &c0, const CRGBA &c1, const C
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
}
+void
+CSprite2d::DrawAnyRect(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4,
+ const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
+{
+ SetVertices(x1, y1, x2, y2, x3, y3, x4, y4, c0, c1, c2, c3);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+ RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEGOURAUD);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)(c0.alpha != 255 || c1.alpha != 255 || c2.alpha != 255 || c3.alpha != 255));
+ RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEGOURAUD);
+}
+
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);
diff --git a/src/render/Sprite2d.h b/src/render/Sprite2d.h
index 0e12d441..04b40591 100644
--- a/src/render/Sprite2d.h
+++ b/src/render/Sprite2d.h
@@ -46,6 +46,8 @@ public:
static void DrawRect(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3);
static void DrawRect(const CRect &r, const CRGBA &col);
static void DrawRectXLU(const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3);
+ static void DrawAnyRect(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4,
+ const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3);
static void Draw2DPolygon(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, const CRGBA &color);
diff --git a/src/render/Timecycle.cpp b/src/render/Timecycle.cpp
index cf3426d7..c120c003 100644
--- a/src/render/Timecycle.cpp
+++ b/src/render/Timecycle.cpp
@@ -10,9 +10,20 @@
#include "FileMgr.h"
#include "Timecycle.h"
+// TODO(MIAMI): change some of the types here
+
int CTimeCycle::m_nAmbientRed[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nAmbientGreen[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nAmbientBlue[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nAmbientRed_Obj[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nAmbientGreen_Obj[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nAmbientBlue_Obj[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nAmbientRed_Bl[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nAmbientGreen_Bl[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nAmbientBlue_Bl[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nAmbientRed_Obj_Bl[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nAmbientGreen_Obj_Bl[NUMHOURS][NUMWEATHERS];
+int CTimeCycle::m_nAmbientBlue_Obj_Bl[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nDirectionalRed[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nDirectionalGreen[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nDirectionalBlue[NUMHOURS][NUMWEATHERS];
@@ -33,7 +44,7 @@ float CTimeCycle::m_fSpriteSize[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fSpriteBrightness[NUMHOURS][NUMWEATHERS];
short CTimeCycle::m_nShadowStrength[NUMHOURS][NUMWEATHERS];
short CTimeCycle::m_nLightShadowStrength[NUMHOURS][NUMWEATHERS];
-short CTimeCycle::m_nTreeShadowStrength[NUMHOURS][NUMWEATHERS];
+short CTimeCycle::m_nPoleShadowStrength[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fFogStart[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fFarClip[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fLightsOnGroundBrightness[NUMHOURS][NUMWEATHERS];
@@ -49,11 +60,24 @@ int CTimeCycle::m_nFluffyCloudsBottomBlue[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fBlurRed[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fBlurGreen[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fBlurBlue[NUMHOURS][NUMWEATHERS];
-float CTimeCycle::m_fBlurAlpha[NUMHOURS][NUMWEATHERS];
+float CTimeCycle::m_fWaterRed[NUMHOURS][NUMWEATHERS];
+float CTimeCycle::m_fWaterGreen[NUMHOURS][NUMWEATHERS];
+float CTimeCycle::m_fWaterBlue[NUMHOURS][NUMWEATHERS];
+float CTimeCycle::m_fWaterAlpha[NUMHOURS][NUMWEATHERS];
+
float CTimeCycle::m_fCurrentAmbientRed;
float CTimeCycle::m_fCurrentAmbientGreen;
float CTimeCycle::m_fCurrentAmbientBlue;
+float CTimeCycle::m_fCurrentAmbientRed_Obj;
+float CTimeCycle::m_fCurrentAmbientGreen_Obj;
+float CTimeCycle::m_fCurrentAmbientBlue_Obj;
+float CTimeCycle::m_fCurrentAmbientRed_Bl;
+float CTimeCycle::m_fCurrentAmbientGreen_Bl;
+float CTimeCycle::m_fCurrentAmbientBlue_Bl;
+float CTimeCycle::m_fCurrentAmbientRed_Obj_Bl;
+float CTimeCycle::m_fCurrentAmbientGreen_Obj_Bl;
+float CTimeCycle::m_fCurrentAmbientBlue_Obj_Bl;
float CTimeCycle::m_fCurrentDirectionalRed;
float CTimeCycle::m_fCurrentDirectionalGreen;
float CTimeCycle::m_fCurrentDirectionalBlue;
@@ -74,7 +98,7 @@ float CTimeCycle::m_fCurrentSpriteSize;
float CTimeCycle::m_fCurrentSpriteBrightness;
int CTimeCycle::m_nCurrentShadowStrength;
int CTimeCycle::m_nCurrentLightShadowStrength;
-int CTimeCycle::m_nCurrentTreeShadowStrength;
+int CTimeCycle::m_nCurrentPoleShadowStrength;
float CTimeCycle::m_fCurrentFogStart;
float CTimeCycle::m_fCurrentFarClip;
float CTimeCycle::m_fCurrentLightsOnGroundBrightness;
@@ -90,7 +114,10 @@ int CTimeCycle::m_nCurrentFluffyCloudsBottomBlue;
float CTimeCycle::m_fCurrentBlurRed;
float CTimeCycle::m_fCurrentBlurGreen;
float CTimeCycle::m_fCurrentBlurBlue;
-float CTimeCycle::m_fCurrentBlurAlpha;
+float CTimeCycle::m_fCurrentWaterRed;
+float CTimeCycle::m_fCurrentWaterGreen;
+float CTimeCycle::m_fCurrentWaterBlue;
+float CTimeCycle::m_fCurrentWaterAlpha;
int CTimeCycle::m_nCurrentFogColourRed;
int CTimeCycle::m_nCurrentFogColourGreen;
int CTimeCycle::m_nCurrentFogColourBlue;
@@ -115,18 +142,22 @@ CTimeCycle::Initialise(void)
char line[1040];
int ambR, ambG, ambB;
+ int ambobjR, ambobjG, ambobjB;
+ int ambblR, ambblG, ambblB;
+ int ambobjblR, ambobjblG, ambobjblB;
int dirR, dirG, dirB;
int skyTopR, skyTopG, skyTopB;
int skyBotR, skyBotG, skyBotB;
int sunCoreR, sunCoreG, sunCoreB;
int sunCoronaR, sunCoronaG, sunCoronaB;
float sunSz, sprSz, sprBght;
- int shad, lightShad, treeShad;
+ int shad, lightShad, poleShad;
float farClp, fogSt, lightGnd;
int cloudR, cloudG, cloudB;
int fluffyTopR, fluffyTopG, fluffyTopB;
int fluffyBotR, fluffyBotG, fluffyBotB;
- float blurR, blurG, blurB, blurA;
+ float blurR, blurG, blurB;
+ float waterR, waterG, waterB, waterA;
debug("Intialising CTimeCycle...\n");
@@ -150,25 +181,39 @@ CTimeCycle::Initialise(void)
bi++;
sscanf(line, "%d %d %d %d %d %d %d %d %d %d %d %d "
+ "%d %d %d %d %d %d %d %d %d "
"%d %d %d %d %d %d %f %f %f %d %d %d %f %f %f "
- "%d %d %d %d %d %d %d %d %d %f %f %f %f",
+ "%d %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f",
&ambR, &ambG, &ambB,
- &dirR, &dirG, &dirB,
+ &ambobjR, &ambobjG, &ambobjB,
+ &ambblR, &ambblG, &ambblB,
+ &ambobjblR, &ambobjblG, &ambobjblB,
+ &dirR, &dirG, &dirB,
&skyTopR, &skyTopG, &skyTopB,
&skyBotR, &skyBotG, &skyBotB,
&sunCoreR, &sunCoreG, &sunCoreB,
&sunCoronaR, &sunCoronaG, &sunCoronaB,
&sunSz, &sprSz, &sprBght,
- &shad, &lightShad, &treeShad,
+ &shad, &lightShad, &poleShad,
&farClp, &fogSt, &lightGnd,
&cloudR, &cloudG, &cloudB,
&fluffyTopR, &fluffyTopG, &fluffyTopB,
&fluffyBotR, &fluffyBotG, &fluffyBotB,
- &blurR, &blurG, &blurB, &blurA);
+ &blurR, &blurG, &blurB,
+ &waterR, &waterG, &waterB, &waterA);
m_nAmbientRed[h][w] = ambR;
m_nAmbientGreen[h][w] = ambG;
m_nAmbientBlue[h][w] = ambB;
+ m_nAmbientRed_Obj[h][w] = ambobjR;
+ m_nAmbientGreen_Obj[h][w] = ambobjG;
+ m_nAmbientBlue_Obj[h][w] = ambobjB;
+ m_nAmbientRed_Bl[h][w] = ambblR;
+ m_nAmbientGreen_Bl[h][w] = ambblG;
+ m_nAmbientBlue_Bl[h][w] = ambblB;
+ m_nAmbientRed_Obj_Bl[h][w] = ambobjblR;
+ m_nAmbientGreen_Obj_Bl[h][w] = ambobjblG;
+ m_nAmbientBlue_Obj_Bl[h][w] = ambobjblB;
m_nDirectionalRed[h][w] = dirR;
m_nDirectionalGreen[h][w] = dirG;
m_nDirectionalBlue[h][w] = dirB;
@@ -189,7 +234,7 @@ CTimeCycle::Initialise(void)
m_fSpriteBrightness[h][w] = sprBght;
m_nShadowStrength[h][w] = shad;
m_nLightShadowStrength[h][w] = lightShad;
- m_nTreeShadowStrength[h][w] = treeShad;
+ m_nPoleShadowStrength[h][w] = poleShad;
m_fFarClip[h][w] = farClp;
m_fFogStart[h][w] = fogSt;
m_fLightsOnGroundBrightness[h][w] = lightGnd;
@@ -205,7 +250,10 @@ CTimeCycle::Initialise(void)
m_fBlurRed[h][w] = blurR;
m_fBlurGreen[h][w] = blurG;
m_fBlurBlue[h][w] = blurB;
- m_fBlurAlpha[h][w] = blurA;
+ m_fWaterRed[h][w] = waterR;
+ m_fWaterGreen[h][w] = waterG;
+ m_fWaterBlue[h][w] = waterB;
+ m_fWaterAlpha[h][w] = waterA;
}
m_FogReduction = 0;
@@ -220,7 +268,7 @@ CTimeCycle::Update(void)
int h2 = (h1+1)%24;
int w1 = CWeather::OldWeatherType;
int w2 = CWeather::NewWeatherType;
- float timeInterp = CClock::GetMinutes()/60.0f;
+ float timeInterp = (CClock::GetMinutes() + CClock::GetSeconds()/60.0f)/60.0f;
// coefficients for a bilinear interpolation
float c0 = (1.0f-timeInterp) * (1.0f-CWeather::InterpolationValue);
float c1 = timeInterp * (1.0f-CWeather::InterpolationValue);
@@ -240,16 +288,22 @@ CTimeCycle::Update(void)
m_fCurrentAmbientRed = INTERP(m_nAmbientRed);
m_fCurrentAmbientGreen = INTERP(m_nAmbientGreen);
m_fCurrentAmbientBlue = INTERP(m_nAmbientBlue);
- m_fCurrentAmbientRed /= 255.0f;
- m_fCurrentAmbientGreen /= 255.0f;
- m_fCurrentAmbientBlue /= 255.0f;
+
+ m_fCurrentAmbientRed_Obj = INTERP(m_nAmbientRed_Obj);
+ m_fCurrentAmbientGreen_Obj = INTERP(m_nAmbientGreen_Obj);
+ m_fCurrentAmbientBlue_Obj = INTERP(m_nAmbientBlue_Obj);
+
+ m_fCurrentAmbientRed_Bl = INTERP(m_nAmbientRed_Bl);
+ m_fCurrentAmbientGreen_Bl = INTERP(m_nAmbientGreen_Bl);
+ m_fCurrentAmbientBlue_Bl = INTERP(m_nAmbientBlue_Bl);
+
+ m_fCurrentAmbientRed_Obj_Bl = INTERP(m_nAmbientRed_Obj_Bl);
+ m_fCurrentAmbientGreen_Obj_Bl = INTERP(m_nAmbientGreen_Obj_Bl);
+ m_fCurrentAmbientBlue_Obj_Bl = INTERP(m_nAmbientBlue_Obj_Bl);
m_fCurrentDirectionalRed = INTERP(m_nDirectionalRed);
m_fCurrentDirectionalGreen = INTERP(m_nDirectionalGreen);
m_fCurrentDirectionalBlue = INTERP(m_nDirectionalBlue);
- m_fCurrentDirectionalRed /= 255.0f;
- m_fCurrentDirectionalGreen /= 255.0f;
- m_fCurrentDirectionalBlue /= 255.0f;
m_nCurrentSunCoreRed = INTERP(m_nSunCoreRed);
m_nCurrentSunCoreGreen = INTERP(m_nSunCoreGreen);
@@ -264,7 +318,7 @@ CTimeCycle::Update(void)
m_fCurrentSpriteBrightness = INTERP(m_fSpriteBrightness);
m_nCurrentShadowStrength = INTERP(m_nShadowStrength);
m_nCurrentLightShadowStrength = INTERP(m_nLightShadowStrength);
- m_nCurrentTreeShadowStrength = INTERP(m_nTreeShadowStrength);
+ m_nCurrentPoleShadowStrength = INTERP(m_nPoleShadowStrength);
m_fCurrentFarClip = INTERP(m_fFarClip);
m_fCurrentFogStart = INTERP(m_fFogStart);
m_fCurrentLightsOnGroundBrightness = INTERP(m_fLightsOnGroundBrightness);
@@ -284,26 +338,49 @@ CTimeCycle::Update(void)
m_fCurrentBlurRed = INTERP(m_fBlurRed);
m_fCurrentBlurGreen = INTERP(m_fBlurGreen);
m_fCurrentBlurBlue = INTERP(m_fBlurBlue);
- m_fCurrentBlurAlpha = INTERP(m_fBlurAlpha);
- if(TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_NORMAL)
- TheCamera.SetMotionBlur(m_fCurrentBlurRed, m_fCurrentBlurGreen, m_fCurrentBlurBlue, m_fCurrentBlurAlpha, MBLUR_NORMAL);
+ m_fCurrentWaterRed = INTERP(m_fWaterRed);
+ m_fCurrentWaterGreen = INTERP(m_fWaterGreen);
+ m_fCurrentWaterBlue = INTERP(m_fWaterBlue);
+ m_fCurrentWaterAlpha = INTERP(m_fWaterAlpha);
if(m_FogReduction != 0)
m_fCurrentFarClip = Max(m_fCurrentFarClip, m_FogReduction/64.0f * 650.0f);
- m_nCurrentFogColourRed = (m_nCurrentSkyTopRed + 2*m_nCurrentSkyBottomRed) / 3;
- m_nCurrentFogColourGreen = (m_nCurrentSkyTopGreen + 2*m_nCurrentSkyBottomGreen) / 3;
- m_nCurrentFogColourBlue = (m_nCurrentSkyTopBlue + 2*m_nCurrentSkyBottomBlue) / 3;
m_CurrentStoredValue = (m_CurrentStoredValue+1)&0xF;
- float sunAngle = 2*PI*(CClock::GetMinutes() + CClock::GetHours()*60)/(24*60);
+ float sunAngle = 2*PI*(CClock::GetSeconds()/60.0f + CClock::GetMinutes() + CClock::GetHours()*60)/(24*60);
CVector &sunPos = GetSunPosition();
sunPos.x = Sin(sunAngle);
sunPos.y = 1.0f;
sunPos.z = 0.2f - Cos(sunAngle);
sunPos.Normalise();
+ // TODO(MIAMI): extra colours
+
+ if(TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_NORMAL)
+ TheCamera.SetMotionBlur(m_fCurrentBlurRed, m_fCurrentBlurGreen, m_fCurrentBlurBlue, 5, MBLUR_NORMAL);
+
+ m_nCurrentFogColourRed = (m_nCurrentSkyTopRed + 2*m_nCurrentSkyBottomRed) / 3;
+ m_nCurrentFogColourGreen = (m_nCurrentSkyTopGreen + 2*m_nCurrentSkyBottomGreen) / 3;
+ m_nCurrentFogColourBlue = (m_nCurrentSkyTopBlue + 2*m_nCurrentSkyBottomBlue) / 3;
+
+ m_fCurrentAmbientRed /= 255.0f;
+ m_fCurrentAmbientGreen /= 255.0f;
+ m_fCurrentAmbientBlue /= 255.0f;
+ m_fCurrentAmbientRed_Obj /= 255.0f;
+ m_fCurrentAmbientGreen_Obj /= 255.0f;
+ m_fCurrentAmbientBlue_Obj /= 255.0f;
+ m_fCurrentAmbientRed_Bl /= 255.0f;
+ m_fCurrentAmbientGreen_Bl /= 255.0f;
+ m_fCurrentAmbientBlue_Bl /= 255.0f;
+ m_fCurrentAmbientRed_Obj_Bl /= 255.0f;
+ m_fCurrentAmbientGreen_Obj_Bl /= 255.0f;
+ m_fCurrentAmbientBlue_Obj_Bl /= 255.0f;
+ m_fCurrentDirectionalRed /= 255.0f;
+ m_fCurrentDirectionalGreen /= 255.0f;
+ m_fCurrentDirectionalBlue /= 255.0f;
+
CShadows::CalcPedShadowValues(sunPos,
&m_fShadowFrontX[m_CurrentStoredValue], &m_fShadowFrontY[m_CurrentStoredValue],
&m_fShadowSideX[m_CurrentStoredValue], &m_fShadowSideY[m_CurrentStoredValue],
diff --git a/src/render/Timecycle.h b/src/render/Timecycle.h
index 28a0b7dd..dc52d493 100644
--- a/src/render/Timecycle.h
+++ b/src/render/Timecycle.h
@@ -5,6 +5,15 @@ class CTimeCycle
static int m_nAmbientRed[NUMHOURS][NUMWEATHERS];
static int m_nAmbientGreen[NUMHOURS][NUMWEATHERS];
static int m_nAmbientBlue[NUMHOURS][NUMWEATHERS];
+ static int m_nAmbientRed_Obj[NUMHOURS][NUMWEATHERS];
+ static int m_nAmbientGreen_Obj[NUMHOURS][NUMWEATHERS];
+ static int m_nAmbientBlue_Obj[NUMHOURS][NUMWEATHERS];
+ static int m_nAmbientRed_Bl[NUMHOURS][NUMWEATHERS];
+ static int m_nAmbientGreen_Bl[NUMHOURS][NUMWEATHERS];
+ static int m_nAmbientBlue_Bl[NUMHOURS][NUMWEATHERS];
+ static int m_nAmbientRed_Obj_Bl[NUMHOURS][NUMWEATHERS];
+ static int m_nAmbientGreen_Obj_Bl[NUMHOURS][NUMWEATHERS];
+ static int m_nAmbientBlue_Obj_Bl[NUMHOURS][NUMWEATHERS];
static int m_nDirectionalRed[NUMHOURS][NUMWEATHERS];
static int m_nDirectionalGreen[NUMHOURS][NUMWEATHERS];
static int m_nDirectionalBlue[NUMHOURS][NUMWEATHERS];
@@ -25,7 +34,7 @@ class CTimeCycle
static float m_fSpriteBrightness[NUMHOURS][NUMWEATHERS];
static short m_nShadowStrength[NUMHOURS][NUMWEATHERS];
static short m_nLightShadowStrength[NUMHOURS][NUMWEATHERS];
- static short m_nTreeShadowStrength[NUMHOURS][NUMWEATHERS];
+ static short m_nPoleShadowStrength[NUMHOURS][NUMWEATHERS];
static float m_fFogStart[NUMHOURS][NUMWEATHERS];
static float m_fFarClip[NUMHOURS][NUMWEATHERS];
static float m_fLightsOnGroundBrightness[NUMHOURS][NUMWEATHERS];
@@ -41,11 +50,23 @@ class CTimeCycle
static float m_fBlurRed[NUMHOURS][NUMWEATHERS];
static float m_fBlurGreen[NUMHOURS][NUMWEATHERS];
static float m_fBlurBlue[NUMHOURS][NUMWEATHERS];
- static float m_fBlurAlpha[NUMHOURS][NUMWEATHERS];
+ static float m_fWaterRed[NUMHOURS][NUMWEATHERS];
+ static float m_fWaterGreen[NUMHOURS][NUMWEATHERS];
+ static float m_fWaterBlue[NUMHOURS][NUMWEATHERS];
+ static float m_fWaterAlpha[NUMHOURS][NUMWEATHERS];
static float m_fCurrentAmbientRed;
static float m_fCurrentAmbientGreen;
static float m_fCurrentAmbientBlue;
+ static float m_fCurrentAmbientRed_Obj;
+ static float m_fCurrentAmbientGreen_Obj;
+ static float m_fCurrentAmbientBlue_Obj;
+ static float m_fCurrentAmbientRed_Bl;
+ static float m_fCurrentAmbientGreen_Bl;
+ static float m_fCurrentAmbientBlue_Bl;
+ static float m_fCurrentAmbientRed_Obj_Bl;
+ static float m_fCurrentAmbientGreen_Obj_Bl;
+ static float m_fCurrentAmbientBlue_Obj_Bl;
static float m_fCurrentDirectionalRed;
static float m_fCurrentDirectionalGreen;
static float m_fCurrentDirectionalBlue;
@@ -66,7 +87,7 @@ class CTimeCycle
static float m_fCurrentSpriteBrightness;
static int m_nCurrentShadowStrength;
static int m_nCurrentLightShadowStrength;
- static int m_nCurrentTreeShadowStrength;
+ static int m_nCurrentPoleShadowStrength;
static float m_fCurrentFogStart;
static float m_fCurrentFarClip;
static float m_fCurrentLightsOnGroundBrightness;
@@ -82,7 +103,10 @@ class CTimeCycle
static float m_fCurrentBlurRed;
static float m_fCurrentBlurGreen;
static float m_fCurrentBlurBlue;
- static float m_fCurrentBlurAlpha;
+ static float m_fCurrentWaterRed;
+ static float m_fCurrentWaterGreen;
+ static float m_fCurrentWaterBlue;
+ static float m_fCurrentWaterAlpha;
static int m_nCurrentFogColourRed;
static int m_nCurrentFogColourGreen;
static int m_nCurrentFogColourBlue;
@@ -102,6 +126,15 @@ public:
static float GetAmbientRed(void) { return m_fCurrentAmbientRed; }
static float GetAmbientGreen(void) { return m_fCurrentAmbientGreen; }
static float GetAmbientBlue(void) { return m_fCurrentAmbientBlue; }
+ static float GetAmbientRed_Obj(void) { return m_fCurrentAmbientRed_Obj; }
+ static float GetAmbientGreen_Obj(void) { return m_fCurrentAmbientGreen_Obj; }
+ static float GetAmbientBlue_Obj(void) { return m_fCurrentAmbientBlue_Obj; }
+ static float GetAmbientRed_Bl(void) { return m_fCurrentAmbientRed_Bl; }
+ static float GetAmbientGreen_Bl(void) { return m_fCurrentAmbientGreen_Bl; }
+ static float GetAmbientBlue_Bl(void) { return m_fCurrentAmbientBlue_Bl; }
+ static float GetAmbientRed_Obj_Bl(void) { return m_fCurrentAmbientRed_Obj_Bl; }
+ static float GetAmbientGreen_Obj_Bl(void) { return m_fCurrentAmbientGreen_Obj_Bl; }
+ static float GetAmbientBlue_Obj_Bl(void) { return m_fCurrentAmbientBlue_Obj_Bl; }
static float GetDirectionalRed(void) { return m_fCurrentDirectionalRed; }
static float GetDirectionalGreen(void) { return m_fCurrentDirectionalGreen; }
static float GetDirectionalBlue(void) { return m_fCurrentDirectionalBlue; }
@@ -140,6 +173,11 @@ public:
static int GetFogBlue(void) { return m_nCurrentFogColourBlue; }
static int GetFogReduction(void) { return m_FogReduction; }
+ static int GetWaterRed(void) { return m_fCurrentWaterRed; }
+ static int GetWaterGreen(void) { return m_fCurrentWaterGreen; }
+ static int GetWaterBlue(void) { return m_fCurrentWaterBlue; }
+ static int GetWaterAlpha(void) { return m_fCurrentWaterAlpha; }
+
static void Initialise(void);
static void Update(void);
static CVector &GetSunPosition(void) { return m_VectorToSun[m_CurrentStoredValue]; }
diff --git a/src/render/WaterLevel.cpp b/src/render/WaterLevel.cpp
index 1a28ce83..f1ccccb3 100644
--- a/src/render/WaterLevel.cpp
+++ b/src/render/WaterLevel.cpp
@@ -36,9 +36,6 @@ RpAtomic *CWaterLevel::ms_pWavyAtomic;
RpGeometry *CWaterLevel::apGeomArray[8];
int16 CWaterLevel::nGeomUsed;
-//RwTexture *gpWaterTex;
-//RwRaster *gpWaterRaster;
-
RwTexture *gpWaterTex;
RwRaster *gpWaterRaster;
@@ -84,7 +81,7 @@ CWaterLevel::Initialise(Const char *pWaterDat)
CTxdStore::SetCurrentTxd(slot);
if ( gpWaterTex == NULL )
- gpWaterTex = RwTextureRead("water_old", NULL);
+ gpWaterTex = RwTextureRead("waterclear256", NULL);
gpWaterRaster = RwTextureGetRaster(gpWaterTex);
CTxdStore::PopCurrentTxd();
@@ -222,7 +219,7 @@ CWaterLevel::DestroyWavyAtomic()
bool
CWaterLevel::GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool bDontCheckZ)
{
- int32 x = WATER_HUGE_X(fX);
+ int32 x = WATER_HUGE_X(fX + WATER_X_OFFSET);
int32 y = WATER_HUGE_Y(fY);
ASSERT( x >= 0 && x < HUGE_SECTOR_SIZE );
@@ -240,8 +237,9 @@ CWaterLevel::GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool
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)) )
+ ( WATER_UNSIGN_Y(fY) - float(y) * MAX_HUGE_SECTORS
+ + WATER_UNSIGN_X(fX + WATER_X_OFFSET) - float(x) * MAX_HUGE_SECTORS )
+
* (TWOPI / MAX_HUGE_SECTORS ) + fAngle
);
@@ -261,7 +259,7 @@ CWaterLevel::GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool
bool
CWaterLevel::GetWaterLevelNoWaves(float fX, float fY, float fZ, float *pfOutLevel)
{
- int32 x = WATER_HUGE_X(fX);
+ int32 x = WATER_HUGE_X(fX + WATER_X_OFFSET);
int32 y = WATER_HUGE_Y(fY);
ASSERT( x >= 0 && x < HUGE_SECTOR_SIZE );
@@ -368,10 +366,10 @@ CWaterLevel::RenderWater()
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);
+
+ color.red = CTimeCycle::GetWaterRed();
+ color.green = CTimeCycle::GetWaterGreen();
+ color.blue = CTimeCycle::GetWaterBlue();
TempBufferVerticesStored = 0;
TempBufferIndicesStored = 0;
@@ -387,15 +385,15 @@ CWaterLevel::RenderWater()
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 nStartX = WATER_TO_HUGE_SECTOR_X(camPos.x - fHugeSectorMaxRenderDist + WATER_X_OFFSET);
+ int32 nEndX = WATER_TO_HUGE_SECTOR_X(camPos.x + fHugeSectorMaxRenderDist + WATER_X_OFFSET) + 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);
+ nStartX = WATER_TO_HUGE_SECTOR_X(camPos.x + WATER_X_OFFSET);
if ( bUseCamEndX )
- nEndX = WATER_TO_HUGE_SECTOR_X(camPos.x);
+ nEndX = WATER_TO_HUGE_SECTOR_X(camPos.x + WATER_X_OFFSET);
if ( bUseCamStartY )
nStartY = WATER_TO_HUGE_SECTOR_Y(camPos.y);
if ( bUseCamEndY )
@@ -415,7 +413,7 @@ CWaterLevel::RenderWater()
|| !(aWaterBlockList[2*x+0][2*y+1] & 128)
|| !(aWaterBlockList[2*x+1][2*y+1] & 128) )
{
- float fX = WATER_FROM_HUGE_SECTOR_X(x);
+ float fX = WATER_FROM_HUGE_SECTOR_X(x) - WATER_X_OFFSET;
float fY = WATER_FROM_HUGE_SECTOR_Y(y);
CVector2D vecHugeSectorCentre
@@ -457,7 +455,7 @@ CWaterLevel::RenderWater()
{
if ( !(aWaterBlockList[x2][y2] & 128) )
{
- float fLargeX = WATER_FROM_LARGE_SECTOR_X(x2);
+ float fLargeX = WATER_FROM_LARGE_SECTOR_X(x2) - WATER_X_OFFSET;
float fLargeY = WATER_FROM_LARGE_SECTOR_Y(y2);
CVector2D vecLargeSectorCentre
@@ -614,15 +612,15 @@ CWaterLevel::RenderWater()
bottom -> top && left -> right
*/
- if ( !bUseCamStartY )
+ for ( int32 x = 0; x < 26; x++ )
{
- for ( int32 x = 0; x < 26; x++ )
+ for ( int32 y = 0; y < 5; y++ )
{
- for ( int32 y = 0; y < 5; y++ )
+ float fX = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f - 400.0f;
+ float fY = WATER_SIGN_Y(float(y) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f;
+
+ if ( !bUseCamStartY )
{
- 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,
@@ -633,8 +631,7 @@ CWaterLevel::RenderWater()
if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr )
{
- if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE),
- &TheCamera.GetCameraMatrix()) )
+ if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE), &TheCamera.GetCameraMatrix()) )
{
RenderOneFlatExtraHugeWaterPoly(
vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2,
@@ -644,6 +641,30 @@ CWaterLevel::RenderWater()
}
}
}
+
+ if ( !bUseCamEndY )
+ {
+ 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), &TheCamera.GetCameraMatrix()) )
+ {
+ RenderOneFlatExtraHugeWaterPoly(
+ vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2,
+ vecExtraHugeSectorCentre.y - EXTRAHUGE_SECTOR_SIZE/2,
+ 0.0f,
+ color);
+ }
+ }
+ }
+
}
}
@@ -651,8 +672,8 @@ CWaterLevel::RenderWater()
{
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 fX = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f - 400.0f;
+ float fX2 = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f + 400.0f;
float fY = WATER_SIGN_Y(float(y) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f;
if ( !bUseCamStartX )
@@ -667,8 +688,7 @@ CWaterLevel::RenderWater()
if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr )
{
- if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE),
- &TheCamera.GetCameraMatrix()) )
+ if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE), &TheCamera.GetCameraMatrix()) )
{
RenderOneFlatExtraHugeWaterPoly(
vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2,
@@ -691,8 +711,7 @@ CWaterLevel::RenderWater()
if ( fCamDistToSector < fHugeSectorMaxRenderDistSqr )
{
- if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE),
- &TheCamera.GetCameraMatrix()) )
+ if ( TheCamera.IsSphereVisible(CVector(vecExtraHugeSectorCentre.x, vecExtraHugeSectorCentre.y, 0.0f), SectorRadius(EXTRAHUGE_SECTOR_SIZE), &TheCamera.GetCameraMatrix()) )
{
RenderOneFlatExtraHugeWaterPoly(
vecExtraHugeSectorCentre.x - EXTRAHUGE_SECTOR_SIZE/2,
@@ -1092,8 +1111,8 @@ 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 nStartX = WATER_TO_SMALL_SECTOR_X(fX - fSectorMaxRenderDist + WATER_X_OFFSET) - 1;
+ int32 nEndX = WATER_TO_SMALL_SECTOR_X(fX + fSectorMaxRenderDist + WATER_X_OFFSET) + 1;
int32 nStartY = WATER_TO_SMALL_SECTOR_Y(fY - fSectorMaxRenderDist) - 1;
int32 nEndY = WATER_TO_SMALL_SECTOR_Y(fY + fSectorMaxRenderDist) + 1;
@@ -1110,7 +1129,7 @@ CWaterLevel::CalcDistanceToWater(float fX, float fY)
{
if ( !(aWaterFineBlockList[x][y] & 128) )
{
- float fSectorX = WATER_FROM_SMALL_SECTOR_X(x);
+ float fSectorX = WATER_FROM_SMALL_SECTOR_X(x) - WATER_X_OFFSET;
float fSectorY = WATER_FROM_SMALL_SECTOR_Y(y);
CVector2D vecDist
diff --git a/src/render/WaterLevel.h b/src/render/WaterLevel.h
index 985c9744..435692c1 100644
--- a/src/render/WaterLevel.h
+++ b/src/render/WaterLevel.h
@@ -1,8 +1,10 @@
#pragma once
+#define WATER_X_OFFSET (400.0f)
+
#define WATER_BLOCK_SIZE LARGE_SECTOR_SIZE
#define WATER_FINEBLOCK_SIZE HUGE_SECTOR_SIZE
-#define WATER_Z_OFFSET (1.5f)
+#define WATER_Z_OFFSET (0.5f)
#define MAX_SMALL_SECTORS 128
#define MAX_LARGE_SECTORS 64
diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp
index b4031705..fc3e0d61 100644
--- a/src/render/Weather.cpp
+++ b/src/render/Weather.cpp
@@ -8,6 +8,7 @@
#include "DMAudio.h"
#include "General.h"
#include "Pad.h"
+#include "PlayerPed.h"
#include "Particle.h"
#include "RenderBuffer.h"
#include "Stats.h"
@@ -32,6 +33,7 @@ uint32 CWeather::LightningFlashLastChange;
uint32 CWeather::WhenToPlayLightningSound;
uint32 CWeather::LightningDuration;
+float CWeather::ExtraSunnyness;
float CWeather::Foggyness;
float CWeather::CloudCoverage;
float CWeather::Wind;
@@ -39,41 +41,60 @@ float CWeather::Rain;
float CWeather::InterpolationValue;
float CWeather::WetRoads;
float CWeather::Rainbow;
+float CWeather::SunGlare;
+float CWeather::WindClipped;
+float CWeather::TrafficLightBrightness;
bool CWeather::bScriptsForceRain;
-bool CWeather::Stored_StateStored;
-
-float CWeather::Stored_InterpolationValue;
-int16 CWeather::Stored_OldWeatherType;
-int16 CWeather::Stored_NewWeatherType;
-float CWeather::Stored_Rain;
tRainStreak Streaks[NUM_RAIN_STREAKS];
const int16 WeatherTypesList[] = {
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
+ WEATHER_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_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_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
- WEATHER_CLOUDY, WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_RAINY,
+ WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_CLOUDY,
+ WEATHER_RAINY, WEATHER_RAINY, 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_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY
+};
+
+const int16 WeatherTypesList_WithHurricanes[] = {
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
+ WEATHER_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_CLOUDY,
+ WEATHER_HURRICANE, WEATHER_HURRICANE, WEATHER_CLOUDY, WEATHER_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_SUNNY, 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,
+ WEATHER_CLOUDY, WEATHER_HURRICANE, WEATHER_HURRICANE, WEATHER_HURRICANE,
+ WEATHER_CLOUDY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
+ WEATHER_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY
};
const float Windiness[] = {
- 0.0f, // WEATHER_SUNNY
+ 0.25f,// WEATHER_SUNNY
0.7f, // WEATHER_CLOUDY
1.0f, // WEATHER_RAINY
- 0.5f // WEATHER_FOGGY
+ 0.0f, // WEATHER_FOGGY
+ 0.0f, // WEATHER_EXTRA_SUNNY
+ 2.0f, // WEATHER_HURRICANE
+ 0.0f
};
#define MIN_TIME_BETWEEN_LIGHTNING_FLASH_CHANGES (50)
@@ -104,10 +125,9 @@ const float Windiness[] = {
void CWeather::Init(void)
{
- NewWeatherType = WEATHER_SUNNY;
+ NewWeatherType = WEATHER_EXTRA_SUNNY;
bScriptsForceRain = false;
- OldWeatherType = WEATHER_CLOUDY;
- Stored_StateStored = false;
+ OldWeatherType = WEATHER_EXTRA_SUNNY;
InterpolationValue = 0.0f;
WhenToPlayLightningSound = 0;
WeatherTypeInList = 0;
@@ -127,16 +147,8 @@ void CWeather::Update(void)
NewWeatherType = ForcedWeatherType;
else {
WeatherTypeInList = (WeatherTypeInList + 1) % ARRAY_SIZE(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;
+ NewWeatherType = CStats::NoMoreHurricanes ? WeatherTypesList[WeatherTypeInList] : WeatherTypesList_WithHurricanes[WeatherTypeInList];
}
-#endif
}
InterpolationValue = fNewInterpolation;
if (CPad::GetPad(1)->GetRightShockJustDown()) {
@@ -188,14 +200,14 @@ void CWeather::Update(void)
}
// Wet roads
- if (OldWeatherType == WEATHER_RAINY) {
- if (NewWeatherType == WEATHER_RAINY)
+ if (OldWeatherType == WEATHER_RAINY || OldWeatherType == WEATHER_HURRICANE) {
+ if (NewWeatherType == WEATHER_RAINY || NewWeatherType == WEATHER_HURRICANE)
WetRoads = 1.0f;
else
WetRoads = 1.0f - InterpolationValue;
}
else {
- if (NewWeatherType == WEATHER_RAINY)
+ if (NewWeatherType == WEATHER_RAINY || NewWeatherType == WEATHER_HURRICANE)
WetRoads = InterpolationValue;
else
WetRoads = 0.0f;
@@ -203,10 +215,10 @@ void CWeather::Update(void)
// Rain
float fNewRain;
- if (NewWeatherType == WEATHER_RAINY) {
+ if (NewWeatherType == WEATHER_RAINY || NewWeatherType == WEATHER_HURRICANE) {
// 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 (OldWeatherType != WEATHER_RAINY && OldWeatherType != WEATHER_HURRICANE) {
if (InterpolationValue < 0.4f)
// if rain has just started (<24 minutes), always 0.5
fNewRain = 0.5f;
@@ -217,19 +229,14 @@ void CWeather::Update(void)
}
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());
- }
+ Rain = fNewRain;
// Clouds
- if (OldWeatherType != WEATHER_SUNNY)
+ if (OldWeatherType != WEATHER_SUNNY && OldWeatherType != WEATHER_EXTRA_SUNNY)
CloudCoverage = 1.0f - InterpolationValue;
else
CloudCoverage = 0.0f;
- if (NewWeatherType != WEATHER_SUNNY)
+ if (NewWeatherType != WEATHER_SUNNY && OldWeatherType != WEATHER_EXTRA_SUNNY)
CloudCoverage += InterpolationValue;
// Fog
@@ -239,12 +246,76 @@ void CWeather::Update(void)
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)
+
+ // Extra Sunnyness
+ if (OldWeatherType == WEATHER_EXTRA_SUNNY)
+ ExtraSunnyness = 1.0f - InterpolationValue;
+ else
+ ExtraSunnyness = 0.0f;
+ if (NewWeatherType == WEATHER_EXTRA_SUNNY)
+ ExtraSunnyness += InterpolationValue;
+
+ // Rainbow
+ if (OldWeatherType == WEATHER_RAINY && (NewWeatherType == WEATHER_SUNNY || NewWeatherType == WEATHER_EXTRA_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;
+
+ // Sun Glare
+ if (OldWeatherType == WEATHER_EXTRA_SUNNY)
+ SunGlare = 1.0f - InterpolationValue;
+ else
+ SunGlare = 0.0f;
+ if (NewWeatherType == WEATHER_EXTRA_SUNNY)
+ SunGlare += InterpolationValue;
+
+ if (SunGlare > 0.0f) {
+ SunGlare *= Min(1.0f, 7.0 * CTimeCycle::GetSunPosition().z);
+ SunGlare = clamp(SunGlare, 0.0f, 1.0f);
+ // TODO(MIAMI): if (CSpecialFX::bSnapShotActive)...
+ }
+
Wind = InterpolationValue * Windiness[NewWeatherType] + (1.0f - InterpolationValue) * Windiness[OldWeatherType];
+ WindClipped = Max(1.0f, Wind);
+
+ if (CClock::GetHours() == 20)
+ TrafficLightBrightness = CClock::GetMinutes() / 60.0f;
+ else if (CClock::GetHours() > 6 && CClock::GetHours() < 20)
+ TrafficLightBrightness = 0.0f;
+ else if (CClock::GetHours() == 6)
+ TrafficLightBrightness = 1.0f - CClock::GetMinutes() / 60.0f;
+ else
+ TrafficLightBrightness = 1.0f;
+ TrafficLightBrightness = Max(WetRoads, TrafficLightBrightness);
+ TrafficLightBrightness = Max(Rain, TrafficLightBrightness);
+
AddRain();
+
+ if ((NewWeatherType == WEATHER_SUNNY || NewWeatherType == WEATHER_EXTRA_SUNNY) &&
+ !CGame::IsInInterior() && !CCutsceneMgr::IsRunning() && (CTimer::GetFrameCounter() & 7) == 0) {
+#ifdef FIX_BUGS
+ if (FindPlayerPed() && (!FindPlayerPed()->CheckIfInTheAir() || FindPlayerPed()->CheckIfInTheAir() && FindPlayerPed()->GetPosition().z < 7.5f &&
+ CClock::GetHours() > 6 && CClock::GetHours() < 18))
+#else
+ if (!FindPlayerPed()->CheckIfInTheAir() || FindPlayerPed()->CheckIfInTheAir() && FindPlayerPed()->GetPosition().z < 7.5f &&
+ CClock::GetHours() > 6 && CClock::GetHours() < 18)
+#endif
+ AddHeatHaze();
+ }
+
+ if ((NewWeatherType == WEATHER_SUNNY || NewWeatherType == WEATHER_EXTRA_SUNNY) && !CGame::IsInInterior() && !CCutsceneMgr::IsRunning())
+ AddBeastie();
+}
+
+void CWeather::AddHeatHaze()
+{
+ /* TODO(MIAMI) */
+}
+
+void CWeather::AddBeastie()
+{
+ /* TODO(MIAMI) */
}
void CWeather::ForceWeather(int16 weather)
@@ -510,23 +581,3 @@ void CWeather::RenderRainStreaks(void)
TempBufferVerticesStored = 0;
TempBufferIndicesStored = 0;
}
-
-void CWeather::StoreWeatherState()
-{
- Stored_StateStored = true;
- Stored_InterpolationValue = InterpolationValue;
- Stored_Rain = Rain;
- Stored_NewWeatherType = NewWeatherType;
- Stored_OldWeatherType = OldWeatherType;
-}
-
-void CWeather::RestoreWeatherState()
-{
-#ifdef FIX_BUGS // it's not used anyway though
- Stored_StateStored = false;
-#endif
- InterpolationValue = Stored_InterpolationValue;
- Rain = Stored_Rain;
- NewWeatherType = Stored_NewWeatherType;
- OldWeatherType = Stored_OldWeatherType;
-}
diff --git a/src/render/Weather.h b/src/render/Weather.h
index 9c670317..bd9b9603 100644
--- a/src/render/Weather.h
+++ b/src/render/Weather.h
@@ -1,21 +1,17 @@
enum {
- WEATHER_SUNNY,
+ WEATHER_RANDOM = -1,
+ WEATHER_SUNNY = 0,
WEATHER_CLOUDY,
WEATHER_RAINY,
- WEATHER_FOGGY
+ WEATHER_FOGGY,
+ WEATHER_EXTRA_SUNNY,
+ WEATHER_HURRICANE,
+ WEATHER_TOTAL
};
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;
@@ -30,6 +26,7 @@ public:
static uint32 WhenToPlayLightningSound;
static uint32 LightningDuration;
+ static float ExtraSunnyness;
static float Foggyness;
static float CloudCoverage;
static float Wind;
@@ -37,13 +34,11 @@ public:
static float InterpolationValue;
static float WetRoads;
static float Rainbow;
+ static float SunGlare;
+ static float WindClipped;
+ static float TrafficLightBrightness;
static bool bScriptsForceRain;
- static bool Stored_StateStored;
- static float Stored_InterpolationValue;
- static int16 Stored_OldWeatherType;
- static int16 Stored_NewWeatherType;
- static float Stored_Rain;
static void RenderRainStreaks(void);
static void Update(void);
@@ -52,9 +47,9 @@ public:
static void ReleaseWeather();
static void ForceWeather(int16);
static void ForceWeatherNow(int16);
- static void StoreWeatherState();
- static void RestoreWeatherState();
static void AddRain();
+ static void AddHeatHaze();
+ static void AddBeastie();
};
enum {
diff --git a/src/render/WindModifiers.cpp b/src/render/WindModifiers.cpp
new file mode 100644
index 00000000..d7405c7a
--- /dev/null
+++ b/src/render/WindModifiers.cpp
@@ -0,0 +1,8 @@
+#include "common.h"
+#include "WindModifiers.h"
+
+int32
+CWindModifiers::FindWindModifier(CVector pos, float *x, float *y)
+{
+ return 0;
+}
diff --git a/src/render/WindModifiers.h b/src/render/WindModifiers.h
new file mode 100644
index 00000000..b4024343
--- /dev/null
+++ b/src/render/WindModifiers.h
@@ -0,0 +1,7 @@
+#pragma once
+
+class CWindModifiers
+{
+public:
+ static int32 FindWindModifier(CVector pos, float *x, float *y);
+};