Skip to content

Commit

Permalink
reconfigurable limits and spark intensity
Browse files Browse the repository at this point in the history
  • Loading branch information
xan1242 committed Feb 21, 2023
1 parent 54f0c05 commit 9c0f7f3
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 32 deletions.
8 changes: 7 additions & 1 deletion NFSMW_XenonEffects.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ UseCGStyle = 0
ContrailSpeed = 44.0
; Controls the state of the contrail rate limiter
LimitContrailRate = 1
; Controls the state of the spark rate limiter
; Controls the state of the spark & other emitters rate limiter
LimitSparkRate = 1

[Limits]
Expand All @@ -26,3 +26,9 @@ SparkTargetFPS = 60.0
; If UseCGStyle is enabled, the intensity is not calculated and only uses MaxIntensity.
ContrailMinIntensity = 0.1
ContrailMaxIntensity = 0.75
; Controls the intensity value of sparks & other emitters. Only works if the emitter has the "zContrail" property enabled.
SparkIntensity = 1.0
; Controls the maximum number of generated particles.
MaxParticles = 10000
; Controls the size of the NGEffectList. This may affect the visibility of particles on screen.
NGEffectListSize = 500
72 changes: 41 additions & 31 deletions dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
// by Xan/Tenjoin

// BUG LIST:
// - particles stay in the world after restart - MAKE A XENON EFFECT RESET
// - contrails get overwritten by sparks
// - Reconfigurable limits
// - particle collision & bouncing
// - particles stay in the world after restart - MAKE A XENON EFFECT RESET
// - contrails get overwritten by sparks at high rates
//

#include "stdafx.h"
Expand All @@ -20,6 +19,7 @@

#pragma runtime_checks( "", off )

// uncomment to enable contrail test near the SkipFE start location in MW's map (next to car lot in College/Rosewood)
//#define CONTRAIL_TEST

bool bContrails = true;
Expand All @@ -33,7 +33,10 @@ float SparkTargetFPS = 60.0f;
float ContrailSpeed = 44.0f;
float ContrailMinIntensity = 0.1f;
float ContrailMaxIntensity = 0.75f;
float SparkIntensity = 1.0f;
char TPKfilename[128] = { "GLOBAL\\XenonEffects.tpk" };
uint32_t MaxParticles = 10000;
uint32_t NGEffectListSize = 500;

uint32_t ContrailFrameDelay = 1;
uint32_t SparkFrameDelay = 1;
Expand All @@ -48,13 +51,6 @@ uint32_t SparkFrameDelay = 1;
#define FRAMECOUNTER_ADDR 0x00982B78
#define eFrameCounter *(uint32_t*)FRAMECOUNTER_ADDR

#define MAX_PARTICLES 10000
#define NGEFFECT_LIST_COUNT 500

#define SIZEOF_NGPARTICLE 0x48
#define PARTICLELIST_SIZE SIZEOF_NGPARTICLE * MAX_PARTICLES


struct bVector3
{
float x;
Expand Down Expand Up @@ -156,13 +152,16 @@ struct NGParticle
unsigned char uv[4];
};

struct ParticleList
{
NGParticle mParticles[MAX_PARTICLES];
unsigned int mNumParticles;
}gParticleList;
//struct ParticleList
//{
// NGParticle mParticles[MAX_PARTICLES];
// unsigned int mNumParticles;
//}gParticleList;

#define numParticles dword ptr gParticleList[PARTICLELIST_SIZE]
NGParticle* gParticleList;
uint32_t NumParticles = 0;

//#define numParticles dword ptr gParticleList[PARTICLELIST_SIZE]

float flt_9C92F0 = 255.0f;
float flt_9C2478 = 1.0f;
Expand Down Expand Up @@ -662,7 +661,7 @@ void(__thiscall* eastl_vector_erase_XenonEffectDef_Abstract)(void* vector, void*
void __stdcall XenonEffectList_Initialize()
{
eastl_vector_reserve_XenonEffectDef_Abstract(&gNGEffectList, NGEFFECT_LIST_COUNT);
eastl_vector_reserve_XenonEffectDef_Abstract(&gNGEffectList, NGEffectListSize);
//eastl_vector_erase_XenonEffectDef_Abstract(&gNGEffectList, gNGEffectList, (void*)((uint32_t)(gNGEffectList + 4)));
}
Expand Down Expand Up @@ -694,7 +693,7 @@ void __declspec(naked) AddXenonEffect() // (AcidEffect *piggyback_fx, Attrib::Co
mov eax, edx
shr eax, 1Fh
add eax, edx
cmp eax, NGEFFECT_LIST_COUNT ; 'd'
cmp eax, NGEffectListSize; 'd'
jnb loc_754DA5
push esi
mov ecx, 10h
Expand Down Expand Up @@ -1026,8 +1025,8 @@ void __declspec(naked) ParticleList_AgeParticles()
push ebx
push ebp
mov ebp, ecx
mov ecx, [ebp+PARTICLELIST_SIZE]
lea edx, [ebp+PARTICLELIST_SIZE]
mov ecx, NumParticles
lea edx, NumParticles
xor eax, eax
cmp ecx, eax
mov ebx, ebp
Expand Down Expand Up @@ -1300,16 +1299,17 @@ loc_73F50C: ; CODE XREF: CGEmitter::SpawnParticles(f
loc_73F540: ; CODE XREF: CGEmitter::SpawnParticles(float,float)+5ED↓j
fld dword ptr [esp+20h]
mov eax, numParticles
cmp eax, MAX_PARTICLES
mov eax, NumParticles
cmp eax, MaxParticles
fsub ds:flt_9C2478
fstp dword ptr [esp+20h]
jnb loc_73F913
lea esi, [eax+eax*8]
lea esi, gParticleList[esi*8] ; ParticleList gParticleList
mov ecx, gParticleList
lea esi, [ecx+esi*8] ; ParticleList gParticleList
inc eax
test esi, esi
mov numParticles, eax
mov NumParticles, eax
jz loc_73F913
mov eax, [ebp+4]
mov ecx, [eax+84h]
Expand Down Expand Up @@ -2103,7 +2103,7 @@ void __declspec(naked) DrawXenonEmitters(void* eView)
mov ecx, eax
push edi
push ecx; float
mov ecx, offset gParticleList
mov ecx, gParticleList
mov[esp + 10h], eax
mov EmitterDeltaTime, 0
call ParticleList_AgeParticles
Expand Down Expand Up @@ -2148,12 +2148,12 @@ void __declspec(naked) DrawXenonEmitters(void* eView)
push eax
mov ecx, offset gNGEffectList
call eastl_vector_erase_XenonEffectDef
mov eax, numParticles
mov eax, NumParticles
test eax, eax
jz loc_754CA6
mov ecx, [ebp + 8]
push eax
push offset gParticleList
push gParticleList
push ecx
mov ecx, offset NGSpriteManager
call XSpriteManager_AddParticle
Expand Down Expand Up @@ -2301,7 +2301,8 @@ void __declspec(naked) InitializeRenderObj()
lea eax, [esp]
push eax
mov ecx, offset NGSpriteManager_ClassData
mov dword ptr[esp + 4], MAX_PARTICLES
mov eax, MaxParticles
mov dword ptr[esp + 4], eax
call sub_743DF0
push 0
push 1
Expand Down Expand Up @@ -2343,7 +2344,7 @@ void __stdcall XSpriteManager_DrawBatch(eView* view)
effect->BeginPass(0);
g_D3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
if (sm->vert_count && gParticleList.mNumParticles)
if (sm->vert_count && NumParticles)
{
g_D3DDevice->SetStreamSource(0, sm->vertex_buffer, 0, 0x18);
g_D3DDevice->SetIndices(sm->index_buffer);
Expand Down Expand Up @@ -2398,14 +2399,14 @@ uint32_t SparkFC = 0;
void AddXenonEffect_Spark_Hook(void* piggyback_fx, void* spec, bMatrix4* mat, bVector4* vel, float intensity)
{
if (!bLimitSparkRate)
return AddXenonEffect_Abstract(piggyback_fx, spec, mat, vel, intensity);
return AddXenonEffect_Abstract(piggyback_fx, spec, mat, vel, SparkIntensity);
if ((SparkFC + SparkFrameDelay) <= eFrameCounter)
{
if (SparkFC != eFrameCounter)
{
SparkFC = eFrameCounter;
AddXenonEffect_Abstract(piggyback_fx, spec, mat, vel, intensity);
AddXenonEffect_Abstract(piggyback_fx, spec, mat, vel, SparkIntensity);
}
}
}
Expand Down Expand Up @@ -2684,6 +2685,12 @@ void InitConfig()
ContrailMinIntensity = std::stof(ini["Limits"]["ContrailMinIntensity"]);
if (ini["Limits"].has("ContrailMaxIntensity"))
ContrailMaxIntensity = std::stof(ini["Limits"]["ContrailMaxIntensity"]);
if (ini["Limits"].has("SparkIntensity"))
SparkIntensity = std::stof(ini["Limits"]["SparkIntensity"]);
if (ini["Limits"].has("MaxParticles"))
MaxParticles = std::stol(ini["Limits"]["MaxParticles"]);
if (ini["Limits"].has("NGEffectListSize"))
NGEffectListSize = std::stol(ini["Limits"]["NGEffectListSize"]);
}
Expand All @@ -2698,6 +2705,9 @@ void InitConfig()
int Init()
{
// allocate for effect list
gParticleList = (NGParticle*)calloc(MaxParticles, sizeof(NGParticle));
// delta time stealer
injector::MakeCALL(0x0050D43C, EmitterSystem_Update_Hook, true);
Expand Down

0 comments on commit 9c0f7f3

Please sign in to comment.