Particle, ParticleMgr done #2

Merged
Fire-Head merged 4 commits from master into master 6 years ago

@ -1,3 +1,6 @@
class CGeneral class CGeneral
{ {
public: public:
@ -11,5 +14,8 @@ public:
{ return myrand() & 0xFFFF; } { return myrand() & 0xFFFF; }
// Probably don't want to ever reach high // Probably don't want to ever reach high
static float GetRandomNumberInRange(float low, float high) static float GetRandomNumberInRange(float low, float high)
{ return low + (high - low)*(GetRandomNumber()/65536.0f); } { return low + (high - low)*(GetRandomNumber()/float(MY_RAND_MAX + 1)); }
static Int32 GetRandomNumberInRange(Int32 low, Int32 high)
{ return low + (high - low)*(GetRandomNumber()/float(MY_RAND_MAX + 1)); }
}; };

@ -0,0 +1,252 @@
#include "common.h"
#include "patcher.h"
#include "FileMgr.h"
#include "ParticleMgr.h"
_TODO("work_buff");
UInt8 work_buff[55000];
cParticleSystemMgr mod_ParticleSystemManager;
const Char *ParticleFilename = "PARTICLE.CFG";
//cParticleSystemMgr::cParticleSystemMgr()
void cParticleSystemMgr::ctor()
{
memset(this, 0, sizeof(*this));
}
void cParticleSystemMgr::Initialise()
{
LoadParticleData();
for ( Int32 i = 0; i < MAX_PARTICLES; i++ )
m_aParticles[i].m_pParticles = NULL;
}
void cParticleSystemMgr::LoadParticleData()
{
CFileMgr::SetDir("DATA");
CFileMgr::LoadFile(ParticleFilename, work_buff, ARRAY_SIZE(work_buff), "r");
CFileMgr::SetDir("");
tParticleSystemData *entry = NULL;
Int32 type = PARTICLE_FIRST;
Char *lineStart = (Char *)work_buff;
Char *lineEnd = lineStart + 1;
Char line[500];
Char delims[4];
while ( true )
{
ASSERT(lineStart != NULL);
ASSERT(lineEnd != NULL);
while ( *lineEnd != '\n' )
++lineEnd;
Int32 lineLength = lineEnd - lineStart;
ASSERT(lineLength < 500);
strncpy(line, lineStart, lineLength);
line[lineLength] = '\0';
if ( !strcmp(line, ";the end") )
break;
if ( *line != ';' )
{
Int32 param = CFG_PARAM_FIRST;
strcpy(delims, " \t");
Char *value = strtok(line, delims);
ASSERT(value != NULL);
do
{
switch ( param )
{
case CFG_PARAM_PARTICLE_TYPE_NAME:
ASSERT(type < MAX_PARTICLES);
entry = &m_aParticles[type];
ASSERT(entry != NULL);
entry->m_Type = (tParticleType)type++;
strcpy(entry->m_aName, value);
break;
case CFG_PARAM_RENDER_COLOURING_R:
entry->m_RenderColouring.red = atoi(value);
break;
case CFG_PARAM_RENDER_COLOURING_G:
entry->m_RenderColouring.green = atoi(value);
break;
case CFG_PARAM_RENDER_COLOURING_B:
entry->m_RenderColouring.blue = atoi(value);
break;
case CFG_PARAM_INITIAL_COLOR_VARIATION:
entry->m_InitialColorVariation = min(atoi(value), 100);
break;
case CFG_PARAM_FADE_DESTINATION_COLOR_R:
entry->m_FadeDestinationColor.red = atoi(value);
break;
case CFG_PARAM_FADE_DESTINATION_COLOR_G:
entry->m_FadeDestinationColor.green = atoi(value);
break;
case CFG_PARAM_FADE_DESTINATION_COLOR_B:
entry->m_FadeDestinationColor.blue = atoi(value);
break;
case CFG_PARAM_COLOR_FADE_TIME:
entry->m_ColorFadeTime = atoi(value);
break;
case CFG_PARAM_DEFAULT_INITIAL_RADIUS:
entry->m_fDefaultInitialRadius = atof(value);
break;
case CFG_PARAM_EXPANSION_RATE:
entry->m_fExpansionRate = atof(value);
break;
case CFG_PARAM_INITIAL_INTENSITY:
entry->m_nFadeToBlackInitialIntensity = atoi(value);
break;
case CFG_PARAM_FADE_TIME:
entry->m_nFadeToBlackTime = atoi(value);
break;
case CFG_PARAM_FADE_AMOUNT:
entry->m_nFadeToBlackAmount = atoi(value);
break;
case CFG_PARAM_INITIAL_ALPHA_INTENSITY:
entry->m_nFadeAlphaInitialIntensity = atoi(value);
break;
case CFG_PARAM_FADE_ALPHA_TIME:
entry->m_nFadeAlphaTime = atoi(value);
break;
case CFG_PARAM_FADE_ALPHA_AMOUNT:
entry->m_nFadeAlphaAmount = atoi(value);
break;
case CFG_PARAM_INITIAL_ANGLE:
entry->m_nZRotationInitialAngle = atoi(value);
break;
case CFG_PARAM_CHANGE_TIME:
entry->m_nZRotationChangeTime = atoi(value);
break;
case CFG_PARAM_ANGLE_CHANGE_AMOUNT:
entry->m_nZRotationAngleChangeAmount = atoi(value);
break;
case CFG_PARAM_INITIAL_Z_RADIUS:
entry->m_fInitialZRadius = atof(value);
break;
case CFG_PARAM_Z_RADIUS_CHANGE_TIME:
entry->m_nZRadiusChangeTime = atoi(value);
break;
case CFG_PARAM_Z_RADIUS_CHANGE_AMOUNT:
entry->m_fZRadiusChangeAmount = atof(value);
break;
case CFG_PARAM_ANIMATION_SPEED:
entry->m_nAnimationSpeed = atoi(value);
break;
case CFG_PARAM_START_ANIMATION_FRAME:
entry->m_nStartAnimationFrame = atoi(value);
break;
case CFG_PARAM_FINAL_ANIMATION_FRAME:
entry->m_nFinalAnimationFrame = atoi(value);
break;
case CFG_PARAM_ROTATION_SPEED:
entry->m_nRotationSpeed = atoi(value);
break;
case CFG_PARAM_GRAVITATIONAL_ACCELERATION:
entry->m_fGravitationalAcceleration = atof(value);
break;
case CFG_PARAM_FRICTION_DECCELERATION:
entry->m_nFrictionDecceleration = atoi(value);
break;
case CFG_PARAM_LIFE_SPAN:
entry->m_nLifeSpan = atoi(value);
break;
case CFG_PARAM_POSITION_RANDOM_ERROR:
entry->m_fPositionRandomError = atof(value);
break;
case CFG_PARAM_VELOCITY_RANDOM_ERROR:
entry->m_fVelocityRandomError = atof(value);
break;
case CFG_PARAM_EXPANSION_RATE_ERROR:
entry->m_fExpansionRateError = atof(value);
break;
case CFG_PARAM_ROTATION_RATE_ERROR:
entry->m_nRotationRateError = atoi(value);
break;
case CFG_PARAM_LIFE_SPAN_ERROR_SHAPE:
entry->m_nLifeSpanErrorShape = atoi(value);
break;
case CFG_PARAM_TRAIL_LENGTH_MULTIPLIER:
entry->m_fTrailLengthMultiplier = atof(value);
break;
case CFG_PARAM_PARTICLE_CREATE_RANGE:
entry->m_fCreateRange = SQR(atof(value));
break;
case CFG_PARAM_FLAGS:
entry->Flags = atoi(value);
break;
}
value = strtok(NULL, delims);
param++;
if ( param > CFG_PARAM_LAST )
param = CFG_PARAM_FIRST;
} while ( value != NULL );
}
lineEnd++;
lineStart = lineEnd;
lineEnd++;
}
}
STARTPATCHES
InjectHook(0x50FCB0, &cParticleSystemMgr::ctor, PATCH_JUMP);
InjectHook(0x50FCD0, &cParticleSystemMgr::Initialise, PATCH_JUMP);
InjectHook(0x50FDF0, &cParticleSystemMgr::LoadParticleData, PATCH_JUMP);
ENDPATCHES

@ -0,0 +1,206 @@
#pragma once
class CParticle;
enum tParticleType
{
PARTICLE_SPARK = 0,
PARTICLE_SPARK_SMALL,
PARTICLE_WHEEL_DIRT,
PARTICLE_WHEEL_WATER,
PARTICLE_BLOOD,
PARTICLE_BLOOD_SMALL,
PARTICLE_BLOOD_SPURT,
PARTICLE_DEBRIS,
PARTICLE_DEBRIS2,
PARTICLE_WATER,
PARTICLE_FLAME,
PARTICLE_FIREBALL,
PARTICLE_GUNFLASH,
PARTICLE_GUNFLASH_NOANIM,
PARTICLE_GUNSMOKE,
PARTICLE_GUNSMOKE2,
PARTICLE_SMOKE,
PARTICLE_SMOKE_SLOWMOTION,
PARTICLE_GARAGEPAINT_SPRAY,
PARTICLE_SHARD,
PARTICLE_SPLASH,
PARTICLE_CARFLAME,
PARTICLE_STEAM,
PARTICLE_STEAM2,
PARTICLE_STEAM_NY,
PARTICLE_STEAM_NY_SLOWMOTION,
PARTICLE_ENGINE_STEAM,
PARTICLE_RAINDROP,
PARTICLE_RAINDROP_SMALL,
PARTICLE_RAIN_SPLASH,
PARTICLE_RAIN_SPLASH_BIGGROW,
PARTICLE_RAIN_SPLASHUP,
PARTICLE_WATERSPRAY,
PARTICLE_EXPLOSION_MEDIUM,
PARTICLE_EXPLOSION_LARGE,
PARTICLE_EXPLOSION_MFAST,
PARTICLE_EXPLOSION_LFAST,
PARTICLE_CAR_SPLASH,
PARTICLE_BOAT_SPLASH,
PARTICLE_BOAT_THRUSTJET,
PARTICLE_BOAT_WAKE,
PARTICLE_WATER_HYDRANT,
PARTICLE_WATER_CANNON,
PARTICLE_EXTINGUISH_STEAM,
PARTICLE_PED_SPLASH,
PARTICLE_PEDFOOT_DUST,
PARTICLE_HELI_DUST,
PARTICLE_HELI_ATTACK,
PARTICLE_ENGINE_SMOKE,
PARTICLE_ENGINE_SMOKE2,
PARTICLE_CARFLAME_SMOKE,
PARTICLE_FIREBALL_SMOKE,
PARTICLE_PAINT_SMOKE,
PARTICLE_TREE_LEAVES,
PARTICLE_CARCOLLISION_DUST,
PARTICLE_CAR_DEBRIS,
PARTICLE_HELI_DEBRIS,
PARTICLE_EXHAUST_FUMES,
PARTICLE_RUBBER_SMOKE,
PARTICLE_BURNINGRUBBER_SMOKE,
PARTICLE_BULLETHIT_SMOKE,
PARTICLE_GUNSHELL_FIRST,
PARTICLE_GUNSHELL,
PARTICLE_GUNSHELL_BUMP1,
PARTICLE_GUNSHELL_BUMP2,
PARTICLE_TEST,
PARTICLE_BIRD_FRONT,
PARTICLE_RAINDROP_2D,
MAX_PARTICLES,
PARTICLE_FIRST = PARTICLE_SPARK,
PARTICLE_LAST = PARTICLE_RAINDROP_2D
};
enum
{
ZCHECK_FIRST = BIT(0),
ZCHECK_STEP = BIT(1),
DRAW_OPAQUE = BIT(2),
SCREEN_TRAIL = BIT(3),
SPEED_TRAIL = BIT(4),
RAND_VERT_V = BIT(5),
CYCLE_ANIM = BIT(6),
DRAW_DARK = BIT(7),
VERT_TRAIL = BIT(8),
_FLAG9 = BIT(9), // unused
DRAWTOP2D = BIT(10),
CLIPOUT2D = BIT(11),
ZCHECK_BUMP = BIT(12),
ZCHECK_BUMP_FIRST = BIT(13)
};
struct tParticleSystemData
{
tParticleType m_Type;
Char m_aName[20];
Float m_fCreateRange;
Float m_fDefaultInitialRadius;
Float m_fExpansionRate;
UInt16 m_nZRotationInitialAngle;
Int16 m_nZRotationAngleChangeAmount;
UInt16 m_nZRotationChangeTime;
UInt16 m_nZRadiusChangeTime;
Float m_fInitialZRadius;
Float m_fZRadiusChangeAmount;
UInt16 m_nFadeToBlackTime;
Int16 m_nFadeToBlackAmount;
UInt8 m_nFadeToBlackInitialIntensity;
UInt8 m_nFadeAlphaInitialIntensity;
UInt16 m_nFadeAlphaTime;
Int16 m_nFadeAlphaAmount;
UInt16 m_nStartAnimationFrame;
UInt16 m_nFinalAnimationFrame;
UInt16 m_nAnimationSpeed;
UInt16 m_nRotationSpeed;
char _pad1[2];
Float m_fGravitationalAcceleration;
Int32 m_nFrictionDecceleration;
Int32 m_nLifeSpan;
Float m_fPositionRandomError;
Float m_fVelocityRandomError;
Float m_fExpansionRateError;
Int32 m_nRotationRateError;
UInt32 m_nLifeSpanErrorShape;
Float m_fTrailLengthMultiplier;
UInt32 Flags;
RwRGBA m_RenderColouring;
UInt8 m_InitialColorVariation;
RwRGBA m_FadeDestinationColor;
char _pad2[3];
UInt32 m_ColorFadeTime;
RwRaster **m_ppRaster;
CParticle *m_pParticles;
};
VALIDATE_SIZE(tParticleSystemData, 0x88);
class cParticleSystemMgr
{
enum
{
CFG_PARAM_PARTICLE_TYPE_NAME = 0,
CFG_PARAM_RENDER_COLOURING_R,
CFG_PARAM_RENDER_COLOURING_G,
CFG_PARAM_RENDER_COLOURING_B,
CFG_PARAM_INITIAL_COLOR_VARIATION,
CFG_PARAM_FADE_DESTINATION_COLOR_R,
CFG_PARAM_FADE_DESTINATION_COLOR_G,
CFG_PARAM_FADE_DESTINATION_COLOR_B,
CFG_PARAM_COLOR_FADE_TIME,
CFG_PARAM_DEFAULT_INITIAL_RADIUS,
CFG_PARAM_EXPANSION_RATE,
CFG_PARAM_INITIAL_INTENSITY,
CFG_PARAM_FADE_TIME,
CFG_PARAM_FADE_AMOUNT,
CFG_PARAM_INITIAL_ALPHA_INTENSITY,
CFG_PARAM_FADE_ALPHA_TIME,
CFG_PARAM_FADE_ALPHA_AMOUNT,
CFG_PARAM_INITIAL_ANGLE,
CFG_PARAM_CHANGE_TIME,
CFG_PARAM_ANGLE_CHANGE_AMOUNT,
CFG_PARAM_INITIAL_Z_RADIUS,
CFG_PARAM_Z_RADIUS_CHANGE_TIME,
CFG_PARAM_Z_RADIUS_CHANGE_AMOUNT,
CFG_PARAM_ANIMATION_SPEED,
CFG_PARAM_START_ANIMATION_FRAME,
CFG_PARAM_FINAL_ANIMATION_FRAME,
CFG_PARAM_ROTATION_SPEED,
CFG_PARAM_GRAVITATIONAL_ACCELERATION,
CFG_PARAM_FRICTION_DECCELERATION,
CFG_PARAM_LIFE_SPAN,
CFG_PARAM_POSITION_RANDOM_ERROR,
CFG_PARAM_VELOCITY_RANDOM_ERROR,
CFG_PARAM_EXPANSION_RATE_ERROR,
CFG_PARAM_ROTATION_RATE_ERROR,
CFG_PARAM_LIFE_SPAN_ERROR_SHAPE,
CFG_PARAM_TRAIL_LENGTH_MULTIPLIER,
CFG_PARAM_PARTICLE_CREATE_RANGE,
CFG_PARAM_FLAGS,
MAX_CFG_PARAMS,
CFG_PARAM_FIRST = CFG_PARAM_PARTICLE_TYPE_NAME,
CFG_PARAM_LAST = CFG_PARAM_FLAGS
};
public:
tParticleSystemData m_aParticles[MAX_PARTICLES];
cParticleSystemMgr() { ctor(); } void ctor();
void Initialise();
void LoadParticleData();
//void RangeCheck(tParticleSystemData *pData);
};
VALIDATE_SIZE(cParticleSystemMgr, 0x2420);
extern cParticleSystemMgr mod_ParticleSystemManager;

@ -3,3 +3,16 @@
#include "ParticleObject.h" #include "ParticleObject.h"
WRAPPER void CParticleObject::AddObject(uint16, const CVector &pos, bool remove) { EAXJMP(0x4BC4D0); } WRAPPER void CParticleObject::AddObject(uint16, const CVector &pos, bool remove) { EAXJMP(0x4BC4D0); }
// Converted from static void __cdecl CParticleObject::Initialise() 0x42C760
void CParticleObject::Initialise()
{
((void (__cdecl *)())0x4BC440)();
}
// Converted from static void __cdecl CParticleObject::UpdateAll() 0x4BCA30
void CParticleObject::UpdateAll()
{
((void (__cdecl *)())0x4BCA30)();
}

@ -28,4 +28,6 @@ class CParticleObject
{ {
public: public:
static void AddObject(uint16, const CVector &pos, bool remove); static void AddObject(uint16, const CVector &pos, bool remove);
static void Initialise();
static void UpdateAll();
}; };

@ -0,0 +1,5 @@
#include "common.h"
#include "RecordDataForChase.h"
UInt8 &CRecordDataForChase::Status = *(UInt8*)0x95CDCE;

@ -0,0 +1,7 @@
#pragma once
class CRecordDataForChase
{
public:
static UInt8 &Status;
};

@ -0,0 +1,4 @@
#include "common.h"
#include "RecordDataForGame.h"
UInt16 &CRecordDataForGame::RecordingState = *(UInt16 *)0x95CC24;

@ -0,0 +1,7 @@
#pragma once
class CRecordDataForGame
{
public:
static UInt16 &RecordingState;
};

@ -1,6 +1,10 @@
#include "common.h" #include "common.h"
#include "patcher.h" #include "patcher.h"
#include "DMAudio.h"
#include "Timer.h" #include "Timer.h"
#include "RecordDataForGame.h"
#include "RecordDataForChase.h"
#include <Windows.h>
uint32 &CTimer::m_snTimeInMilliseconds = *(uint32*)0x885B48; uint32 &CTimer::m_snTimeInMilliseconds = *(uint32*)0x885B48;
uint32 &CTimer::m_snTimeInMillisecondsPauseMode = *(uint32*)0x5F7614; uint32 &CTimer::m_snTimeInMillisecondsPauseMode = *(uint32*)0x5F7614;
@ -12,3 +16,217 @@ float &CTimer::ms_fTimeStep = *(float*)0x8E2CB4;
float &CTimer::ms_fTimeStepNonClipped = *(float*)0x8E2C4C; float &CTimer::ms_fTimeStepNonClipped = *(float*)0x8E2C4C;
bool &CTimer::m_UserPause = *(bool*)0x95CD7C; bool &CTimer::m_UserPause = *(bool*)0x95CD7C;
bool &CTimer::m_CodePause = *(bool*)0x95CDB1; bool &CTimer::m_CodePause = *(bool*)0x95CDB1;
UInt32 oldPcTimer;
UInt32 suspendPcTimer;
UInt32 _nCyclesPerMS = 1;
LARGE_INTEGER _oldPerfCounter;
LARGE_INTEGER perfSuspendCounter;
UInt32 suspendDepth;
_TODO("We need skeleton.c for RsTimer()");
RwUInt32 RsTimer(void)
{
return ((RwUInt32 (__cdecl *)())0x584890)();
}
void CTimer::Initialise(void)
{
debug("Initialising CTimer...\n");
ms_fTimeScale = 1.0f;
ms_fTimeStep = 1.0f;
suspendDepth = 0;
m_UserPause = false;
m_CodePause = false;
m_snTimeInMillisecondsNonClipped = 0;
m_snPreviousTimeInMilliseconds = 0;
m_snTimeInMilliseconds = 1;
LARGE_INTEGER perfFreq;
if ( QueryPerformanceFrequency(&perfFreq) )
{
OutputDebugString("Performance counter available\n");
_nCyclesPerMS = UInt32(perfFreq.QuadPart / 1000);
QueryPerformanceCounter(&_oldPerfCounter);
}
else
{
OutputDebugString("Performance counter not available, using millesecond timer\n");
_nCyclesPerMS = 0;
oldPcTimer = RsTimer();
}
m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds;
m_FrameCounter = 0;
DMAudio.ResetTimers(m_snPreviousTimeInMilliseconds);
debug("CTimer ready\n");
}
void CTimer::Shutdown(void)
{
;
}
void CTimer::Update(void)
{
m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds;
if ( (Double)_nCyclesPerMS != 0.0 )
{
LARGE_INTEGER pc;
QueryPerformanceCounter(&pc);
Int64 updInCycles = (pc.LowPart - _oldPerfCounter.LowPart) & 0x7FFFFFFF;
_oldPerfCounter = pc;
Double updInCyclesScaled = (Double)updInCycles * ms_fTimeScale;
Double upd = updInCyclesScaled / (Double)_nCyclesPerMS;
m_snTimeInMillisecondsPauseMode += Int64(upd);
if ( GetIsPaused() )
ms_fTimeStep = 0.0f;
else
{
m_snTimeInMilliseconds = Int64(upd);
m_snTimeInMillisecondsNonClipped += Int64(upd);
ms_fTimeStep = updInCyclesScaled / (Double)_nCyclesPerMS / 20.0;
}
}
else
{
UInt32 timer = RsTimer();
UInt32 updInMs = timer - oldPcTimer;
Double upd = (Double)updInMs * ms_fTimeScale;
oldPcTimer = timer;
m_snTimeInMillisecondsPauseMode += Int64(upd);
if ( GetIsPaused() )
ms_fTimeStep = 0.0f;
else
{
m_snTimeInMilliseconds += Int64(upd);
m_snTimeInMillisecondsNonClipped += Int64(upd);
ms_fTimeStep = upd / 1000.0f * 50.0f;
}
}
if ( ms_fTimeStep < 0.01f && !GetIsPaused() )
ms_fTimeStep = 0.01f;
ms_fTimeStepNonClipped = ms_fTimeStep;
if ( CRecordDataForGame::RecordingState != _TODOCONST(2) )
{
ms_fTimeStep = min(3.0f, ms_fTimeStep);
if ( (m_snTimeInMilliseconds - m_snPreviousTimeInMilliseconds) > 60 )
m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 60;
}
if ( CRecordDataForChase::Status == _TODOCONST(1) )
{
ms_fTimeStep = 1.0f;
m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 16;
}
m_FrameCounter++;
}
void CTimer::Suspend(void)
{
if ( ++suspendDepth > 1 )
return;
if ( (Double)_nCyclesPerMS != 0.0 )
QueryPerformanceCounter(&perfSuspendCounter);
else
suspendPcTimer = RsTimer();
}
void CTimer::Resume(void)
{
if ( --suspendDepth != 0 )
return;
if ( (Double)_nCyclesPerMS != 0.0 )
{
LARGE_INTEGER pc;
QueryPerformanceCounter(&pc);
_oldPerfCounter.LowPart += pc.LowPart - perfSuspendCounter.LowPart;
}
else
oldPcTimer += RsTimer() - suspendPcTimer;
}
UInt32 CTimer::GetCyclesPerMillisecond(void)
{
if (_nCyclesPerMS != 0)
return _nCyclesPerMS;
else
return 1;
}
UInt32 CTimer::GetCurrentTimeInCycles(void)
{
if ( _nCyclesPerMS != 0 )
{
LARGE_INTEGER pc;
QueryPerformanceCounter(&pc);
return (pc.LowPart - _oldPerfCounter.LowPart) & 0x7FFFFFFF;
}
else
return RsTimer() - oldPcTimer;
}
Bool CTimer::GetIsSlowMotionActive(void)
{
return ms_fTimeScale < 1.0f;
}
void CTimer::Stop(void)
{
m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds;
}
void CTimer::StartUserPause(void)
{
m_UserPause = true;
}
void CTimer::EndUserPause(void)
{
m_UserPause = false;
}
#if 0
STARTPATCHES
InjectHook(0x4ACE60, CTimer::Initialise, PATCH_JUMP);
InjectHook(0x4ACF60, CTimer::Shutdown, PATCH_JUMP);
InjectHook(0x4ACF70, CTimer::Update, PATCH_JUMP);
InjectHook(0x4AD310, CTimer::Suspend, PATCH_JUMP);
InjectHook(0x4AD370, CTimer::Resume, PATCH_JUMP);
InjectHook(0x4AD3F0, CTimer::GetCyclesPerMillisecond, PATCH_JUMP);
InjectHook(0x4AD410, CTimer::GetCurrentTimeInCycles, PATCH_JUMP);
InjectHook(0x4AD450, CTimer::GetIsSlowMotionActive, PATCH_JUMP);
InjectHook(0x4AD480, CTimer::Stop, PATCH_JUMP);
InjectHook(0x4AD490, CTimer::StartUserPause, PATCH_JUMP);
InjectHook(0x4AD4A0, CTimer::EndUserPause, PATCH_JUMP);
ENDPATCHES
#endif

@ -17,4 +17,18 @@ public:
static void SetTimeStep(float ts) { ms_fTimeStep = ts; } static void SetTimeStep(float ts) { ms_fTimeStep = ts; }
static uint32 GetFrameCounter(void) { return m_FrameCounter; } static uint32 GetFrameCounter(void) { return m_FrameCounter; }
static uint32 GetTimeInMilliseconds(void) { return m_snTimeInMilliseconds; } static uint32 GetTimeInMilliseconds(void) { return m_snTimeInMilliseconds; }
static inline Bool GetIsPaused() { return m_UserPause || m_CodePause; }
static void Initialise(void);
static void Shutdown(void);
static void Update(void);
static void Suspend(void);
static void Resume(void);
static UInt32 GetCyclesPerMillisecond(void);
static UInt32 GetCurrentTimeInCycles(void);
static Bool GetIsSlowMotionActive(void);
static void Stop(void);
static void StartUserPause(void);
static void EndUserPause(void);
}; };

@ -0,0 +1,7 @@
#include "common.h"
#include "AudioScriptObject.h"
void PlayOneShotScriptObject(UInt8 id, CVector const &pos)
{
((void (__cdecl *)(UInt8, CVector const &))0x57C5F0)(id, pos);
}

@ -0,0 +1,131 @@
#pragma once
enum /*eSounds*/
{
SOUND_TEST_1 = 0,
_SOUND_UNK_1 = 1,
_SOUND_UNK_2 = 2,
_SOUND_UNK_3 = 3,
_SOUND_CLUB_1_S = 4,
_SOUND_CLUB_1_L = 5,
_SOUND_CLUB_2_S = 6,
_SOUND_CLUB_2_L = 7,
_SOUND_CLUB_3_S = 8,
_SOUND_CLUB_3_L = 9,
_SOUND_CLUB_4_S = 10,
_SOUND_CLUB_4_L = 11,
_SOUND_CLUB_5_S = 12,
_SOUND_CLUB_5_L = 13,
_SOUND_CLUB_6_S = 14,
_SOUND_CLUB_6_L = 15,
_SOUND_CLUB_7_S = 16,
_SOUND_CLUB_7_L = 17,
_SOUND_CLUB_8_S = 18,
_SOUND_CLUB_8_L = 19,
_SOUND_CLUB_9_S = 20,
_SOUND_CLUB_9_L = 21,
_SOUND_CLUB_10_S = 22,
_SOUND_CLUB_10_L = 23,
_SOUND_CLUB_11_S = 24,
_SOUND_CLUB_11_L = 25,
_SOUND_CLUB_12_S = 26,
_SOUND_CLUB_12_L = 27,
_SOUND_CLUB_RAGGA_S = 28,
_SOUND_CLUB_RAGGA_L = 29,
SOUND_STRIP_CLUB_LOOP_1_S = 30,
_SOUND_STRIP_CLUB_LOOP_1_L = 31,
SOUND_STRIP_CLUB_LOOP_2_S = 32,
_SOUND_STRIP_CLUB_LOOP_2_L = 33,
_SOUND_SFX_WORKSHOP_1 = 34,
_SOUND_SFX_WORKSHOP_2 = 35,
_SOUND_SAWMILL_LOOP_S = 36,
SOUND_SAWMILL_LOOP_L = 37,
_SOUND_DOG_FOOD_FACTORY_S = 38,
_SOUND_DOG_FOOD_FACTORY_L = 39,
_SOUND_LAUNDERETTE_1 = 40,
_SOUND_LAUNDERETTE_2 = 41,
_SOUND_RESTAURANT_CHINATOWN_S = 42,
_SOUND_RESTAURANT_CHINATOWN_L = 43,
_SOUND_RESTAURANT_ITALY_S = 44,
_SOUND_RESTAURANT_ITALY_L = 45,
_SOUND_RESTAURANT_GENERIC_1_S = 46,
_SOUND_RESTAURANT_GENERIC_1_L = 47,
_SOUND_RESTAURANT_GENERIC_2_S = 48,
_SOUND_RESTAURANT_GENERIC_2_L = 49,
_SOUND_AIRPORT_ANNOUNCEMENT_S = 50,
_SOUND_AIRPORT_ANNOUNCEMENT_L = 51,
_SOUND_SHOP_LOOP_1 = 52,
_SOUND_SHOP_LOOP_2 = 53,
_SOUND_CINEMA_S = 54,
_SOUND_CINEMA_L = 55,
_SOUND_DOCKS_FOGHORN_S = 56,
_SOUND_DOCKS_FOGHORN_L = 57,
_SOUND_HOME_S = 58,
_SOUND_HOME_L = 59,
_SOUND_PIANO_BAR = 60,
_SOUND_CLUB = 61,
SOUND_PORN_CINEMA_1_S = 62,
_SOUND_PORN_CINEMA_1_L = 63,
SOUND_PORN_CINEMA_2_S = 64,
_SOUND_PORN_CINEMA_2_L = 65,
SOUND_PORN_CINEMA_3_S = 66,
_SOUND_PORN_CINEMA_3_L = 67,
_SOUND_BANK_ALARM_LOOP_S = 68,
SOUND_BANK_ALARM_LOOP_L = 69,
_SOUND_POLICE_BALL_LOOP_S = 70,
SOUND_POLICE_BALL_LOOP_L = 71,
_SOUND_RAVE_LOOP_INDUSTRIAL_S = 72,
SOUND_RAVE_LOOP_INDUSTRIAL_L = 73,
_SOUND_UNK_74 = 74,
_SOUND_UNK_75 = 75,
_SOUND_POLICE_CELL_BEATING_LOOP_S = 76,
SOUND_POLICE_CELL_BEATING_LOOP_L = 77,
SOUND_INJURED_PED_MALE_OUCH_S = 78,
SOUND_INJURED_PED_MALE_OUCH_L = 79,
SOUND_INJURED_PED_FEMALE_OUCH_S = 80,
SOUND_INJURED_PED_FEMALE_OUCH_L = 81,
SOUND_EVIDENCE_PICKUP = 82,
SOUND_UNLOAD_GOLD = 83,
_SOUND_RAVE_INDUSTRIAL_S = 84,
_SOUND_RAVE_INDUSTRIAL_L = 85,
_SOUND_RAVE_COMMERCIAL_S = 86,
_SOUND_RAVE_COMMERCIAL_L = 87,
_SOUND_RAVE_SUBURBAN_S = 88,
_SOUND_RAVE_SUBURBAN_L = 89,
_SOUND_GROAN_S = 90,
_SOUND_GROAN_L = 91,
SOUND_GATE_START_CLUNK = 92,
SOUND_GATE_STOP_CLUNK = 93,
SOUND_PART_MISSION_COMPLETE = 94,
SOUND_CHUNKY_RUN_SHOUT = 95,
SOUND_SECURITY_GUARD_RUN_AWAY_SHOUT = 96,
SOUND_RACE_START_1 = 97,
SOUND_RACE_START_2 = 98,
SOUND_RACE_START_3 = 99,
SOUND_RACE_START_GO = 100,
SOUND_SWAT_PED_SHOUT = 101,
SOUND_PRETEND_FIRE_LOOP = 102,
SOUND_AMMUNATION_CHAT_1 = 103,
SOUND_AMMUNATION_CHAT_2 = 104,
SOUND_AMMUNATION_CHAT_3 = 105,
_SOUND_BULLET_WALL_1 = 106,
_SOUND_BULLET_WALL_2 = 107,
_SOUND_BULLET_WALL_3 = 108,
_SOUND_UNK_109 = 109,
_SOUND_GLASSFX2_1 = 110,
_SOUND_GLASSFX2_2 = 111,
_SOUND_PHONE_RING = 112,
_SOUND_UNK_113 = 113,
_SOUND_GLASS_SMASH_1 = 114,
_SOUND_GLASS_SMASH_2 = 115,
_SOUND_GLASS_CRACK = 116,
_SOUND_GLASS_SHARD = 117,
_SOUND_WOODEN_BOX_SMASH = 118,
_SOUND_CARDBOARD_BOX_SMASH = 119,
_SOUND_COL_CAR = 120,
_SOUND_TYRE_BUMP = 121,
_SOUND_BULLET_SHELL_HIT_GROUND_1 = 122,
_SOUND_BULLET_SHELL_HIT_GROUND_2 = 123,
};
extern void PlayOneShotScriptObject(UInt8 id, CVector const &pos);

@ -5,3 +5,9 @@
cDMAudio &DMAudio = *(cDMAudio*)0x95CDBE; cDMAudio &DMAudio = *(cDMAudio*)0x95CDBE;
WRAPPER void cDMAudio::ReportCollision(CEntity *A, CEntity *B, uint8 surfA, uint8 surfB, float impulse, float speed) { EAXJMP(0x57CBE0); } 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);
}

@ -6,5 +6,6 @@ class cDMAudio
{ {
public: public:
void ReportCollision(CEntity *A, CEntity *B, uint8 surfA, uint8 surfB, float impulse, float speed); void ReportCollision(CEntity *A, CEntity *B, uint8 surfA, uint8 surfB, float impulse, float speed);
void ResetTimers(UInt32 timerval);
}; };
extern cDMAudio &DMAudio; extern cDMAudio &DMAudio;

@ -25,6 +25,24 @@ typedef uint32_t uint32;
typedef int32_t int32; typedef int32_t int32;
typedef uintptr_t uintptr; typedef uintptr_t uintptr;
typedef char Int8;
typedef unsigned char UInt8;
typedef signed char SInt8;
typedef short Int16;
typedef unsigned short UInt16;
typedef signed short SInt16;
typedef int Int32;
typedef unsigned int UInt32;
typedef signed int SInt32;
typedef float Float;
typedef double Double;
typedef Int8 Bool; //typedef bool Bool;
typedef char Char;
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
typedef signed __int64 SInt64;
#define nil NULL #define nil NULL
#include "config.h" #include "config.h"
@ -62,6 +80,15 @@ extern RsGlobalType &RsGlobal;
#define SCREENW (RsGlobal.maximumWidth) #define SCREENW (RsGlobal.maximumWidth)
#define SCREENH (RsGlobal.maximumHeight) #define SCREENH (RsGlobal.maximumHeight)
#define DEFAULT_SCREEN_WIDTH (640)
#define DEFAULT_SCREEN_HEIGHT (448)
#define SCREEN_WIDTH Float(RsGlobal.width)
#define SCREEN_HEIGHT Float(RsGlobal.height)
#define SCREEN_STRETCH_X(a) Float( a * ( SCREEN_WIDTH / Float(DEFAULT_SCREEN_WIDTH) ) )
#define SCREEN_STRETCH_Y(a) Float( a * ( SCREEN_HEIGHT / Float(DEFAULT_SCREEN_HEIGHT) ) )
#define SCREEN_FROM_RIGHT(a) Float( SCREEN_WIDTH - SCREEN_STRETCH_X(a) )
#define SCREEN_FROM_BOTTOM(a) Float( SCREEN_HEIGHT - SCREEN_STRETCH_Y(a) )
char *GetUserDirectory(void); char *GetUserDirectory(void);
struct GlobalScene struct GlobalScene
@ -79,22 +106,70 @@ extern GlobalScene &Scene;
class CRGBA class CRGBA
{ {
public: public:
uint8 r, g, b, a; union
{
uint32 color32;
struct { uint8 r, g, b, a; };
struct { uint8 red, green, blue, alpha; };
#ifdef RWCORE_H
struct { RwRGBA rwRGBA; };
#endif
};
CRGBA(void) { } CRGBA(void) { }
CRGBA(uint8 r, uint8 g, uint8 b, uint8 a) : r(r), g(g), b(b), a(a) { } CRGBA(uint8 r, uint8 g, uint8 b, uint8 a) : r(r), g(g), b(b), a(a) { }
#ifdef RWCORE_H
operator RwRGBA &(void)
{
return rwRGBA;
}
operator RwRGBA *(void)
{
return &rwRGBA;
}
operator RwRGBA (void) const
{
return rwRGBA;
}
#endif
}; };
inline float // inline float clamp(float v, float min, float max){ return v<min ? min : v>max ? max : v; }
clamp(float v, float min, float max){ return v<min ? min : v>max ? max : v; }
inline float inline float
sq(float x) { return x*x; } sq(float x) { return x*x; }
#define SQR(x) ( x * x )
#define PI M_PI #define PI M_PI
#define DEGTORAD(d) (d/180.0f*PI) #define DEGTORAD(x) ((x) * PI / 180.0f)
#define RADTODEG(x) ((x) * 180.0f / PI)
#if USE_PS2_RAND == TRUE
#define MY_RAND_MAX 65535
#else
#define MY_RAND_MAX 32767
#endif
int myrand(void); int myrand(void);
void mysrand(unsigned int seed); void mysrand(unsigned int seed);
#define debug printf #define debug printf
#define ASSERT assert
#define _TODO(x)
#define _TODOCONST(x) (x)
#define VALIDATE_SIZE(struc, size) static_assert(sizeof(struc) == size, "Invalid structure size of " #struc)
#define VALIDATE_OFFSET(struc, member, offset) static_assert(offsetof(struc, member) == offset, "The offset of " #member " in " #struc " is not " #offset "...")
#define clamp(v, a, b) (max(min(v, b), a))
//#define min(a, b) ((a) < (b) ? (a) : (b)) //#define min(a, b) ((a) < (b) ? (a) : (b))
//#define max(a, b) ((a) > (b) ? (a) : (b)) //#define max(a, b) ((a) > (b) ? (a) : (b))
#define PERCENT(x, p) ( ( Float(x) * ( Float(p) / 100.0f ) ) )
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
#define BIT(num) (1<<(num))

@ -53,4 +53,6 @@ enum Config {
NUMHOURS = 24, NUMHOURS = 24,
}; };
#define USE_PS2_RAND TRUE
#endif #endif

@ -24,17 +24,37 @@ void operator delete(void *ptr) noexcept { gtadelete(ptr); }
unsigned __int64 myrand_seed = 1; unsigned __int64 myrand_seed = 1;
int _cwrand() // original codewarrior rand
{
return ((int (__cdecl *)())0x5A41D0)();
}
int int
myrand(void) myps2rand(void)
{ {
return _cwrand();
myrand_seed = 0x5851F42D4C957F2D * myrand_seed + 1; myrand_seed = 0x5851F42D4C957F2D * myrand_seed + 1;
return ((myrand_seed >> 32) & 0x7FFFFFFF); return ((myrand_seed >> 32) & 0x7FFFFFFF);
} }
int myrand(void)
{
#if USE_PS2_RAND == TRUE
return myps2rand();
#else
return _cwrand();
#endif
}
void void
mysrand(unsigned int seed) mysrand(unsigned int seed)
{ {
#if USE_PS2_RAND == TRUE
myrand_seed = seed; myrand_seed = seed;
#else
;
#endif
} }
// platform stuff // platform stuff

@ -0,0 +1,78 @@
#include "common.h"
#include "Vector.h"
void CVector::Normalise()
{
float sq = MagnitudeSqr();
if(sq > 0.0f){
float invsqrt = 1.0f/sqrt(sq); // CMaths::RecipSqrt
x *= invsqrt;
y *= invsqrt;
z *= invsqrt;
}else
x = 1.0f;
}
// operator +
CVector operator + (CVector const &refLeft, CVector const &refRight)
{
return CVector(refLeft.x + refRight.x, refLeft.y + refRight.y, refLeft.z + refRight.z);
}
CVector operator + (CVector const &refLeft, float fRight)
{
return CVector(refLeft.x + fRight, refLeft.y + fRight, refLeft.z + fRight);
}
CVector operator + (float fLeft, CVector const &refRight)
{
return CVector(fLeft + refRight.x, fLeft + refRight.y, fLeft + refRight.z);
}
// operator -
CVector operator - (CVector const &refLeft, CVector const &refRight)
{
return CVector(refLeft.x - refRight.x, refLeft.y - refRight.y, refLeft.z - refRight.z);
}
CVector operator - (CVector const &refLeft, float fRight)
{
return CVector(refLeft.x - fRight, refLeft.y - fRight, refLeft.z - fRight);
}
CVector operator - (float fLeft, CVector const &refRight)
{
return CVector(fLeft - refRight.x, fLeft - refRight.y, fLeft - refRight.z);
}
// operator *
CVector operator * (CVector const &refLeft, CVector const &refRight)
{
return CVector(refLeft.x * refRight.x, refLeft.y * refRight.y, refLeft.z * refRight.z);
}
CVector operator * (CVector const &refLeft, float fRight)
{
return CVector(refLeft.x * fRight, refLeft.y * fRight, refLeft.z * fRight);
}
CVector operator * (float fLeft, CVector const &refRight)
{
return CVector(fLeft * refRight.x, fLeft * refRight.y, fLeft * refRight.z);
}
// operator /
CVector operator / (CVector const &refLeft, CVector const &refRight)
{
return CVector(refLeft.x / refRight.x, refLeft.y / refRight.y, refLeft.z / refRight.z);
}
CVector operator / (CVector const &refLeft, float fRight)
{
return CVector(refLeft.x / fRight, refLeft.y / fRight, refLeft.z / fRight);
}
CVector operator / (float fLeft, CVector const &refRight)
{
return CVector(fLeft / refRight.x, fLeft / refRight.y, fLeft / refRight.z);
}

@ -6,67 +6,128 @@ public:
float x, y, z; float x, y, z;
CVector(void) {} CVector(void) {}
CVector(float x, float y, float z) : x(x), y(y), z(z) {} CVector(float x, float y, float z) : x(x), y(y), z(z) {}
// CVector(rw::V3d const &v) : x(v.x), y(v.y), z(v.z) {} // CVector(CVector &refVector) : x(refVector.x), y(refVector.y), z(refVector.z) { }
// CVector(const CVector &refVector) : x(refVector.x), y(refVector.y), z(refVector.z) {}
// CVector(CVector2D &refVector, float _z = 0.0f) : x(refVector.x), y(refVector.y), z(_z) {}
#ifdef RWCORE_H
CVector(RwV3d const &v) : x(v.x), y(v.y), z(v.z) {}
operator RwV3d (void) const {
RwV3d vecRw = { this->x, this->y, this->z };
return vecRw;
}
operator RwV3d *(void)
{
return (RwV3d *)this;
}
operator RwV3d &(void)
{
return *((RwV3d *)this);
}
#endif
float Magnitude(void) const { return sqrt(x*x + y*y + z*z); } float Magnitude(void) const { return sqrt(x*x + y*y + z*z); }
float MagnitudeSqr(void) const { return x*x + y*y + z*z; } float MagnitudeSqr(void) const { return x*x + y*y + z*z; }
float Magnitude2D(void) const { return sqrt(x*x + y*y); } float Magnitude2D(void) const { return sqrt(x*x + y*y); }
void Normalise(void){ void Normalise(void);
float sq = MagnitudeSqr();
if(sq > 0.0f){
float invsqrt = 1.0f/sqrt(sq); // operator =
x *= invsqrt; inline CVector const& operator = (CVector const &refRight)
y *= invsqrt; {
z *= invsqrt; x = refRight.x;
}else y = refRight.y;
x = 1.0f; z = refRight.z;
} return *this;
// rw::V3d ToRW(void){ }
// return rw::makeV3d(x, y, z);
// } inline CVector const& operator = (float fRight)
// void operator=(rw::V3d const &rhs){ {
// x = rhs.x; x = fRight;
// y = rhs.y; y = fRight;
// z = rhs.z; z = fRight;
// } return *this;
CVector operator-(const CVector &rhs) const { }
return CVector(x-rhs.x, y-rhs.y, z-rhs.z);
} // operator +=
CVector operator+(const CVector &rhs) const { inline CVector const& operator += (CVector const &refRight)
return CVector(x+rhs.x, y+rhs.y, z+rhs.z); {
} x += refRight.x;
CVector operator*(float t) const { y += refRight.y;
return CVector(x*t, y*t, z*t); z += refRight.z;
} return *this;
CVector operator/(float t) const { }
return CVector(x/t, y/t, z/t);
} inline CVector const& operator += (float fRight)
CVector &operator-=(const CVector &rhs) { {
this->x -= rhs.x; x += fRight;
this->y -= rhs.y; y += fRight;
this->z -= rhs.z; z += fRight;
return *this;
}
// operator -=
inline CVector const& operator -= (CVector const &refRight)
{
x -= refRight.x;
y -= refRight.y;
z -= refRight.z;
return *this; return *this;
} }
CVector &operator+=(const CVector &rhs) {
this->x += rhs.x; inline CVector const& operator -= (float fRight)
this->y += rhs.y; {
this->z += rhs.z; x -= fRight;
y -= fRight;
z -= fRight;
return *this; return *this;
} }
CVector &operator*=(float t) {
this->x *= t; // operator *=
this->y *= t; inline CVector const& operator *= (CVector const &refRight)
this->z *= t; {
x *= refRight.x;
y *= refRight.y;
z *= refRight.z;
return *this; return *this;
} }
CVector &operator/=(float t) {
this->x /= t; inline CVector const& operator *= (float fRight)
this->y /= t; {
this->z /= t; x *= fRight;
y *= fRight;
z *= fRight;
return *this;
}
// operator /=
inline CVector const& operator /= (CVector const &refRight)
{
x /= refRight.x;
y /= refRight.y;
z /= refRight.z;
return *this; return *this;
} }
inline CVector const& operator /= (float fRight)
{
x /= fRight;
y /= fRight;
z /= fRight;
return *this;
}
inline CVector operator - () const
{
return CVector(-x, -y, -z);
}
bool IsZero(void) { return x == 0.0f && y == 0.0f && z == 0.0f; } bool IsZero(void) { return x == 0.0f && y == 0.0f && z == 0.0f; }
}; };
//extern CVector operator*(CMatrix const& matrix, CVector const& vector);
inline float inline float
DotProduct(const CVector &v1, const CVector &v2) DotProduct(const CVector &v1, const CVector &v2)
{ {
@ -81,3 +142,23 @@ CrossProduct(const CVector &v1, const CVector &v2)
v1.z*v2.x - v1.x*v2.z, v1.z*v2.x - v1.x*v2.z,
v1.x*v2.y - v1.y*v2.x); v1.x*v2.y - v1.y*v2.x);
} }
// operator +
extern CVector operator + (CVector const &refLeft, CVector const &refRight);
extern CVector operator + (CVector const &refLeft, float fRight);
extern CVector operator + (float fLeft, CVector const &refRight);
// operator -
extern CVector operator - (CVector const &refLeft, CVector const &refRight);
extern CVector operator - (CVector const &refLeft, float fRight);
extern CVector operator - (float fLeft, CVector const &refRight);
// operator *
extern CVector operator * (CVector const &refLeft, CVector const &refRight);
extern CVector operator * (CVector const &refLeft, float fRight);
extern CVector operator * (float fLeft, CVector const &refRight);
// operator /
extern CVector operator / (CVector const &refLeft, CVector const &refRight);
extern CVector operator / (CVector const &refLeft, float fRight);
extern CVector operator / (float fLeft, CVector const &refRight);

File diff suppressed because it is too large Load Diff

@ -1,82 +1,100 @@
#pragma once #pragma once
#include "ParticleMgr.h"
enum tParticleType
{
PARTICLE_SPARK,
PARTICLE_SPARK_SMALL,
PARTICLE_WHEEL_DIRT,
PARTICLE_WHEEL_WATER,
PARTICLE_BLOOD,
PARTICLE_BLOOD_SMALL,
PARTICLE_BLOOD_SPURT,
PARTICLE_DEBRIS,
PARTICLE_DEBRIS2,
PARTICLE_WATER,
PARTICLE_FLAME,
PARTICLE_FIREBALL,
PARTICLE_GUNFLASH,
PARTICLE_GUNFLASH_NOANIM,
PARTICLE_GUNSMOKE,
PARTICLE_GUNSMOKE2,
PARTICLE_SMOKE,
PARTICLE_SMOKE_SLOWMOTION,
PARTICLE_GARAGEPAINT_SPRAY,
PARTICLE_SHARD,
PARTICLE_SPLASH,
PARTICLE_CARFLAME,
PARTICLE_STEAM,
PARTICLE_STEAM2,
PARTICLE_STEAM_NY,
PARTICLE_STEAM_NY_SLOWMOTION,
PARTICLE_ENGINE_STEAM,
PARTICLE_RAINDROP,
PARTICLE_RAINDROP_SMALL,
PARTICLE_RAIN_SPLASH,
PARTICLE_RAIN_SPLASH_BIGGROW,
PARTICLE_RAIN_SPLASHUP,
PARTICLE_WATERSPRAY,
PARTICLE_EXPLOSION_MEDIUM,
PARTICLE_EXPLOSION_LARGE,
PARTICLE_EXPLOSION_MFAST,
PARTICLE_EXPLOSION_LFAST,
PARTICLE_CAR_SPLASH,
PARTICLE_BOAT_SPLASH,
PARTICLE_BOAT_THRUSTJET,
PARTICLE_BOAT_WAKE,
PARTICLE_WATER_HYDRANT,
PARTICLE_WATER_CANNON,
PARTICLE_EXTINGUISH_STEAM,
PARTICLE_PED_SPLASH,
PARTICLE_PEDFOOT_DUST,
PARTICLE_HELI_DUST,
PARTICLE_HELI_ATTACK,
PARTICLE_ENGINE_SMOKE,
PARTICLE_ENGINE_SMOKE2,
PARTICLE_CARFLAME_SMOKE,
PARTICLE_FIREBALL_SMOKE,
PARTICLE_PAINT_SMOKE,
PARTICLE_TREE_LEAVES,
PARTICLE_CARCOLLISION_DUST,
PARTICLE_CAR_DEBRIS,
PARTICLE_HELI_DEBRIS,
PARTICLE_EXHAUST_FUMES,
PARTICLE_RUBBER_SMOKE,
PARTICLE_BURNINGRUBBER_SMOKE,
PARTICLE_BULLETHIT_SMOKE,
PARTICLE_GUNSHELL_FIRST,
PARTICLE_GUNSHELL,
PARTICLE_GUNSHELL_BUMP1,
PARTICLE_GUNSHELL_BUMP2,
PARTICLE_TEST,
PARTICLE_BIRD_FRONT,
PARTICLE_RAINDROP_2D,
};
class CEntity; class CEntity;
class CParticle class CParticle
{ {
enum
{
RAND_TABLE_SIZE = 20,
SIN_COS_TABLE_SIZE = 1024
};
public: public:
static void AddParticle(tParticleType, const CVector &pos, const CVector &velocity, CEntity *ent = nil, CVector m_vecPosition;
float size = 0.0, int32 rotationStep = 0, int32 rotation = 0, int startFrame = 0, int lifeSpan = 0); CVector m_vecVelocity;
CVector m_vecScreenPosition;
UInt32 m_nTimeWhenWillBeDestroyed;
UInt32 m_nTimeWhenColorWillBeChanged;
Float m_fZGround;
CVector m_vecParticleMovementOffset;
Int16 m_nCurrentZRotation;
UInt16 m_nZRotationTimer;
Float m_fCurrentZRadius;
UInt16 m_nZRadiusTimer;
char _pad0[2];
Float m_fSize;
Float m_fExpansionRate;
UInt16 m_nFadeToBlackTimer;
UInt16 m_nFadeAlphaTimer;
UInt8 m_nColorIntensity;
UInt8 m_nAlpha;
UInt16 m_nCurrentFrame;
Int16 m_nAnimationSpeedTimer;
Int16 m_nRotationStep;
Int16 m_nRotation;
RwRGBA m_Color;
char _pad1[2];
CParticle *m_pNext;
CParticle()
{
;
}
~CParticle()
{
;
}
//static Float ms_afRandTable[RAND_TABLE_SIZE];
static Float (&ms_afRandTable)[RAND_TABLE_SIZE];
static CParticle *m_pUnusedListHead;
/*
static Float m_SinTable[SIN_COS_TABLE_SIZE];
static Float m_CosTable[SIN_COS_TABLE_SIZE];
*/
static Float (&m_SinTable)[SIN_COS_TABLE_SIZE];
static Float (&m_CosTable)[SIN_COS_TABLE_SIZE];
static void ReloadConfig();
static void Initialise();
static void Shutdown();
static CParticle *AddParticle(tParticleType type, CVector const &vecPos, CVector const &vecDir, CEntity *pEntity = NULL, Float fSize = 0.0f, Int32 nRotationSpeed = 0, Int32 nRotation = 0, Int32 nCurFrame = 0, Int32 nLifeSpan = 0);
static CParticle *AddParticle(tParticleType type, CVector const &vecPos, CVector const &vecDir, CEntity *pEntity, Float fSize, RwRGBA const &color, Int32 nRotationSpeed = 0, Int32 nRotation = 0, Int32 nCurFrame = 0, Int32 nLifeSpan = 0);
static void Update();
static void Render();
static void RemovePSystem(tParticleType type);
static void RemoveParticle(CParticle *pParticle, CParticle *pPrevParticle, tParticleSystemData *pPSystemData);
static inline void _Next(CParticle *&pParticle, CParticle *&pPrevParticle, tParticleSystemData *pPSystemData, Bool bRemoveParticle)
{
if ( bRemoveParticle )
{
RemoveParticle(pParticle, pPrevParticle, pPSystemData);
if ( pPrevParticle )
pParticle = pPrevParticle->m_pNext;
else
pParticle = pPSystemData->m_pParticles;
}
else
{
pPrevParticle = pParticle;
pParticle = pParticle->m_pNext;
}
}
static void AddJetExplosion(CVector const &vecPos, Float fPower, Float fSize);
static void AddYardieDoorSmoke(CVector const &vecPos, CMatrix const &matMatrix);
}; };
VALIDATE_SIZE(CParticle, 0x68);

@ -0,0 +1,7 @@
#include "common.h"
#include "Shadows.h"
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)
{
((void (__cdecl *)(unsigned char, RwTexture*, CVector*, float, float, float, float, short, unsigned char, unsigned char, unsigned char, float, unsigned int, float))0x56EC50)(ShadowType, pTexture, pPosn, fX1, fY1, fX2, fY2, nTransparency, nRed, nGreen, nBlue, fZDistance, nTime, fScale);
}

@ -0,0 +1,9 @@
#pragma once
struct RwTexture;
class CShadows
{
public:
static void 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);
};