From 71059e6a59937195bb74cf11f406f287fa8db265 Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 12 Jun 2019 12:55:35 +0200 Subject: [PATCH 1/4] updated README --- README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/README.md b/README.md index 019f2ff5..19a9ae08 100644 --- a/README.md +++ b/README.md @@ -110,3 +110,35 @@ type functionname ( args ) Indentation is done with TABS. +As for the less cosmetic choices, here are some guidelines how the code should look: + +* Don't use magic numbers where the original source code would have had an enum or similar. +Even if you don't know the exact meaning it's better to call something `FOOBAR_TYPE_4` than just `4`, +since `4` will be used in other places and you can't easily see where else the enum value is used. + +* Don't just copy paste code from IDA, make it look nice + +* Use the right types. In particular: + + * don't use types like `__int16`, we have `int16` for that + + * don't use `unsigned`, we have typedefs for that + + * don't use `char` for anything but actual characters, use `int8`, `uint8` or `bool` + + * don't even think about using win32 types (`BYTE`, `WORD`, &c.) unless you're writing win32 specific code + +* As for variable names, the original gta source code was not written in a uniform style, +but here are some observations: + + * many variables employ a form of hungarian notation, i.e.: + + * `m_` may be used for class member variables (mostly those that are considered private) + + * `ms_` for (mostly private) static members + + * `f` is a float, `i` or `n` is an integer, `b` is a boolean, `a` is an array + + * do *not* use `dw` for `DWORD` or so, we're not programming win32 + +* Generally, try to make the code look as if R* could have written it From 01babd43b1e500b36d67d28077b5cffd13212068 Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 12 Jun 2019 13:46:02 +0200 Subject: [PATCH 2/4] little cleanup --- src/User.cpp | 75 +++++++++++++++++++++--------------------- src/User.h | 14 ++------ src/control/Replay.h | 6 +++- src/control/Script.cpp | 6 ++++ src/control/Script.h | 7 ++++ 5 files changed, 59 insertions(+), 49 deletions(-) create mode 100644 src/control/Script.cpp create mode 100644 src/control/Script.h diff --git a/src/User.cpp b/src/User.cpp index c36f62eb..c9ab761d 100644 --- a/src/User.cpp +++ b/src/User.cpp @@ -1,4 +1,3 @@ -#include "User.h" #include "common.h" #include "patcher.h" @@ -6,15 +5,15 @@ #include "Hud.h" #include "Replay.h" #include "Timer.h" +#include "Script.h" +#include "User.h" CPlaceName& CUserDisplay::PlaceName = *(CPlaceName*)0x8F29BC; COnscreenTimer& CUserDisplay::OnscnTimer = *(COnscreenTimer*)0x862238; CPager& CUserDisplay::Pager = *(CPager*)0x8F2744; CCurrentVehicle& CUserDisplay::CurrentVehicle = *(CCurrentVehicle*)0x8F5FE8; -char* CTheScripts::ScriptSpace = (char*)0x74B248; - -int COnscreenTimer::Init() { +void COnscreenTimer::Init() { m_bDisabled = false; for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++) { m_sEntries[i].m_nTimerOffset = 0; @@ -29,11 +28,10 @@ int COnscreenTimer::Init() { m_sEntries[i].m_bTimerProcessed = 0; m_sEntries[i].m_bCounterProcessed = 0; } - return 1; } void COnscreenTimer::Process() { - if(CReplay::Mode != 1 && !m_bDisabled) { + if(CReplay::Mode != CReplay::MODE_1 && !m_bDisabled) { for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++) { m_sEntries[i].Process(); } @@ -83,7 +81,7 @@ void COnscreenTimer::AddCounter(uint32 offset, uint16 type, char* text) { m_sEntries[i].m_nCounterOffset = offset; if(text) { - strncpy((char*)m_sEntries[i].m_aCounterText, text, 10); + strncpy(m_sEntries[i].m_aCounterText, text, 10); } else { m_sEntries[i].m_aCounterText[0] = 0; } @@ -102,28 +100,31 @@ void COnscreenTimer::AddClock(uint32 offset, char* text) { m_sEntries[i].m_nTimerOffset = offset; if(text) { - strncpy((char*)m_sEntries[i].m_aTimerText, text, 10u); + strncpy(m_sEntries[i].m_aTimerText, text, 10); } else { m_sEntries[i].m_aTimerText[0] = 0; } } void COnscreenTimerEntry::Process() { - if(m_nTimerOffset) { - uint32* timerPtr = (uint32*)&CTheScripts::ScriptSpace[m_nTimerOffset]; - uint32 oldTime = *timerPtr; - int32 newTime = int32(oldTime - uint32(20.0f * CTimer::GetTimeStep())); - if(newTime < 0) { - *timerPtr = 0; - m_bTimerProcessed = 0; - m_nTimerOffset = 0; - m_aTimerText[0] = 0; - } else { - *timerPtr = (uint32)newTime; - uint32 oldTimeSeconds = oldTime / 1000; - if(oldTimeSeconds <= 11 && newTime / 1000 != oldTimeSeconds) { - DMAudio.PlayFrontEndSound(0x93u, newTime / 1000); - } + if(m_nTimerOffset == 0) { + return; + } + + uint32* timerPtr = (uint32*)&CTheScripts::ScriptSpace[m_nTimerOffset]; + uint32 oldTime = *timerPtr; + int32 newTime = int32(oldTime - uint32(20.0f * CTimer::GetTimeStep())); + if(newTime < 0) { + *timerPtr = 0; + m_bTimerProcessed = 0; + m_nTimerOffset = 0; + m_aTimerText[0] = 0; + } else { + *timerPtr = (uint32)newTime; + uint32 oldTimeSeconds = oldTime / 1000; + if(oldTimeSeconds <= 11 && newTime / 1000 != oldTimeSeconds) { + // TODO: use an enum here + DMAudio.PlayFrontEndSound(0x93, newTime / 1000); } } } @@ -132,16 +133,16 @@ bool COnscreenTimerEntry::ProcessForDisplay() { m_bTimerProcessed = false; m_bCounterProcessed = false; - if(!m_nTimerOffset && !m_nCounterOffset) { + if(m_nTimerOffset == 0 && m_nCounterOffset == 0) { return false; } - if(m_nTimerOffset) { + if(m_nTimerOffset != 0) { m_bTimerProcessed = true; ProcessForDisplayTimer(); } - if(m_nCounterOffset) { + if(m_nCounterOffset != 0) { m_bCounterProcessed = true; ProcessForDisplayCounter(); } @@ -160,16 +161,16 @@ int COnscreenTimerEntry::ProcessForDisplayCounter() { } STARTPATCHES -InjectHook(0x429160, &COnscreenTimerEntry::Process, PATCH_JUMP); -InjectHook(0x429110, &COnscreenTimerEntry::ProcessForDisplay, PATCH_JUMP); -InjectHook(0x429080, &COnscreenTimerEntry::ProcessForDisplayTimer, PATCH_JUMP); -InjectHook(0x4290F0, &COnscreenTimerEntry::ProcessForDisplayCounter, PATCH_JUMP); + InjectHook(0x429160, &COnscreenTimerEntry::Process, PATCH_JUMP); + InjectHook(0x429110, &COnscreenTimerEntry::ProcessForDisplay, PATCH_JUMP); + InjectHook(0x429080, &COnscreenTimerEntry::ProcessForDisplayTimer, PATCH_JUMP); + InjectHook(0x4290F0, &COnscreenTimerEntry::ProcessForDisplayCounter, PATCH_JUMP); -InjectHook(0x429220, &COnscreenTimer::Init, PATCH_JUMP); -InjectHook(0x429320, &COnscreenTimer::Process, PATCH_JUMP); -InjectHook(0x4292E0, &COnscreenTimer::ProcessForDisplay, PATCH_JUMP); -InjectHook(0x429450, &COnscreenTimer::ClearCounter, PATCH_JUMP); -InjectHook(0x429410, &COnscreenTimer::ClearClock, PATCH_JUMP); -InjectHook(0x4293B0, &COnscreenTimer::AddCounter, PATCH_JUMP); -InjectHook(0x429350, &COnscreenTimer::AddClock, PATCH_JUMP); + InjectHook(0x429220, &COnscreenTimer::Init, PATCH_JUMP); + InjectHook(0x429320, &COnscreenTimer::Process, PATCH_JUMP); + InjectHook(0x4292E0, &COnscreenTimer::ProcessForDisplay, PATCH_JUMP); + InjectHook(0x429450, &COnscreenTimer::ClearCounter, PATCH_JUMP); + InjectHook(0x429410, &COnscreenTimer::ClearClock, PATCH_JUMP); + InjectHook(0x4293B0, &COnscreenTimer::AddCounter, PATCH_JUMP); + InjectHook(0x429350, &COnscreenTimer::AddClock, PATCH_JUMP); ENDPATCHES diff --git a/src/User.h b/src/User.h index b2d0b053..8b744c7e 100644 --- a/src/User.h +++ b/src/User.h @@ -1,14 +1,12 @@ #pragma once -#include "common.h" - class COnscreenTimerEntry { public: uint32 m_nTimerOffset; uint32 m_nCounterOffset; - uint8 m_aTimerText[10]; - uint8 m_aCounterText[10]; + char m_aTimerText[10]; + char m_aCounterText[10]; uint16 m_nType; char m_bCounterBuffer[42]; char m_bTimerBuffer[42]; @@ -24,20 +22,14 @@ public: static_assert(sizeof(COnscreenTimerEntry) == 0x74, "COnscreenTimerEntry: error"); -class CTheScripts{ -public: - static char *ScriptSpace;//[163840] -}; - class COnscreenTimer { public: COnscreenTimerEntry m_sEntries[NUMONSCREENTIMERENTRIES]; bool m_bProcessed; bool m_bDisabled; - char field_119[2]; - int Init(); + void Init(); void Process(); void ProcessForDisplay(); diff --git a/src/control/Replay.h b/src/control/Replay.h index eca818d6..85a9e35e 100644 --- a/src/control/Replay.h +++ b/src/control/Replay.h @@ -3,7 +3,11 @@ class CReplay { public: - static void Display(void); + enum { + MODE_1 + }; static uint8 &Mode; + + static void Display(void); }; diff --git a/src/control/Script.cpp b/src/control/Script.cpp new file mode 100644 index 00000000..71fc7bcd --- /dev/null +++ b/src/control/Script.cpp @@ -0,0 +1,6 @@ +#include "common.h" +#include "patcher.h" + +#include "Script.h" + +uint8 *CTheScripts::ScriptSpace = (uint8*)0x74B248; diff --git a/src/control/Script.h b/src/control/Script.h new file mode 100644 index 00000000..6f329e1f --- /dev/null +++ b/src/control/Script.h @@ -0,0 +1,7 @@ +#pragma once + +class CTheScripts +{ +public: + static uint8 *ScriptSpace;//[160*1024] +}; From 83cc43eeff8c4f3dc34fdd4df789e9b9cecaac8e Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 12 Jun 2019 14:35:15 +0200 Subject: [PATCH 3/4] added NodeName plugin --- src/NodeName.cpp | 64 +++++++++++++++++++++++++++++++++++++++++++++++- src/NodeName.h | 1 + src/main.cpp | 4 +-- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/NodeName.cpp b/src/NodeName.cpp index c2ffe048..2aea3c83 100644 --- a/src/NodeName.cpp +++ b/src/NodeName.cpp @@ -2,10 +2,72 @@ #include "patcher.h" #include "NodeName.h" -int &gPluginOffset = *(int*)0x64C610; +static int32 &gPluginOffset = *(int32*)0x64C610; + +enum +{ + ID_NODENAME = MAKECHUNKID(rwVENDORID_ROCKSTAR, 0xFE), +}; #define NODENAMEEXT(o) (RWPLUGINOFFSET(char, o, gPluginOffset)) +void* +NodeNameConstructor(void *object, RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + if(gPluginOffset > 0) + NODENAMEEXT(object)[0] = '\0'; + return object; +} + +void* +NodeNameDestructor(void *object, RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + return object; +} + +void* +NodeNameCopy(void *dstObject, const void *srcObject, RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + strncpy(NODENAMEEXT(dstObject), NODENAMEEXT(srcObject), 23); + return nil; +} + +RwStream* +NodeNameStreamRead(RwStream *stream, RwInt32 binaryLength, void *object, RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + RwStreamRead(stream, NODENAMEEXT(object), binaryLength); + NODENAMEEXT(object)[binaryLength] = '\0'; + return stream; +} + +RwStream* +NodeNameStreamWrite(RwStream *stream, RwInt32 binaryLength, const void *object, RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + RwStreamWrite(stream, NODENAMEEXT(object), binaryLength); + return stream; +} + +RwInt32 +NodeNameStreamGetSize(const void *object, RwInt32 offsetInObject, RwInt32 sizeInObject) +{ + // game checks for null pointer on node name extension but that really happen + return rwstrlen(NODENAMEEXT(object)); +} + +bool +NodeNamePluginAttach(void) +{ + gPluginOffset = RwFrameRegisterPlugin(24, ID_NODENAME, + NodeNameConstructor, + NodeNameDestructor, + NodeNameCopy); + RwFrameRegisterPluginStream(ID_NODENAME, + NodeNameStreamRead, + NodeNameStreamWrite, + NodeNameStreamGetSize); + return gPluginOffset != -1; +} + char* GetFrameNodeName(RwFrame *frame) { diff --git a/src/NodeName.h b/src/NodeName.h index a4dcf0cf..1a3e057b 100644 --- a/src/NodeName.h +++ b/src/NodeName.h @@ -1,3 +1,4 @@ #pragma once +bool NodeNamePluginAttach(void); char *GetFrameNodeName(RwFrame *frame); diff --git a/src/main.cpp b/src/main.cpp index e56d6938..e0fd8544 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,6 +33,7 @@ #include "Garages.h" #include "MusicManager.h" #include "VisibilityPlugins.h" +#include "NodeName.h" #include "DMAudio.h" #include "CutsceneMgr.h" #include "Lights.h" @@ -55,9 +56,6 @@ WRAPPER void CameraSize(RwCamera *camera, void *rect, float viewWindow, float aspectRatio) { EAXJMP(0x527170); } -//WRAPPER RwBool RpAnimBlendPluginAttach() { EAXJMP(0x4052D0); } -WRAPPER RwBool NodeNamePluginAttach() { EAXJMP(0x527100); } - bool &b_FoundRecentSavedGameWantToLoad = *(bool*)0x95CDA8; From ec0b8b573048bc4832cca412e33956e64ce4f5fa Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 12 Jun 2019 16:52:26 +0200 Subject: [PATCH 4/4] implemented CTimeCycle --- src/CutsceneMgr.cpp | 1 + src/CutsceneMgr.h | 2 + src/Timecycle.cpp | 229 +++++++++++++++++++++++++++++++++++++ src/Timecycle.h | 13 ++- src/common.h | 2 + src/main.cpp | 1 + src/render/ParticleMgr.cpp | 3 - src/render/Shadows.cpp | 1 + src/render/Shadows.h | 1 + 9 files changed, 248 insertions(+), 5 deletions(-) diff --git a/src/CutsceneMgr.cpp b/src/CutsceneMgr.cpp index 598c48a1..1fdf4b65 100644 --- a/src/CutsceneMgr.cpp +++ b/src/CutsceneMgr.cpp @@ -2,4 +2,5 @@ #include "patcher.h" #include "CutsceneMgr.h" +bool &CCutsceneMgr::ms_running = *(bool*)0x95CCF5; bool &CCutsceneMgr::ms_cutsceneProcessing = *(bool*)0x95CD9F; diff --git a/src/CutsceneMgr.h b/src/CutsceneMgr.h index 0bd79d10..4b810114 100644 --- a/src/CutsceneMgr.h +++ b/src/CutsceneMgr.h @@ -2,7 +2,9 @@ class CCutsceneMgr { + static bool &ms_running; static bool &ms_cutsceneProcessing; public: + static bool IsRunning(void) { return ms_running; } static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; } }; diff --git a/src/Timecycle.cpp b/src/Timecycle.cpp index 10fd6bf6..501691c3 100644 --- a/src/Timecycle.cpp +++ b/src/Timecycle.cpp @@ -1,4 +1,12 @@ #include "common.h" +#include "patcher.h" +#include "Clock.h" +#include "Weather.h" +#include "Camera.h" +#include "Shadows.h" +#include "CullZones.h" +#include "CutsceneMgr.h" +#include "FileMgr.h" #include "Timecycle.h" int (*CTimeCycle::m_nAmbientRed)[NUMWEATHERS] = (int(*)[NUMWEATHERS])0x86AF78; @@ -90,3 +98,224 @@ int &CTimeCycle::m_FogReduction = *(int*)0x880FB8; int &CTimeCycle::m_CurrentStoredValue = *(int*)0x94057C; CVector *CTimeCycle::m_VectorToSun = (CVector*)0x665548; // [16] +float *CTimeCycle::m_fShadowFrontX = (float*)0x72CE90; +float *CTimeCycle::m_fShadowFrontY = (float*)0x72CE50; +float *CTimeCycle::m_fShadowSideX = (float*)0x87C708; +float *CTimeCycle::m_fShadowSideY = (float*)0x87C6C8; +float *CTimeCycle::m_fShadowDisplacementX = (float*)0x6F0748; +float *CTimeCycle::m_fShadowDisplacementY = (float*)0x6F0788; + + +void +CTimeCycle::Initialise(void) +{ + int w, h; + int li, bi; + char line[1040]; + + int ambR, ambG, ambB; + 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; + float farClp, fogSt, lightGnd; + int cloudR, cloudG, cloudB; + int fluffyTopR, fluffyTopG, fluffyTopB; + int fluffyBotR, fluffyBotG, fluffyBotB; + float blurR, blurG, blurB, blurA; + + debug("Intialising CTimeCycle...\n"); + + CFileMgr::SetDir("DATA"); + CFileMgr::LoadFile("TIMECYC.DAT", work_buff, sizeof(work_buff), "rb"); + CFileMgr::SetDir(""); + + line[0] = '\0'; + bi = 0; + for(w = 0; w < NUMWEATHERS; w++) + for(h = 0; h < NUMHOURS; h++){ + li = 0; + while(work_buff[bi] == '/'){ + while(work_buff[bi] != '\n') + bi++; + bi++; + } + while(work_buff[bi] != '\n') + line[li++] = work_buff[bi++]; + line[li] = '\0'; + bi++; + + sscanf(line, "%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", + &ambR, &ambG, &ambB, + &dirR, &dirG, &dirB, + &skyTopR, &skyTopG, &skyTopB, + &skyBotR, &skyBotG, &skyBotB, + &sunCoreR, &sunCoreG, &sunCoreB, + &sunCoronaR, &sunCoronaG, &sunCoronaB, + &sunSz, &sprSz, &sprBght, + &shad, &lightShad, &treeShad, + &farClp, &fogSt, &lightGnd, + &cloudR, &cloudG, &cloudB, + &fluffyTopR, &fluffyTopG, &fluffyTopB, + &fluffyBotR, &fluffyBotG, &fluffyBotB, + &blurR, &blurG, &blurB, &blurA); + + m_nAmbientRed[h][w] = ambR; + m_nAmbientGreen[h][w] = ambG; + m_nAmbientBlue[h][w] = ambB; + m_nDirectionalRed[h][w] = dirR; + m_nDirectionalGreen[h][w] = dirG; + m_nDirectionalBlue[h][w] = dirB; + m_nSkyTopRed[h][w] = skyTopR; + m_nSkyTopGreen[h][w] = skyTopG; + m_nSkyTopBlue[h][w] = skyTopB; + m_nSkyBottomRed[h][w] = skyBotR; + m_nSkyBottomGreen[h][w] = skyBotG; + m_nSkyBottomBlue[h][w] = skyBotB; + m_nSunCoreRed[h][w] = sunCoreR; + m_nSunCoreGreen[h][w] = sunCoreG; + m_nSunCoreBlue[h][w] = sunCoreB; + m_nSunCoronaRed[h][w] = sunCoronaR; + m_nSunCoronaGreen[h][w] = sunCoronaG; + m_nSunCoronaBlue[h][w] = sunCoronaB; + m_fSunSize[h][w] = sunSz; + m_fSpriteSize[h][w] = sprSz; + m_fSpriteBrightness[h][w] = sprBght; + m_nShadowStrength[h][w] = shad; + m_nLightShadowStrength[h][w] = lightShad; + m_nTreeShadowStrength[h][w] = treeShad; + m_fFarClip[h][w] = farClp; + m_fFogStart[h][w] = fogSt; + m_fLightsOnGroundBrightness[h][w] = lightGnd; + m_nLowCloudsRed[h][w] = cloudR; + m_nLowCloudsGreen[h][w] = cloudG; + m_nLowCloudsBlue[h][w] = cloudB; + m_nFluffyCloudsTopRed[h][w] = fluffyTopR; + m_nFluffyCloudsTopGreen[h][w] = fluffyTopG; + m_nFluffyCloudsTopBlue[h][w] = fluffyTopB; + m_nFluffyCloudsBottomRed[h][w] = fluffyBotR; + m_nFluffyCloudsBottomGreen[h][w] = fluffyBotG; + m_nFluffyCloudsBottomBlue[h][w] = fluffyBotB; + m_fBlurRed[h][w] = blurR; + m_fBlurGreen[h][w] = blurG; + m_fBlurBlue[h][w] = blurB; + m_fBlurAlpha[h][w] = blurA; + } + + m_FogReduction = 0; + + debug("CTimeCycle ready\n"); +} + +void +CTimeCycle::Update(void) +{ + int h1 = CClock::GetHours(); + int h2 = (h1+1)%24; + int w1 = CWeather::OldWeatherType; + int w2 = CWeather::NewWeatherType; + float timeInterp = CClock::GetMinutes()/60.0f; + // coefficients for a bilinear interpolation + float c0 = (1.0f-timeInterp) * (1.0f-CWeather::InterpolationValue); + float c1 = timeInterp * (1.0f-CWeather::InterpolationValue); + float c2 = (1.0f-timeInterp) * CWeather::InterpolationValue; + float c3 = timeInterp * CWeather::InterpolationValue; + +#define INTERP(v) v[h1][w1]*c0 + v[h2][w1]*c1 + v[h1][w2]*c2 + v[h2][w2]*c3; + + m_nCurrentSkyTopRed = INTERP(m_nSkyTopRed); + m_nCurrentSkyTopGreen = INTERP(m_nSkyTopGreen); + m_nCurrentSkyTopBlue = INTERP(m_nSkyTopBlue); + + m_nCurrentSkyBottomRed = INTERP(m_nSkyBottomRed); + m_nCurrentSkyBottomGreen = INTERP(m_nSkyBottomGreen); + m_nCurrentSkyBottomBlue = INTERP(m_nSkyBottomBlue); + + 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_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); + m_nCurrentSunCoreBlue = INTERP(m_nSunCoreBlue); + + m_nCurrentSunCoronaRed = INTERP(m_nSunCoronaRed); + m_nCurrentSunCoronaGreen = INTERP(m_nSunCoronaGreen); + m_nCurrentSunCoronaBlue = INTERP(m_nSunCoronaBlue); + + m_fCurrentSunSize = INTERP(m_fSunSize); + m_fCurrentSpriteSize = INTERP(m_fSpriteSize); + m_fCurrentSpriteBrightness = INTERP(m_fSpriteBrightness); + m_nCurrentShadowStrength = INTERP(m_nShadowStrength); + m_nCurrentLightShadowStrength = INTERP(m_nLightShadowStrength); + m_nCurrentTreeShadowStrength = INTERP(m_nTreeShadowStrength); + m_fCurrentFarClip = INTERP(m_fFarClip); + m_fCurrentFogStart = INTERP(m_fFogStart); + m_fCurrentLightsOnGroundBrightness = INTERP(m_fLightsOnGroundBrightness); + + m_nCurrentLowCloudsRed = INTERP(m_nLowCloudsRed); + m_nCurrentLowCloudsGreen = INTERP(m_nLowCloudsGreen); + m_nCurrentLowCloudsBlue = INTERP(m_nLowCloudsBlue); + + m_nCurrentFluffyCloudsTopRed = INTERP(m_nFluffyCloudsTopRed); + m_nCurrentFluffyCloudsTopGreen = INTERP(m_nFluffyCloudsTopGreen); + m_nCurrentFluffyCloudsTopBlue = INTERP(m_nFluffyCloudsTopBlue); + + m_nCurrentFluffyCloudsBottomRed = INTERP(m_nFluffyCloudsBottomRed); + m_nCurrentFluffyCloudsBottomGreen = INTERP(m_nFluffyCloudsBottomGreen); + m_nCurrentFluffyCloudsBottomBlue = INTERP(m_nFluffyCloudsBottomBlue); + + 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); + + if(m_FogReduction != 0) + m_fCurrentFarClip = max(m_fCurrentFarClip, m_FogReduction/64 * 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); + CVector &sunPos = GetSunPosition(); + sunPos.x = sinf(sunAngle); + sunPos.y = 1.0f; + sunPos.z = 0.2f - cosf(sunAngle); + sunPos.Normalise(); + + CShadows::CalcPedShadowValues(sunPos, + &m_fShadowFrontX[m_CurrentStoredValue], &m_fShadowFrontY[m_CurrentStoredValue], + &m_fShadowSideX[m_CurrentStoredValue], &m_fShadowSideY[m_CurrentStoredValue], + &m_fShadowDisplacementX[m_CurrentStoredValue], &m_fShadowDisplacementY[m_CurrentStoredValue]); + + if(TheCamera.GetForward().z < -0.9f || + !CWeather::bScriptsForceRain && (CCullZones::PlayerNoRain() || CCullZones::CamNoRain() || CCutsceneMgr::IsRunning())) + m_FogReduction = min(m_FogReduction+1, 64); + else + m_FogReduction = max(m_FogReduction-1, 0); +} + +STARTPATCHES + InjectHook(0x4ABAE0, CTimeCycle::Initialise, PATCH_JUMP); + InjectHook(0x4ABF40, CTimeCycle::Update, PATCH_JUMP); +ENDPATCHES diff --git a/src/Timecycle.h b/src/Timecycle.h index fa59dfd1..546e6e0f 100644 --- a/src/Timecycle.h +++ b/src/Timecycle.h @@ -1,9 +1,10 @@ +#pragma once + class CTimeCycle { static int (*m_nAmbientRed)[NUMWEATHERS]; static int (*m_nAmbientGreen)[NUMWEATHERS]; static int (*m_nAmbientBlue)[NUMWEATHERS]; - static int (*m_nDirectionalRed)[NUMWEATHERS]; static int (*m_nDirectionalGreen)[NUMWEATHERS]; static int (*m_nDirectionalBlue)[NUMWEATHERS]; @@ -91,6 +92,12 @@ class CTimeCycle public: static int &m_CurrentStoredValue; static CVector *m_VectorToSun; // [16] + static float *m_fShadowFrontX; // [16] + static float *m_fShadowFrontY; // [16] + static float *m_fShadowSideX; // [16] + static float *m_fShadowSideY; // [16] + static float *m_fShadowDisplacementX; // [16] + static float *m_fShadowDisplacementY; // [16] static float GetAmbientRed(void) { return m_fCurrentAmbientRed; } static float GetAmbientGreen(void) { return m_fCurrentAmbientGreen; } @@ -127,5 +134,7 @@ public: static int GetFogGreen(void) { return m_nCurrentFogColourGreen; } static int GetFogBlue(void) { return m_nCurrentFogColourBlue; } - static const CVector &GetSunPosition(void) { return m_VectorToSun[m_CurrentStoredValue]; } + static void Initialise(void); + static void Update(void); + static CVector &GetSunPosition(void) { return m_VectorToSun[m_CurrentStoredValue]; } }; diff --git a/src/common.h b/src/common.h index f59e3aa4..d5223b6f 100644 --- a/src/common.h +++ b/src/common.h @@ -134,6 +134,8 @@ inline float sq(float x) { return x*x; } int myrand(void); void mysrand(unsigned int seed); +extern uint8 work_buff[55000]; + void re3_debug(char *format, ...); void re3_trace(const char *filename, unsigned int lineno, const char *func, char *format, ...); void re3_assert(const char *expr, const char *filename, unsigned int lineno, const char *func); diff --git a/src/main.cpp b/src/main.cpp index e0fd8544..d2a69f8b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -56,6 +56,7 @@ WRAPPER void CameraSize(RwCamera *camera, void *rect, float viewWindow, float aspectRatio) { EAXJMP(0x527170); } +uint8 work_buff[55000]; bool &b_FoundRecentSavedGameWantToLoad = *(bool*)0x95CDA8; diff --git a/src/render/ParticleMgr.cpp b/src/render/ParticleMgr.cpp index d259c4b4..9757a6ca 100644 --- a/src/render/ParticleMgr.cpp +++ b/src/render/ParticleMgr.cpp @@ -3,9 +3,6 @@ #include "FileMgr.h" #include "ParticleMgr.h" -_TODO("work_buff"); -UInt8 work_buff[55000]; - cParticleSystemMgr mod_ParticleSystemManager; const Char *ParticleFilename = "PARTICLE.CFG"; diff --git a/src/render/Shadows.cpp b/src/render/Shadows.cpp index 7e184ce7..498df6e9 100644 --- a/src/render/Shadows.cpp +++ b/src/render/Shadows.cpp @@ -6,3 +6,4 @@ WRAPPER void CShadows::AddPermanentShadow(unsigned char ShadowType, RwTexture* p WRAPPER void CShadows::RenderStaticShadows(void) { EAXJMP(0x5145F0); } WRAPPER void CShadows::RenderStoredShadows(void) { EAXJMP(0x514010); } WRAPPER void CShadows::RenderExtraPlayerShadows(void) { EAXJMP(0x516F90); } +WRAPPER void CShadows::CalcPedShadowValues(CVector light, float *frontX, float *frontY, float *sideX, float *sideY, float *dispX, float *dispY) { EAXJMP(0x516EB0); } \ No newline at end of file diff --git a/src/render/Shadows.h b/src/render/Shadows.h index 9cb3bc71..1efe6507 100644 --- a/src/render/Shadows.h +++ b/src/render/Shadows.h @@ -9,4 +9,5 @@ public: static void RenderStaticShadows(void); static void RenderStoredShadows(void); static void RenderExtraPlayerShadows(void); + static void CalcPedShadowValues(CVector light, float *frontX, float *frontY, float *sideX, float *sideY, float *dispX, float *dispY); };