diff --git a/src/Camera.cpp b/src/Camera.cpp index ed3a474c..fe96f574 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -8,6 +8,7 @@ #include "General.h" #include "CullZones.h" #include "SurfaceTable.h" +#include "MBlur.h" #include "Camera.h" const float DefaultFOV = 80.0f; // actually 70.0f @@ -72,6 +73,16 @@ WRAPPER void CCamera::Fade(float timeout, int16 direction) { EAXJMP(0x46B3A0); } WRAPPER void CCamera::ProcessFade(void) { EAXJMP(0x46F080); } WRAPPER void CCamera::ProcessMusicFade(void) { EAXJMP(0x46F1E0); } +int +CCamera::GetScreenFadeStatus(void) +{ + if(m_fFLOATingFade == 0.0f) + return FADE_0; + if(m_fFLOATingFade == 255.0f) + return FADE_2; + return FADE_1; +} + void CCamera::SetFadeColour(uint8 r, uint8 g, uint8 b) { @@ -81,6 +92,34 @@ CCamera::SetFadeColour(uint8 r, uint8 g, uint8 b) CDraw::FadeBlue = b; } +void +CCamera::SetMotionBlur(int r, int g, int b, int a, int type) +{ + m_BlurRed = r; + m_BlurGreen = g; + m_BlurBlue = b; + m_motionBlur = a; + m_BlurType = type; +} + +void +CCamera::SetMotionBlurAlpha(int a) +{ + m_imotionBlurAddAlpha = a; +} + +void +CCamera::RenderMotionBlur(void) +{ + if(m_BlurType == 0) + return; + + CMBlur::MotionBlurRender(m_pRwCamera, + m_BlurRed, m_BlurGreen, m_BlurBlue, + m_motionBlur, m_BlurType, m_imotionBlurAddAlpha); +} + + /* * * CCam @@ -1202,6 +1241,10 @@ STARTPATCHES InjectHook(0x42C760, &CCamera::IsSphereVisible, PATCH_JUMP); InjectHook(0x46FD00, &CCamera::SetFadeColour, PATCH_JUMP); + InjectHook(0x46FD40, &CCamera::SetMotionBlur, PATCH_JUMP); + InjectHook(0x46FD80, &CCamera::SetMotionBlurAlpha, PATCH_JUMP); + InjectHook(0x46F940, &CCamera::RenderMotionBlur, PATCH_JUMP); + InjectHook(0x456F40, WellBufferMe, PATCH_JUMP); InjectHook(0x4582F0, &CCam::GetVectorsReadyForRW, PATCH_JUMP); InjectHook(0x457710, &CCam::DoAverageOnVector, PATCH_JUMP); diff --git a/src/Camera.h b/src/Camera.h index 21d017d7..30ca98e6 100644 --- a/src/Camera.h +++ b/src/Camera.h @@ -212,6 +212,31 @@ enum LOOKING_FORWARD, }; +enum +{ + // TODO: figure out + FADE_0, + FADE_1, // mid fade + FADE_2, + + FADE_OUT, + FADE_IN, +}; + +enum +{ + MBLUR_NONE, + MBLUR_SNIPER, + MBLUR_NORMAL, + MBLUR_INTRO1, // green camera + MBLUR_INTRO2, // unused + MBLUR_INTRO3, // bank scene + MBLUR_INTRO4, // jail break scene + MBLUR_INTRO5, // explosion + MBLUR_INTRO6, // player shot + MBLUR_UNUSED, // pinkish +}; + struct CCamera : public CPlaceable { bool m_bAboveGroundTrainNodesLoaded; @@ -421,10 +446,15 @@ int m_iModeObbeCamIsInForCar; bool IsBoxVisible(RwV3d *box, const CMatrix *mat); void Fade(float timeout, int16 direction); + int GetScreenFadeStatus(void); void ProcessFade(void); void ProcessMusicFade(void); void SetFadeColour(uint8 r, uint8 g, uint8 b); + void SetMotionBlur(int r, int g, int b, int a, int type); + void SetMotionBlurAlpha(int a); + void RenderMotionBlur(void); + void DrawBordersForWideScreen(void); }; static_assert(offsetof(CCamera, m_WideScreenOn) == 0x70, "CCamera: error"); diff --git a/src/CutsceneMgr.cpp b/src/CutsceneMgr.cpp new file mode 100644 index 00000000..598c48a1 --- /dev/null +++ b/src/CutsceneMgr.cpp @@ -0,0 +1,5 @@ +#include "common.h" +#include "patcher.h" +#include "CutsceneMgr.h" + +bool &CCutsceneMgr::ms_cutsceneProcessing = *(bool*)0x95CD9F; diff --git a/src/CutsceneMgr.h b/src/CutsceneMgr.h new file mode 100644 index 00000000..0bd79d10 --- /dev/null +++ b/src/CutsceneMgr.h @@ -0,0 +1,8 @@ +#pragma once + +class CCutsceneMgr +{ + static bool &ms_cutsceneProcessing; +public: + static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; } +}; diff --git a/src/Frontend.cpp b/src/Frontend.cpp index e1738172..c4495e05 100644 --- a/src/Frontend.cpp +++ b/src/Frontend.cpp @@ -4,6 +4,9 @@ int &CMenuManager::m_PrefsBrightness = *(int*)0x5F2E50; int &CMenuManager::m_PrefsLanguage = *(int*)0x941238; +bool &CMenuManager::m_PrefsUseWideScreen = *(bool*)0x95CD23; + CMenuManager &FrontEndMenuManager = *(CMenuManager*)0x8F59D8; +WRAPPER void CMenuManager::Process(void) { EAXJMP(0x485100); } WRAPPER void CMenuManager::DrawFrontEnd(void) { EAXJMP(0x47A540); } diff --git a/src/Frontend.h b/src/Frontend.h index 838139df..f82921d7 100644 --- a/src/Frontend.h +++ b/src/Frontend.h @@ -85,7 +85,9 @@ public: static int &m_PrefsBrightness; static int &m_PrefsLanguage; + static bool &m_PrefsUseWideScreen; + void Process(void); void DrawFrontEnd(void); }; static_assert(sizeof(CMenuManager) == 0x564, "CMenuManager: error"); diff --git a/src/Game.cpp b/src/Game.cpp index 7f9d86a0..2cac69ea 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -3,3 +3,7 @@ #include "Game.h" int &CGame::currLevel = *(int*)0x941514; +bool &CGame::bDemoMode = *(bool*)0x5F4DD0; +bool &CGame::nastyGame = *(bool*)0x5F4DD4; + +WRAPPER void CGame::Process(void) { EAXJMP(0x48C850); } diff --git a/src/Game.h b/src/Game.h index 83a51fab..19a85a47 100644 --- a/src/Game.h +++ b/src/Game.h @@ -12,4 +12,8 @@ class CGame { public: static int &currLevel; + static bool &bDemoMode; + static bool &nastyGame; + + static void Process(void); }; diff --git a/src/Pad.cpp b/src/Pad.cpp index 869c4d48..f27954e8 100644 --- a/src/Pad.cpp +++ b/src/Pad.cpp @@ -12,6 +12,7 @@ CMouseControllerState &CPad::OldMouseControllerState = *(CMouseControllerState*) CMouseControllerState &CPad::NewMouseControllerState = *(CMouseControllerState*)0x8809F0; CMouseControllerState &CPad::PCTempMouseControllerState = *(CMouseControllerState*)0x6F1E60; +WRAPPER void CPad::UpdatePads(void) { EAXJMP(0x492720); } WRAPPER void CPad::PrintErrorMessage(void) { EAXJMP(0x4942B0); } void diff --git a/src/Pad.h b/src/Pad.h index 48e19e6f..195a20d4 100644 --- a/src/Pad.h +++ b/src/Pad.h @@ -120,6 +120,7 @@ public: bool GetLookLeft(void); bool GetLookRight(void); + static void UpdatePads(void); static CPad *GetPad(int n) { return &Pads[n]; } static void PrintErrorMessage(void); }; diff --git a/src/Timecycle.h b/src/Timecycle.h index bfbda281..1698e0c5 100644 --- a/src/Timecycle.h +++ b/src/Timecycle.h @@ -98,6 +98,15 @@ public: static float GetDirectionalRed(void) { return m_fCurrentDirectionalRed; } static float GetDirectionalGreen(void) { return m_fCurrentDirectionalGreen; } static float GetDirectionalBlue(void) { return m_fCurrentDirectionalBlue; } + static int GetSkyTopRed(void) { return m_nCurrentSkyTopRed; } + static int GetSkyTopGreen(void) { return m_nCurrentSkyTopGreen; } + static int GetSkyTopBlue(void) { return m_nCurrentSkyTopBlue; } + static int GetSkyBottomRed(void) { return m_nCurrentSkyBottomRed; } + static int GetSkyBottomGreen(void) { return m_nCurrentSkyBottomGreen; } + static int GetSkyBottomBlue(void) { return m_nCurrentSkyBottomBlue; } + static float GetFarClip(void) { return m_fCurrentFarClip; } + static float GetFogStart(void) { return m_fCurrentFogStart; } + static int GetLowCloudsRed(void) { return m_nCurrentLowCloudsRed; } static int GetLowCloudsGreen(void) { return m_nCurrentLowCloudsGreen; } static int GetLowCloudsBlue(void) { return m_nCurrentLowCloudsBlue; } diff --git a/src/Timer.cpp b/src/Timer.cpp index 35e569ac..69dd2881 100644 --- a/src/Timer.cpp +++ b/src/Timer.cpp @@ -74,6 +74,9 @@ void CTimer::Shutdown(void) ; } +#if 1 +WRAPPER void CTimer::Update(void) { EAXJMP(0x4ACF70); } +#else void CTimer::Update(void) { m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds; @@ -145,6 +148,7 @@ void CTimer::Update(void) m_FrameCounter++; } +#endif void CTimer::Suspend(void) { diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp index 400f3fdc..a1165110 100644 --- a/src/audio/DMAudio.cpp +++ b/src/audio/DMAudio.cpp @@ -4,10 +4,6 @@ cDMAudio &DMAudio = *(cDMAudio*)0x95CDBE; +WRAPPER void cDMAudio::Service(void) { EAXJMP(0x57C7A0); } WRAPPER void cDMAudio::ReportCollision(CEntity *A, CEntity *B, uint8 surfA, uint8 surfB, float impulse, float speed) { EAXJMP(0x57CBE0); } - - -void cDMAudio::ResetTimers(UInt32 timerval) -{ - ((void (__thiscall *)(cDMAudio *, UInt32))0x57CCD0)(this, timerval); -} \ No newline at end of file +WRAPPER void cDMAudio::ResetTimers(UInt32 timerval) { EAXJMP(0x57CCD0); } diff --git a/src/audio/DMAudio.h b/src/audio/DMAudio.h index b6d5fc64..fb341d82 100644 --- a/src/audio/DMAudio.h +++ b/src/audio/DMAudio.h @@ -5,6 +5,7 @@ class CEntity; class cDMAudio { public: + void Service(void); void ReportCollision(CEntity *A, CEntity *B, uint8 surfA, uint8 surfB, float impulse, float speed); void ResetTimers(UInt32 timerval); }; diff --git a/src/entities/Heli.cpp b/src/entities/Heli.cpp new file mode 100644 index 00000000..21731fed --- /dev/null +++ b/src/entities/Heli.cpp @@ -0,0 +1,5 @@ +#include "common.h" +#include "patcher.h" +#include "Heli.h" + +WRAPPER void CHeli::SpecialHeliPreRender(void) { EAXJMP(0x54AE10); } diff --git a/src/entities/Heli.h b/src/entities/Heli.h new file mode 100644 index 00000000..57c3db0f --- /dev/null +++ b/src/entities/Heli.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Vehicle.h" + +class CHeli : public CVehicle +{ +public: + // 0x288 + uint8 stuff[180]; + + static void SpecialHeliPreRender(void); +}; +static_assert(sizeof(CHeli) == 0x33C, "CHeli: error"); diff --git a/src/main.cpp b/src/main.cpp index ff254a1e..07463402 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -32,8 +32,175 @@ #include "Darkel.h" #include "Garages.h" #include "MusicManager.h" +#include "VisibilityPlugins.h" +#include "DMAudio.h" +#include "CutsceneMgr.h" +#include "Lights.h" +#include "Credits.h" +#include "CullZones.h" +#include "TimeCycle.h" #include "Frontend.h" +WRAPPER int psCameraBeginUpdate(RwCamera *camera) { EAXJMP(0x580C70); } +WRAPPER void psCameraShowRaster(RwCamera *camera) { EAXJMP(0x580CA0); } + +WRAPPER void CameraSize(RwCamera *camera, CRect *rect, float viewWindow, float aspectRatio) { EAXJMP(0x527170); } +int RsCameraBeginUpdate(RwCamera *camera) { return psCameraBeginUpdate(camera); } // argument actually ignored +void RsCameraShowRaster(RwCamera *camera) { psCameraShowRaster(camera); } + +bool &b_FoundRecentSavedGameWantToLoad = *(bool*)0x95CDA8; + + +bool DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); +void DoRWStuffEndOfFrame(void); + +void RenderScene(void); +void RenderDebugShit(void); +void RenderEffects(void); +void Render2dStuff(void); +void RenderMenus(void); +void DoFade(void); +void Render2dStuffAfterFade(void); + +extern void (*DebugMenuProcess)(void); +extern void (*DebugMenuRender)(void); + + +RwRGBA gColourTop; + +void +Idle(void *arg) +{ + CTimer::Update(); + CSprite2d::InitPerFrame(); + CFont::InitPerFrame(); + CPointLights::InitPerFrame(); + CGame::Process(); + DMAudio.Service(); + + if(CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()){ + FrontEndMenuManager.m_bStartGameLoading = true; + FrontEndMenuManager.m_bLoadingSavedGame = false; + return; + } + + if(FrontEndMenuManager.m_bStartGameLoading || b_FoundRecentSavedGameWantToLoad) + return; + + SetLightsWithTimeOfDayColour(Scene.world); + + if(arg == nil) + return; + + if((!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.field_452 == 1) && + TheCamera.GetScreenFadeStatus() != FADE_2){ + CRenderer::ConstructRenderList(); + CRenderer::PreRender(); + + if(CWeather::LightningFlash && !CCullZones::CamNoRain()){ + if(!DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255)) + return; + }else{ + if(!DoRWStuffStartOfFrame_Horizon(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(), + CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(), + 255)) + return; + } + + DefinedState(); + + // BUG. This has to be done BEFORE RwCameraBeginUpdate + RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip()); + RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart()); + + RenderScene(); + RenderDebugShit(); + RenderEffects(); + + if((TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_NORMAL) && + TheCamera.m_ScreenReductionPercentage > 0.0) + TheCamera.SetMotionBlurAlpha(150); + TheCamera.RenderMotionBlur(); + + Render2dStuff(); + }else{ + float viewWindow = tan(DEGTORAD(CDraw::GetFOV() * 0.5f)); + // ASPECT + CameraSize(Scene.camera, nil, viewWindow, 4.0f/3.0f); + CVisibilityPlugins::SetRenderWareCamera(Scene.camera); + RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ); + if(!RsCameraBeginUpdate(Scene.camera)) + return; + } + + RenderMenus(); + DoFade(); + Render2dStuffAfterFade(); + CCredits::Render(); + DoRWStuffEndOfFrame(); + +// if(g_SlowMode) +// ProcessSlowMode(); +} + +void +FrontendIdle(void) +{ + CTimer::Update(); + CSprite2d::SetRecipNearClip(); + CSprite2d::InitPerFrame(); + CFont::InitPerFrame(); + CPad::UpdatePads(); + FrontEndMenuManager.Process(); + + if(RsGlobal.quit) + return; + + float viewWindow = tan(DEGTORAD(CDraw::GetFOV() * 0.5f)); + // ASPECT + CameraSize(Scene.camera, nil, viewWindow, 4.0f/3.0f); + CVisibilityPlugins::SetRenderWareCamera(Scene.camera); + RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ); + if(!RsCameraBeginUpdate(Scene.camera)) + return; + + DefinedState(); + RenderMenus(); + DoFade(); + Render2dStuffAfterFade(); + CFont::DrawFonts(); + DoRWStuffEndOfFrame(); +} + +bool +DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha) +{ + float viewWindow = tan(DEGTORAD(CDraw::GetFOV() * 0.5f)); + // ASPECT + float aspectRatio = CMenuManager::m_PrefsUseWideScreen ? 16.0f/9.0f : 4.0f/3.0f; + CameraSize(Scene.camera, nil, viewWindow, aspectRatio); + CVisibilityPlugins::SetRenderWareCamera(Scene.camera); + RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ); + + if(!RsCameraBeginUpdate(Scene.camera)) + return false; + + TheCamera.m_viewMatrix.Update(); + CClouds::RenderBackground(TopRed, TopGreen, TopBlue, BottomRed, BottomGreen, BottomBlue, Alpha); + + return true; +} + +void +DoRWStuffEndOfFrame(void) +{ + // CDebug::DebugDisplayTextBuffer(); + // FlushObrsPrintfs(); + RwCameraEndUpdate(Scene.camera); + RsCameraShowRaster(Scene.camera); +} + + // This is certainly a very useful function void DoRWRenderHorizon(void) @@ -143,6 +310,8 @@ Render2dStuff(void) CGarages::PrintMessages(); CPad::PrintErrorMessage(); CFont::DrawFonts(); + + DebugMenuRender(); } void @@ -154,8 +323,8 @@ RenderMenus(void) bool &JustLoadedDontFadeInYet = *(bool*)0x95CDB4; bool &StillToFadeOut = *(bool*)0x95CD99; -int32 &TimeStartedCountingForFade = *(int32*)0x9430EC; -int32 &TimeToStayFadedBeforeFadeOut = *(int32*)0x611564; +uint32 &TimeStartedCountingForFade = *(uint32*)0x9430EC; +uint32 &TimeToStayFadedBeforeFadeOut = *(uint32*)0x611564; void DoFade(void) @@ -171,12 +340,12 @@ DoFade(void) if(StillToFadeOut){ if(CTimer::GetTimeInMilliseconds() - TimeStartedCountingForFade > TimeToStayFadedBeforeFadeOut){ StillToFadeOut = false; - TheCamera.Fade(3.0f, 1); + TheCamera.Fade(3.0f, FADE_IN); TheCamera.ProcessFade(); TheCamera.ProcessMusicFade(); }else{ TheCamera.SetFadeColour(0, 0, 0); - TheCamera.Fade(0.0f, 0); + TheCamera.Fade(0.0f, FADE_OUT); TheCamera.ProcessFade(); } } @@ -246,6 +415,10 @@ Render2dStuffAfterFade(void) STARTPATCHES + InjectHook(0x48E480, Idle, PATCH_JUMP); + InjectHook(0x48E700, FrontendIdle, PATCH_JUMP); + + InjectHook(0x48D040, DoRWStuffStartOfFrame_Horizon, PATCH_JUMP); InjectHook(0x48E030, RenderScene, PATCH_JUMP); InjectHook(0x48E080, RenderDebugShit, PATCH_JUMP); InjectHook(0x48E090, RenderEffects, PATCH_JUMP); diff --git a/src/re3.cpp b/src/re3.cpp index 0d235cc0..08d02d12 100644 --- a/src/re3.cpp +++ b/src/re3.cpp @@ -4,6 +4,7 @@ #include "patcher.h" #include "Renderer.h" #include "Credits.h" +#include "Camera.h" #include "debugmenu_public.h" void **rwengine = *(void***)0x5A10E1; @@ -71,10 +72,30 @@ open_script(const char *path, const char *mode) int gDbgSurf; +void (*DebugMenuProcess)(void); +void (*DebugMenuRender)(void); +static void stub(void) { } + +void +DebugMenuInit(void) +{ + if(DebugMenuLoad()){ + DebugMenuProcess = (void(*)(void))GetProcAddress(gDebugMenuAPI.module, "DebugMenuProcess"); + DebugMenuRender = (void(*)(void))GetProcAddress(gDebugMenuAPI.module, "DebugMenuRender"); + } + if(DebugMenuProcess == nil || DebugMenuRender == nil){ + DebugMenuProcess = stub; + DebugMenuRender = stub; + } + +} + int (*RsEventHandler_orig)(int a, int b); int delayedPatches10(int a, int b) { + DebugMenuInit(); + if(DebugMenuLoad()){ DebugMenuAddVarBool8("Debug", "Show Ped Road Groups", (int8*)&gbShowPedRoadGroups, nil); DebugMenuAddVarBool8("Debug", "Show Car Road Groups", (int8*)&gbShowCarRoadGroups, nil); @@ -85,6 +106,8 @@ delayedPatches10(int a, int b) DebugMenuAddVarBool8("Debug", "Don't render Objects", (int8*)&gbDontRenderObjects, nil); DebugMenuAddVar("Debug", "Dbg Surface", &gDbgSurf, nil, 1, 0, 34, nil); + DebugMenuAddVar("Debug", "blur type", &TheCamera.m_BlurType, nil, 1, 0, 10, nil); + DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start); DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop); } diff --git a/src/render/MBlur.cpp b/src/render/MBlur.cpp index b7a65adc..1d344d35 100644 --- a/src/render/MBlur.cpp +++ b/src/render/MBlur.cpp @@ -1,6 +1,7 @@ #include "common.h" #include "patcher.h" #include "RwHelper.h" +#include "Camera.h" #include "MBlur.h" RwRaster *&CMBlur::pFrontBuffer = *(RwRaster**)0x8E2C48; @@ -104,26 +105,26 @@ CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect) } void -CMBlur::MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 alpha, int32 type, uint32 bluralpha) +CMBlur::MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 addalpha) { - RwRGBA color = { red, green, blue, alpha }; + RwRGBA color = { red, green, blue, blur }; if(BlurOn){ if(pFrontBuffer){ if(ms_bJustInitialised) ms_bJustInitialised = false; else - OverlayRender(cam, pFrontBuffer, color, type, bluralpha); + OverlayRender(cam, pFrontBuffer, color, type, addalpha); } RwRasterPushContext(pFrontBuffer); RwRasterRenderFast(RwCameraGetRaster(cam), 0, 0); RwRasterPopContext(); }else{ - OverlayRender(cam, nil, color, type, bluralpha); + OverlayRender(cam, nil, color, type, addalpha); } } void -CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, uint32 bluralpha) +CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, uint32 addalpha) { int r, g, b, a; @@ -135,31 +136,31 @@ CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, DefinedState(); switch(type){ - case 3: + case MBLUR_INTRO1: r = 0; g = 255; b = 0; a = 128; break; - case 5: + case MBLUR_INTRO3: r = 100; g = 220; b = 230; a = 158; break; - case 6: + case MBLUR_INTRO4: r = 80; g = 255; b = 230; a = 138; break; - case 8: + case MBLUR_INTRO6: r = 255; g = 60; b = 60; a = 200; break; - case 9: + case MBLUR_UNUSED: r = 255; g = 180; b = 180; @@ -191,7 +192,7 @@ CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6); - a = bluralpha/2; + a = addalpha/2; if(a < 30) a = 30; diff --git a/src/render/MBlur.h b/src/render/MBlur.h index 67ed658f..baa82b80 100644 --- a/src/render/MBlur.h +++ b/src/render/MBlur.h @@ -10,6 +10,6 @@ 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 alpha, int32 type, uint32 bluralpha); + 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); }; diff --git a/src/render/PointLights.cpp b/src/render/PointLights.cpp index 8496d8aa..34cfa658 100644 --- a/src/render/PointLights.cpp +++ b/src/render/PointLights.cpp @@ -2,4 +2,12 @@ #include "patcher.h" #include "PointLights.h" +int16 &CPointLights::NumLights = *(int16*)0x95CC3E; + WRAPPER void CPointLights::RenderFogEffect(void) { EAXJMP(0x510C30); } + +void +CPointLights::InitPerFrame(void) +{ + NumLights = 0; +} diff --git a/src/render/PointLights.h b/src/render/PointLights.h index d20fbb7e..e72e8ede 100644 --- a/src/render/PointLights.h +++ b/src/render/PointLights.h @@ -2,6 +2,8 @@ class CPointLights { + static int16 &NumLights; public: + static void InitPerFrame(void); static void RenderFogEffect(void); }; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 70002dcf..6979bb19 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -5,6 +5,7 @@ #include "Treadable.h" #include "Ped.h" #include "Vehicle.h" +#include "Heli.h" #include "Object.h" #include "PathFind.h" #include "Collision.h" @@ -14,6 +15,7 @@ #include "Camera.h" #include "ModelIndices.h" #include "Streaming.h" +#include "Shadows.h" #include "Renderer.h" bool gbShowPedRoadGroups; @@ -48,6 +50,28 @@ CRenderer::Init(void) gSortedVehiclesAndPeds.Init(40); SortBIGBuildings(); } + +void +CRenderer::PreRender(void) +{ + int i; + CLink *node; + + for(i = 0; i < ms_nNoOfVisibleEntities; i++) + ms_aVisibleEntityPtrs[i]->PreRender(); + + for(i = 0; i < ms_nNoOfInVisibleEntities; i++) + ms_aInVisibleEntityPtrs[i]->PreRender(); + + for(node = CVisibilityPlugins::m_alphaEntityList.tail.prev; + node != &CVisibilityPlugins::m_alphaEntityList.head; + node = node->prev) + ((CEntity*)node->item.entity)->PreRender(); + + CHeli::SpecialHeliPreRender(); + CShadows::RenderExtraPlayerShadows(); +} + void CRenderer::RenderOneRoad(CEntity *e) { diff --git a/src/render/Renderer.h b/src/render/Renderer.h index 970d6ba5..38f2b6f7 100644 --- a/src/render/Renderer.h +++ b/src/render/Renderer.h @@ -26,7 +26,7 @@ class CRenderer static bool &m_loadingPriority; public: static void Init(void); - // TODO: PreRender, needs CHeli and CShadows + static void PreRender(void); static void RenderRoads(void); static void RenderFadingInEntities(void); diff --git a/src/render/Shadows.cpp b/src/render/Shadows.cpp index 81ba75aa..7e184ce7 100644 --- a/src/render/Shadows.cpp +++ b/src/render/Shadows.cpp @@ -5,3 +5,4 @@ WRAPPER void CShadows::AddPermanentShadow(unsigned char ShadowType, RwTexture* pTexture, CVector* pPosn, float fX1, float fY1, float fX2, float fY2, short nTransparency, unsigned char nRed, unsigned char nGreen, unsigned char nBlue, float fZDistance, unsigned int nTime, float fScale) { EAXJMP(0x512FD0); } WRAPPER void CShadows::RenderStaticShadows(void) { EAXJMP(0x5145F0); } WRAPPER void CShadows::RenderStoredShadows(void) { EAXJMP(0x514010); } +WRAPPER void CShadows::RenderExtraPlayerShadows(void) { EAXJMP(0x516F90); } diff --git a/src/render/Shadows.h b/src/render/Shadows.h index 0a475f6f..9cb3bc71 100644 --- a/src/render/Shadows.h +++ b/src/render/Shadows.h @@ -8,4 +8,5 @@ public: static void AddPermanentShadow(uint8 ShadowType, RwTexture* pTexture, CVector* pPosn, float fX1, float fY1, float fX2, float fY2, short nTransparency, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, uint32 nTime, float fScale); static void RenderStaticShadows(void); static void RenderStoredShadows(void); -}; \ No newline at end of file + static void RenderExtraPlayerShadows(void); +}; diff --git a/src/render/VisibilityPlugins.cpp b/src/render/VisibilityPlugins.cpp index d9e87553..5608c933 100644 --- a/src/render/VisibilityPlugins.cpp +++ b/src/render/VisibilityPlugins.cpp @@ -5,6 +5,7 @@ #include "ModelInfo.h" #include "Lights.h" #include "Renderer.h" +#include "Camera.h" #include "VisibilityPlugins.h" #define FADE_DISTANCE 20.0f @@ -24,6 +25,7 @@ int32 &CVisibilityPlugins::ms_atomicPluginOffset = *(int32*)0x600124; int32 &CVisibilityPlugins::ms_framePluginOffset = *(int32*)0x600128; int32 &CVisibilityPlugins::ms_clumpPluginOffset = *(int32*)0x60012C; +RwCamera *&CVisibilityPlugins::ms_pCamera = *(RwCamera**)0x8F2514; RwV3d *&CVisibilityPlugins::ms_pCameraPosn = *(RwV3d**)0x8F6270; float &CVisibilityPlugins::ms_cullCompsDist = *(float*)0x8F2BC4; float &CVisibilityPlugins::ms_vehicleLod0Dist = *(float*)0x885B28; @@ -82,6 +84,28 @@ CVisibilityPlugins::InsertAtomicIntoSortedList(RpAtomic *a, float dist) return ret; } +void +CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera) +{ + ms_pCamera = camera; + ms_pCameraPosn = RwMatrixGetPos(RwFrameGetMatrix(RwCameraGetFrame(camera))); + + if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN1 || + TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWNPED) + ms_cullCompsDist = 1000000.0f; + else + ms_cullCompsDist = sq(TheCamera.LODDistMultiplier * 20.0f); + + ms_vehicleLod0Dist = sq(70.0 * TheCamera.GenerationDistMultiplier); + ms_vehicleLod1Dist = sq(90.0 * TheCamera.GenerationDistMultiplier); + ms_vehicleFadeDist = sq(100.0 * TheCamera.GenerationDistMultiplier); + ms_bigVehicleLod0Dist = sq(60.0 * TheCamera.GenerationDistMultiplier); + ms_bigVehicleLod1Dist = sq(150.0 * TheCamera.GenerationDistMultiplier); + ms_pedLod0Dist = sq(25.0 * TheCamera.LODDistMultiplier); + ms_pedLod1Dist = sq(60.0 * TheCamera.LODDistMultiplier); + ms_pedFadeDist = sq(70.0 * TheCamera.LODDistMultiplier); +} + RpMaterial* SetAlphaCB(RpMaterial *material, void *data) { @@ -802,6 +826,8 @@ STARTPATCHES InjectHook(0x528FF0, CVisibilityPlugins::InsertEntityIntoSortedList, PATCH_JUMP); InjectHook(0x528F80, CVisibilityPlugins::InitAlphaAtomicList, PATCH_JUMP); InjectHook(0x528FA0, CVisibilityPlugins::InsertAtomicIntoSortedList, PATCH_JUMP); + InjectHook(0x528C50, CVisibilityPlugins::SetRenderWareCamera, PATCH_JUMP); + InjectHook(0x527F60, SetAlphaCB, PATCH_JUMP); InjectHook(0x529040, CVisibilityPlugins::RenderAlphaAtomics, PATCH_JUMP); InjectHook(0x529070, CVisibilityPlugins::RenderFadingEntities, PATCH_JUMP); diff --git a/src/render/VisibilityPlugins.h b/src/render/VisibilityPlugins.h index f041b24e..89222dce 100644 --- a/src/render/VisibilityPlugins.h +++ b/src/render/VisibilityPlugins.h @@ -22,6 +22,7 @@ public: static CLinkList &m_alphaList; static CLinkList &m_alphaEntityList; + static RwCamera *&ms_pCamera; static RwV3d *&ms_pCameraPosn; static float &ms_cullCompsDist; static float &ms_vehicleLod0Dist; @@ -39,6 +40,8 @@ public: static void InitAlphaAtomicList(void); static bool InsertAtomicIntoSortedList(RpAtomic *a, float dist); + static void SetRenderWareCamera(RwCamera *camera); + static RpAtomic *RenderWheelAtomicCB(RpAtomic *atomic); static RpAtomic *RenderObjNormalAtomic(RpAtomic *atomic); static RpAtomic *RenderAlphaAtomic(RpAtomic *atomic, int alpha);