From f7ac85e4925f6133f359385b9efb35c8d9d63a5a Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Tue, 7 Apr 2020 23:43:19 +0300 Subject: [PATCH 1/8] weather stuff --- src/render/Timecycle.h | 1 + src/render/Weather.cpp | 471 ++++++++++++++++++++++++++++++++++++++++- src/render/Weather.h | 22 ++ 3 files changed, 488 insertions(+), 6 deletions(-) diff --git a/src/render/Timecycle.h b/src/render/Timecycle.h index 235d559c..f126dca6 100644 --- a/src/render/Timecycle.h +++ b/src/render/Timecycle.h @@ -136,6 +136,7 @@ public: static int GetFogRed(void) { return m_nCurrentFogColourRed; } static int GetFogGreen(void) { return m_nCurrentFogColourGreen; } static int GetFogBlue(void) { return m_nCurrentFogColourBlue; } + static int GetFogReduction(void) { return m_FogReduction; } static void Initialise(void); static void Update(void); diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp index c1988ab4..cb19f6cf 100644 --- a/src/render/Weather.cpp +++ b/src/render/Weather.cpp @@ -2,6 +2,22 @@ #include "patcher.h" #include "Weather.h" +#include "Camera.h" +#include "Clock.h" +#include "CutsceneMgr.h" +#include "DMAudio.h" +#include "General.h" +#include "Pad.h" +#include "Particle.h" +#include "RenderBuffer.h" +#include "Stats.h" +#include "Shadows.h" +#include "Timecycle.h" +#include "Timer.h" +#include "Vehicle.h" +#include "World.h" +#include "ZoneCull.h" + int32 &CWeather::SoundHandle = *(int32*)0x5FFBC4; int32 &CWeather::WeatherTypeInList = *(int32*)0x8F626C; @@ -32,13 +48,195 @@ int16 &CWeather::Stored_OldWeatherType = *(int16*)0x95CC68; int16 &CWeather::Stored_NewWeatherType = *(int16*)0x95CCAE; float &CWeather::Stored_Rain = *(float*)0x885B4C; -WRAPPER void CWeather::RenderRainStreaks(void) { EAXJMP(0x524550); } -WRAPPER void CWeather::Update(void) { EAXJMP(0x522C10); } -WRAPPER void CWeather::Init(void) { EAXJMP(0x522BA0); } +tRainStreak Streaks[NUM_RAIN_STREAKS]; -void CWeather::ReleaseWeather() +const int16 WeatherTypesList[] = { + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_CLOUDY, WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_RAINY, + WEATHER_CLOUDY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_CLOUDY, WEATHER_FOGGY, WEATHER_FOGGY, WEATHER_CLOUDY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_CLOUDY, WEATHER_CLOUDY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_CLOUDY, WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_RAINY, + WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_CLOUDY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_FOGGY, WEATHER_FOGGY, WEATHER_SUNNY, + WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_RAINY, WEATHER_CLOUDY, +}; + +const float Windiness[] = { + 0.0f, // WEATHER_SUNNY + 0.7f, // WEATHER_RAINY + 1.0f, // WEATHER_CLOUDY + 0.5f // WEATHER_FOGGY +}; + +#define MIN_TIME_BETWEEN_LIGHTNING_FLASH_CHANGES (50) + +#define RAIN_CHANGE_SPEED (0.003f) + +#define DROPLETS_LEFT_OFFSET (10.0f) +#define DROPLETS_RIGHT_OFFSET (10.0f) +#define DROPLETS_TOP_OFFSET (10.0f) +#define DROPLETS_BOTTOM_OFFSET (10.0f) + +#define STREAK_U (10.0f) +#define STREAK_V (18.0f) +#define LARGE_STREAK_COEFFICIENT (1.23f) +#define STREAK_MIN_DISTANCE (8.0f) +#define STREAK_MAX_DISTANCE (16.0f) + +#define STREAK_LIFETIME (4.0f) +#define STREAK_INTEROLATION_TIME (0.3f) + +void CWeather::Init(void) { - ForcedWeatherType = -1; + NewWeatherType = WEATHER_SUNNY; + bScriptsForceRain = false; + OldWeatherType = WEATHER_RAINY; + Stored_StateStored = false; + InterpolationValue = 0.0f; + WhenToPlayLightningSound = 0; + WeatherTypeInList = 0; + ForcedWeatherType = WEATHER_RANDOM; + SoundHandle = DMAudio.CreateEntity(AUDIOTYPE_WEATHER, (void*)1); + if (SoundHandle >= 0) + DMAudio.SetEntityStatus(SoundHandle, 1); +} + +void CWeather::Update(void) +{ + float fNewInterpolation = CClock::GetMinutes() / 60.0f; + if (fNewInterpolation < InterpolationValue) { + // new hour + OldWeatherType = NewWeatherType; + if (ForcedWeatherType >= 0) + NewWeatherType = ForcedWeatherType; + else { + WeatherTypeInList = (WeatherTypeInList + 1) % ARRAYSIZE(WeatherTypesList); + NewWeatherType = WeatherTypesList[WeatherTypeInList]; +#ifdef FIX_BUGS + } + if (NewWeatherType == WEATHER_RAINY) + CStats::mmRain += CGeneral::GetRandomNumber() & 7; +#else + if (NewWeatherType == WEATHER_RAINY) + CStats::mmRain += CGeneral::GetRandomNumber() & 7; + } +#endif + } + InterpolationValue = fNewInterpolation; + if (CPad::GetPad(1)->GetRightShockJustDown()) { + NewWeatherType = (NewWeatherType + 1) % WEATHER_TOTAL; + OldWeatherType = NewWeatherType; + } + + // Lightning + if (NewWeatherType != WEATHER_RAINY || OldWeatherType != WEATHER_RAINY) { + LightningFlash = false; + LightningBurst = false; + } + else{ + if (LightningBurst) { + if ((CGeneral::GetRandomNumber() & 255) >= 32) { + // 0.875 probability + if (CTimer::GetTimeInMilliseconds() - LightningFlashLastChange > MIN_TIME_BETWEEN_LIGHTNING_FLASH_CHANGES) { + bool bOldLightningFlash = LightningFlash; + LightningFlash = CGeneral::GetRandomTrueFalse(); + if (LightningFlash != bOldLightningFlash) + LightningFlashLastChange = CTimer::GetTimeInMilliseconds(); + } + } + else { + // 0.125 probability + LightningBurst = false; + LightningDuration = min(CTimer::GetFrameCounter() - LightningStart, 20); + LightningFlash = false; + WhenToPlayLightningSound = CTimer::GetTimeInMilliseconds() + 150 * (20 - LightningDuration); + } + } + else { + if (CGeneral::GetRandomNumber() >= 200) { + // lower probability on PC due to randomness bug + LightningFlash = false; + } + else { + LightningBurst = true; + LightningStart = CTimer::GetFrameCounter(); + LightningFlashLastChange = CTimer::GetTimeInMilliseconds(); + LightningFlash = true; + } + } + } + if (WhenToPlayLightningSound && CTimer::GetTimeInMilliseconds() > WhenToPlayLightningSound) { + DMAudio.PlayOneShot(SoundHandle, SOUND_LIGHTNING, LightningDuration); + CPad::GetPad(0)->StartShake(40 * LightningDuration + 100, 2 * LightningDuration + 80); + WhenToPlayLightningSound = 0; + } + + // Wet roads + if (OldWeatherType == WEATHER_RAINY) { + if (NewWeatherType == WEATHER_RAINY) + WetRoads = 1.0f; + else + WetRoads = 1.0f - InterpolationValue; + } + else { + if (NewWeatherType == WEATHER_RAINY) + WetRoads = InterpolationValue; + else + WetRoads = 0.0f; + } + + // Rain + float fNewRain; + if (NewWeatherType == WEATHER_RAINY) { + // if raining for >1 hour, values: 0, 0.33, 0.66, 0.99, switching every ~16.5s + fNewRain = ((uint16)CTimer::GetTimeInMilliseconds() >> 14) * 0.33f; + if (OldWeatherType != WEATHER_RAINY) { + if (InterpolationValue < 0.4f) + // if rain has just started (<24 minutes), always 0.5 + fNewRain = 0.5f; + else + // if rain is ongoing for >24 minutes, values: 0.25, 0.5, 0.75, 1.0, switching every ~16.5s + fNewRain = 0.25f + ((uint16)CTimer::GetTimeInMilliseconds() >> 14) * 0.25f; + } + } + else + fNewRain = 0.0f; + if (Rain != fNewRain) { // ok to use comparasion + if (Rain > fNewRain) + Rain = min(fNewRain, Rain + RAIN_CHANGE_SPEED * CTimer::GetTimeStep()); + else + Rain = max(fNewRain, Rain - RAIN_CHANGE_SPEED * CTimer::GetTimeStep()); + } + + // Clouds + if (OldWeatherType != WEATHER_SUNNY) + CloudCoverage = 1.0f - InterpolationValue; + else + CloudCoverage = 0.0f; + if (NewWeatherType != WEATHER_SUNNY) + CloudCoverage += InterpolationValue; + + // Fog + if (OldWeatherType == WEATHER_FOGGY) + Foggyness = 1.0f - InterpolationValue; + else + Foggyness = 0.0f; + if (NewWeatherType == WEATHER_FOGGY) + Foggyness += InterpolationValue; + if (OldWeatherType == WEATHER_RAINY && NewWeatherType == WEATHER_SUNNY && InterpolationValue < 0.5f && CClock::GetHours() > 6 && CClock::GetHours() < 21) + Rainbow = 1.0f - 4.0f * Abs(InterpolationValue - 0.25f) / 4.0f; + else + Rainbow = 0.0f; + Wind = InterpolationValue * Windiness[NewWeatherType] + (1.0f - InterpolationValue) * Windiness[OldWeatherType]; + AddRain(); } void CWeather::ForceWeather(int16 weather) @@ -53,6 +251,267 @@ void CWeather::ForceWeatherNow(int16 weather) ForcedWeatherType = weather; } +void CWeather::ReleaseWeather() +{ + ForcedWeatherType = -1; +} + +void CWeather::AddRain() +{ + if (CCullZones::CamNoRain() || CCullZones::PlayerNoRain()) + return; + if (TheCamera.GetLookingLRBFirstPerson()) { + CVehicle* pVehicle = FindPlayerVehicle(); + if (pVehicle && pVehicle->CarHasRoof()) { + CParticle::RemovePSystem(PARTICLE_RAINDROP_2D); + return; + } + } + if (Rain <= 0.1f) + return; + static RwRGBA colour; + float screen_width = RsGlobal.width; + float screen_height = RsGlobal.height; + int cur_frame = (int)(3 * Rain) & 3; + int num_drops = (int)(2 * Rain) + 2; + static int STATIC_RAIN_ANGLE = -45; + static int count = 1500; + static int add_angle = 1; + if (--count == 0) { + count = 1; + if (add_angle) { + STATIC_RAIN_ANGLE += 12; + if (STATIC_RAIN_ANGLE > 45) { + count = 1500; + add_angle = !add_angle; + } + } + else { + STATIC_RAIN_ANGLE -= 12; + if (STATIC_RAIN_ANGLE < -45) { + count = 1500; + add_angle = !add_angle; + } + } + } + float rain_angle = DEGTORAD(STATIC_RAIN_ANGLE + ((STATIC_RAIN_ANGLE < 0) ? 360 : 0)); + float sin_angle = Sin(rain_angle); + float cos_angle = Cos(rain_angle); + float base_x = 0.0f * sin_angle - 1.0f * cos_angle; + float base_y = 1.0f * sin_angle + 0.0f * cos_angle; + CVector xpos(0.0f, 0.0f, 0.0f); + for (int i = 0; i < 2 * num_drops; i++) { + CVector dir; + dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f); + dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f); + dir.z = 0; + CParticle::AddParticle(PARTICLE_RAINDROP_2D, xpos, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f), + colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(0, 20) - 10, cur_frame); + xpos.x += screen_width / (2 * num_drops); + xpos.x += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f); + } + CVector ypos(0.0f, 0.0f, 0.0f); + for (int i = 0; i < num_drops; i++) { + CVector dir; + dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f); + dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f); + dir.z = 0; + CParticle::AddParticle(PARTICLE_RAINDROP_2D, ypos, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f), + colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(0, 20) - 10, cur_frame); + ypos.y += screen_width / num_drops; + ypos.y += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f); + } + CVector ypos2(0.0f, 0.0f, 0.0f); + for (int i = 0; i < num_drops; i++) { + CVector dir; + dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f); + dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f); + dir.z = 0; + CParticle::AddParticle(PARTICLE_RAINDROP_2D, ypos2, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f), + colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(0, 20) - 10, cur_frame); + ypos2.y += screen_width / num_drops; + ypos2.y += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f); + } + for (int i = 0; i < num_drops; i++) { + CVector pos; + pos.x = CGeneral::GetRandomNumberInRange(DROPLETS_LEFT_OFFSET, screen_width - DROPLETS_RIGHT_OFFSET); + pos.y = CGeneral::GetRandomNumberInRange(DROPLETS_TOP_OFFSET, screen_height - DROPLETS_TOP_OFFSET); + pos.z = 0.0f; + CParticle::AddParticle(PARTICLE_RAINDROP_2D, pos, CVector(0.0f, 0.0f, 0.0f), nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f), + colour, CGeneral::GetRandomNumberInRange(0.0f, 20.0f) - 10, 360 - rain_angle + CGeneral::GetRandomNumberInRange(0.0f, 60.0f) - 30, cur_frame, 0); + } + int num_splash_attempts = (int)(3 * Rain) + 1; + int num_splashes = (int)(3 * Rain) + 4; + CVector splash_points[4]; + splash_points[0] = CVector(-RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) * + RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude(); + splash_points[1] = CVector(RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) * + RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude(); + splash_points[2] = 4.0f * CVector(-RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) * + RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude(); + splash_points[3] = 4.0f * CVector(RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) * + RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude(); + RwV3dTransformPoints((RwV3d*)splash_points, (RwV3d*)splash_points, 4, RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera))); + CVector fp = (splash_points[0] + splash_points[1] + splash_points[2] + splash_points[3]) / 4; + for (int i = 0; i < num_splash_attempts; i++) { + CColPoint point; + CEntity* entity; + if (CWorld::ProcessVerticalLine(fp + CVector(CGeneral::GetRandomNumberInRange(-7.0f, 7.0f), CGeneral::GetRandomNumberInRange(-7.0f, 7.0f), 0.0f) + CVector(0.0f, 0.0f, 40.0f), -40.0f, + point, entity, true, false, false, false, true, false, nil)) { + for (int j = 0; j < num_splashes; j++) + CParticle::AddParticle((CGeneral::GetRandomTrueFalse() ? PARTICLE_RAIN_SPLASH : PARTICLE_RAIN_SPLASHUP), + CVector(fp.x + CGeneral::GetRandomNumberInRange(-2.0f, 2.0f), fp.y + CGeneral::GetRandomNumberInRange(-2.0f, 2.0f), point.point.z + 1.0f), + CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, colour); + } + } +} + +WRAPPER void RenderOneRainStreak(CVector pos, CVector unused, int intensity, bool scale, float distance) { EAXJMP(0x5240E0); } +/* +void RenderOneRainStreak(CVector pos, CVector unused, int intensity, bool scale, float distance) +{ + static float RandomTex; + static float RandomTexX; + static float RandomTexY; + TempBufferRenderIndexList[TempBufferIndicesStored + 0] = TempBufferVerticesStored + 0; + TempBufferRenderIndexList[TempBufferIndicesStored + 1] = TempBufferVerticesStored + 2; + TempBufferRenderIndexList[TempBufferIndicesStored + 2] = TempBufferVerticesStored + 1; + TempBufferRenderIndexList[TempBufferIndicesStored + 3] = TempBufferVerticesStored + 0; + TempBufferRenderIndexList[TempBufferIndicesStored + 4] = TempBufferVerticesStored + 3; + TempBufferRenderIndexList[TempBufferIndicesStored + 5] = TempBufferVerticesStored + 2; + TempBufferRenderIndexList[TempBufferIndicesStored + 6] = TempBufferVerticesStored + 1; + TempBufferRenderIndexList[TempBufferIndicesStored + 7] = TempBufferVerticesStored + 2; + TempBufferRenderIndexList[TempBufferIndicesStored + 8] = TempBufferVerticesStored + 4; + TempBufferRenderIndexList[TempBufferIndicesStored + 9] = TempBufferVerticesStored + 2; + TempBufferRenderIndexList[TempBufferIndicesStored + 10] = TempBufferVerticesStored + 3; + TempBufferRenderIndexList[TempBufferIndicesStored + 11] = TempBufferVerticesStored + 4; + RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 0], 0, 0, 0, 0); + RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 0], pos.x + TheCamera.GetUp().x, pos.y + TheCamera.GetUp().y, pos.z + TheCamera.GetUp().z); + RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 1], 0, 0, 0, 0); + RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 1], pos.x - TheCamera.GetUp().x, pos.y - TheCamera.GetUp().y, pos.z - TheCamera.GetUp().z); + RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 2], 200 * intensity / 256, 200 * intensity / 256, intensity, 255); + RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 2], pos.x, pos.y, pos.z); + RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 3], 0, 0, 0, 0); + RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 3], pos.x + 9.0f * TheCamera.GetRight().x, pos.y + 9.0f * TheCamera.GetRight().y, pos.z + 9.0f * TheCamera.GetUp().z); + RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 4], 0, 0, 0, 0); + RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 4], pos.x - 11.0f * TheCamera.GetRight().x, pos.y - 11.0f * TheCamera.GetRight().y, pos.z - 11.0f * TheCamera.GetUp().z); + float u = STREAK_U; + float v = STREAK_V; + if (scale) { + u *= LARGE_STREAK_COEFFICIENT; + v *= LARGE_STREAK_COEFFICIENT; + } + float distance_coefficient; + if (distance < STREAK_MIN_DISTANCE) + distance_coefficient = 1.0f; + else if (distance > STREAK_MAX_DISTANCE) + distance_coefficient = 0.5f; + else + distance_coefficient = 1.0f - 0.5f * (distance - STREAK_MIN_DISTANCE) / (STREAK_MAX_DISTANCE - STREAK_MIN_DISTANCE); + u *= distance_coefficient; + v *= distance_coefficient; + if (!CTimer::GetIsPaused()) { + RandomTex = ((CGeneral::GetRandomNumber() & 255) - 128) * 0.01f; + RandomTexX = (CGeneral::GetRandomNumber() & 127) * 0.01f; + RandomTexY = (CGeneral::GetRandomNumber() & 127) * 0.01f; + } + RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 0], 0.5f * u - RandomTex + RandomTexX); + RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 0], -v * 0.5f + RandomTexY); + RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 1], RandomTexX); + RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 1], RandomTexY); + RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 2], 0.5f * u + RandomTexX); + RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 2], RandomTexY); + RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 3], u + RandomTexX); + RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 3], RandomTexY); + RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 4], 0.5f * u + RandomTex + RandomTexX); + RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 5], 0.5f * v - RandomTexY); + TempBufferIndicesStored += 12; + TempBufferVerticesStored += 5; +} +*/ + + +WRAPPER void CWeather::RenderRainStreaks(void) { EAXJMP(0x524550); } +/* +void CWeather::RenderRainStreaks(void) +{ + if (CTimer::GetIsCodePaused()) + return; + int default_visibility = (64.0f - CTimeCycle::GetFogReduction()) / 64.0f * int(255 * Rain); + if (!default_visibility) + return; + TempBufferIndicesStored = 0; + TempBufferVerticesStored = 0; + for (int i = 0; i < NUM_RAIN_STREAKS; i++) { + if (Streaks[i].timer) { + float secondsElapsed = (CTimer::GetTimeInMilliseconds() - Streaks[i].timer) / 1024.0f; + if (secondsElapsed > STREAK_LIFETIME) + Streaks[i].timer = 0; + else{ + int intensity; + if (secondsElapsed < STREAK_INTEROLATION_TIME) { + intensity = default_visibility * 0.5f * secondsElapsed / STREAK_INTEROLATION_TIME; + } + else if (secondsElapsed > STREAK_LIFETIME - STREAK_INTEROLATION_TIME) { + intensity = (STREAK_LIFETIME - secondsElapsed) * default_visibility / STREAK_INTEROLATION_TIME; + } + else { + intensity = default_visibility; + } + CVector dir = Streaks[i].direction; + dir.Normalise(); + CVector pos = Streaks[i].direction + secondsElapsed * Streaks[i].direction; + RenderOneRainStreak(pos, dir, intensity, false, (pos - TheCamera.GetPosition()).Magnitude()); +#ifndef FIX_BUGS // remove useless code + if (secondsElapsed > 1.0f && secondsElapsed < STREAK_LIFETIME - 1.0f) { + CGeneral::GetRandomNumber(), CGeneral::GetRandomNumber(); + } +#endif + } + } + else if ((CGeneral::GetRandomNumber() & 0xF00) == 0){ + // 1/16 probability + Streaks[i].direction = CVector(4.0f, 4.0f, -4.0f); + Streaks[i].position = 6.0f * TheCamera.GetForward() + TheCamera.GetPosition(); + Streaks[i].position += CVector(-1.8f * Streaks[i].direction.x, -1.8f * Streaks[i].direction.y, 8.0f); + if (!CCutsceneMgr::IsCutsceneProcessing()) { + Streaks[i].position.x += 2.0f * FindPlayerSpeed().x * 60.0f; + Streaks[i].position.y += 2.0f * FindPlayerSpeed().y * 60.0f; + } + else + Streaks[i].position += (TheCamera.GetPosition() - TheCamera.m_RealPreviousCameraPosition) * 20.0f; + Streaks[i].position.x += ((CGeneral::GetRandomNumber() & 255) - 128) * 0.08f; + Streaks[i].position.y += ((CGeneral::GetRandomNumber() & 255) - 128) * 0.08f; + Streaks[i].timer = CTimer::GetTimeInMilliseconds(); + } + } + if (TempBufferIndicesStored) + { + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, 0); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)1); + RwRenderStateSet(rwRENDERSTATEFOGENABLE, 0); + RwRenderStateSet(rwRENDERSTATEFOGTYPE, (void*)1); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)2); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)2); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)1); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRainDropTex[3]->raster); + if (RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, 0, 1)) + { + RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored); + RwIm3DEnd(); + } + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)1); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)1); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)5); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)6); + RwRenderStateSet(rwRENDERSTATEFOGENABLE, 0); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, 0); + } + TempBufferVerticesStored = 0; + TempBufferIndicesStored = 0; +} +*/ + void CWeather::StoreWeatherState() { Stored_StateStored = true; @@ -71,4 +530,4 @@ void CWeather::RestoreWeatherState() Rain = Stored_Rain; NewWeatherType = Stored_NewWeatherType; OldWeatherType = Stored_OldWeatherType; -} \ No newline at end of file +} diff --git a/src/render/Weather.h b/src/render/Weather.h index 63def9b9..9e4ea378 100644 --- a/src/render/Weather.h +++ b/src/render/Weather.h @@ -8,6 +8,14 @@ enum { class CWeather { public: + enum { + WEATHER_RANDOM = -1, + WEATHER_SUNNY = 0, + WEATHER_CLOUDY = 1, + WEATHER_RAINY = 2, + WEATHER_FOGGY = 3, + WEATHER_TOTAL = 4 + }; static int32 &SoundHandle; static int32 &WeatherTypeInList; @@ -46,4 +54,18 @@ public: static void ForceWeatherNow(int16); static void StoreWeatherState(); static void RestoreWeatherState(); + static void AddRain(); }; + +enum { + NUM_RAIN_STREAKS = 35 +}; + +struct tRainStreak +{ + CVector position; + CVector direction; + uint32 timer; +}; + +extern RwTexture* (&gpRainDropTex)[4]; \ No newline at end of file From e556ffd3f650d6dea89b79abc6cdb3400cb6eb50 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Wed, 8 Apr 2020 01:52:08 +0300 Subject: [PATCH 2/8] fixes --- src/core/re3.cpp | 2 +- src/render/Weather.cpp | 42 +++++++++++++++++------------------------- 2 files changed, 18 insertions(+), 26 deletions(-) diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 6d4ff252..6eae8685 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -458,7 +458,7 @@ void re3_debug(const char *format, ...) vsprintf_s(re3_buff, re3_buffsize, format, va); va_end(va); -// printf("%s", re3_buff); + printf("%s", re3_buff); CDebug::DebugAddText(re3_buff); } diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp index cb19f6cf..73807d5c 100644 --- a/src/render/Weather.cpp +++ b/src/render/Weather.cpp @@ -211,9 +211,9 @@ void CWeather::Update(void) fNewRain = 0.0f; if (Rain != fNewRain) { // ok to use comparasion if (Rain > fNewRain) - Rain = min(fNewRain, Rain + RAIN_CHANGE_SPEED * CTimer::GetTimeStep()); + Rain = max(fNewRain, Rain + RAIN_CHANGE_SPEED * CTimer::GetTimeStep()); else - Rain = max(fNewRain, Rain - RAIN_CHANGE_SPEED * CTimer::GetTimeStep()); + Rain = min(fNewRain, Rain - RAIN_CHANGE_SPEED * CTimer::GetTimeStep()); } // Clouds @@ -356,18 +356,16 @@ void CWeather::AddRain() for (int i = 0; i < num_splash_attempts; i++) { CColPoint point; CEntity* entity; - if (CWorld::ProcessVerticalLine(fp + CVector(CGeneral::GetRandomNumberInRange(-7.0f, 7.0f), CGeneral::GetRandomNumberInRange(-7.0f, 7.0f), 0.0f) + CVector(0.0f, 0.0f, 40.0f), -40.0f, - point, entity, true, false, false, false, true, false, nil)) { + CVector np = fp + CVector(CGeneral::GetRandomNumberInRange(-7.0f, 7.0f), CGeneral::GetRandomNumberInRange(-7.0f, 7.0f), 0.0f); + if (CWorld::ProcessVerticalLine(np + CVector(0.0f, 0.0f, 40.0f), -40.0f, point, entity, true, false, false, false, true, false, nil)) { for (int j = 0; j < num_splashes; j++) CParticle::AddParticle((CGeneral::GetRandomTrueFalse() ? PARTICLE_RAIN_SPLASH : PARTICLE_RAIN_SPLASHUP), - CVector(fp.x + CGeneral::GetRandomNumberInRange(-2.0f, 2.0f), fp.y + CGeneral::GetRandomNumberInRange(-2.0f, 2.0f), point.point.z + 1.0f), + CVector(np.x + CGeneral::GetRandomNumberInRange(-2.0f, 2.0f), np.y + CGeneral::GetRandomNumberInRange(-2.0f, 2.0f), point.point.z + 0.1f), CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, colour); } } } -WRAPPER void RenderOneRainStreak(CVector pos, CVector unused, int intensity, bool scale, float distance) { EAXJMP(0x5240E0); } -/* void RenderOneRainStreak(CVector pos, CVector unused, int intensity, bool scale, float distance) { static float RandomTex; @@ -386,15 +384,15 @@ void RenderOneRainStreak(CVector pos, CVector unused, int intensity, bool scale, TempBufferRenderIndexList[TempBufferIndicesStored + 10] = TempBufferVerticesStored + 3; TempBufferRenderIndexList[TempBufferIndicesStored + 11] = TempBufferVerticesStored + 4; RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 0], 0, 0, 0, 0); - RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 0], pos.x + TheCamera.GetUp().x, pos.y + TheCamera.GetUp().y, pos.z + TheCamera.GetUp().z); + RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 0], pos.x + 11.0f * TheCamera.GetUp().x, pos.y + 11.0f * TheCamera.GetUp().y, pos.z + 11.0f * TheCamera.GetUp().z); RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 1], 0, 0, 0, 0); - RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 1], pos.x - TheCamera.GetUp().x, pos.y - TheCamera.GetUp().y, pos.z - TheCamera.GetUp().z); + RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 1], pos.x - 9.0f * TheCamera.GetRight().x, pos.y - 9.0f * TheCamera.GetRight().y, pos.z - 9.0f * TheCamera.GetUp().z); RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 2], 200 * intensity / 256, 200 * intensity / 256, intensity, 255); RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 2], pos.x, pos.y, pos.z); RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 3], 0, 0, 0, 0); RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 3], pos.x + 9.0f * TheCamera.GetRight().x, pos.y + 9.0f * TheCamera.GetRight().y, pos.z + 9.0f * TheCamera.GetUp().z); - RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 4], 0, 0, 0, 0); - RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 4], pos.x - 11.0f * TheCamera.GetRight().x, pos.y - 11.0f * TheCamera.GetRight().y, pos.z - 11.0f * TheCamera.GetUp().z); + RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 4], 0, 0, 0, 0); + RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 4], pos.x - 11.0f * TheCamera.GetUp().x, pos.y - 11.0f * TheCamera.GetUp().y, pos.z - 11.0f * TheCamera.GetUp().z); float u = STREAK_U; float v = STREAK_V; if (scale) { @@ -424,21 +422,17 @@ void RenderOneRainStreak(CVector pos, CVector unused, int intensity, bool scale, RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 3], u + RandomTexX); RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 3], RandomTexY); RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 4], 0.5f * u + RandomTex + RandomTexX); - RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 5], 0.5f * v - RandomTexY); + RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 5], 0.5f * v + RandomTexY); TempBufferIndicesStored += 12; TempBufferVerticesStored += 5; } -*/ - -WRAPPER void CWeather::RenderRainStreaks(void) { EAXJMP(0x524550); } -/* void CWeather::RenderRainStreaks(void) { if (CTimer::GetIsCodePaused()) return; int default_visibility = (64.0f - CTimeCycle::GetFogReduction()) / 64.0f * int(255 * Rain); - if (!default_visibility) + if (default_visibility == 0) return; TempBufferIndicesStored = 0; TempBufferVerticesStored = 0; @@ -452,15 +446,16 @@ void CWeather::RenderRainStreaks(void) if (secondsElapsed < STREAK_INTEROLATION_TIME) { intensity = default_visibility * 0.5f * secondsElapsed / STREAK_INTEROLATION_TIME; } - else if (secondsElapsed > STREAK_LIFETIME - STREAK_INTEROLATION_TIME) { + else if (secondsElapsed > (STREAK_LIFETIME - STREAK_INTEROLATION_TIME)) { intensity = (STREAK_LIFETIME - secondsElapsed) * default_visibility / STREAK_INTEROLATION_TIME; } else { intensity = default_visibility; } + debug("intensity: %d\n", intensity); CVector dir = Streaks[i].direction; dir.Normalise(); - CVector pos = Streaks[i].direction + secondsElapsed * Streaks[i].direction; + CVector pos = Streaks[i].position + secondsElapsed * Streaks[i].direction; RenderOneRainStreak(pos, dir, intensity, false, (pos - TheCamera.GetPosition()).Magnitude()); #ifndef FIX_BUGS // remove useless code if (secondsElapsed > 1.0f && secondsElapsed < STREAK_LIFETIME - 1.0f) { @@ -472,8 +467,7 @@ void CWeather::RenderRainStreaks(void) else if ((CGeneral::GetRandomNumber() & 0xF00) == 0){ // 1/16 probability Streaks[i].direction = CVector(4.0f, 4.0f, -4.0f); - Streaks[i].position = 6.0f * TheCamera.GetForward() + TheCamera.GetPosition(); - Streaks[i].position += CVector(-1.8f * Streaks[i].direction.x, -1.8f * Streaks[i].direction.y, 8.0f); + Streaks[i].position = 6.0f * TheCamera.GetForward() + TheCamera.GetPosition() + CVector(-1.8f * Streaks[i].direction.x, -1.8f * Streaks[i].direction.y, 8.0f); if (!CCutsceneMgr::IsCutsceneProcessing()) { Streaks[i].position.x += 2.0f * FindPlayerSpeed().x * 60.0f; Streaks[i].position.y += 2.0f * FindPlayerSpeed().y * 60.0f; @@ -485,8 +479,7 @@ void CWeather::RenderRainStreaks(void) Streaks[i].timer = CTimer::GetTimeInMilliseconds(); } } - if (TempBufferIndicesStored) - { + if (TempBufferIndicesStored){ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, 0); RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)1); RwRenderStateSet(rwRENDERSTATEFOGENABLE, 0); @@ -495,7 +488,7 @@ void CWeather::RenderRainStreaks(void) RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)2); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)1); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRainDropTex[3]->raster); - if (RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, 0, 1)) + if (RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, 1)) { RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored); RwIm3DEnd(); @@ -510,7 +503,6 @@ void CWeather::RenderRainStreaks(void) TempBufferVerticesStored = 0; TempBufferIndicesStored = 0; } -*/ void CWeather::StoreWeatherState() { From 24fc11a13766a81f1c8c92ff789a6e866eb6404d Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Wed, 8 Apr 2020 14:25:23 +0300 Subject: [PATCH 3/8] rain fix --- src/render/Weather.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp index 73807d5c..5e19987a 100644 --- a/src/render/Weather.cpp +++ b/src/render/Weather.cpp @@ -210,10 +210,10 @@ void CWeather::Update(void) else fNewRain = 0.0f; if (Rain != fNewRain) { // ok to use comparasion - if (Rain > fNewRain) - Rain = max(fNewRain, Rain + RAIN_CHANGE_SPEED * CTimer::GetTimeStep()); + if (Rain < fNewRain) + Rain = min(fNewRain, Rain + RAIN_CHANGE_SPEED * CTimer::GetTimeStep()); else - Rain = min(fNewRain, Rain - RAIN_CHANGE_SPEED * CTimer::GetTimeStep()); + Rain = max(fNewRain, Rain - RAIN_CHANGE_SPEED * CTimer::GetTimeStep()); } // Clouds @@ -431,8 +431,8 @@ void CWeather::RenderRainStreaks(void) { if (CTimer::GetIsCodePaused()) return; - int default_visibility = (64.0f - CTimeCycle::GetFogReduction()) / 64.0f * int(255 * Rain); - if (default_visibility == 0) + int base_intensity = (64.0f - CTimeCycle::GetFogReduction()) / 64.0f * int(255 * Rain); + if (base_intensity == 0) return; TempBufferIndicesStored = 0; TempBufferVerticesStored = 0; @@ -444,13 +444,13 @@ void CWeather::RenderRainStreaks(void) else{ int intensity; if (secondsElapsed < STREAK_INTEROLATION_TIME) { - intensity = default_visibility * 0.5f * secondsElapsed / STREAK_INTEROLATION_TIME; + intensity = base_intensity * 0.5f * secondsElapsed / STREAK_INTEROLATION_TIME; } else if (secondsElapsed > (STREAK_LIFETIME - STREAK_INTEROLATION_TIME)) { - intensity = (STREAK_LIFETIME - secondsElapsed) * default_visibility / STREAK_INTEROLATION_TIME; + intensity = (STREAK_LIFETIME - secondsElapsed) * 0.5f * base_intensity / STREAK_INTEROLATION_TIME; } else { - intensity = default_visibility; + intensity = base_intensity * 0.5f; } debug("intensity: %d\n", intensity); CVector dir = Streaks[i].direction; From b3571706d1cd89aed852ceecf57b130dff0343e0 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Wed, 8 Apr 2020 20:30:45 +0300 Subject: [PATCH 4/8] fix --- src/render/Weather.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp index 5e19987a..0970b94b 100644 --- a/src/render/Weather.cpp +++ b/src/render/Weather.cpp @@ -111,7 +111,7 @@ void CWeather::Init(void) void CWeather::Update(void) { - float fNewInterpolation = CClock::GetMinutes() / 60.0f; + float fNewInterpolation = CClock::GetMinutes() * 1.0f / 60; if (fNewInterpolation < InterpolationValue) { // new hour OldWeatherType = NewWeatherType; From cf36e09d391eb4d25d84c834579be1fd33c85a94 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Wed, 8 Apr 2020 21:18:19 +0300 Subject: [PATCH 5/8] final fixes --- src/render/Weather.cpp | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp index 0970b94b..34caf1bd 100644 --- a/src/render/Weather.cpp +++ b/src/render/Weather.cpp @@ -91,9 +91,17 @@ const float Windiness[] = { #define STREAK_MIN_DISTANCE (8.0f) #define STREAK_MAX_DISTANCE (16.0f) +#define SPLASH_CHECK_RADIUS (7.0f) +#define SPLASH_OFFSET_RADIUS (2.0f) + #define STREAK_LIFETIME (4.0f) #define STREAK_INTEROLATION_TIME (0.3f) +#define RAIN_COLOUR_R (200) +#define RAIN_COLOUR_G (200) +#define RAIN_COLOUR_B (256) +#define RAIN_ALPHA (255) + void CWeather::Init(void) { NewWeatherType = WEATHER_SUNNY; @@ -356,11 +364,14 @@ void CWeather::AddRain() for (int i = 0; i < num_splash_attempts; i++) { CColPoint point; CEntity* entity; - CVector np = fp + CVector(CGeneral::GetRandomNumberInRange(-7.0f, 7.0f), CGeneral::GetRandomNumberInRange(-7.0f, 7.0f), 0.0f); + CVector np = fp + CVector(CGeneral::GetRandomNumberInRange(-SPLASH_CHECK_RADIUS, SPLASH_CHECK_RADIUS), CGeneral::GetRandomNumberInRange(-SPLASH_CHECK_RADIUS, SPLASH_CHECK_RADIUS), 0.0f); if (CWorld::ProcessVerticalLine(np + CVector(0.0f, 0.0f, 40.0f), -40.0f, point, entity, true, false, false, false, true, false, nil)) { for (int j = 0; j < num_splashes; j++) CParticle::AddParticle((CGeneral::GetRandomTrueFalse() ? PARTICLE_RAIN_SPLASH : PARTICLE_RAIN_SPLASHUP), - CVector(np.x + CGeneral::GetRandomNumberInRange(-2.0f, 2.0f), np.y + CGeneral::GetRandomNumberInRange(-2.0f, 2.0f), point.point.z + 0.1f), + CVector( + np.x + CGeneral::GetRandomNumberInRange(-SPLASH_OFFSET_RADIUS, SPLASH_OFFSET_RADIUS), + np.y + CGeneral::GetRandomNumberInRange(-SPLASH_OFFSET_RADIUS, SPLASH_OFFSET_RADIUS), + point.point.z + 0.1f), CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, colour); } } @@ -387,7 +398,7 @@ void RenderOneRainStreak(CVector pos, CVector unused, int intensity, bool scale, RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 0], pos.x + 11.0f * TheCamera.GetUp().x, pos.y + 11.0f * TheCamera.GetUp().y, pos.z + 11.0f * TheCamera.GetUp().z); RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 1], 0, 0, 0, 0); RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 1], pos.x - 9.0f * TheCamera.GetRight().x, pos.y - 9.0f * TheCamera.GetRight().y, pos.z - 9.0f * TheCamera.GetUp().z); - RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 2], 200 * intensity / 256, 200 * intensity / 256, intensity, 255); + RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 2], RAIN_COLOUR_R * intensity / 256, RAIN_COLOUR_G * intensity / 256, RAIN_COLOUR_B * intensity / 256, RAIN_ALPHA); RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 2], pos.x, pos.y, pos.z); RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 3], 0, 0, 0, 0); RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 3], pos.x + 9.0f * TheCamera.GetRight().x, pos.y + 9.0f * TheCamera.GetRight().y, pos.z + 9.0f * TheCamera.GetUp().z); @@ -443,16 +454,12 @@ void CWeather::RenderRainStreaks(void) Streaks[i].timer = 0; else{ int intensity; - if (secondsElapsed < STREAK_INTEROLATION_TIME) { + if (secondsElapsed < STREAK_INTEROLATION_TIME) intensity = base_intensity * 0.5f * secondsElapsed / STREAK_INTEROLATION_TIME; - } - else if (secondsElapsed > (STREAK_LIFETIME - STREAK_INTEROLATION_TIME)) { + else if (secondsElapsed > (STREAK_LIFETIME - STREAK_INTEROLATION_TIME)) intensity = (STREAK_LIFETIME - secondsElapsed) * 0.5f * base_intensity / STREAK_INTEROLATION_TIME; - } - else { + else intensity = base_intensity * 0.5f; - } - debug("intensity: %d\n", intensity); CVector dir = Streaks[i].direction; dir.Normalise(); CVector pos = Streaks[i].position + secondsElapsed * Streaks[i].direction; From ebba8519d97fb0920d87f5cf7ad3c99332736456 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Wed, 8 Apr 2020 21:40:02 +0300 Subject: [PATCH 6/8] review fixes --- src/render/Weather.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp index 34caf1bd..712e70bf 100644 --- a/src/render/Weather.cpp +++ b/src/render/Weather.cpp @@ -305,8 +305,8 @@ void CWeather::AddRain() float rain_angle = DEGTORAD(STATIC_RAIN_ANGLE + ((STATIC_RAIN_ANGLE < 0) ? 360 : 0)); float sin_angle = Sin(rain_angle); float cos_angle = Cos(rain_angle); - float base_x = 0.0f * sin_angle - 1.0f * cos_angle; - float base_y = 1.0f * sin_angle + 0.0f * cos_angle; + float base_x = 0.0f * cos_angle - 1.0f * sin_angle; + float base_y = 1.0f * cos_angle + 0.0f * sin_angle; CVector xpos(0.0f, 0.0f, 0.0f); for (int i = 0; i < 2 * num_drops; i++) { CVector dir; @@ -487,25 +487,25 @@ void CWeather::RenderRainStreaks(void) } } if (TempBufferIndicesStored){ - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, 0); - RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)1); - RwRenderStateSet(rwRENDERSTATEFOGENABLE, 0); - RwRenderStateSet(rwRENDERSTATEFOGTYPE, (void*)1); - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)2); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)2); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)1); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEFOGTYPE, (void*)rwFOGTYPELINEAR); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRainDropTex[3]->raster); if (RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, 1)) { RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored); RwIm3DEnd(); } - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)1); - RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)1); - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)5); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)6); - RwRenderStateSet(rwRENDERSTATEFOGENABLE, 0); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, 0); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); } TempBufferVerticesStored = 0; TempBufferIndicesStored = 0; From b9a20da7d85d06d2b061736120d2713ef6fb92f0 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Wed, 8 Apr 2020 21:47:58 +0300 Subject: [PATCH 7/8] review fix --- src/render/Weather.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp index 712e70bf..d3be7fcf 100644 --- a/src/render/Weather.cpp +++ b/src/render/Weather.cpp @@ -494,7 +494,7 @@ void CWeather::RenderRainStreaks(void) RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRainDropTex[3]->raster); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRainDropTex[3])); if (RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, 1)) { RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored); From d5f34e425ef1b1de09cef7872b6a61bdbc6db06c Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Wed, 8 Apr 2020 21:56:33 +0300 Subject: [PATCH 8/8] fixed random number retrieval --- src/render/Weather.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp index d3be7fcf..d132ffdb 100644 --- a/src/render/Weather.cpp +++ b/src/render/Weather.cpp @@ -314,7 +314,7 @@ void CWeather::AddRain() dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f); dir.z = 0; CParticle::AddParticle(PARTICLE_RAINDROP_2D, xpos, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f), - colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(0, 20) - 10, cur_frame); + colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame); xpos.x += screen_width / (2 * num_drops); xpos.x += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f); } @@ -325,7 +325,7 @@ void CWeather::AddRain() dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f); dir.z = 0; CParticle::AddParticle(PARTICLE_RAINDROP_2D, ypos, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f), - colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(0, 20) - 10, cur_frame); + colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame); ypos.y += screen_width / num_drops; ypos.y += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f); } @@ -336,7 +336,7 @@ void CWeather::AddRain() dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f); dir.z = 0; CParticle::AddParticle(PARTICLE_RAINDROP_2D, ypos2, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f), - colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(0, 20) - 10, cur_frame); + colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame); ypos2.y += screen_width / num_drops; ypos2.y += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f); } @@ -346,7 +346,7 @@ void CWeather::AddRain() pos.y = CGeneral::GetRandomNumberInRange(DROPLETS_TOP_OFFSET, screen_height - DROPLETS_TOP_OFFSET); pos.z = 0.0f; CParticle::AddParticle(PARTICLE_RAINDROP_2D, pos, CVector(0.0f, 0.0f, 0.0f), nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f), - colour, CGeneral::GetRandomNumberInRange(0.0f, 20.0f) - 10, 360 - rain_angle + CGeneral::GetRandomNumberInRange(0.0f, 60.0f) - 30, cur_frame, 0); + colour, CGeneral::GetRandomNumberInRange(-10, 10), 360 - rain_angle + CGeneral::GetRandomNumberInRange(-30, 30), cur_frame, 0); } int num_splash_attempts = (int)(3 * Rain) + 1; int num_splashes = (int)(3 * Rain) + 4;