Skip to content

Commit

Permalink
Add grain effect functions (PR #2422)
Browse files Browse the repository at this point in the history
  • Loading branch information
tederis authored Jul 25, 2023
1 parent 89e2d37 commit b01fcd2
Show file tree
Hide file tree
Showing 9 changed files with 242 additions and 53 deletions.
4 changes: 4 additions & 0 deletions Client/mods/deathmatch/logic/CClientGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5345,6 +5345,10 @@ void CClientGame::ResetMapInfo()
g_pMultiplayer->ResetWater();
g_pMultiplayer->ResetColorFilter();

// Grain effect
g_pMultiplayer->SetGrainMultiplier(eGrainMultiplierType::ALL, 1.0f);
g_pMultiplayer->SetGrainLevel(0);

// Water
GetManager()->GetWaterManager()->ResetWorldWaterLevel();

Expand Down
9 changes: 9 additions & 0 deletions Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,15 @@ ADD_ENUM(WING_AIRTRAIL, "wing_airtrail")
ADD_ENUM(VEH_GUN, "veh_gun")
IMPLEMENT_ENUM_END("vehicle-dummy")

IMPLEMENT_ENUM_CLASS_BEGIN(eGrainMultiplierType)
ADD_ENUM(eGrainMultiplierType::MASTER, "master")
ADD_ENUM(eGrainMultiplierType::INFRARED, "infrared")
ADD_ENUM(eGrainMultiplierType::NIGHT, "night")
ADD_ENUM(eGrainMultiplierType::RAIN, "rain")
ADD_ENUM(eGrainMultiplierType::OVERLAY, "overlay")
ADD_ENUM(eGrainMultiplierType::ALL, "all")
IMPLEMENT_ENUM_CLASS_END("grain-multiplier-type")

IMPLEMENT_ENUM_CLASS_BEGIN(eResizableVehicleWheelGroup)
ADD_ENUM(eResizableVehicleWheelGroup::FRONT_AXLE, "front_axle")
ADD_ENUM(eResizableVehicleWheelGroup::REAR_AXLE, "rear_axle")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ DECLARE_ENUM(eCursorType)
DECLARE_ENUM(eWheelPosition)
DECLARE_ENUM(D3DPRIMITIVETYPE);
DECLARE_ENUM(eVehicleDummies);
DECLARE_ENUM_CLASS(eGrainMultiplierType);
DECLARE_ENUM_CLASS(eResizableVehicleWheelGroup);
DECLARE_ENUM(eSurfaceProperties);
DECLARE_ENUM(eSurfaceAudio);
Expand Down
14 changes: 14 additions & 0 deletions Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ void CLuaWorldDefs::LoadFunctions()
// World set funcs
{"setTime", SetTime},
{"setColorFilter", ArgumentParser<SetColorFilter>},
{"setGrainMultiplier", ArgumentParser<SetGrainMultiplier>},
{"setGrainLevel", ArgumentParser<SetGrainLevel>},
{"setSkyGradient", SetSkyGradient},
{"setHeatHaze", SetHeatHaze},
{"setWeather", SetWeather},
Expand Down Expand Up @@ -1999,6 +2001,18 @@ bool CLuaWorldDefs::SetColorFilter(uchar ucPass0Red, uchar ucPass0Green, uchar u
return true;
}

bool CLuaWorldDefs::SetGrainMultiplier(eGrainMultiplierType type, float fMultiplier)
{
g_pMultiplayer->SetGrainMultiplier(type, fMultiplier);
return true;
}

bool CLuaWorldDefs::SetGrainLevel(uchar ucLevel)
{
g_pMultiplayer->SetGrainLevel(ucLevel);
return true;
}

bool CLuaWorldDefs::SetCoronaReflectionsEnabled(uchar ucEnabled)
{
if (ucEnabled > 2)
Expand Down
3 changes: 3 additions & 0 deletions Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ class CLuaWorldDefs : public CLuaDefs
static bool SetColorFilter(uchar ucPass0Red, uchar ucPass0Green, uchar ucPass0Blue, uchar ucPass0Alpha, uchar ucPass1Red, uchar ucPass1Green,
uchar ucPass1Blue, uchar ucPass1Alpha);

static bool SetGrainMultiplier(eGrainMultiplierType type, float fMultiplier);
static bool SetGrainLevel(uchar ucLevel);

static bool SetCoronaReflectionsEnabled(uchar ucEnabled);
static uchar GetCoronaReflectionsEnabled();
static bool ResetCoronaReflectionsEnabled();
Expand Down
56 changes: 3 additions & 53 deletions Client/multiplayer_sa/CMultiplayerSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ void CMultiplayerSA::InitHooks()

HookInstall(HOOKPOS_CAnimManager_AddAnimation, (DWORD)HOOK_CAnimManager_AddAnimation, 10);
HookInstall(HOOKPOS_CAnimManager_AddAnimationAndSync, (DWORD)HOOK_CAnimManager_AddAnimationAndSync, 10);
HookInstall(HOOKPOS_CAnimManager_BlendAnimation_Hierarchy, (DWORD)HOOK_CAnimManager_BlendAnimation_Hierarchy, 5);
HookInstall(HOOKPOS_CAnimManager_BlendAnimation_Hierarchy, (DWORD)HOOK_CAnimManager_BlendAnimation_Hierarchy, 5);

HookInstall(HOOKPOS_CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume_StartRadio,
(DWORD)HOOK_CAEAmbienceTrackManager__UpdateAmbienceTrackAndVolume_StartRadio, 5);
Expand Down Expand Up @@ -1593,6 +1593,8 @@ void CMultiplayerSA::InitHooks()
InitHooks_FrameRateFixes();
InitHooks_ProjectileCollisionFix();
InitHooks_ObjectStreamerOptimization();

InitHooks_Postprocess();
}

// Used to store copied pointers for explosions in the FxSystem
Expand Down Expand Up @@ -3956,58 +3958,6 @@ void CMultiplayerSA::RebuildMultiplayerPlayer(CPed* player)
TIMING_CHECKPOINT("-RebuldMulplrPlr");
}

void CMultiplayerSA::SetNightVisionEnabled(bool bEnabled, bool bNoiseEnabled)
{
if (bEnabled)
{
MemPutFast<BYTE>(0xC402B8, 1);
}
else
{
MemPutFast<BYTE>(0xC402B8, 0);
}
if (bNoiseEnabled)
{
BYTE originalCodes[5] = {0xE8, 0xD3, 0xE8, 0xFF, 0xFF};
MemCpy((void*)0x704EE8, &originalCodes, 5);
}
else
{
MemSet((void*)0x704EE8, 0x90, 5);
}
}

void CMultiplayerSA::SetThermalVisionEnabled(bool bEnabled, bool bNoiseEnabled)
{
if (bEnabled)
{
MemPutFast<BYTE>(0xC402B9, 1);
}
else
{
MemPutFast<BYTE>(0xC402B9, 0);
}
if (bNoiseEnabled)
{
BYTE originalCodes[5] = {0xE8, 0x62, 0xE8, 0xFF, 0xFF};
MemCpy((void*)0x704F59, &originalCodes, 5);
}
else
{
MemSet((void*)0x704F59, 0x90, 5);
}
}

bool CMultiplayerSA::IsNightVisionEnabled()
{
return (*(BYTE*)0xC402B8 == 1);
}

bool CMultiplayerSA::IsThermalVisionEnabled()
{
return (*(BYTE*)0xC402B9 == 1);
}

float CMultiplayerSA::GetGlobalGravity()
{
return fGlobalGravity;
Expand Down
3 changes: 3 additions & 0 deletions Client/multiplayer_sa/CMultiplayerSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class CMultiplayerSA : public CMultiplayer
void InitHooks_FrameRateFixes();
void InitHooks_ProjectileCollisionFix();
void InitHooks_ObjectStreamerOptimization();
void InitHooks_Postprocess();
CRemoteDataStorage* CreateRemoteDataStorage();
void DestroyRemoteDataStorage(CRemoteDataStorage* pData);
void AddRemoteDataStorage(CPlayerPed* pPed, CRemoteDataStorage* pData);
Expand Down Expand Up @@ -154,6 +155,8 @@ class CMultiplayerSA : public CMultiplayer
void GetHeatHaze(SHeatHazeSettings& settings);
void ResetColorFilter();
void SetColorFilter(DWORD dwPass0Color, DWORD dwPass1Color);
void SetGrainMultiplier(eGrainMultiplierType type, float fMultiplier);
void SetGrainLevel(BYTE ucLevel);
void ResetHeatHaze();
void SetHeatHazeEnabled(bool bEnabled);
void ApplyHeatHazeEnabled();
Expand Down
193 changes: 193 additions & 0 deletions Client/multiplayer_sa/CMultiplayerSA_Postprocess.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* LICENSE: See LICENSE in the top level directory
* FILE: multiplayer_sa/CMultiplayerSA_Postprocess.cpp
*
* Multi Theft Auto is available from http://www.multitheftauto.com/
*
*****************************************************************************/

#include "StdInc.h"

#define HOOKPOS_GrainEffect_NightModifier 0x704EE8
#define HOOKPOS_GrainEffect_InfraredModifier 0x704F59
#define HOOKPOS_GrainEffect_RainModifier 0x705078
#define HOOKPOS_GrainEffect_OverlayModifier 0x705091

namespace GrainEffect
{

static BYTE ucGrainEnabled = FALSE;
static DWORD dwGrainStrength = 1;

struct MasterModifier
{
static float fMultiplier;

static int ApplyEffect(BYTE ucLevel, BYTE ucUpdate)
{
return ((int(__cdecl*)(char, char))0x7037C0)(ucLevel * fMultiplier, ucUpdate);
}
};

struct InfraredModifier
{
static float fMultiplier;

static int ApplyEffect(BYTE ucLevel, BYTE ucUpdate)
{
return MasterModifier::ApplyEffect(ucLevel * fMultiplier, ucUpdate);
}
};

struct NightModifier
{
static float fMultiplier;

static int ApplyEffect(BYTE ucLevel, BYTE ucUpdate)
{
return MasterModifier::ApplyEffect(ucLevel * fMultiplier, ucUpdate);
}
};

struct RainModifier
{
static float fMultiplier;

static int ApplyEffect(BYTE ucLevel, BYTE ucUpdate)
{
return MasterModifier::ApplyEffect(ucLevel * fMultiplier, ucUpdate);
}
};

struct OverlayModifier
{
static float fMultiplier;

static int ApplyEffect(BYTE ucLevel, BYTE ucUpdate)
{
return MasterModifier::ApplyEffect(ucLevel * fMultiplier, ucUpdate);
}
};

float MasterModifier::fMultiplier = 1.0f;
float InfraredModifier::fMultiplier = 1.0f;
float NightModifier::fMultiplier = 1.0f;
float RainModifier::fMultiplier = 1.0f;
float OverlayModifier::fMultiplier = 1.0f;

}

void CMultiplayerSA::SetGrainMultiplier(eGrainMultiplierType type, float fMultiplier)
{
using namespace GrainEffect;

fMultiplier = Clamp(0.0f, fMultiplier, 1.0f);

switch (type)
{
case eGrainMultiplierType::MASTER:
MasterModifier::fMultiplier = fMultiplier;
break;
case eGrainMultiplierType::INFRARED:
InfraredModifier::fMultiplier = fMultiplier;
break;
case eGrainMultiplierType::NIGHT:
NightModifier::fMultiplier = fMultiplier;
break;
case eGrainMultiplierType::RAIN:
RainModifier::fMultiplier = fMultiplier;
break;
case eGrainMultiplierType::OVERLAY:
OverlayModifier::fMultiplier = fMultiplier;
break;
case eGrainMultiplierType::ALL:
MasterModifier::fMultiplier = InfraredModifier::fMultiplier = NightModifier::fMultiplier = RainModifier::fMultiplier = OverlayModifier::fMultiplier = fMultiplier;
break;
default:
break;
}
}

void CMultiplayerSA::SetGrainLevel(BYTE ucLevel)
{
const bool bOverridden = *(DWORD*)0x705081 != (DWORD)0x00C402B4;
const bool bEnable = ucLevel > 0;

GrainEffect::ucGrainEnabled = static_cast<BYTE>(bEnable);
GrainEffect::dwGrainStrength = static_cast<DWORD>(ucLevel);

if (bEnable == bOverridden)
return;

if (bEnable)
{
MemPut<DWORD>(0x705081, (DWORD)&GrainEffect::ucGrainEnabled);
MemPut<DWORD>(0x70508A, (DWORD)&GrainEffect::dwGrainStrength);
}
else
{
// Restore the original address
MemPut<DWORD>(0x705081, (DWORD)0x00C402B4);
MemPut<DWORD>(0x70508A, (DWORD)0x008D5094);
}
}

void CMultiplayerSA::SetNightVisionEnabled(bool bEnabled, bool bNoiseEnabled)
{
if (bEnabled)
{
MemPutFast<BYTE>(0xC402B8, 1);
}
else
{
MemPutFast<BYTE>(0xC402B8, 0);
}
if (bNoiseEnabled)
{
HookInstallCall(0x704EE8, (DWORD)GrainEffect::NightModifier::ApplyEffect);
}
else
{
MemSet((void*)0x704EE8, 0x90, 5);
}
}

void CMultiplayerSA::SetThermalVisionEnabled(bool bEnabled, bool bNoiseEnabled)
{
if (bEnabled)
{
MemPutFast<BYTE>(0xC402B9, 1);
}
else
{
MemPutFast<BYTE>(0xC402B9, 0);
}
if (bNoiseEnabled)
{
HookInstallCall(0x704F59, (DWORD)GrainEffect::InfraredModifier::ApplyEffect);
}
else
{
MemSet((void*)0x704F59, 0x90, 5);
}
}

bool CMultiplayerSA::IsNightVisionEnabled()
{
return (*(BYTE*)0xC402B8 == 1);
}

bool CMultiplayerSA::IsThermalVisionEnabled()
{
return (*(BYTE*)0xC402B9 == 1);
}

void CMultiplayerSA::InitHooks_Postprocess()
{
HookInstallCall(HOOKPOS_GrainEffect_NightModifier, (DWORD)GrainEffect::NightModifier::ApplyEffect);
HookInstallCall(HOOKPOS_GrainEffect_InfraredModifier, (DWORD)GrainEffect::InfraredModifier::ApplyEffect);
HookInstallCall(HOOKPOS_GrainEffect_RainModifier, (DWORD)GrainEffect::RainModifier::ApplyEffect);
HookInstallCall(HOOKPOS_GrainEffect_OverlayModifier, (DWORD)GrainEffect::OverlayModifier::ApplyEffect);
}
12 changes: 12 additions & 0 deletions Client/sdk/multiplayer/CMultiplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ enum EVehicleWeaponType : int
HEAT_SEEKING_ROCKET,
};

enum class eGrainMultiplierType
{
MASTER = 0,
INFRARED,
NIGHT,
RAIN,
OVERLAY,
ALL
};

struct SVehicleWeaponHitEvent
{
EVehicleWeaponType weaponType;
Expand Down Expand Up @@ -260,6 +270,8 @@ class CMultiplayer
virtual void GetHeatHaze(SHeatHazeSettings& settings) = 0;
virtual void ResetColorFilter() = 0;
virtual void SetColorFilter(DWORD dwPass0Color, DWORD dwPass1Color) = 0;
virtual void SetGrainMultiplier(eGrainMultiplierType type, float fMultiplier) = 0;
virtual void SetGrainLevel(BYTE ucLevel) = 0;
virtual void ResetHeatHaze() = 0;
virtual void SetHeatHazeEnabled(bool bEnabled) = 0;
virtual bool HasWaterColor() = 0;
Expand Down

0 comments on commit b01fcd2

Please sign in to comment.