1
0
Fork 0
mirror of https://git.rip/DMCA_FUCKER/re3.git synced 2024-10-31 23:35:55 +00:00

Merge branch 'master' into master

This commit is contained in:
Nikolay Korolev 2020-04-06 19:26:04 +03:00 committed by GitHub
commit b991fd9766
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
157 changed files with 17781 additions and 4127 deletions

View file

@ -38,27 +38,18 @@ to reverse at the time, calling the original functions is acceptable.
### Unreversed / incomplete classes (at least the ones we know)
```
cAudioManager - being worked on
cAudioManager - WIP
CBoat
CBrightLights
CBulletInfo
CBulletTraces
CCam
CCamera
CCopPed
CCrane
CCranes
CCullZone
CCullZones
CExplosion
CFallingGlassPane
CFire
CFireManager
CGame
CGarage
CGarages
CGlass
CMenuManager
CMenuManager - WIP
CMotionBlurStreaks
CObject
CPacManPickups
@ -68,15 +59,10 @@ CRoadBlocks
CRubbish
CSceneEdit
CSkidmarks
CShotInfo
CSpecialFX
CStats
CTrafficLights
CWanted
CWaterCannon
CWaterCannons
CWeapon
CWeaponEffects
CWeather
CWorld
```

BIN
gamefiles/JAPANESE.gxt Normal file

Binary file not shown.

BIN
gamefiles/fonts_j.txd Normal file

Binary file not shown.

BIN
gamefiles/fonts_r.txd Normal file

Binary file not shown.

BIN
gamefiles/russian.gxt Normal file

Binary file not shown.

View file

@ -3906,8 +3906,8 @@ MACRO_STOP
#pragma warning( disable : 344 )
#endif /* (defined(__ICL)) */
#include <windows.h>
//nobody needed that - AAP
//#include <windows.h>
#if (defined(RWDEBUG))
#if (defined(RWMEMDEBUG) && !defined(_CRTDBG_MAP_ALLOC))

View file

@ -203,6 +203,15 @@ CAnimBlendAssociation::UpdateBlend(float timeDelta)
return true;
}
#include <new>
class CAnimBlendAssociation_ : public CAnimBlendAssociation
{
public:
CAnimBlendAssociation *ctor1(void) { return ::new (this) CAnimBlendAssociation(); }
CAnimBlendAssociation *ctor2(CAnimBlendAssociation &other) { return ::new (this) CAnimBlendAssociation(other); }
void dtor(void) { this->CAnimBlendAssociation::~CAnimBlendAssociation(); }
};
STARTPATCHES
InjectHook(0x4016A0, &CAnimBlendAssociation::AllocateAnimBlendNodeArray, PATCH_JUMP);
@ -219,7 +228,7 @@ STARTPATCHES
InjectHook(0x4031F0, &CAnimBlendAssociation::UpdateTime, PATCH_JUMP);
InjectHook(0x4032B0, &CAnimBlendAssociation::UpdateBlend, PATCH_JUMP);
InjectHook(0x401460, &CAnimBlendAssociation::ctor1, PATCH_JUMP);
InjectHook(0x4014C0, &CAnimBlendAssociation::ctor2, PATCH_JUMP);
InjectHook(0x401520, &CAnimBlendAssociation::dtor, PATCH_JUMP);
InjectHook(0x401460, &CAnimBlendAssociation_::ctor1, PATCH_JUMP);
InjectHook(0x4014C0, &CAnimBlendAssociation_::ctor2, PATCH_JUMP);
InjectHook(0x401520, &CAnimBlendAssociation_::dtor, PATCH_JUMP);
ENDPATCHES

View file

@ -85,9 +85,5 @@ public:
static CAnimBlendAssociation *FromLink(CAnimBlendLink *l) {
return (CAnimBlendAssociation*)((uint8*)l - offsetof(CAnimBlendAssociation, link));
}
CAnimBlendAssociation *ctor1(void) { return ::new (this) CAnimBlendAssociation(); }
CAnimBlendAssociation *ctor2(CAnimBlendAssociation &other) { return ::new (this) CAnimBlendAssociation(other); }
void dtor(void) { this->CAnimBlendAssociation::~CAnimBlendAssociation(); }
};
static_assert(sizeof(CAnimBlendAssociation) == 0x40, "CAnimBlendAssociation: error");

View file

@ -36,9 +36,19 @@ CAnimBlendClumpData::ForAllFrames(void (*cb)(AnimBlendFrameData*, void*), void *
cb(&frames[i], arg);
}
#include <new>
class CAnimBlendClumpData_ : public CAnimBlendClumpData
{
public:
CAnimBlendClumpData *ctor(void) { return ::new (this) CAnimBlendClumpData(); }
void dtor(void) { this->CAnimBlendClumpData::~CAnimBlendClumpData(); }
};
STARTPATCHES
InjectHook(0x401880, &CAnimBlendClumpData::ctor, PATCH_JUMP);
InjectHook(0x4018B0, &CAnimBlendClumpData::dtor, PATCH_JUMP);
InjectHook(0x401880, &CAnimBlendClumpData_::ctor, PATCH_JUMP);
InjectHook(0x4018B0, &CAnimBlendClumpData_::dtor, PATCH_JUMP);
InjectHook(0x4018F0, &CAnimBlendClumpData::SetNumberOfFrames, PATCH_JUMP);
InjectHook(0x401930, &CAnimBlendClumpData::ForAllFrames, PATCH_JUMP);
ENDPATCHES

View file

@ -49,9 +49,5 @@ public:
void SetNumberOfBones(int n) { SetNumberOfFrames(n); }
#endif
void ForAllFrames(void (*cb)(AnimBlendFrameData*, void*), void *arg);
CAnimBlendClumpData *ctor(void) { return ::new (this) CAnimBlendClumpData(); }
void dtor(void) { this->CAnimBlendClumpData::~CAnimBlendClumpData(); }
};
static_assert(sizeof(CAnimBlendClumpData) == 0x14, "CAnimBlendClumpData: error");

View file

@ -20,6 +20,7 @@
#include "MusicManager.h"
#include "Pad.h"
#include "Ped.h"
#include "Fire.h"
#include "Physical.h"
#include "Placeable.h"
#include "Plane.h"
@ -67,6 +68,7 @@ const int molotovVolume = 50;
const int rainOnVehicleIntensity = 22;
const int reverseGearIntensity = 30;
const int engineDamageIntensity = 40;
const bool hornPatternsArray[8][44] = {
@ -416,7 +418,7 @@ cAudioManager::AddReleasingSounds()
}
sample.field_56 = 0;
}
memcpy(&m_sQueueSample, &sample, sizeof(sample));
memcpy(&m_sQueueSample, &sample, sizeof(tSound));
AddSampleToRequestedQueue();
}
}
@ -2742,11 +2744,215 @@ cAudioManager::PreTerminateGameSpecificShutdown()
}
}
WRAPPER
void
cAudioManager::ProcessActiveQueues()
{
EAXJMP(0x57BA60);
bool flag;
float position2;
float position1;
uint32 v28;
uint32 v29;
float x;
float usedX;
float usedY;
float usedZ;
uint8 vol;
uint8 emittingVol;
CVector position;
for (int32 i = 0; i < m_bActiveSamples; i++) {
m_asSamples[m_bActiveSampleQueue][i].m_bIsProcessed = 0;
m_asActiveSamples[i].m_bIsProcessed = 0;
}
for (int32 i = 0; i < m_bSampleRequestQueuesStatus[m_bActiveSampleQueue]; ++i) {
tSound& sample = m_asSamples[m_bActiveSampleQueue][m_abSampleQueueIndexTable[m_bActiveSampleQueue][i]];
if (sample.m_nSampleIndex != NO_SAMPLE) {
for (int32 j = 0; j < m_bActiveSamples; ++j) {
if (sample.m_nEntityIndex == m_asActiveSamples[j].m_nEntityIndex &&
sample.m_counter == m_asActiveSamples[j].m_counter &&
sample.m_nSampleIndex == m_asActiveSamples[j].m_nSampleIndex) {
if (sample.m_nLoopCount) {
if (m_FrameCounter & 1) {
flag = !!(j & 1);
}
else {
flag = !(j & 1);
}
if (flag && !SampleManager.GetChannelUsedFlag(j)) {
sample.m_bLoopEnded = 1;
m_asActiveSamples[j].m_bLoopEnded = 1;
m_asActiveSamples[j].m_nSampleIndex = NO_SAMPLE;
m_asActiveSamples[j].m_nEntityIndex = AEHANDLE_NONE;
continue;
}
}
sample.m_bIsProcessed = 1;
m_asActiveSamples[j].m_bIsProcessed = 1;
sample.field_88 = -1;
if (!sample.field_56) {
if (sample.m_bIsDistant) {
if (field_4) {
emittingVol = 2 * min(63, sample.m_bEmittingVolume);
}
else {
emittingVol = sample.m_bEmittingVolume;
}
SampleManager.SetChannelFrequency(j, sample.m_nFrequency);
SampleManager.SetChannelEmittingVolume(j, emittingVol);
}
else {
m_asActiveSamples[j].m_fDistance = sample.m_fDistance;
position2 = sample.m_fDistance;
position1 = m_asActiveSamples[j].m_fDistance;
sample.m_nFrequency = ComputeDopplerEffectedFrequency(
sample.m_nFrequency, position1, position2, sample.field_48);
if (sample.m_nFrequency != m_asActiveSamples[j].m_nFrequency) {
int32 freq;
if (sample.m_nFrequency <=
m_asActiveSamples[j].m_nFrequency) {
freq = max(sample.m_nFrequency,
m_asActiveSamples[j].m_nFrequency -
6000);
}
else {
freq = min(sample.m_nFrequency,
m_asActiveSamples[j].m_nFrequency +
6000);
}
m_asActiveSamples[j].m_nFrequency = freq;
SampleManager.SetChannelFrequency(j, freq);
}
if (sample.m_bEmittingVolume !=
m_asActiveSamples[j].m_bEmittingVolume) {
if (sample.m_bEmittingVolume <=
m_asActiveSamples[j].m_bEmittingVolume) {
vol = max(
m_asActiveSamples[j].m_bEmittingVolume - 10,
sample.m_bEmittingVolume);
}
else {
vol = min(
m_asActiveSamples[j].m_bEmittingVolume + 10,
sample.m_bEmittingVolume);
}
uint8 emittingVol;
if (field_4) {
emittingVol = 2 * min(63, vol);
}
else {
emittingVol = vol;
}
SampleManager.SetChannelEmittingVolume(j, emittingVol);
m_asActiveSamples[j].m_bEmittingVolume = vol;
}
TranslateEntity(&sample.m_vecPos, &position);
SampleManager.SetChannel3DPosition(j, position.x, position.y,
position.z);
SampleManager.SetChannel3DDistances(
j, sample.m_fSoundIntensity,
0.25f * sample.m_fSoundIntensity);
}
SampleManager.SetChannelReverbFlag(j, sample.m_bReverbFlag);
continue;
}
sample.m_bIsProcessed = 0;
m_asActiveSamples[j].m_bIsProcessed = 0;
break;
}
}
}
}
for (int32 i = 0; i < m_bActiveSamples; i++) {
if (m_asActiveSamples[i].m_nSampleIndex != NO_SAMPLE && !m_asActiveSamples[i].m_bIsProcessed) {
SampleManager.StopChannel(i);
m_asActiveSamples[i].m_nSampleIndex = NO_SAMPLE;
m_asActiveSamples[i].m_nEntityIndex = -5;
}
}
for (int32 i = 0; i < m_bSampleRequestQueuesStatus[m_bActiveSampleQueue]; ++i) {
tSound& sample = m_asSamples[m_bActiveSampleQueue][m_abSampleQueueIndexTable[m_bActiveSampleQueue][i]];
if (!sample.m_bIsProcessed && !sample.m_bLoopEnded &&
m_asAudioEntities[sample.m_nEntityIndex].m_bIsUsed && sample.m_nSampleIndex < NO_SAMPLE) {
if (sample.m_counter > 255 && sample.m_nLoopCount && sample.m_bLoopsRemaining) {
--sample.m_bLoopsRemaining;
sample.field_76 = 1;
}
else {
for (int32 j = 0; j < m_bActiveSamples; ++j) {
if (!m_asActiveSamples[j].m_bIsProcessed) {
if (sample.m_nLoopCount) {
v28 = sample.m_nFrequency / field_19192;
v29 = sample.m_nLoopCount *
SampleManager.GetSampleLength(sample.m_nSampleIndex);
if (v28 == 0) continue;
sample.field_76 = v29 / v28 + 1;
}
memcpy(&m_asActiveSamples[j], &sample, sizeof(tSound));
if (!m_asActiveSamples[j].m_bIsDistant)
TranslateEntity(&m_asActiveSamples[j].m_vecPos, &position);
if (field_4) {
emittingVol =
2 * min(63, m_asActiveSamples[j].m_bEmittingVolume);
}
else {
emittingVol = m_asActiveSamples[j].m_bEmittingVolume;
}
if (SampleManager.InitialiseChannel(j,
m_asActiveSamples[j].m_nSampleIndex,
m_asActiveSamples[j].m_bBankIndex)) {
SampleManager.SetChannelFrequency(
j, m_asActiveSamples[j].m_nFrequency);
SampleManager.SetChannelEmittingVolume(j, emittingVol);
SampleManager.SetChannelLoopPoints(
j, m_asActiveSamples[j].m_nLoopStart,
m_asActiveSamples[j].m_nLoopEnd);
SampleManager.SetChannelLoopCount(
j, m_asActiveSamples[j].m_nLoopCount);
SampleManager.SetChannelReverbFlag(
j, m_asActiveSamples[j].m_bReverbFlag);
if (m_asActiveSamples[j].m_bIsDistant) {
uint8 offset = m_asActiveSamples[j].m_bOffset;
if (offset == 63) {
x = 0.f;
}
else if (offset >= 63) {
x = (offset - 63) * 1000.f / 63;
}
else {
x = -(63 - offset) * 1000.f / 63;
}
usedX = x;
usedY = 0.f;
usedZ = 0.f;
m_asActiveSamples[j].m_fSoundIntensity = 100000.0f;
}
else {
usedX = position.x;
usedY = position.y;
usedZ = position.z;
}
SampleManager.SetChannel3DPosition(j, usedX, usedY, usedZ);
SampleManager.SetChannel3DDistances(
j, m_asActiveSamples[j].m_fSoundIntensity,
0.25f * m_asActiveSamples[j].m_fSoundIntensity);
SampleManager.StartChannel(j);
}
m_asActiveSamples[j].m_bIsProcessed = 1;
sample.m_bIsProcessed = 1;
sample.field_88 = -1;
break;
}
}
}
}
}
}
bool
@ -3056,7 +3262,7 @@ cAudioManager::ProcessBridgeMotor()
m_sQueueSample.m_bVolume = ComputeVolume(maxVolume, bridgeIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_counter = 1;
m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE;
m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; // todo check sfx name
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
m_sQueueSample.m_bIsDistant = false;
m_sQueueSample.field_16 = 1;
@ -3127,7 +3333,7 @@ cAudioManager::ProcessBridgeWarning()
m_sQueueSample.m_bVolume = ComputeVolume(100, 450.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_counter = 0;
m_sQueueSample.m_nSampleIndex = 457;
m_sQueueSample.m_nSampleIndex = SFX_BRIDGE_OPEN_WARNING;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
m_sQueueSample.m_bIsDistant = false;
m_sQueueSample.field_16 = 1;
@ -3153,7 +3359,7 @@ cAudioManager::ProcessCarBombTick(cVehicleParams *params)
{
CAutomobile *automobile;
if(params->m_fDistance >= 1600.f) return false;
if(params->m_fDistance >= SQR(40.f)) return false;
automobile = (CAutomobile *)params->m_pVehicle;
if(automobile->bEngineOn && automobile->m_bombType == CARBOMB_TIMEDACTIVE) {
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
@ -3410,11 +3616,11 @@ cAudioManager::ProcessEngineDamage(cVehicleParams *params)
uint8 engineStatus;
uint8 emittingVolume;
if(params->m_fDistance >= 1600.f) return false;
if(params->m_fDistance >= SQR(engineDamageIntensity)) return false;
veh = (CAutomobile *)params->m_pVehicle;
if(veh->bEngineOn) {
engineStatus = veh->Damage.GetEngineStatus();
if(engineStatus > 250u || engineStatus < 100) return true;
if(engineStatus > 250 || engineStatus < 100) return true;
if(engineStatus < 225) {
m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI;
emittingVolume = 6;
@ -3427,7 +3633,7 @@ cAudioManager::ProcessEngineDamage(cVehicleParams *params)
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE);
}
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
m_sQueueSample.m_bVolume = ComputeVolume(emittingVolume, 40.f, m_sQueueSample.m_fDistance);
m_sQueueSample.m_bVolume = ComputeVolume(emittingVolume, engineDamageIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_counter = 28;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
@ -3438,7 +3644,7 @@ cAudioManager::ProcessEngineDamage(cVehicleParams *params)
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.field_48 = 2.0f;
m_sQueueSample.m_fSoundIntensity = 40.0f;
m_sQueueSample.m_fSoundIntensity = engineDamageIntensity;
m_sQueueSample.field_56 = 0;
m_sQueueSample.field_76 = 3;
m_sQueueSample.m_bReverbFlag = true;
@ -3534,7 +3740,7 @@ cAudioManager::ProcessExplosions(int32 explosion)
CVector *pos;
float distSquared;
for(uint8 i = 0; i < 48; i++) {
for(uint8 i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
if(CExplosion::GetExplosionActiveCounter(i) == 1) {
CExplosion::ResetExplosionActiveCounter(i);
type = CExplosion::GetExplosionType(i);
@ -3732,7 +3938,7 @@ cAudioManager::ProcessFrontEnd()
break;
case SOUND_GARAGE_NO_MONEY:
case SOUND_GARAGE_BAD_VEHICLE:
case SOUND_3C:
case SOUND_GARAGE_BOMB_ALREADY_SET:
m_sQueueSample.m_nSampleIndex = SFX_PICKUP_ERROR_LEFT;
stereo = true;
break;
@ -3889,7 +4095,7 @@ cAudioManager::ProcessGarages()
CalculateDistance(distCalculated, distSquared); \
m_sQueueSample.m_bVolume = ComputeVolume(60, 80.f, m_sQueueSample.m_fDistance); \
if(m_sQueueSample.m_bVolume) { \
if(CGarages::Garages[i].m_eGarageType == GARAGE_CRUSHER) { \
if(CGarages::aGarages[i].m_eGarageType == GARAGE_CRUSHER) { \
m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_PANEL_2; \
m_sQueueSample.m_nFrequency = 6735; \
} else if(m_asAudioEntities[m_sQueueSample.m_nEntityIndex] \
@ -3905,7 +4111,7 @@ cAudioManager::ProcessGarages()
m_sQueueSample.m_bEmittingVolume = 60; \
m_sQueueSample.field_48 = 0.0f; \
m_sQueueSample.m_fSoundIntensity = 80.0f; \
m_sQueueSample.field_16 = 4; \
/*m_sQueueSample.field_16 = 4;*/ \
m_sQueueSample.m_bReverbFlag = true; \
/*m_sQueueSample.m_bReverbFlag = true;*/ \
m_sQueueSample.m_bIsDistant = false; \
@ -3915,7 +4121,7 @@ cAudioManager::ProcessGarages()
m_sQueueSample.m_nLoopEnd = -1; \
m_sQueueSample.m_counter = iSound++; \
if(iSound < 32) iSound = 32; \
m_sQueueSample.m_bRequireReflection = 1; \
m_sQueueSample.m_bRequireReflection = true; \
AddSampleToRequestedQueue(); \
} \
} \
@ -3925,20 +4131,20 @@ cAudioManager::ProcessGarages()
}
for(uint32 i = 0; i < CGarages::NumGarages; ++i) {
if(CGarages::Garages[i].m_eGarageType == GARAGE_NONE) continue;
entity = CGarages::Garages[i].m_pDoor1;
if(CGarages::aGarages[i].m_eGarageType == GARAGE_NONE) continue;
entity = CGarages::aGarages[i].m_pDoor1;
if(!entity) continue;
m_sQueueSample.m_vecPos = entity->GetPosition();
distCalculated = false;
distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(distSquared < 6400.f) {
state = CGarages::Garages[i].m_eGarageState;
state = CGarages::aGarages[i].m_eGarageState;
if(state == GS_OPENING || state == GS_CLOSING || state == GS_AFTERDROPOFF) {
CalculateDistance(distCalculated, distSquared);
m_sQueueSample.m_bVolume = ComputeVolume(90u, 80.f, m_sQueueSample.m_fDistance);
m_sQueueSample.m_bVolume = ComputeVolume(90, 80.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
if(CGarages::Garages[i].m_eGarageType == GARAGE_CRUSHER) {
if(CGarages::Garages[i].m_eGarageState == GS_AFTERDROPOFF) {
if(CGarages::aGarages[i].m_eGarageType == GARAGE_CRUSHER) {
if(CGarages::aGarages[i].m_eGarageState == GS_AFTERDROPOFF) {
if(!(m_FrameCounter & 1)) {
LOOP_HELPER
continue;
@ -3955,11 +4161,11 @@ cAudioManager::ProcessGarages()
m_sQueueSample.m_nSampleIndex) >>
1;
m_sQueueSample.m_nFrequency +=
RandomDisplacement((int32)m_sQueueSample.m_nFrequency >> 4);
RandomDisplacement(m_sQueueSample.m_nFrequency >> 4);
m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.field_56 = 1;
m_sQueueSample.m_counter = iSound++;
if(iSound < 32u) iSound = 32;
if(iSound < 32) iSound = 32;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
m_sQueueSample.m_bIsDistant = false;
m_sQueueSample.field_16 = 3;
@ -4001,9 +4207,9 @@ cAudioManager::ProcessGarages()
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
LOOP_HELPER
}
}
LOOP_HELPER
}
}
#undef LOOP_HELPER
@ -4183,11 +4389,8 @@ cAudioManager::ProcessJumboAccel(CPlane *plane)
void
cAudioManager::ProcessJumboDecel(CPlane *plane)
{
float modificator;
if(SetupJumboFlySound(20) && SetupJumboTaxiSound(75)) {
modificator = (plane->m_fSpeed - 0.10334f) * 1.676f;
if(modificator > 1.0f) modificator = 1.0f;
const float modificator = min(1.f, (plane->m_fSpeed - 0.10334f) * 1.676f);
SetupJumboEngineSound(maxVolume * modificator, 6050.f * modificator + 16000);
SetupJumboWhineSound(18, 29500);
}
@ -4202,7 +4405,7 @@ cAudioManager::ProcessJumboFlying()
void
cAudioManager::ProcessJumboLanding(CPlane *plane)
{
float modificator = (LandingPoint - PlanePathPosition[plane->m_nPlaneId]) / 350.f;
const float modificator = (LandingPoint - PlanePathPosition[plane->m_nPlaneId]) / 350.f;
if(SetupJumboFlySound(107.f * modificator + 20)) {
if(SetupJumboTaxiSound(75.f * (1.f - modificator))) {
SetupJumboEngineSound(maxVolume, 22050);
@ -4214,7 +4417,7 @@ cAudioManager::ProcessJumboLanding(CPlane *plane)
void
cAudioManager::ProcessJumboTakeOff(CPlane *plane)
{
float modificator = (PlanePathPosition[plane->m_nPlaneId] - TakeOffPoint) / 300.f;
const float modificator = (PlanePathPosition[plane->m_nPlaneId] - TakeOffPoint) / 300.f;
if(SetupJumboFlySound((107.f * modificator) + 20) && SetupJumboRumbleSound(maxVolume * (1.f - modificator))) {
if(SetupJumboEngineSound(maxVolume, 22050)) SetupJumboWhineSound(18.f * (1.f - modificator), 44100);
@ -5003,13 +5206,11 @@ cAudioManager::ProcessMissionAudio()
void
cAudioManager::ProcessModelCarEngine(cVehicleParams *params)
{
cAudioManager *v2;
CAutomobile *automobile;
float allowedVelocity;
int32 emittingVol;
float velocityChange;
v2 = this;
if(params->m_fDistance < 900.f) {
automobile = (CAutomobile *)params->m_pVehicle;
if(automobile->bEngineOn) {
@ -5311,13 +5512,13 @@ cAudioManager::ProcessPed(CPhysical *ped)
{
cPedParams params;
params.m_pPed = 0;
params.m_bDistanceCalculated = 0;
params.m_pPed = nil;
params.m_bDistanceCalculated = false;
params.m_fDistance = 0.0f;
m_sQueueSample.m_vecPos = ped->GetPosition();
params.m_bDistanceCalculated = 0;
//params.m_bDistanceCalculated = false;
params.m_pPed = (CPed *)ped;
params.m_fDistance = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(ped->m_modelIndex == MI_FATMALE02) ProcessPedHeadphones(&params);
@ -5328,7 +5529,7 @@ void
cAudioManager::ProcessPedHeadphones(cPedParams *params)
{
CPed *ped;
CVehicle *veh;
CAutomobile *veh;
uint8 emittingVol;
if(params->m_fDistance < 49.f) {
@ -5337,9 +5538,9 @@ cAudioManager::ProcessPedHeadphones(cPedParams *params)
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
if(ped->bInVehicle && ped->m_nPedState == PED_DRIVING) {
emittingVol = 10;
veh = ped->m_pMyVehicle;
veh = (CAutomobile*)ped->m_pMyVehicle;
if(veh && veh->IsCar()) {
for(int32 i = 2; i < 6; i++) {
for(int32 i = 2; i < ARRAYSIZE(veh->Doors); i++) {
if(!veh->IsDoorClosed((eDoors)i) || veh->IsDoorMissing((eDoors)i)) {
emittingVol = 42;
break;
@ -7234,11 +7435,224 @@ cAudioManager::ProcessVehicleDoors(cVehicleParams *params)
return true;
}
WRAPPER
bool
cAudioManager::ProcessVehicleEngine(cVehicleParams *params)
void
cAudioManager::ProcessVehicleEngine(cVehicleParams* params)
{
EAXJMP(0x56A610);
CVehicle* playerVeh;
CVehicle* veh;
CAutomobile* automobile;
float relativeGearChange;
float relativeChange;
float reverseRelativechange;
uint8 volume;
eSfxSample accelerationSample;
int32 freq;
uint8 emittingVol;
cTransmission* transmission;
uint8 currentGear;
float modificator;
float traction = 0.f;
if (params->m_fDistance < SQR(50.f)) {
playerVeh = FindPlayerVehicle();
veh = params->m_pVehicle;
if (playerVeh == veh && veh->m_status == STATUS_WRECKED) {
SampleManager.StopChannel(m_bActiveSamples);
return;
}
if (veh->bEngineOn) {
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
automobile = (CAutomobile*)params->m_pVehicle;
if (params->m_nIndex == DODO) {
ProcessCesna(params);
return;
}
if (FindPlayerVehicle() == veh) {
ProcessPlayersVehicleEngine(params, automobile);
return;
}
transmission = params->m_pTransmission;
if (transmission) {
currentGear = params->m_pVehicle->m_nCurrentGear;
if (automobile->m_nWheelsOnGround) {
if (automobile->bIsHandbrakeOn) {
if (0.f == params->m_fVelocityChange) traction = 0.9f;
}
else if (params->m_pVehicle->m_status == STATUS_SIMPLE) {
traction = 0.f;
}
else {
switch (transmission->nDriveType) {
case '4':
for (int32 i = 0; i < ARRAY_SIZE(automobile->m_aWheelState); i++) {
if (automobile->m_aWheelState[i] == WHEEL_STATE_SPINNING)
traction += 0.05f;
}
break;
case 'F':
if (automobile->m_aWheelState[0] == WHEEL_STATE_SPINNING)
traction += 0.1f;
if (automobile->m_aWheelState[2] == WHEEL_STATE_SPINNING)
traction += 0.1f;
break;
case 'R':
if (automobile->m_aWheelState[1] == WHEEL_STATE_SPINNING)
traction += 0.1f;
if (automobile->m_aWheelState[3] == WHEEL_STATE_SPINNING)
traction += 0.1f;
break;
}
}
if (transmission->fMaxVelocity <= 0.f) {
relativeChange = 0.f;
}
else if (currentGear) {
if ((params->m_fVelocityChange -
transmission->Gears[currentGear].fShiftDownVelocity) /
transmission->fMaxVelocity * 2.5f <=
1.f)
relativeGearChange =
(params->m_fVelocityChange -
transmission->Gears[currentGear].fShiftDownVelocity) /
transmission->fMaxVelocity * 2.5f;
else
relativeGearChange = 1.f;
if (0.f == traction && automobile->m_status != STATUS_SIMPLE &&
params->m_fVelocityChange >=
transmission->Gears[1].fShiftUpVelocity) {
traction = 0.7f;
}
relativeChange = traction * automobile->m_fGasPedalAudio * 0.95f +
(1.f - traction) * relativeGearChange;
}
else {
reverseRelativechange =
Abs((params->m_fVelocityChange -
transmission->Gears[0].fShiftDownVelocity) /
transmission->fMaxReverseVelocity);
if (1.f - reverseRelativechange <= 1.f) {
relativeChange = 1.f - reverseRelativechange;
}
else {
relativeChange = 1.f;
}
}
}
else {
if (automobile->m_nDriveWheelsOnGround)
automobile->m_fGasPedalAudio = automobile->m_fGasPedalAudio * 0.4f;
relativeChange = automobile->m_fGasPedalAudio;
}
modificator = relativeChange;
if (currentGear || !automobile->m_nWheelsOnGround)
freq = 1200 * currentGear + 18000.f * modificator + 14000;
else
freq = 13000.f * modificator + 14000;
if (modificator >= 0.75f) {
emittingVol = 120;
volume = ComputeVolume(120, 50.f, m_sQueueSample.m_fDistance);
}
else {
emittingVol = modificator * 4 / 3 * 40.f + 80.f;
volume = ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance);
}
}
else {
modificator = 0.f;
emittingVol = 80;
volume = ComputeVolume(80, 50.f, m_sQueueSample.m_fDistance);
}
m_sQueueSample.m_bVolume = volume;
if (m_sQueueSample.m_bVolume) {
if (automobile->m_status == STATUS_SIMPLE) {
if (modificator < 0.02f) {
m_sQueueSample.m_nSampleIndex =
CarSounds[params->m_nIndex].m_bEngineSoundType + SFX_CAR_REV_10;
freq = 10000.f * modificator + 22050;
m_sQueueSample.m_counter = 52;
m_sQueueSample.m_bBankIndex = 0;
m_sQueueSample.m_bIsDistant = 0;
m_sQueueSample.field_16 = 3;
m_sQueueSample.m_nFrequency =
freq + 100 * m_sQueueSample.m_nEntityIndex % 1000;
if (m_sQueueSample.m_nSampleIndex == SFX_CAR_IDLE_6 ||
m_sQueueSample.m_nSampleIndex == SFX_CAR_REV_6)
m_sQueueSample.m_nFrequency = m_sQueueSample.m_nFrequency >> 1;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(
m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd =
SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.field_48 = 6.0f;
m_sQueueSample.m_fSoundIntensity = 50.0f;
m_sQueueSample.field_56 = 0;
m_sQueueSample.field_76 = 8;
m_sQueueSample.m_bReverbFlag = 1;
m_sQueueSample.m_bRequireReflection = 0;
AddSampleToRequestedQueue();
return;
}
accelerationSample = CarSounds[params->m_nIndex].m_nAccelerationSampleIndex;
}
else {
if (automobile->m_fGasPedal < 0.05f) {
m_sQueueSample.m_nSampleIndex =
CarSounds[params->m_nIndex].m_bEngineSoundType +
SFX_CAR_REV_10; // to recheck idle sounds start 1 postion later
freq = 10000.f * modificator + 22050;
m_sQueueSample.m_counter = 52;
m_sQueueSample.m_bBankIndex = 0;
m_sQueueSample.m_bIsDistant = 0;
m_sQueueSample.field_16 = 3;
m_sQueueSample.m_nFrequency =
freq + 100 * m_sQueueSample.m_nEntityIndex % 1000;
if (m_sQueueSample.m_nSampleIndex == SFX_CAR_IDLE_6 ||
m_sQueueSample.m_nSampleIndex == SFX_CAR_REV_6)
m_sQueueSample.m_nFrequency = m_sQueueSample.m_nFrequency >> 1;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(
m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd =
SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.field_48 = 6.0f;
m_sQueueSample.m_fSoundIntensity = 50.0f;
m_sQueueSample.field_56 = 0;
m_sQueueSample.field_76 = 8;
m_sQueueSample.m_bReverbFlag = 1;
m_sQueueSample.m_bRequireReflection = 0;
AddSampleToRequestedQueue();
return;
}
accelerationSample = CarSounds[params->m_nIndex].m_nAccelerationSampleIndex;
}
m_sQueueSample.m_nSampleIndex = accelerationSample;
m_sQueueSample.m_counter = 2;
m_sQueueSample.m_bBankIndex = 0;
m_sQueueSample.m_bIsDistant = 0;
m_sQueueSample.field_16 = 3;
m_sQueueSample.m_nFrequency = freq + 100 * m_sQueueSample.m_nEntityIndex % 1000;
if (m_sQueueSample.m_nSampleIndex == SFX_CAR_IDLE_6 ||
m_sQueueSample.m_nSampleIndex == SFX_CAR_REV_6)
m_sQueueSample.m_nFrequency = m_sQueueSample.m_nFrequency >> 1;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd =
SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.field_48 = 6.0f;
m_sQueueSample.m_fSoundIntensity = 50.0f;
m_sQueueSample.field_56 = 0;
m_sQueueSample.field_76 = 8;
m_sQueueSample.m_bReverbFlag = 1;
m_sQueueSample.m_bRequireReflection = 0;
AddSampleToRequestedQueue();
return;
}
}
}
}
void
@ -7358,7 +7772,7 @@ cAudioManager::ProcessVehicleRoadNoise(cVehicleParams *params)
freq = 6050 * emittingVol / 30 + 16000;
} else {
m_sQueueSample.m_nSampleIndex = SFX_ROAD_NOISE;
modificator = m_sQueueSample.m_fDistance * 1.f / 95.f * 0.5f;
modificator = m_sQueueSample.m_fDistance / 190.f;
sampleFreq = SampleManager.GetSampleBaseFrequency(
SFX_ROAD_NOISE);
freq = (sampleFreq * modificator) + ((3 * sampleFreq) >> 2);
@ -7533,8 +7947,8 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams *params)
void cAudioManager::ProcessWaterCannon(int32)
{
for(int32 i = 0; i < NUM_WATERCANNONS; i++) {
if(aCannons[i].m_nId) {
m_sQueueSample.m_vecPos = aCannons[0].m_avecPos[aCannons[i].m_wIndex];
if(CWaterCannons::aCannons[i].m_nId) {
m_sQueueSample.m_vecPos = CWaterCannons::aCannons[0].m_avecPos[CWaterCannons::aCannons[i].m_nCur];
float distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(distSquared < 900.f) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
@ -7647,7 +8061,7 @@ cAudioManager::ProcessWetRoadNoise(cVehicleParams *params)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
m_sQueueSample.m_bIsDistant = false;
m_sQueueSample.field_16 = 3;
modificator = m_sQueueSample.m_fDistance * 1.f / 3.f * 0.5f;
modificator = m_sQueueSample.m_fDistance / 6.f;
freq = SampleManager.GetSampleBaseFrequency(SFX_ROAD_NOISE);
m_sQueueSample.m_nFrequency = freq + freq * modificator;
m_sQueueSample.m_nLoopCount = 0;

View file

@ -489,7 +489,7 @@ public:
void PreloadMissionAudio(const char *name); /// ok
void PreTerminateGameSpecificShutdown(); /// ok
/// processX - main logic of adding new sounds
void ProcessActiveQueues(); // todo
void ProcessActiveQueues(); /// ok
bool ProcessAirBrakes(cVehicleParams *params); /// ok
void ProcessAirportScriptObject(uint8 sound); /// ok
bool ProcessBoatEngine(cVehicleParams *params); /// ok
@ -544,7 +544,7 @@ public:
bool ProcessTrainNoise(cVehicleParams *params); /// ok
void ProcessVehicle(CVehicle *vehicle); /// ok
bool ProcessVehicleDoors(cVehicleParams *params); /// ok
bool ProcessVehicleEngine(cVehicleParams *params); // todo
void ProcessVehicleEngine(cVehicleParams *params); /// ok
void ProcessVehicleHorn(cVehicleParams *params); /// ok
void ProcessVehicleOneShots(void *); // todo
bool ProcessVehicleReverseWarning(cVehicleParams *params); /// ok

View file

@ -2,13 +2,12 @@
#include "patcher.h"
#include "AudioScriptObject.h"
#include "Pools.h"
WRAPPER void cAudioScriptObject::SaveAllAudioScriptObjects(uint8 *buf, uint32 *size) { EAXJMP(0x57c460); }
#include "DMAudio.h"
void
cAudioScriptObject::Reset()
{
AudioId = 125;
AudioId = SCRSOUND_INVALID;
Posn = CVector(0.0f, 0.0f, 0.0f);
AudioEntity = AEHANDLE_NONE;
}
@ -18,22 +17,66 @@ cAudioScriptObject::operator new(size_t sz)
{
return CPools::GetAudioScriptObjectPool()->New();
}
void *
cAudioScriptObject::operator new(size_t sz, int handle)
{
return CPools::GetAudioScriptObjectPool()->New(handle);
}
void
cAudioScriptObject::operator delete(void *p, size_t sz)
{
CPools::GetAudioScriptObjectPool()->Delete((cAudioScriptObject *)p);
}
void
cAudioScriptObject::operator delete(void *p, int handle)
{
CPools::GetAudioScriptObjectPool()->Delete((cAudioScriptObject *)p);
}
void
cAudioScriptObject::LoadAllAudioScriptObjects(uint8 *buf, uint32 size)
{
INITSAVEBUF
CheckSaveHeader(buf, 'A', 'U', 'D', '\0', size - SAVE_HEADER_SIZE);
int32 pool_size = ReadSaveBuf<int32>(buf);
for (int32 i = 0; i < pool_size; i++) {
int handle = ReadSaveBuf<int32>(buf);
cAudioScriptObject *p = new(handle) cAudioScriptObject;
assert(p != nil);
*p = ReadSaveBuf<cAudioScriptObject>(buf);
p->AudioEntity = DMAudio.CreateLoopingScriptObject(p);
}
VALIDATESAVEBUF(size);
}
void
cAudioScriptObject::SaveAllAudioScriptObjects(uint8 *buf, uint32 *size)
{
INITSAVEBUF
int32 pool_size = CPools::GetAudioScriptObjectPool()->GetNoOfUsedSpaces();
*size = SAVE_HEADER_SIZE + pool_size * (sizeof(cAudioScriptObject) + sizeof(int32));
WriteSaveHeader(buf, 'A', 'U', 'D', '\0', *size - SAVE_HEADER_SIZE);
WriteSaveBuf(buf, pool_size);
int32 i = CPools::GetAudioScriptObjectPool()->GetSize();
while (i--) {
cAudioScriptObject *p = CPools::GetAudioScriptObjectPool()->GetSlot(i);
if (p != nil) {
WriteSaveBuf(buf, CPools::GetAudioScriptObjectPool()->GetIndex(p));
WriteSaveBuf(buf, *p);
}
}
VALIDATESAVEBUF(*size);
}
void
PlayOneShotScriptObject(uint8 id, CVector const &pos)
{
@ -47,4 +90,6 @@ PlayOneShotScriptObject(uint8 id, CVector const &pos)
STARTPATCHES
InjectHook(0x57C430, &cAudioScriptObject::Reset, PATCH_JUMP);
InjectHook(0x57C5F0, &PlayOneShotScriptObject, PATCH_JUMP);
InjectHook(0x57C560, &cAudioScriptObject::LoadAllAudioScriptObjects, PATCH_JUMP);
InjectHook(0x57c460, &cAudioScriptObject::SaveAllAudioScriptObjects, PATCH_JUMP);
ENDPATCHES

View file

@ -2,130 +2,132 @@
enum
{
SCRSOUND_TEST_1 = 0,
_SCRSOUND_UNK_1 = 1,
_SCRSOUND_UNK_2 = 2,
_SCRSOUND_UNK_3 = 3,
_SCRSOUND_CLUB_1_S = 4,
_SCRSOUND_CLUB_1_L = 5,
_SCRSOUND_CLUB_2_S = 6,
_SCRSOUND_CLUB_2_L = 7,
_SCRSOUND_CLUB_3_S = 8,
_SCRSOUND_CLUB_3_L = 9,
_SCRSOUND_CLUB_4_S = 10,
_SCRSOUND_CLUB_4_L = 11,
_SCRSOUND_CLUB_5_S = 12,
_SCRSOUND_CLUB_5_L = 13,
_SCRSOUND_CLUB_6_S = 14,
_SCRSOUND_CLUB_6_L = 15,
_SCRSOUND_CLUB_7_S = 16,
_SCRSOUND_CLUB_7_L = 17,
_SCRSOUND_CLUB_8_S = 18,
_SCRSOUND_CLUB_8_L = 19,
_SCRSOUND_CLUB_9_S = 20,
_SCRSOUND_CLUB_9_L = 21,
_SCRSOUND_CLUB_10_S = 22,
_SCRSOUND_CLUB_10_L = 23,
_SCRSOUND_CLUB_11_S = 24,
_SCRSOUND_CLUB_11_L = 25,
_SCRSOUND_CLUB_12_S = 26,
_SCRSOUND_CLUB_12_L = 27,
_SCRSOUND_CLUB_RAGGA_S = 28,
_SCRSOUND_CLUB_RAGGA_L = 29,
SCRSOUND_STRIP_CLUB_LOOP_1_S = 30,
_SCRSOUND_STRIP_CLUB_LOOP_1_L = 31,
SCRSOUND_STRIP_CLUB_LOOP_2_S = 32,
_SCRSOUND_STRIP_CLUB_LOOP_2_L = 33,
_SCRSOUND_SFX_WORKSHOP_1 = 34,
_SCRSOUND_SFX_WORKSHOP_2 = 35,
_SCRSOUND_SAWMILL_LOOP_S = 36,
SCRSOUND_SAWMILL_LOOP_L = 37,
_SCRSOUND_DOG_FOOD_FACTORY_S = 38,
_SCRSOUND_DOG_FOOD_FACTORY_L = 39,
_SCRSOUND_LAUNDERETTE_1 = 40,
_SCRSOUND_LAUNDERETTE_2 = 41,
_SCRSOUND_RESTAURANT_CHINATOWN_S = 42,
_SCRSOUND_RESTAURANT_CHINATOWN_L = 43,
_SCRSOUND_RESTAURANT_ITALY_S = 44,
_SCRSOUND_RESTAURANT_ITALY_L = 45,
_SCRSOUND_RESTAURANT_GENERIC_1_S = 46,
_SCRSOUND_RESTAURANT_GENERIC_1_L = 47,
_SCRSOUND_RESTAURANT_GENERIC_2_S = 48,
_SCRSOUND_RESTAURANT_GENERIC_2_L = 49,
_SCRSOUND_AIRPORT_ANNOUNCEMENT_S = 50,
_SCRSOUND_AIRPORT_ANNOUNCEMENT_L = 51,
_SCRSOUND_SHOP_LOOP_1 = 52,
_SCRSOUND_SHOP_LOOP_2 = 53,
_SCRSOUND_CINEMA_S = 54,
_SCRSOUND_CINEMA_L = 55,
_SCRSOUND_DOCKS_FOGHORN_S = 56,
_SCRSOUND_DOCKS_FOGHORN_L = 57,
_SCRSOUND_HOME_S = 58,
_SCRSOUND_HOME_L = 59,
_SCRSOUND_PIANO_BAR = 60,
_SCRSOUND_CLUB = 61,
SCRSOUND_PORN_CINEMA_1_S = 62,
_SCRSOUND_PORN_CINEMA_1_L = 63,
SCRSOUND_PORN_CINEMA_2_S = 64,
_SCRSOUND_PORN_CINEMA_2_L = 65,
SCRSOUND_PORN_CINEMA_3_S = 66,
_SCRSOUND_PORN_CINEMA_3_L = 67,
_SCRSOUND_BANK_ALARM_LOOP_S = 68,
SCRSOUND_BANK_ALARM_LOOP_L = 69,
_SCRSOUND_POLICE_BALL_LOOP_S = 70,
SCRSOUND_POLICE_BALL_LOOP_L = 71,
_SCRSOUND_RAVE_LOOP_INDUSTRIAL_S = 72,
SCRSOUND_RAVE_LOOP_INDUSTRIAL_L = 73,
_SCRSOUND_UNK_74 = 74,
_SCRSOUND_UNK_75 = 75,
_SCRSOUND_POLICE_CELL_BEATING_LOOP_S = 76,
SCRSOUND_POLICE_CELL_BEATING_LOOP_L = 77,
SCRSOUND_INJURED_PED_MALE_OUCH_S = 78,
SCRSOUND_INJURED_PED_MALE_OUCH_L = 79,
SCRSOUND_INJURED_PED_FEMALE_OUCH_S = 80,
SCRSOUND_INJURED_PED_FEMALE_OUCH_L = 81,
SCRSOUND_EVIDENCE_PICKUP = 82,
SCRSOUND_UNLOAD_GOLD = 83,
_SCRSOUND_RAVE_INDUSTRIAL_S = 84,
_SCRSOUND_RAVE_INDUSTRIAL_L = 85,
_SCRSOUND_RAVE_COMMERCIAL_S = 86,
_SCRSOUND_RAVE_COMMERCIAL_L = 87,
_SCRSOUND_RAVE_SUBURBAN_S = 88,
_SCRSOUND_RAVE_SUBURBAN_L = 89,
_SCRSOUND_GROAN_S = 90,
_SCRSOUND_GROAN_L = 91,
SCRSOUND_GATE_START_CLUNK = 92,
SCRSOUND_GATE_STOP_CLUNK = 93,
SCRSOUND_PART_MISSION_COMPLETE = 94,
SCRSOUND_CHUNKY_RUN_SHOUT = 95,
SCRSOUND_SECURITY_GUARD_RUN_AWAY_SHOUT = 96,
SCRSOUND_RACE_START_1 = 97,
SCRSOUND_RACE_START_2 = 98,
SCRSOUND_RACE_START_3 = 99,
SCRSOUND_RACE_START_GO = 100,
SCRSOUND_SWAT_PED_SHOUT = 101,
SCRSOUND_PRETEND_FIRE_LOOP = 102,
SCRSOUND_AMMUNATION_CHAT_1 = 103,
SCRSOUND_AMMUNATION_CHAT_2 = 104,
SCRSOUND_AMMUNATION_CHAT_3 = 105,
_SCRSOUND_BULLET_WALL_1 = 106,
_SCRSOUND_BULLET_WALL_2 = 107,
_SCRSOUND_BULLET_WALL_3 = 108,
_SCRSOUND_UNK_109 = 109,
_SCRSOUND_GLASSFX2_1 = 110,
_SCRSOUND_GLASSFX2_2 = 111,
_SCRSOUND_PHONE_RING = 112,
_SCRSOUND_UNK_113 = 113,
_SCRSOUND_GLASS_SMASH_1 = 114,
_SCRSOUND_GLASS_SMASH_2 = 115,
_SCRSOUND_GLASS_CRACK = 116,
_SCRSOUND_GLASS_SHARD = 117,
_SCRSOUND_WOODEN_BOX_SMASH = 118,
_SCRSOUND_CARDBOARD_BOX_SMASH = 119,
_SCRSOUND_COL_CAR = 120,
_SCRSOUND_TYRE_BUMP = 121,
_SCRSOUND_BULLET_SHELL_HIT_GROUND_1 = 122,
_SCRSOUND_BULLET_SHELL_HIT_GROUND_2 = 123,
SCRSOUND_TEST_1,
_SCRSOUND_UNK_1,
_SCRSOUND_UNK_2,
_SCRSOUND_UNK_3,
_SCRSOUND_CLUB_1_S,
_SCRSOUND_CLUB_1_L,
_SCRSOUND_CLUB_2_S,
_SCRSOUND_CLUB_2_L,
_SCRSOUND_CLUB_3_S,
_SCRSOUND_CLUB_3_L,
_SCRSOUND_CLUB_4_S,
_SCRSOUND_CLUB_4_L,
_SCRSOUND_CLUB_5_S,
_SCRSOUND_CLUB_5_L,
_SCRSOUND_CLUB_6_S,
_SCRSOUND_CLUB_6_L,
_SCRSOUND_CLUB_7_S,
_SCRSOUND_CLUB_7_L,
_SCRSOUND_CLUB_8_S,
_SCRSOUND_CLUB_8_L,
_SCRSOUND_CLUB_9_S,
_SCRSOUND_CLUB_9_L,
_SCRSOUND_CLUB_10_S,
_SCRSOUND_CLUB_10_L,
_SCRSOUND_CLUB_11_S,
_SCRSOUND_CLUB_11_L,
_SCRSOUND_CLUB_12_S,
_SCRSOUND_CLUB_12_L,
_SCRSOUND_CLUB_RAGGA_S,
_SCRSOUND_CLUB_RAGGA_L,
SCRSOUND_STRIP_CLUB_LOOP_1_S,
_SCRSOUND_STRIP_CLUB_LOOP_1_L,
SCRSOUND_STRIP_CLUB_LOOP_2_S,
_SCRSOUND_STRIP_CLUB_LOOP_2_L,
_SCRSOUND_SFX_WORKSHOP_1,
_SCRSOUND_SFX_WORKSHOP_2,
_SCRSOUND_SAWMILL_LOOP_S,
SCRSOUND_SAWMILL_LOOP_L,
_SCRSOUND_DOG_FOOD_FACTORY_S,
_SCRSOUND_DOG_FOOD_FACTORY_L,
_SCRSOUND_LAUNDERETTE_1,
_SCRSOUND_LAUNDERETTE_2,
_SCRSOUND_RESTAURANT_CHINATOWN_S,
_SCRSOUND_RESTAURANT_CHINATOWN_L,
_SCRSOUND_RESTAURANT_ITALY_S,
_SCRSOUND_RESTAURANT_ITALY_L,
_SCRSOUND_RESTAURANT_GENERIC_1_S,
_SCRSOUND_RESTAURANT_GENERIC_1_L,
_SCRSOUND_RESTAURANT_GENERIC_2_S,
_SCRSOUND_RESTAURANT_GENERIC_2_L,
_SCRSOUND_AIRPORT_ANNOUNCEMENT_S,
_SCRSOUND_AIRPORT_ANNOUNCEMENT_L,
_SCRSOUND_SHOP_LOOP_1,
_SCRSOUND_SHOP_LOOP_2,
_SCRSOUND_CINEMA_S,
_SCRSOUND_CINEMA_L,
_SCRSOUND_DOCKS_FOGHORN_S,
_SCRSOUND_DOCKS_FOGHORN_L,
_SCRSOUND_HOME_S,
_SCRSOUND_HOME_L,
_SCRSOUND_PIANO_BAR,
_SCRSOUND_CLUB,
SCRSOUND_PORN_CINEMA_1_S,
_SCRSOUND_PORN_CINEMA_1_L,
SCRSOUND_PORN_CINEMA_2_S,
_SCRSOUND_PORN_CINEMA_2_L,
SCRSOUND_PORN_CINEMA_3_S,
_SCRSOUND_PORN_CINEMA_3_L,
_SCRSOUND_BANK_ALARM_LOOP_S,
SCRSOUND_BANK_ALARM_LOOP_L,
_SCRSOUND_POLICE_BALL_LOOP_S,
SCRSOUND_POLICE_BALL_LOOP_L,
_SCRSOUND_RAVE_LOOP_INDUSTRIAL_S,
SCRSOUND_RAVE_LOOP_INDUSTRIAL_L,
_SCRSOUND_UNK_74,
_SCRSOUND_UNK_75,
_SCRSOUND_POLICE_CELL_BEATING_LOOP_S,
SCRSOUND_POLICE_CELL_BEATING_LOOP_L,
SCRSOUND_INJURED_PED_MALE_OUCH_S,
SCRSOUND_INJURED_PED_MALE_OUCH_L,
SCRSOUND_INJURED_PED_FEMALE_OUCH_S,
SCRSOUND_INJURED_PED_FEMALE_OUCH_L,
SCRSOUND_EVIDENCE_PICKUP,
SCRSOUND_UNLOAD_GOLD,
_SCRSOUND_RAVE_INDUSTRIAL_S,
_SCRSOUND_RAVE_INDUSTRIAL_L,
_SCRSOUND_RAVE_COMMERCIAL_S,
_SCRSOUND_RAVE_COMMERCIAL_L,
_SCRSOUND_RAVE_SUBURBAN_S,
_SCRSOUND_RAVE_SUBURBAN_L,
_SCRSOUND_GROAN_S,
_SCRSOUND_GROAN_L,
SCRSOUND_GATE_START_CLUNK,
SCRSOUND_GATE_STOP_CLUNK,
SCRSOUND_PART_MISSION_COMPLETE,
SCRSOUND_CHUNKY_RUN_SHOUT,
SCRSOUND_SECURITY_GUARD_RUN_AWAY_SHOUT,
SCRSOUND_RACE_START_1,
SCRSOUND_RACE_START_2,
SCRSOUND_RACE_START_3,
SCRSOUND_RACE_START_GO,
SCRSOUND_SWAT_PED_SHOUT,
SCRSOUND_PRETEND_FIRE_LOOP,
SCRSOUND_AMMUNATION_CHAT_1,
SCRSOUND_AMMUNATION_CHAT_2,
SCRSOUND_AMMUNATION_CHAT_3,
_SCRSOUND_BULLET_WALL_1,
_SCRSOUND_BULLET_WALL_2,
_SCRSOUND_BULLET_WALL_3,
_SCRSOUND_UNK_109,
_SCRSOUND_GLASSFX2_1,
_SCRSOUND_GLASSFX2_2,
_SCRSOUND_PHONE_RING,
_SCRSOUND_UNK_113,
_SCRSOUND_GLASS_SMASH_1,
_SCRSOUND_GLASS_SMASH_2,
_SCRSOUND_GLASS_CRACK,
_SCRSOUND_GLASS_SHARD,
_SCRSOUND_WOODEN_BOX_SMASH,
_SCRSOUND_CARDBOARD_BOX_SMASH,
_SCRSOUND_COL_CAR,
_SCRSOUND_TYRE_BUMP,
_SCRSOUND_BULLET_SHELL_HIT_GROUND_1,
_SCRSOUND_BULLET_SHELL_HIT_GROUND_2,
TOTAL_SCRSOUNDS,
SCRSOUND_INVALID
};
class cAudioScriptObject
@ -142,6 +144,7 @@ public:
static void operator delete(void*, size_t);
static void operator delete(void*, int);
static void LoadAllAudioScriptObjects(uint8 *buf, uint32 size);
static void SaveAllAudioScriptObjects(uint8 *buf, uint32 *size);
};

View file

@ -1,7 +1,6 @@
#pragma once
#include "audio_enums.h"
#include "Wanted.h"
enum eSound : int16
{
@ -65,7 +64,7 @@ enum eSound : int16
SOUND_GARAGE_NO_MONEY = 57,
SOUND_GARAGE_BAD_VEHICLE = 58,
SOUND_GARAGE_OPENING = 59,
SOUND_3C = 60,
SOUND_GARAGE_BOMB_ALREADY_SET = 60,
SOUND_GARAGE_BOMB1_SET = 61,
SOUND_GARAGE_BOMB2_SET = 62,
SOUND_GARAGE_BOMB3_SET = 63,

View file

@ -8,6 +8,7 @@
#include "Hud.h"
#include "ModelIndices.h"
#include "Replay.h"
#include "Pad.h"
#include "Text.h"
#include "Timer.h"
#include "World.h"
@ -16,8 +17,6 @@
cMusicManager &MusicManager = *(cMusicManager *)0x8F3964;
int32 &gNumRetunePresses = *(int32 *)0x650B80;
wchar *pCurrentStation = (wchar *)0x650B9C;
uint8 &cDisplay = *(uint8 *)0x650BA1;
int32 &gRetuneCounter = *(int32*)0x650B84;
bool& bHasStarted = *(bool*)0x650B7C;
@ -71,6 +70,8 @@ cMusicManager::DisplayRadioStationName()
int8 pRetune;
int8 gStreamedSound;
int8 gRetuneCounter;
static wchar *pCurrentStation = nil;
static uint8 cDisplay = 0;
if(!CTimer::GetIsPaused() && !TheCamera.m_WideScreenOn && PlayerInCar() &&
!CReplay::IsPlayingBack()) {

View file

@ -1,5 +1,7 @@
#pragma once
#include "Wanted.h"
struct cAMCrime {
int32 type;
CVector position;

View file

@ -6,9 +6,6 @@
#include "Curves.h"
#include "PathFind.h"
#if 0
WRAPPER void CAutoPilot::ModifySpeed(float) { EAXJMP(0x4137B0); }
#else
void CAutoPilot::ModifySpeed(float speed)
{
m_fMaxTrafficSpeed = max(0.01f, speed);
@ -41,7 +38,6 @@ void CAutoPilot::ModifySpeed(float speed)
m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() - positionBetweenNodes * m_nSpeedScaleFactor;
#endif
}
#endif
void CAutoPilot::RemoveOnePathNode()
{

View file

@ -1,5 +1,6 @@
#pragma once
#include "Entity.h"
class CEntity;
enum bridgeStates {
STATE_BRIDGE_LOCKED,

View file

@ -9,6 +9,9 @@
#include "HandlingMgr.h"
#include "ModelIndices.h"
#include "PlayerPed.h"
#include "Wanted.h"
#include "DMAudio.h"
#include "Fire.h"
#include "Pools.h"
#include "Timer.h"
#include "TrafficLights.h"

View file

@ -19,6 +19,7 @@
#include "Ped.h"
#include "PlayerInfo.h"
#include "PlayerPed.h"
#include "Wanted.h"
#include "Pools.h"
#include "Renderer.h"
#include "RoadBlocks.h"
@ -27,7 +28,7 @@
#include "Streaming.h"
#include "VisibilityPlugins.h"
#include "Vehicle.h"
#include "Wanted.h"
#include "Fire.h"
#include "World.h"
#include "Zones.h"
@ -880,9 +881,7 @@ CCarCtrl::SlowCarOnRailsDownForTrafficAndLights(CVehicle* pVehicle)
pVehicle->AutoPilot.ModifySpeed(max(maxSpeed, curSpeed - 0.5f * CTimer::GetTimeStep()));
}
}
#if 0
WRAPPER void CCarCtrl::SlowCarDownForPedsSectorList(CPtrList&, CVehicle*, float, float, float, float, float*, float) { EAXJMP(0x419300); }
#else
void CCarCtrl::SlowCarDownForPedsSectorList(CPtrList& lst, CVehicle* pVehicle, float x_inf, float y_inf, float x_sup, float y_sup, float* pSpeed, float curSpeed)
{
float frontOffset = pVehicle->GetModelInfo()->GetColModel()->boundingBox.max.y;
@ -990,7 +989,6 @@ void CCarCtrl::SlowCarDownForPedsSectorList(CPtrList& lst, CVehicle* pVehicle, f
}
}
}
#endif
void CCarCtrl::SlowCarDownForCarsSectorList(CPtrList& lst, CVehicle* pVehicle, float x_inf, float y_inf, float x_sup, float y_sup, float* pSpeed, float curSpeed)
{
@ -1054,9 +1052,6 @@ void CCarCtrl::SlowCarDownForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle,
}
}
#if 0
WRAPPER float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle* pVehicleB, float projectionX, float projectionY, CVector* pForwardA, CVector* pForwardB, uint8 id) { EAXJMP(0x41A020); }
#else
float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle* pVehicleB, float projectionX, float projectionY, CVector* pForwardA, CVector* pForwardB, uint8 id)
{
CVector2D vecBToA = pVehicleA->GetPosition() - pVehicleB->GetPosition();
@ -1179,7 +1174,6 @@ float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle*
}
return proximity;
}
#endif
float CCarCtrl::FindAngleToWeaveThroughTraffic(CVehicle* pVehicle, CPhysical* pTarget, float angleToTarget, float angleForward)
{

View file

@ -2,9 +2,6 @@
#include "patcher.h"
#include "Curves.h"
#if 0
WRAPPER float CCurves::CalcSpeedScaleFactor(CVector*, CVector*, float, float, float, float) { EAXJMP(0x420410); }
#else
float CCurves::CalcSpeedScaleFactor(CVector* pPoint1, CVector* pPoint2, float dir1X, float dir1Y, float dir2X, float dir2Y)
{
CVector2D dir1(dir1X, dir1Y);
@ -16,11 +13,7 @@ float CCurves::CalcSpeedScaleFactor(CVector* pPoint1, CVector* pPoint2, float di
else
return ((1.0f - dp) * 0.2f + 1.0f) * distance;
}
#endif
#if 0
WRAPPER void CCurves::CalcCurvePoint(CVector*, CVector*, CVector*, CVector*, float, int32, CVector*, CVector*) { EAXJMP(0x4204D0); }
#else
void CCurves::CalcCurvePoint(CVector* pPos1, CVector* pPos2, CVector* pDir1, CVector* pDir2, float between, int32 timeOnCurve, CVector* pOutPos, CVector* pOutDir)
{
float actualFactor = CalcSpeedScaleFactor(pPos1, pPos2, pDir1->x, pDir1->y, pDir2->x, pDir2->y);
@ -36,4 +29,3 @@ void CCurves::CalcCurvePoint(CVector* pPos1, CVector* pPos2, CVector* pDir1, CVe
(dir1.y * (1.0f - curveCoef) + dir2.y * curveCoef) / (timeOnCurve * 0.001f),
0.0f);
}
#endif

View file

@ -3,6 +3,7 @@
#include "main.h"
#include "Darkel.h"
#include "PlayerPed.h"
#include "Wanted.h"
#include "Timer.h"
#include "DMAudio.h"
#include "Population.h"
@ -161,9 +162,6 @@ CDarkel::ReadStatus()
return Status;
}
#if 0
WRAPPER void CDarkel::RegisterCarBlownUpByPlayer(CVehicle *vehicle) { EAXJMP(0x421070); }
#else
void
CDarkel::RegisterCarBlownUpByPlayer(CVehicle *vehicle)
{
@ -177,11 +175,7 @@ CDarkel::RegisterCarBlownUpByPlayer(CVehicle *vehicle)
RegisteredKills[vehicle->GetModelIndex()]++;
CStats::CarsExploded++;
}
#endif
#if 0
WRAPPER void CDarkel::RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool headshot) { EAXJMP(0x420F60); }
#else
void
CDarkel::RegisterKillByPlayer(CPed *victim, eWeaponType weapon, bool headshot)
{
@ -206,7 +200,6 @@ CDarkel::RegisterKillByPlayer(CPed *victim, eWeaponType weapon, bool headshot)
CStats::HeadsPopped++;
CStats::KillsSinceLastCheckpoint++;
}
#endif
void
CDarkel::RegisterKillNotByPlayer(CPed* victim, eWeaponType weapontype)
@ -221,9 +214,6 @@ CDarkel::ResetModelsKilledByPlayer()
RegisteredKills[i] = 0;
}
#if 0
WRAPPER void CDarkel::ResetOnPlayerDeath() { EAXJMP(0x420E70); }
#else
void
CDarkel::ResetOnPlayerDeath()
{
@ -252,11 +242,7 @@ CDarkel::ResetOnPlayerDeath()
player->MakeChangesForNewWeapon(player->m_currentWeapon);
}
}
#endif
#if 0
WRAPPER void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot) { EAXJMP(0x4210E0); }
#else
void
CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot)
{
@ -305,7 +291,6 @@ CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 mode
if (CDarkel::bStandardSoundAndMessages)
DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_START, 0);
}
#endif
void
CDarkel::Update()

View file

@ -1,9 +1,9 @@
#pragma once
#include "Weapon.h"
#include "ModelIndices.h"
class CVehicle;
class CPed;
enum eWeaponType;
enum
{

View file

@ -9,6 +9,7 @@
#include "CutsceneMgr.h"
#include "World.h"
#include "PlayerPed.h"
#include "Wanted.h"
#include "Camera.h"
#include "Messages.h"
#include "CarCtrl.h"
@ -56,7 +57,7 @@ CGameLogic::SortOutStreamingAndMemory(const CVector &pos)
CStreaming::FlushRequestList();
CStreaming::DeleteRwObjectsAfterDeath(pos);
CStreaming::RemoveUnusedModelsInLoadedList();
CGame::DrasticTidyUpMemory();
CGame::DrasticTidyUpMemory(true);
CStreaming::LoadScene(pos);
CTimer::Update();
}

View file

@ -2,6 +2,7 @@
#include "patcher.h"
#include "ModelIndices.h"
#include "Gangs.h"
#include "Weapon.h"
//CGangInfo(&CGangs::Gang)[NUM_GANGS] = *(CGangInfo(*)[NUM_GANGS])*(uintptr*)0x6EDF78;
CGangInfo CGangs::Gang[NUM_GANGS];
@ -13,7 +14,7 @@ CGangInfo::CGangInfo() :
m_Weapon2(WEAPONTYPE_UNARMED)
{}
void CGangs::Initialize(void)
void CGangs::Initialise(void)
{
Gang[GANG_MAFIA].m_nVehicleMI = MI_MAFIA;
Gang[GANG_TRIAD].m_nVehicleMI = MI_BELLYUP;
@ -38,8 +39,8 @@ void CGangs::SetGangVehicleModel(int16 gang, int32 model)
void CGangs::SetGangWeapons(int16 gang, int32 weapon1, int32 weapon2)
{
CGangInfo *gi = GetGangInfo(gang);
gi->m_Weapon1 = (eWeaponType)weapon1;
gi->m_Weapon2 = (eWeaponType)weapon2;
gi->m_Weapon1 = weapon1;
gi->m_Weapon2 = weapon2;
}
void CGangs::SetGangPedModelOverride(int16 gang, int8 ovrd)
@ -66,7 +67,7 @@ VALIDATESAVEBUF(*size);
void CGangs::LoadAllGangData(uint8 *buf, uint32 size)
{
Initialize();
Initialise();
INITSAVEBUF
// original: SkipSaveBuf(buf, SAVE_HEADER_SIZE);
@ -78,7 +79,7 @@ VALIDATESAVEBUF(size);
}
STARTPATCHES
InjectHook(0x4C3FB0, CGangs::Initialize, PATCH_JUMP);
InjectHook(0x4C3FB0, CGangs::Initialise, PATCH_JUMP);
InjectHook(0x4C4010, CGangs::SetGangVehicleModel, PATCH_JUMP);
InjectHook(0x4C4030, CGangs::SetGangWeapons, PATCH_JUMP);
InjectHook(0x4C4050, CGangs::SetGangPedModelOverride, PATCH_JUMP);

View file

@ -1,13 +1,11 @@
#pragma once
#include "Weapon.h"
struct CGangInfo
{
int32 m_nVehicleMI;
int8 m_nPedModelOverride;
eWeaponType m_Weapon1;
eWeaponType m_Weapon2;
int32 m_Weapon1;
int32 m_Weapon2;
CGangInfo();
};
@ -30,7 +28,7 @@ enum {
class CGangs
{
public:
static void Initialize(void);
static void Initialise(void);
static void SetGangVehicleModel(int16, int32);
static void SetGangWeapons(int16, int32, int32);
static void SetGangPedModelOverride(int16, int8);

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,11 @@
#pragma once
#include "Automobile.h"
#include "audio_enums.h"
#include "Camera.h"
#include "config.h"
class CVehicle;
class CCamera;
enum eGarageState : int8
{
@ -44,7 +46,8 @@ enum eGarageType : int8
enum
{
TOTAL_COLLECTCARS_GARAGES = GARAGE_COLLECTCARS_3 - GARAGE_COLLECTCARS_1 + 1
TOTAL_COLLECTCARS_GARAGES = GARAGE_COLLECTCARS_3 - GARAGE_COLLECTCARS_1 + 1,
TOTAL_COLLECTCARS_CARS = 16
};
class CStoredCar
@ -63,34 +66,43 @@ class CStoredCar
int8 m_nVariationA;
int8 m_nVariationB;
int8 m_nCarBombType;
public:
void Init() { m_nModelIndex = 0; }
void Clear() { m_nModelIndex = 0; }
bool HasCar() { return m_nModelIndex != 0; }
CStoredCar(const CStoredCar& other);
void StoreCar(CVehicle*);
CVehicle* RestoreCar();
};
static_assert(sizeof(CStoredCar) == 0x28, "CStoredCar");
#define SWITCH_GARAGE_DISTANCE_CLOSE 40.0f
class CGarage
{
public:
eGarageType m_eGarageType;
eGarageState m_eGarageState;
char field_2;
char m_bClosingWithoutTargetCar;
char m_bDeactivated;
char m_bResprayHappened;
char field_6;
char field_7;
bool field_2; // unused
bool m_bClosingWithoutTargetCar;
bool m_bDeactivated;
bool m_bResprayHappened;
int m_nTargetModelIndex;
CEntity *m_pDoor1;
CEntity *m_pDoor2;
char m_bDoor1PoolIndex;
char m_bDoor2PoolIndex;
char m_bIsDoor1Object;
char m_bIsDoor2Object;
char field_24;
char m_bRotatedDoor;
char m_bCameraFollowsPlayer;
char field_27;
CVector m_vecInf;
CVector m_vecSup;
uint8 m_bDoor1PoolIndex;
uint8 m_bDoor2PoolIndex;
bool m_bDoor1IsDummy;
bool m_bDoor2IsDummy;
bool m_bRecreateDoorOnNextRefresh;
bool m_bRotatedDoor;
bool m_bCameraFollowsPlayer;
float m_fX1;
float m_fX2;
float m_fY1;
float m_fY2;
float m_fZ1;
float m_fZ2;
float m_fDoorPos;
float m_fDoorHeight;
float m_fDoor1X;
@ -99,26 +111,74 @@ public:
float m_fDoor2Y;
float m_fDoor1Z;
float m_fDoor2Z;
int m_nDoorOpenTime;
char m_bCollectedCarsState;
char field_89;
char field_90;
char field_91;
uint32 m_nTimeToStartAction;
uint8 m_bCollectedCarsState;
CVehicle *m_pTarget;
int field_96;
CStoredCar m_sStoredCar;
void* field_96; // unused
CStoredCar m_sStoredCar; // not needed
void OpenThisGarage();
void CloseThisGarage();
bool IsOpen() { return m_eGarageState == GS_OPENED || m_eGarageState == GS_OPENEDCONTAINSCAR; }
bool IsClosed() { return m_eGarageState == GS_FULLYCLOSED; }
bool IsUsed() { return m_eGarageType != GARAGE_NONE; }
void Update();
float GetGarageCenterX() { return (m_fX1 + m_fX2) / 2; }
float GetGarageCenterY() { return (m_fY1 + m_fY2) / 2; }
bool IsFar()
{
#ifdef FIX_BUGS
return Abs(TheCamera.GetPosition().x - GetGarageCenterX()) > SWITCH_GARAGE_DISTANCE_CLOSE ||
Abs(TheCamera.GetPosition().y - GetGarageCenterY()) > SWITCH_GARAGE_DISTANCE_CLOSE;
#else
return Abs(TheCamera.GetPosition().x - m_fX1) > SWITCH_GARAGE_DISTANCE_CLOSE ||
Abs(TheCamera.GetPosition().y - m_fY1) > SWITCH_GARAGE_DISTANCE_CLOSE;
#endif
}
void TidyUpGarageClose();
void TidyUpGarage();
void RefreshDoorPointers(bool);
void UpdateCrusherAngle();
void UpdateDoorsHeight();
bool IsEntityEntirelyInside3D(CEntity*, float);
bool IsEntityEntirelyOutside(CEntity*, float);
bool IsEntityEntirelyInside(CEntity*);
float CalcDistToGarageRectangleSquared(float, float);
float CalcSmallestDistToGarageDoorSquared(float, float);
bool IsAnyOtherCarTouchingGarage(CVehicle* pException);
bool IsStaticPlayerCarEntirelyInside();
bool IsPlayerOutsideGarage();
bool IsAnyCarBlockingDoor();
void CenterCarInGarage(CVehicle*);
bool DoesCraigNeedThisCar(int32);
bool MarkThisCarAsCollectedForCraig(int32);
bool HasCraigCollectedThisCar(int32);
bool IsGarageEmpty();
void UpdateCrusherShake(float, float);
int32 CountCarsWithCenterPointWithinGarage(CEntity* pException);
void RemoveCarsBlockingDoorNotInside();
void StoreAndRemoveCarsForThisHideout(CStoredCar*, int32);
bool RestoreCarsForThisHideout(CStoredCar*);
bool IsEntityTouching3D(CEntity*);
bool EntityHasASphereWayOutsideGarage(CEntity*, float);
bool IsAnyOtherPedTouchingGarage(CPed* pException);
void BuildRotatedDoorMatrix(CEntity*, float);
void FindDoorsEntities();
void FindDoorsEntitiesSectorList(CPtrList&, bool);
void PlayerArrestedOrDied();
friend class CGarages;
friend class cAudioManager;
friend class CCamera;
};
static_assert(sizeof(CGarage) == 140, "CGarage");
class CGarages
{
public:
enum {
MESSAGE_LENGTH = 8
};
static int32 &BankVansCollected;
static bool &BombsAreFree;
static bool &RespraysAreFree;
@ -127,7 +187,7 @@ public:
static int32 &CrushedCarId;
static uint32 &LastTimeHelpMessage;
static int32 &MessageNumberInString;
static const char *MessageIDString;
static char(&MessageIDString)[MESSAGE_LENGTH];
static int32 &MessageNumberInString2;
static uint32 &MessageStartTime;
static uint32 &MessageEndTime;
@ -135,36 +195,62 @@ public:
static bool &PlayerInGarage;
static int32 &PoliceCarsCollected;
static uint32 &GarageToBeTidied;
static CGarage(&Garages)[NUM_GARAGES];
static CGarage(&aGarages)[NUM_GARAGES];
static CStoredCar(&aCarsInSafeHouse1)[NUM_GARAGE_STORED_CARS];
static CStoredCar(&aCarsInSafeHouse2)[NUM_GARAGE_STORED_CARS];
static CStoredCar(&aCarsInSafeHouse3)[NUM_GARAGE_STORED_CARS];
static int32 &AudioEntity;
static bool &bCamShouldBeOutisde;
public:
static bool IsModelIndexADoor(uint32 id);
static void TriggerMessage(const char *text, int16, uint16 time, int16);
static void PrintMessages(void);
static bool HasCarBeenCrushed(int32);
static bool IsPointWithinHideOutGarage(CVector&);
static bool IsPointWithinAnyGarage(CVector&);
static void PlayerArrestedOrDied();
static void Init(void);
#ifndef PS2
static void Shutdown(void);
#endif
static void Update(void);
static void Load(uint8 *buf, uint32 size);
static void Save(uint8 *buf, uint32 *size);
static int16 AddOne(float, float, float, float, float, float, uint8, uint32);
static int16 AddOne(float X1, float Y1, float Z1, float X2, float Y2, float Z2, eGarageType type, int32 targetId);
static void ChangeGarageType(int16, eGarageType, int32);
static void PrintMessages(void);
static void TriggerMessage(const char* text, int16, uint16 time, int16);
static void SetTargetCarForMissonGarage(int16, CVehicle*);
static bool HasCarBeenDroppedOffYet(int16);
static void ActivateGarage(int16);
static void DeActivateGarage(int16);
static void ActivateGarage(int16);
static int32 QueryCarsCollected(int16);
static bool HasThisCarBeenCollected(int16, uint8);
static void ChangeGarageType(int16, eGarageType, int32);
static bool HasResprayHappened(int16);
static void GivePlayerDetonator();
static bool HasImportExportGarageCollectedThisCar(int16, int8);
static bool IsGarageOpen(int16);
static bool IsGarageClosed(int16);
static bool HasThisCarBeenCollected(int16, uint8);
static void OpenGarage(int16 garage) { aGarages[garage].OpenThisGarage(); }
static void CloseGarage(int16 garage) { aGarages[garage].CloseThisGarage(); }
static bool HasResprayHappened(int16);
static void SetGarageDoorToRotate(int16);
static bool HasImportExportGarageCollectedThisCar(int16, int8);
static void SetLeaveCameraForThisGarage(int16);
static bool IsThisCarWithinGarageArea(int16, CEntity*);
static bool HasCarBeenCrushed(int32);
static bool IsPointInAGarageCameraZone(CVector);
static bool CameraShouldBeOutside(void);
static void GivePlayerDetonator(void);
static void PlayerArrestedOrDied(void);
static bool IsPointWithinHideOutGarage(CVector&);
static bool IsPointWithinAnyGarage(CVector&);
static void SetAllDoorsBackToOriginalHeight(void);
static void Save(uint8* buf, uint32* size);
static void Load(uint8* buf, uint32 size);
static bool IsModelIndexADoor(uint32 id);
static void SetFreeBombs(bool bValue) { BombsAreFree = bValue; }
static void SetFreeResprays(bool bValue) { RespraysAreFree = bValue; }
static int GetCarsCollectedIndexForGarageType(eGarageType type) { return type - GARAGE_COLLECTCARS_1; }
private:
static bool IsCarSprayable(CVehicle*);
static float FindDoorHeightForMI(int32);
static void CloseHideOutGaragesBeforeSave(void);
static int32 CountCarsInHideoutGarage(eGarageType);
static int32 FindMaxNumStoredCarsForGarage(eGarageType);
static int32 GetBombTypeForGarageType(eGarageType type) { return type - GARAGE_BOMBSHOP1 + 1; }
static int32 GetCarsCollectedIndexForGarageType(eGarageType type) { return type - GARAGE_COLLECTCARS_1; }
friend class cAudioManager;
friend class CGarage;
};

View file

@ -11,19 +11,10 @@ CPathFind &ThePaths = *(CPathFind*)0x8F6754;
WRAPPER bool CPedPath::CalcPedRoute(uint8, CVector, CVector, CVector*, int16*, int16) { EAXJMP(0x42E680); }
enum
{
NodeTypeExtern = 1,
NodeTypeIntern = 2,
ObjectFlag1 = 1,
ObjectEastWest = 2,
MAX_DIST = INT16_MAX-1
};
#define MAX_DIST INT16_MAX-1
// object flags:
// 1
// 1 UseInRoadBlock
// 2 east/west road(?)
CPathInfoForObject *&InfoForTileCars = *(CPathInfoForObject**)0x8F1A8C;
@ -218,14 +209,14 @@ CPathFind::PreparePathData(void)
if(numIntern == 1 && numExtern == 2){
if(numLanes < 4){
if((i & 7) == 4){ // WHAT?
m_objectFlags[i] |= ObjectFlag1;
m_objectFlags[i] |= UseInRoadBlock;
if(maxX > maxY)
m_objectFlags[i] |= ObjectEastWest;
else
m_objectFlags[i] &= ~ObjectEastWest;
}
}else{
m_objectFlags[i] |= ObjectFlag1;
m_objectFlags[i] |= UseInRoadBlock;
if(maxX > maxY)
m_objectFlags[i] |= ObjectEastWest;
else

View file

@ -9,6 +9,15 @@ public:
static bool CalcPedRoute(uint8, CVector, CVector, CVector*, int16*, int16);
};
enum
{
NodeTypeExtern = 1,
NodeTypeIntern = 2,
UseInRoadBlock = 1,
ObjectEastWest = 2,
};
enum
{
PATH_CAR = 0,

View file

@ -11,6 +11,7 @@
#include "General.h"
#include "AudioScriptObject.h"
#include "RpAnimBlend.h"
#include "AnimBlendAssociation.h"
CPhoneInfo &gPhoneInfo = *(CPhoneInfo*)0x732A20;

View file

@ -15,8 +15,14 @@
#include "Pad.h"
#include "Pickups.h"
#include "PlayerPed.h"
#include "Wanted.h"
#include "DMAudio.h"
#include "Fire.h"
#include "PointLights.h"
#include "Pools.h"
#ifdef FIX_BUGS
#include "Replay.h"
#endif
#include "Script.h"
#include "Shadows.h"
#include "SpecialFX.h"
@ -639,32 +645,26 @@ CPickups::AddToCollectedPickupsArray(int32 index)
void
CPickups::Update()
{
#ifndef FIX_BUGS
// BUG: this code can only reach 318 out of 320 pickups
#ifdef FIX_BUGS // RIP speedrunning (solution from SA)
if (CReplay::IsPlayingBack())
return;
#endif
#define PICKUPS_FRAME_SPAN (6)
#define PICKUPS_PER_FRAME (NUMGENERALPICKUPS/PICKUPS_FRAME_SPAN)
for (uint32 i = PICKUPS_PER_FRAME * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN); i < PICKUPS_PER_FRAME * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1); i++) {
#ifdef FIX_BUGS
for (uint32 i = NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN) / PICKUPS_FRAME_SPAN; i < NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1) / PICKUPS_FRAME_SPAN; i++) {
#else // BUG: this code can only reach 318 out of 320 pickups
for (uint32 i = NUMGENERALPICKUPS / PICKUPS_FRAME_SPAN * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN); i < NUMGENERALPICKUPS / PICKUPS_FRAME_SPAN * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1); i++) {
#endif
if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
AddToCollectedPickupsArray(i);
}
}
#undef PICKUPS_FRAME_SPAN
for (uint32 i = NUMGENERALPICKUPS; i < NUMPICKUPS; i++) {
if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
AddToCollectedPickupsArray(i);
}
}
#undef PICKUPS_FRAME_SPAN
#undef PICKUPS_PER_FRAME
#else
for (uint32 i = 0; i < NUMPICKUPS; i++) {
if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
AddToCollectedPickupsArray(i);
}
}
#endif
}
void

View file

@ -35,7 +35,7 @@ CRemote::GivePlayerRemoteControlledCar(float x, float y, float z, float rot, uin
CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle = car;
CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->RegisterReference((CEntity**)&CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle);
TheCamera.TakeControl(car, CCam::MODE_BEHINDCAR, INTERPOLATION, CAM_CONTROLLER_1);
TheCamera.TakeControl(car, CCam::MODE_BEHINDCAR, INTERPOLATION, CAMCONTROL_SCRIPT);
}
void

View file

@ -5,6 +5,7 @@
#include "SpecialFX.h"
#include "CarCtrl.h"
#include "CivilianPed.h"
#include "Wanted.h"
#include "Clock.h"
#include "DMAudio.h"
#include "Draw.h"
@ -22,6 +23,8 @@
#include "Pools.h"
#include "Population.h"
#include "Replay.h"
#include "References.h"
#include "Pools.h"
#include "RpAnimBlend.h"
#include "RwHelper.h"
#include "CutsceneMgr.h"
@ -33,6 +36,8 @@
#include "Zones.h"
#include "Font.h"
#include "Text.h"
#include "Camera.h"
#include "Radar.h"
uint8 &CReplay::Mode = *(uint8*)0x95CD5B;
CAddressInReplayBuffer &CReplay::Record = *(CAddressInReplayBuffer*)0x942F7C;
@ -108,9 +113,6 @@ static void(*CBArray_RE3[])(CAnimBlendAssociation*, void*) =
&CPed::PedLandCB, &FinishFuckUCB, &CPed::RestoreHeadingRateCB, &CPed::PedSetQuickDraggedOutCarPositionCB, &CPed::PedSetDraggedOutCarPositionCB
};
#if 0
WRAPPER uint8 FindCBFunctionID(void(*f)(CAnimBlendAssociation*, void*)) { EAXJMP(0x584E70); }
#else
static uint8 FindCBFunctionID(void(*f)(CAnimBlendAssociation*, void*))
{
for (int i = 0; i < sizeof(CBArray) / sizeof(*CBArray); i++){
@ -123,16 +125,12 @@ static uint8 FindCBFunctionID(void(*f)(CAnimBlendAssociation*, void*))
}
return 0;
}
#endif
static void(*FindCBFunction(uint8 id))(CAnimBlendAssociation*, void*)
{
return CBArray_RE3[id];
}
#if 0
WRAPPER static void ApplyPanelDamageToCar(uint32, CAutomobile*, bool) { EAXJMP(0x584EA0); }
#else
static void ApplyPanelDamageToCar(uint32 panels, CAutomobile* vehicle, bool flying)
{
if(vehicle->Damage.GetPanelStatus(VEHPANEL_FRONT_LEFT) != CDamageManager::GetPanelStatus(panels, VEHPANEL_FRONT_LEFT)){
@ -164,7 +162,6 @@ static void ApplyPanelDamageToCar(uint32 panels, CAutomobile* vehicle, bool flyi
vehicle->SetPanelDamage(CAR_BUMP_REAR, VEHBUMPER_REAR, flying);
}
}
#endif
void PrintElementsInPtrList(void)
{
@ -257,9 +254,6 @@ void CReplay::Update(void)
}
}
#if 0
WRAPPER void CReplay::RecordThisFrame(void) { EAXJMP(0x5932B0); }
#else
void CReplay::RecordThisFrame(void)
{
#ifdef FIX_REPLAY_BUGS
@ -372,11 +366,7 @@ void CReplay::RecordThisFrame(void)
MarkEverythingAsNew();
#endif
}
#endif
#if 0
WRAPPER void CReplay::StorePedUpdate(CPed *ped, int id) { EAXJMP(0x5935B0); }
#else
void CReplay::StorePedUpdate(CPed *ped, int id)
{
tPedUpdatePacket* pp = (tPedUpdatePacket*)&Record.m_pBase[Record.m_nOffset];
@ -394,11 +384,7 @@ void CReplay::StorePedUpdate(CPed *ped, int id)
StorePedAnimation(ped, &pp->anim_state);
Record.m_nOffset += sizeof(tPedUpdatePacket);
}
#endif
#if 0
WRAPPER void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state) { EAXJMP(0x593670); }
#else
void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state)
{
CAnimBlendAssociation* second;
@ -437,11 +423,7 @@ void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state)
state->partBlendAmount = 0;
}
}
#endif
#if 0
WRAPPER void CReplay::StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState *state) { EAXJMP(0x593BB0); }
#else
void CReplay::StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState *state)
{
for (int i = 0; i < NUM_MAIN_ANIMS_IN_REPLAY; i++){
@ -498,10 +480,7 @@ void CReplay::StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState
}
}
}
#endif
#if 0
WRAPPER void CReplay::ProcessPedUpdate(CPed *ped, float interpolation, CAddressInReplayBuffer *buffer) { EAXJMP(0x594050); }
#else
void CReplay::ProcessPedUpdate(CPed *ped, float interpolation, CAddressInReplayBuffer *buffer)
{
tPedUpdatePacket *pp = (tPedUpdatePacket*)&buffer->m_pBase[buffer->m_nOffset];
@ -538,11 +517,7 @@ void CReplay::ProcessPedUpdate(CPed *ped, float interpolation, CAddressInReplayB
CWorld::Add(ped);
buffer->m_nOffset += sizeof(tPedUpdatePacket);
}
#endif
#if 0
WRAPPER void CReplay::RetrievePedAnimation(CPed *ped, CStoredAnimationState *state) { EAXJMP(0x5942A0); }
#else
void CReplay::RetrievePedAnimation(CPed *ped, CStoredAnimationState *state)
{
CAnimBlendAssociation* anim1 = CAnimManager::BlendAnimation(
@ -580,11 +555,7 @@ void CReplay::RetrievePedAnimation(CPed *ped, CStoredAnimationState *state)
}
}
}
#endif
#if 0
WRAPPER void CReplay::RetrieveDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState *state) { EAXJMP(0x5944B0); }
#else
void CReplay::RetrieveDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState *state)
{
#ifdef FIX_REPLAY_BUGS
@ -653,11 +624,7 @@ void CReplay::RetrieveDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationSt
anim->SetDeleteCallback(FindCBFunction(callback & 0x7F), ped);
}
}
#endif
#if 0
WRAPPER void CReplay::PlaybackThisFrame(void) { EAXJMP(0x5946B0); }
#else
void CReplay::PlaybackThisFrame(void)
{
static int FrameSloMo = 0;
@ -682,7 +649,6 @@ void CReplay::PlaybackThisFrame(void)
DMAudio.SetEffectsFadeVol(0);
DMAudio.SetMusicFadeVol(0);
}
#endif
// next two functions are only found in mobile version
// most likely they were optimized out for being unused
@ -707,9 +673,6 @@ bool CReplay::FastForwardToTime(uint32 start)
return true;
}
#if 0
WRAPPER void CReplay::StoreCarUpdate(CVehicle *vehicle, int id) { EAXJMP(0x5947F0); }
#else
void CReplay::StoreCarUpdate(CVehicle *vehicle, int id)
{
tVehicleUpdatePacket* vp = (tVehicleUpdatePacket*)&Record.m_pBase[Record.m_nOffset];
@ -745,11 +708,7 @@ void CReplay::StoreCarUpdate(CVehicle *vehicle, int id)
}
Record.m_nOffset += sizeof(tVehicleUpdatePacket);
}
#endif
#if 0
WRAPPER void CReplay::ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressInReplayBuffer *buffer) { EAXJMP(0x594D10); }
#else
void CReplay::ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressInReplayBuffer *buffer)
{
tVehicleUpdatePacket* vp = (tVehicleUpdatePacket*)&buffer->m_pBase[buffer->m_nOffset];
@ -819,11 +778,7 @@ void CReplay::ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressI
((CBoat*)vehicle)->m_bIsAnchored = false;
}
}
#endif
#if 0
WRAPPER bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, float interpolation, uint32 *pTimer) { EAXJMP(0x595240); }
#else
bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, float interpolation, uint32 *pTimer){
/* Mistake. Not even sure what this is even doing here...
* PlayerWanted is a backup to restore at the end of replay.
@ -1023,10 +978,7 @@ bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, flo
ProcessReplayCamera();
return false;
}
#endif
#if 0
WRAPPER void CReplay::FinishPlayback(void) { EAXJMP(0x595B20); }
#else
void CReplay::FinishPlayback(void)
{
if (Mode != MODE_PLAYBACK)
@ -1048,11 +1000,7 @@ void CReplay::FinishPlayback(void)
DMAudio.SetEffectsFadeVol(127);
DMAudio.SetMusicFadeVol(127);
}
#endif
#if 0
WRAPPER void CReplay::EmptyReplayBuffer(void) { EAXJMP(0x595BD0); }
#else
void CReplay::EmptyReplayBuffer(void)
{
if (Mode == MODE_PLAYBACK)
@ -1067,11 +1015,7 @@ void CReplay::EmptyReplayBuffer(void)
Record.m_pBase[Record.m_nOffset] = 0;
MarkEverythingAsNew();
}
#endif
#if 0
WRAPPER void CReplay::ProcessReplayCamera(void) { EAXJMP(0x595C40); }
#else
void CReplay::ProcessReplayCamera(void)
{
switch (CameraMode) {
@ -1115,11 +1059,7 @@ void CReplay::ProcessReplayCamera(void)
RwMatrixUpdate(RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)));
RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera));
}
#endif
#if 0
WRAPPER void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float cam_z, bool load_scene) { EAXJMP(0x596030); }
#else
void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float cam_z, bool load_scene)
{
if (Mode != MODE_RECORD)
@ -1169,11 +1109,7 @@ void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float ca
if (cam_mode == REPLAYCAMMODE_ASSTORED)
TheCamera.CarZoomIndicator = 5.0f;
}
#endif
#if 0
WRAPPER void CReplay::StoreStuffInMem(void) { EAXJMP(0x5961F0); }
#else
void CReplay::StoreStuffInMem(void)
{
CPools::GetVehiclePool()->Store(pBuf0, pBuf1);
@ -1218,11 +1154,7 @@ void CReplay::StoreStuffInMem(void)
StoreDetailedPedAnimation(ped, &pPedAnims[i]);
}
}
#endif
#if 0
WRAPPER void CReplay::RestoreStuffFromMem(void) { EAXJMP(0x5966E0); }
#else
void CReplay::RestoreStuffFromMem(void)
{
CPools::GetVehiclePool()->CopyBack(pBuf0, pBuf1);
@ -1383,11 +1315,7 @@ void CReplay::RestoreStuffFromMem(void)
DMAudio.SetRadioInCar(OldRadioStation);
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
}
#endif
#if 0
WRAPPER void CReplay::EmptyPedsAndVehiclePools(void) { EAXJMP(0x5970E0); }
#else
void CReplay::EmptyPedsAndVehiclePools(void)
{
int i = CPools::GetVehiclePool()->GetSize();
@ -1407,11 +1335,7 @@ void CReplay::EmptyPedsAndVehiclePools(void)
delete p;
}
}
#endif
#if 0
WRAPPER void CReplay::EmptyAllPools(void) { EAXJMP(0x5971B0); }
#else
void CReplay::EmptyAllPools(void)
{
EmptyPedsAndVehiclePools();
@ -1432,11 +1356,7 @@ void CReplay::EmptyAllPools(void)
delete d;
}
}
#endif
#if 0
WRAPPER void CReplay::MarkEverythingAsNew(void) { EAXJMP(0x597280); }
#else
void CReplay::MarkEverythingAsNew(void)
{
int i = CPools::GetVehiclePool()->GetSize();
@ -1454,11 +1374,7 @@ void CReplay::MarkEverythingAsNew(void)
p->bHasAlreadyBeenRecorded = false;
}
}
#endif
#if 0
WRAPPER void CReplay::SaveReplayToHD(void) { EAXJMP(0x597330); }
#else
void CReplay::SaveReplayToHD(void)
{
CFileMgr::SetDirMyDocuments();
@ -1489,11 +1405,7 @@ void CReplay::SaveReplayToHD(void)
CFileMgr::CloseFile(fw);
CFileMgr::SetDir("");
}
#endif
#if 0
WRAPPER void PlayReplayFromHD(void) { EAXJMP(0x597420); }
#else
void PlayReplayFromHD(void)
{
CFileMgr::SetDirMyDocuments();
@ -1525,11 +1437,7 @@ void PlayReplayFromHD(void)
CReplay::bAllowLookAroundCam = true;
CReplay::StreamAllNecessaryCarsAndPeds();
}
#endif
#if 0
WRAPPER void CReplay::StreamAllNecessaryCarsAndPeds(void) { EAXJMP(0x597560); }
#else
void CReplay::StreamAllNecessaryCarsAndPeds(void)
{
for (int slot = 0; slot < NUM_REPLAYBUFFERS; slot++) {
@ -1550,11 +1458,7 @@ void CReplay::StreamAllNecessaryCarsAndPeds(void)
}
CStreaming::LoadAllRequestedModels(false);
}
#endif
#if 0
WRAPPER void CReplay::FindFirstFocusCoordinate(CVector *coord) { EAXJMP(0x5975E0); }
#else
void CReplay::FindFirstFocusCoordinate(CVector *coord)
{
*coord = CVector(0.0f, 0.0f, 0.0f);
@ -1569,11 +1473,7 @@ void CReplay::FindFirstFocusCoordinate(CVector *coord)
}
}
}
#endif
#if 0
WRAPPER bool CReplay::ShouldStandardCameraBeProcessed(void) { EAXJMP(0x597680); }
#else
bool CReplay::ShouldStandardCameraBeProcessed(void)
{
if (Mode != MODE_PLAYBACK)
@ -1582,11 +1482,7 @@ bool CReplay::ShouldStandardCameraBeProcessed(void)
return false;
return FindPlayerVehicle() != nil;
}
#endif
#if 0
WRAPPER void CReplay::ProcessLookAroundCam(void) { EAXJMP(0x5976C0); }
#else
void CReplay::ProcessLookAroundCam(void)
{
if (!bAllowLookAroundCam)
@ -1642,11 +1538,7 @@ void CReplay::ProcessLookAroundCam(void)
RwMatrixUpdate(RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)));
RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera));
}
#endif
#if 0
WRAPPER size_t CReplay::FindSizeOfPacket(uint8 type) { EAXJMP(0x597CC0); }
#else
size_t CReplay::FindSizeOfPacket(uint8 type)
{
switch (type) {
@ -1664,11 +1556,7 @@ size_t CReplay::FindSizeOfPacket(uint8 type)
}
return 0;
}
#endif
#if 0
WRAPPER void CReplay::Display(void) { EAXJMP(0x595EE0); }
#else
void CReplay::Display()
{
static int TimeCount = 0;
@ -1686,7 +1574,6 @@ void CReplay::Display()
if (Mode == MODE_PLAYBACK)
CFont::PrintString(SCREEN_SCALE_X(63.5f), SCREEN_SCALE_Y(30.0f), TheText.Get("REPLAY"));
}
#endif
STARTPATCHES
InjectHook(0x592FE0, &CReplay::Init, PATCH_JUMP);

View file

@ -1,14 +1,7 @@
#pragma once
#include "Camera.h"
#include "Ped.h"
#include "Pools.h"
#include "Radar.h"
#include "References.h"
#include "Vehicle.h"
#include "Wanted.h"
#include "World.h"
#include "common.h"
#ifdef FIX_BUGS
#ifndef DONT_FIX_REPLAY_BUGS
@ -16,6 +9,9 @@
#endif
#endif
class CVehicle;
struct CReference;
struct CAddressInReplayBuffer
{
uint32 m_nOffset;

View file

@ -1,7 +1,37 @@
#include "common.h"
#include "patcher.h"
#include "RoadBlocks.h"
#include "PathFind.h"
int16 &CRoadBlocks::NumRoadBlocks = *(int16*)0x95CC34;
int16 (&CRoadBlocks::RoadBlockObjects)[NUMROADBLOCKS] = *(int16(*)[NUMROADBLOCKS]) * (uintptr*)0x72B3A8;
bool (&CRoadBlocks::InOrOut)[NUMROADBLOCKS] = *(bool(*)[NUMROADBLOCKS]) * (uintptr*)0x733810;
WRAPPER void CRoadBlocks::Init(void) { EAXJMP(0x436F50); }
WRAPPER void CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle*, int32, int16) { EAXJMP(0x4376A0); }
WRAPPER void CRoadBlocks::GenerateRoadBlocks(void) { EAXJMP(0x436FA0); }
void
CRoadBlocks::Init(void)
{
NumRoadBlocks = 0;
for (int objId = 0; objId < ThePaths.m_numMapObjects; objId++) {
if (ThePaths.m_objectFlags[objId] & UseInRoadBlock) {
if (NumRoadBlocks < 600) {
InOrOut[NumRoadBlocks] = true;
RoadBlockObjects[NumRoadBlocks] = objId;
NumRoadBlocks++;
} else {
#ifndef MASTER
printf("Not enough room for the potential roadblocks\n");
#endif
// FIX: Don't iterate loop after NUMROADBLOCKS
return;
}
}
}
}
STARTPATCHES
InjectHook(0x436F50, &CRoadBlocks::Init, PATCH_JUMP);
ENDPATCHES

View file

@ -6,6 +6,10 @@ class CVehicle;
class CRoadBlocks
{
public:
static int16 (&NumRoadBlocks);
static int16 (&RoadBlockObjects)[NUMROADBLOCKS];
static bool (&InOrOut)[NUMROADBLOCKS];
static void Init(void);
static void GenerateRoadBlockCopsForCar(CVehicle*, int32, int16);
static void GenerateRoadBlocks(void);

View file

@ -2,5 +2,11 @@
#include "patcher.h"
#include "SceneEdit.h"
bool &CSceneEdit::m_bEditOn = *(bool*)0x95CD77;
int32 &CSceneEdit::m_bCameraFollowActor = *(int*)0x940590;
bool &CSceneEdit::m_bRecording = *(bool*)0x95CD1F;
CVector &CSceneEdit::m_vecCurrentPosition = *(CVector*)0x943064;
CVector &CSceneEdit::m_vecCamHeading = *(CVector*)0x942F8C;
WRAPPER void CSceneEdit::Update(void) { EAXJMP(0x585570); }
WRAPPER void CSceneEdit::Init(void) { EAXJMP(0x585170); }

View file

@ -3,6 +3,12 @@
class CSceneEdit
{
public:
static bool &m_bEditOn;
static int32 &m_bCameraFollowActor;
static bool &m_bRecording;
static CVector &m_vecCurrentPosition;
static CVector &m_vecCamHeading;
static void Update(void);
static void Init(void);
};

View file

@ -1,3 +1,4 @@
#define WITHWINDOWS // for our script loading hack
#include "common.h"
#include "patcher.h"
@ -52,6 +53,8 @@
#include "Restart.h"
#include "Replay.h"
#include "RpAnimBlend.h"
#include "AnimBlendAssociation.h"
#include "Fire.h"
#include "Rubbish.h"
#include "Shadows.h"
#include "SpecialFX.h"
@ -64,6 +67,7 @@
#include "Weather.h"
#include "World.h"
#include "Zones.h"
#include "Radar.h"
#define PICKUP_PLACEMENT_OFFSET 0.5f
#define PED_FIND_Z_OFFSET 5.0f
@ -2838,9 +2842,6 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
return -1;
}
#if 0
WRAPPER int8 CRunningScript::ProcessCommand300To399(int32 command) { EAXJMP(0x43ED30); }
#else
int8 CRunningScript::ProcessCommands300To399(int32 command)
{
switch (command) {
@ -3072,7 +3073,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
{
CollectParameters(&m_nIp, 3);
// ScriptParams[0] is unused.
TheCamera.TakeControl(nil, ScriptParams[1], ScriptParams[2], CAM_CONTROLLER_1);
TheCamera.TakeControl(nil, ScriptParams[1], ScriptParams[2], CAMCONTROL_SCRIPT);
return 0;
}
case COMMAND_POINT_CAMERA_AT_CAR:
@ -3080,7 +3081,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
CollectParameters(&m_nIp, 3);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(pVehicle);
TheCamera.TakeControl(pVehicle, ScriptParams[1], ScriptParams[2], CAM_CONTROLLER_1);
TheCamera.TakeControl(pVehicle, ScriptParams[1], ScriptParams[2], CAMCONTROL_SCRIPT);
return 0;
}
case COMMAND_POINT_CAMERA_AT_CHAR:
@ -3088,7 +3089,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
CollectParameters(&m_nIp, 3);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
assert(pPed);
TheCamera.TakeControl(pPed, ScriptParams[1], ScriptParams[2], CAM_CONTROLLER_1);
TheCamera.TakeControl(pPed, ScriptParams[1], ScriptParams[2], CAMCONTROL_SCRIPT);
return 0;
}
case COMMAND_RESTORE_CAMERA:
@ -3139,7 +3140,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
CVector pos = *(CVector*)&ScriptParams[0];
if (pos.z <= MAP_Z_LOW_LIMIT)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
TheCamera.TakeControlNoEntity(pos, ScriptParams[3], CAM_CONTROLLER_1);
TheCamera.TakeControlNoEntity(pos, ScriptParams[3], CAMCONTROL_SCRIPT);
return 0;
}
case COMMAND_ADD_BLIP_FOR_CAR_OLD:
@ -3572,11 +3573,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
}
return -1;
}
#endif
#if 0
WRAPPER int8 CRunningScript::ProcessCommands400To499(int32 command) { EAXJMP(0x440CB0); }
#else
int8 CRunningScript::ProcessCommands400To499(int32 command)
{
switch (command) {
@ -4366,11 +4363,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
}
return -1;
}
#endif
#if 0
WRAPPER int8 CRunningScript::ProcessCommands500To599(int32 command) { EAXJMP(0x4429C0); }
#else
int8 CRunningScript::ProcessCommands500To599(int32 command)
{
switch (command) {
@ -4629,7 +4622,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
infZ = *(float*)&ScriptParams[5];
supZ = *(float*)&ScriptParams[2];
}
ScriptParams[0] = CGarages::AddOne(infX, infY, infZ, supX, supY, supZ, ScriptParams[6], 0);
ScriptParams[0] = CGarages::AddOne(infX, infY, infZ, supX, supY, supZ, (eGarageType)ScriptParams[6], 0);
StoreParameters(&m_nIp, 1);
return 0;
}
@ -4654,7 +4647,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
infZ = *(float*)&ScriptParams[5];
supZ = *(float*)&ScriptParams[2];
}
ScriptParams[0] = CGarages::AddOne(infX, infY, infZ, supX, supY, supZ, ScriptParams[6], ScriptParams[7]);
ScriptParams[0] = CGarages::AddOne(infX, infY, infZ, supX, supY, supZ, (eGarageType)ScriptParams[6], ScriptParams[7]);
StoreParameters(&m_nIp, 1);
return 0;
}
@ -4678,7 +4671,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
return 0;
case COMMAND_SET_FREE_BOMBS:
CollectParameters(&m_nIp, 1);
CGarages::BombsAreFree = (ScriptParams[0] != 0);
CGarages::SetFreeBombs(ScriptParams[0] != 0);
return 0;
#ifdef GTA_PS2
case COMMAND_SET_POWERPOINT:
@ -5197,11 +5190,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
}
return -1;
}
#endif
#if 0
WRAPPER int8 CRunningScript::ProcessCommands600To699(int32 command) { EAXJMP(0x444B20); }
#else
int8 CRunningScript::ProcessCommands600To699(int32 command)
{
switch (command){
@ -5555,11 +5544,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
}
return -1;
}
#endif
#if 0
WRAPPER int8 CRunningScript::ProcessCommands700To799(int32 command) { EAXJMP(0x4458A0); }
#else
int8 CRunningScript::ProcessCommands700To799(int32 command)
{
switch (command){
@ -6425,11 +6410,6 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
}
return -1;
}
#endif
#if 0
WRAPPER int8 CRunningScript::ProcessCommands800To899(int32 command) { EAXJMP(0x448240); }
#else
int8 CRunningScript::ProcessCommands800To899(int32 command)
{
CMatrix tmp_matrix;
@ -6682,7 +6662,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
}
case COMMAND_SET_FREE_RESPRAYS:
CollectParameters(&m_nIp, 1);
CGarages::RespraysAreFree = (ScriptParams[0] != 0);
CGarages::SetFreeResprays(ScriptParams[0] != 0);
return 0;
case COMMAND_SET_PLAYER_VISIBLE:
{
@ -7130,13 +7110,13 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
case COMMAND_OPEN_GARAGE:
{
CollectParameters(&m_nIp, 1);
CGarages::Garages[ScriptParams[0]].OpenThisGarage();
CGarages::OpenGarage(ScriptParams[0]);
return 0;
}
case COMMAND_CLOSE_GARAGE:
{
CollectParameters(&m_nIp, 1);
CGarages::Garages[ScriptParams[0]].CloseThisGarage();
CGarages::CloseGarage(ScriptParams[1]);
return 0;
}
case COMMAND_WARP_CHAR_FROM_CAR_TO_COORD:
@ -7511,11 +7491,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
}
return -1;
}
#endif
#if 0
WRAPPER int8 CRunningScript::ProcessCommands900To999(int32 command) { EAXJMP(0x44CB80); }
#else
int8 CRunningScript::ProcessCommands900To999(int32 command)
{
char str[52];
@ -8416,7 +8392,6 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
}
return -1;
}
#endif
int8 CRunningScript::ProcessCommands1000To1099(int32 command)
{
@ -9815,7 +9790,7 @@ void CTheScripts::UndoBuildingSwaps()
}
}
void CTheScripts::UndoEntityVisibilitySettings()
void CTheScripts::UndoEntityInvisibilitySettings()
{
for (int i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++) {
if (InvisibilitySettingArray[i]) {
@ -11653,7 +11628,7 @@ InjectHook(0x439040, &CTheScripts::Process, PATCH_JUMP);
InjectHook(0x439400, &CTheScripts::StartTestScript, PATCH_JUMP);
InjectHook(0x439410, &CTheScripts::IsPlayerOnAMission, PATCH_JUMP);
InjectHook(0x44FD10, &CTheScripts::UndoBuildingSwaps, PATCH_JUMP);
InjectHook(0x44FD60, &CTheScripts::UndoEntityVisibilitySettings, PATCH_JUMP);
InjectHook(0x44FD60, &CTheScripts::UndoEntityInvisibilitySettings, PATCH_JUMP);
InjectHook(0x4534E0, &CTheScripts::ScriptDebugLine3D, PATCH_JUMP);
InjectHook(0x453550, &CTheScripts::RenderTheScriptDebugLines, PATCH_JUMP);
InjectHook(0x4535E0, &CTheScripts::SaveAllScripts, PATCH_JUMP);

View file

@ -281,7 +281,7 @@ public:
static void ClearSpaceForMissionEntity(const CVector&, CEntity*);
static void UndoBuildingSwaps();
static void UndoEntityVisibilitySettings();
static void UndoEntityInvisibilitySettings();
static void ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, uint32 col, uint32 col2);
static void RenderTheScriptDebugLines();

View file

@ -33,6 +33,7 @@
#include "Clock.h"
#include "Timecycle.h"
#include "RpAnimBlend.h"
#include "AnimBlendAssociation.h"
#include "Shadows.h"
#include "Radar.h"
#include "Hud.h"
@ -207,6 +208,7 @@ PlayAnimation(RpClump *clump, AssocGroupId animGroup, AnimationId anim)
animAssoc->SetRun();
}
extern void (*DebugMenuProcess)(void);
void
CAnimViewer::Update(void)
{
@ -246,6 +248,9 @@ CAnimViewer::Update(void)
}
CPad::UpdatePads();
CPad* pad = CPad::GetPad(0);
DebugMenuProcess();
CStreaming::UpdateForAnimViewer();
CStreaming::RequestModel(modelId, 0);
if (CStreaming::HasModelLoaded(modelId)) {
@ -289,7 +294,7 @@ CAnimViewer::Update(void)
}
newEntity->GetPosition() = CVector(0.0f, 0.0f, 0.0f);
CWorld::Add(newEntity);
TheCamera.TakeControl(pTarget, CCam::MODE_MODELVIEW, JUMP_CUT, CAM_CONTROLLER_1);
TheCamera.TakeControl(pTarget, CCam::MODE_MODELVIEW, JUMP_CUT, CAMCONTROL_SCRIPT);
}
if (pTarget->m_type == ENTITY_TYPE_VEHICLE || pTarget->m_type == ENTITY_TYPE_PED || pTarget->m_type == ENTITY_TYPE_OBJECT) {
((CPhysical*)pTarget)->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);

5292
src/core/Cam.cpp Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -4,11 +4,28 @@
class CEntity;
class CPed;
class CAutomobile;
class CGarage;
#define NUMBER_OF_VECTORS_FOR_AVERAGE 2
extern int16 &DebugCamMode;
struct CCam
enum
{
NUMBER_OF_VECTORS_FOR_AVERAGE = 2,
MAX_NUM_OF_SPLINETYPES = 4,
MAX_NUM_OF_NODES = 800 // for trains
};
#define DEFAULT_NEAR (0.9f)
#define CAM_ZOOM_1STPRS (0.0f)
#define CAM_ZOOM_1 (1.0f)
#define CAM_ZOOM_2 (2.0f)
#define CAM_ZOOM_3 (3.0f)
#define CAM_ZOOM_TOPDOWN (4.0f)
#define CAM_ZOOM_CINEMATIC (5.0f)
class CCam
{
public:
enum
{
MODE_NONE = 0,
@ -66,17 +83,17 @@ struct CCam
bool m_bTheHeightFixerVehicleIsATrain;
bool LookBehindCamWasInFront;
bool LookingBehind;
bool LookingLeft; // 32
bool LookingLeft;
bool LookingRight;
bool ResetStatics; //for interpolation type stuff to work
bool Rotating;
int16 Mode; // CameraMode
uint32 m_uiFinishTime; // 52
uint32 m_uiFinishTime;
int m_iDoCollisionChecksOnFrameNum;
int m_iDoCollisionCheckEveryNumOfFrames;
int m_iFrameNumWereAt; // 64
int m_iFrameNumWereAt;
int m_iRunningVectorArrayPos;
int m_iRunningVectorCounter;
int DirectionWasLooking;
@ -85,9 +102,9 @@ struct CCam
float f_Roll; //used for adding a slight roll to the camera in the
float f_rollSpeed;
float m_fSyphonModeTargetZOffSet;
float m_fUnknownZOffSet;
float m_fRoadOffSet;
float m_fAmountFractionObscured;
float m_fAlphaSpeedOverOneFrame; // 100
float m_fAlphaSpeedOverOneFrame;
float m_fBetaSpeedOverOneFrame;
float m_fBufferedTargetBeta;
float m_fBufferedTargetOrientation;
@ -95,7 +112,7 @@ struct CCam
float m_fCamBufferedHeight;
float m_fCamBufferedHeightSpeed;
float m_fCloseInPedHeightOffset;
float m_fCloseInPedHeightOffsetSpeed; // 132
float m_fCloseInPedHeightOffsetSpeed;
float m_fCloseInCarHeightOffset;
float m_fCloseInCarHeightOffsetSpeed;
float m_fDimensionOfHighestNearCar;
@ -103,7 +120,7 @@ struct CCam
float m_fFovSpeedOverOneFrame;
float m_fMinDistAwayFromCamWhenInterPolating;
float m_fPedBetweenCameraHeightOffset;
float m_fPlayerInFrontSyphonAngleOffSet; // 164
float m_fPlayerInFrontSyphonAngleOffSet;
float m_fRadiusForDead;
float m_fRealGroundDist; //used for follow ped mode
float m_fTargetBeta;
@ -111,7 +128,7 @@ struct CCam
float m_fTransitionBeta;
float m_fTrueBeta;
float m_fTrueAlpha; // 200
float m_fTrueAlpha;
float m_fInitialPlayerOrientation; //used for first person
float Alpha;
@ -120,34 +137,25 @@ struct CCam
float FOVSpeed;
float Beta;
float BetaSpeed;
float Distance; // 232
float Distance;
float DistanceSpeed;
float CA_MIN_DISTANCE;
float CA_MAX_DISTANCE;
float SpeedVar;
// ped onfoot zoom distance
float m_fTargetZoomGroundOne;
float m_fTargetZoomGroundTwo; // 256
float m_fTargetZoomGroundThree;
// ped onfoot alpha angle offset
float m_fTargetZoomOneZExtra;
float m_fTargetZoomTwoZExtra;
float m_fTargetZoomThreeZExtra;
CVector m_cvecSourceSpeedOverOneFrame;
CVector m_cvecTargetSpeedOverOneFrame;
CVector m_cvecUpOverOneFrame;
float m_fTargetZoomZCloseIn;
float m_fMinRealGroundDist;
float m_fTargetCloseInDist;
CVector m_cvecTargetCoorsForFudgeInter; // 360
CVector m_cvecCamFixedModeVector; // 372
CVector m_cvecCamFixedModeSource; // 384
CVector m_cvecCamFixedModeUpOffSet; // 396
CVector m_vecLastAboveWaterCamPosition; //408 //helper for when the player has gone under the water
CVector m_vecBufferedPlayerBodyOffset; // 420
CVector m_cvecTargetCoorsForFudgeInter;
CVector m_cvecCamFixedModeVector;
CVector m_cvecCamFixedModeSource;
CVector m_cvecCamFixedModeUpOffSet;
CVector m_vecLastAboveWaterCamPosition; //helper for when the player has gone under the water
CVector m_vecBufferedPlayerBodyOffset;
// The three vectors that determine this camera for this frame
CVector Front; // 432 // Direction of looking in
CVector Front; // Direction of looking in
CVector Source; // Coors in world space
CVector SourceBeforeLookBehind;
CVector Up; // Just that
@ -162,6 +170,10 @@ struct CCam
bool m_bFirstPersonRunAboutActive;
CCam(void) { Init(); }
void Init(void);
void Process(void);
void ProcessSpecialHeightRoutines(void);
void GetVectorsReadyForRW(void);
CVector DoAverageOnVector(const CVector &vec);
float GetPedBetaAngleForClearView(const CVector &Target, float Dist, float BetaOffset, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies);
@ -171,21 +183,74 @@ struct CCam
bool FixCamIfObscured(CVector &TargetCoors, float TargetHeight, float TargetOrientation);
void Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist);
void FixCamWhenObscuredByVehicle(const CVector &TargetCoors);
bool Using3rdPersonMouseCam();
bool GetWeaponFirstPersonOn();
void LookBehind(void);
void LookLeft(void);
void LookRight(void);
void ClipIfPedInFrontOfPlayer(void);
void KeepTrackOfTheSpeed(const CVector &source, const CVector &target, const CVector &up, const float &alpha, const float &beta, const float &fov);
bool Using3rdPersonMouseCam(void);
bool GetWeaponFirstPersonOn(void);
bool IsTargetInWater(const CVector &CamCoors);
void AvoidWallsTopDownPed(const CVector &TargetCoors, const CVector &Offset, float *Adjuster, float *AdjusterSpeed, float yDistLimit);
void PrintMode(void);
void Process_Debug(float *vec, float a, float b, float c);
void Process_Debug(const CVector&, float, float, float);
void Process_Editor(const CVector&, float, float, float);
void Process_ModelView(const CVector &CameraTarget, float, float, float);
void Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_BehindCar(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_Cam_On_A_String(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_TopDown(const CVector &CameraTarget, float TargetOrientation, float SpeedVar, float TargetSpeedVar);
void Process_TopDownPed(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_Rocket(const CVector &CameraTarget, float, float, float);
void Process_M16_1stPerson(const CVector &CameraTarget, float, float, float);
void Process_1stPerson(const CVector &CameraTarget, float, float, float);
void Process_1rstPersonPedOnPC(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_Sniper(const CVector &CameraTarget, float, float, float);
void Process_Syphon(const CVector &CameraTarget, float, float, float);
void Process_Syphon_Crim_In_Front(const CVector &CameraTarget, float, float, float);
void Process_BehindBoat(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_Fight_Cam(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_FlyBy(const CVector&, float, float, float);
void Process_WheelCam(const CVector&, float, float, float);
void Process_Fixed(const CVector &CameraTarget, float, float, float);
void Process_Player_Fallen_Water(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_Circle(const CVector &CameraTarget, float, float, float);
void Process_SpecialFixedForSyphon(const CVector &CameraTarget, float, float, float);
void ProcessPedsDeadBaby(void);
bool ProcessArrestCamOne(void);
bool ProcessArrestCamTwo(void);
/* Some of the unused PS2 cams */
void Process_Chris_With_Binding_PlusRotation(const CVector &CameraTarget, float, float, float);
void Process_ReactionCam(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_FollowPed_WithBinding(const CVector &CameraTarget, float TargetOrientation, float, float);
// TODO:
// CCam::Process_CushyPillows_Arse
// CCam::Process_Look_At_Cars
// CCam::Process_CheesyZoom
// CCam::Process_Aiming
// CCam::Process_Bill // same as BehindCar due to unused variables
// CCam::Process_Im_The_Passenger_Woo_Woo
// CCam::Process_Blood_On_The_Tracks
// CCam::Process_Cam_Running_Side_Train
// CCam::Process_Cam_On_Train_Roof
// custom stuff
void Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_FollowCar_SA(const CVector &CameraTarget, float TargetOrientation, float, float);
};
static_assert(sizeof(CCam) == 0x1A4, "CCam: wrong size");
static_assert(offsetof(CCam, Alpha) == 0xA8, "CCam: error");
static_assert(offsetof(CCam, Front) == 0x140, "CCam: error");
struct CCamPathSplines
class CCamPathSplines
{
float m_arr_PathData[800];
public:
enum {MAXPATHLENGTH=800};
float m_arr_PathData[MAXPATHLENGTH];
CCamPathSplines(void);
};
struct CTrainCamNode
@ -223,6 +288,7 @@ enum
FADE_OUT = 0,
FADE_IN,
FADE_NONE
};
enum
@ -248,13 +314,14 @@ enum
enum
{
CAM_CONTROLLER_0,
CAM_CONTROLLER_1,
CAM_CONTROLLER_2
CAMCONTROL_GAME,
CAMCONTROL_SCRIPT,
CAMCONTROL_OBBE
};
struct CCamera : public CPlaceable
class CCamera : public CPlaceable
{
public:
bool m_bAboveGroundTrainNodesLoaded;
bool m_bBelowGroundTrainNodesLoaded;
bool m_bCamDirectlyBehind;
@ -296,16 +363,12 @@ struct CCamera : public CPlaceable
bool m_bHeadBob;
bool m_bFailedCullZoneTestPreviously;
bool m_FadeTargetIsSplashScreen;
bool m_FadeTargetIsSplashScreen;
bool WorldViewerBeingUsed;
uint8 ActiveCam;
uint32 m_uiCamShakeStart;
uint32 m_uiFirstPersonCamLastInputTime;
// where are those?
//bool m_bVehicleSuspenHigh;
//bool m_bEnable1rstPersonCamCntrlsScript;
//bool m_bAllow1rstPersonWeaponsCamera;
uint32 m_uiLongestTimeInMill;
uint32 m_uiNumberOfTrainCamNodes;
@ -321,7 +384,7 @@ bool m_FadeTargetIsSplashScreen;
int m_BlurRed;
int m_BlurType;
uint32 unknown;
uint32 unknown; // some counter having to do with music
int m_iWorkOutSpeedThisNumFrames;
int m_iNumFramesSoFar;
@ -364,20 +427,20 @@ uint32 unknown;
float m_fOldBetaDiff;
float m_fPedZoomValue;
float m_fPedZoomValueScript;
float m_fPedZoomValueSmooth;
float m_fPositionAlongSpline;
float m_ScreenReductionPercentage;
float m_ScreenReductionSpeed;
float m_AlphaForPlayerAnim1rstPerson;
float Orientation;
float PedZoomIndicator;
float PlayerExhaustion;
float SoundDistUp, SoundDistLeft, SoundDistRight;
float SoundDistUpAsRead, SoundDistLeftAsRead, SoundDistRightAsRead;
float SoundDistUpAsReadOld, SoundDistLeftAsReadOld, SoundDistRightAsReadOld;
float m_fWideScreenReductionAmount;
float m_fStartingFOVForInterPol;
float m_fPedZoomValueScript;
float m_fPedZoomValueSmooth;
float m_fPositionAlongSpline;
float m_ScreenReductionPercentage;
float m_ScreenReductionSpeed;
float m_AlphaForPlayerAnim1rstPerson;
float Orientation;
float PedZoomIndicator;
float PlayerExhaustion;
float SoundDistUp, SoundDistLeft, SoundDistRight;
float SoundDistUpAsRead, SoundDistLeftAsRead, SoundDistRightAsRead;
float SoundDistUpAsReadOld, SoundDistLeftAsReadOld, SoundDistRightAsReadOld;
float m_fWideScreenReductionAmount;
float m_fStartingFOVForInterPol;
// not static yet
float m_fMouseAccelHorzntl;// acceleration multiplier for 1st person controls
@ -387,8 +450,8 @@ uint32 unknown;
CCam Cams[3];
void *pToGarageWeAreIn;
void *pToGarageWeAreInForHackAvoidFirstPerson;
CGarage *pToGarageWeAreIn;
CGarage *pToGarageWeAreInForHackAvoidFirstPerson;
CQueuedMode m_PlayerMode;
CQueuedMode PlayerWeaponMode;
CVector m_PreviousCameraPosition;
@ -399,17 +462,15 @@ uint32 unknown;
CVector m_vecFixedModeUpOffSet;
CVector m_vecCutSceneOffset;
// one of those has to go
CVector m_cvecStartingSourceForInterPol;
CVector m_cvecStartingTargetForInterPol;
CVector m_cvecStartingUpForInterPol;
CVector m_cvecSourceSpeedAtStartInter;
CVector m_cvecTargetSpeedAtStartInter;
CVector m_cvecUpSpeedAtStartInter;
CVector m_vecSourceWhenInterPol;
CVector m_vecTargetWhenInterPol;
CVector m_vecUpWhenInterPol;
//CVector m_vecClearGeometryVec;
CVector m_cvecStartingSourceForInterPol;
CVector m_cvecStartingTargetForInterPol;
CVector m_cvecStartingUpForInterPol;
CVector m_cvecSourceSpeedAtStartInter;
CVector m_cvecTargetSpeedAtStartInter;
CVector m_cvecUpSpeedAtStartInter;
CVector m_vecSourceWhenInterPol;
CVector m_vecTargetWhenInterPol;
CVector m_vecUpWhenInterPol;
CVector m_vecGameCamPos;
CVector SourceDuringInter;
@ -417,8 +478,8 @@ uint32 unknown;
CVector UpDuringInter;
RwCamera *m_pRwCamera;
CEntity *pTargetEntity;
CCamPathSplines m_arrPathArray[4];
CTrainCamNode m_arrTrainCamNode[800];
CCamPathSplines m_arrPathArray[MAX_NUM_OF_SPLINETYPES];
CTrainCamNode m_arrTrainCamNode[MAX_NUM_OF_NODES];
CMatrix m_cameraMatrix;
bool m_bGarageFixedCamPositionSet;
bool m_vecDoingSpecialInterPolation;
@ -442,11 +503,11 @@ uint32 unknown;
float m_fScriptPercentageInterToStopMoving;
float m_fScriptPercentageInterToCatchUp;
uint32 m_fScriptTimeForInterPolation;
uint32 m_fScriptTimeForInterPolation;
int16 m_iFadingDirection;
int m_iModeObbeCamIsInForCar;
int16 m_iFadingDirection;
int m_iModeObbeCamIsInForCar;
int16 m_iModeToGoTo;
int16 m_iMusicFadingDirection;
int16 m_iTypeOfSwitch;
@ -455,67 +516,97 @@ int m_iModeObbeCamIsInForCar;
uint32 m_uiFadeTimeStartedMusic;
static bool &m_bUseMouse3rdPerson;
#ifdef FREE_CAM
static bool bFreeCam;
#endif
// High level and misc
void Init(void);
void Process(void);
void CamControl(void);
void UpdateTargetEntity(void);
void UpdateSoundDistances(void);
void InitialiseCameraForDebugMode(void);
void CamShake(float strength, float x, float y, float z);
bool Get_Just_Switched_Status() { return m_bJust_Switched; }
inline const CMatrix& GetCameraMatrix(void) { return m_cameraMatrix; }
CVector &GetGameCamPosition(void) { return m_vecGameCamPos; }
// Who's in control
void TakeControl(CEntity *target, int16 mode, int16 typeOfSwitch, int32 controller);
void TakeControlNoEntity(const CVector &position, int16 typeOfSwitch, int32 controller);
void TakeControlWithSpline(int16 typeOfSwitch);
void Restore(void);
void RestoreWithJumpCut(void);
void SetCamPositionForFixedMode(const CVector &Source, const CVector &UppOffSet);
// Transition
void StartTransition(int16 mode);
void StartTransitionWhenNotFinishedInter(int16 mode);
void StoreValuesDuringInterPol(CVector &source, CVector &target, CVector &up, float &FOV);
// Widescreen borders
void SetWideScreenOn(void);
void SetWideScreenOff(void);
void ProcessWideScreenOn(void);
void DrawBordersForWideScreen(void);
// Obbe's cam
bool IsItTimeForNewcam(int32 obbeMode, int32 time);
bool TryToStartNewCamMode(int32 obbeMode);
void DontProcessObbeCinemaCamera(void);
void ProcessObbeCinemaCameraCar(void);
void ProcessObbeCinemaCameraPed(void);
// Train
void LoadTrainCamNodes(char const *name);
void Process_Train_Camera_Control(void);
// Script
void LoadPathSplines(int file);
void FinishCutscene(void);
float GetPositionAlongSpline(void) { return m_fPositionAlongSpline; }
uint32 GetCutSceneFinishTime(void);
void SetCamCutSceneOffSet(const CVector &pos);
void SetPercentAlongCutScene(float percent);
void SetParametersForScriptInterpolation(float stopMoving, float catchUp, int32 time);
void SetZoomValueFollowPedScript(int16 dist);
void SetZoomValueCamStringScript(int16 dist);
void SetNearClipScript(float);
// Fading
void ProcessFade(void);
void ProcessMusicFade(void);
void Fade(float timeout, int16 direction);
void SetFadeColour(uint8 r, uint8 g, uint8 b);
bool GetFading(void);
int GetFadingDirection(void);
int GetScreenFadeStatus(void);
// Motion blur
void RenderMotionBlur(void);
void SetMotionBlur(int r, int g, int b, int a, int type);
void SetMotionBlurAlpha(int a);
// Player looking and aiming
int GetLookDirection(void);
bool GetLookingForwardFirstPerson(void);
bool GetLookingLRBFirstPerson(void);
void SetCameraDirectlyInFrontForFollowPed_CamOnAString(void);
void SetCameraDirectlyBehindForFollowPed_CamOnAString(void);
void SetNewPlayerWeaponMode(int16 mode, int16 minZoom, int16 maxZoom);
void ClearPlayerWeaponMode(void);
void UpdateAimingCoors(CVector const &coors);
void Find3rdPersonCamTargetVector(float dist, CVector pos, CVector &source, CVector &target);
float Find3rdPersonQuickAimPitch(void);
// Physical camera
void SetRwCamera(RwCamera *cam);
const CMatrix& GetCameraMatrix(void) { return m_cameraMatrix; }
CVector &GetGameCamPosition(void) { return m_vecGameCamPos; }
void CalculateDerivedValues(void);
bool IsPointVisible(const CVector &center, const CMatrix *mat);
bool IsSphereVisible(const CVector &center, float radius, const CMatrix *mat);
bool IsSphereVisible(const CVector &center, float radius);
bool IsBoxVisible(RwV3d *box, const CMatrix *mat);
int GetLookDirection(void);
bool GetLookingForwardFirstPerson(void);
void Fade(float timeout, int16 direction);
int GetScreenFadeStatus(void);
void ProcessFade(void);
void ProcessMusicFade(void);
void SetFadeColour(uint8 r, uint8 g, uint8 b);
void CamShake(float strength, float x, float y, float z);
void SetMotionBlur(int r, int g, int b, int a, int type);
void SetMotionBlurAlpha(int a);
void RenderMotionBlur(void);
void ClearPlayerWeaponMode();
void CalculateDerivedValues(void);
void DrawBordersForWideScreen(void);
void Restore(void);
void SetWideScreenOn(void);
void SetWideScreenOff(void);
void SetNearClipScript(float);
float Find3rdPersonQuickAimPitch(void);
void TakeControl(CEntity*, int16, int16, int32);
void TakeControlNoEntity(const CVector&, int16, int32);
void SetCamPositionForFixedMode(const CVector&, const CVector&);
bool GetFading();
void Init();
void SetRwCamera(RwCamera*);
void Process();
void LoadPathSplines(int file);
uint32 GetCutSceneFinishTime(void);
void FinishCutscene(void);
void SetCamCutSceneOffSet(const CVector&);
void TakeControlWithSpline(short);
void RestoreWithJumpCut(void);
void SetCameraDirectlyInFrontForFollowPed_CamOnAString(void);
void SetCameraDirectlyBehindForFollowPed_CamOnAString(void);
void SetZoomValueFollowPedScript(int16);
void SetZoomValueCamStringScript(int16);
void SetNewPlayerWeaponMode(int16, int16, int16);
void UpdateAimingCoors(CVector const &);
void SetPercentAlongCutScene(float);
void SetParametersForScriptInterpolation(float, float, int32);
void dtor(void) { this->CCamera::~CCamera(); }
};
static_assert(offsetof(CCamera, DistanceToWater) == 0xe4, "CCamera: error");
static_assert(offsetof(CCamera, m_WideScreenOn) == 0x70, "CCamera: error");
@ -525,8 +616,14 @@ static_assert(offsetof(CCamera, m_uiTransitionState) == 0x89, "CCamera: error");
static_assert(offsetof(CCamera, m_uiTimeTransitionStart) == 0x94, "CCamera: error");
static_assert(offsetof(CCamera, m_BlurBlue) == 0x9C, "CCamera: error");
static_assert(offsetof(CCamera, Cams) == 0x1A4, "CCamera: error");
static_assert(offsetof(CCamera, pToGarageWeAreIn) == 0x690, "CCamera: error");
static_assert(offsetof(CCamera, m_PreviousCameraPosition) == 0x6B0, "CCamera: error");
static_assert(offsetof(CCamera, m_vecCutSceneOffset) == 0x6F8, "CCamera: error");
static_assert(offsetof(CCamera, m_arrPathArray) == 0x7a8, "CCamera: error");
static_assert(sizeof(CCamera) == 0xE9D8, "CCamera: wrong size");
extern CCamera &TheCamera;
void CamShakeNoPos(CCamera*, float);
void MakeAngleLessThan180(float &Angle);
void WellBufferMe(float Target, float *CurrentValue, float *CurrentSpeed, float MaxSpeed, float Acceleration, bool IsAngle);

View file

@ -43,6 +43,7 @@ BOOL _gbCdStreamOverlapped;
BOOL _gbCdStreamAsync;
DWORD _gdwCdStreamFlags;
DWORD WINAPI CdStreamThread(LPVOID lpThreadParameter);
void
CdStreamInitThread(void)

View file

@ -39,7 +39,6 @@ int32 CdStreamSync(int32 channel);
void AddToQueue(Queue *queue, int32 item);
int32 GetFirstInQueue(Queue *queue);
void RemoveFirstInQueue(Queue *queue);
DWORD WINAPI CdStreamThread(LPVOID lpThreadParameter);
bool CdStreamAddImage(char const *path);
char *CdStreamGetImageName(int32 cd);
void CdStreamRemoveImages(void);

View file

@ -2061,6 +2061,19 @@ CColModel::operator=(const CColModel &other)
return *this;
}
#include <new>
struct CColLine_ : public CColLine
{
CColLine *ctor(CVector *p0, CVector *p1) { return ::new (this) CColLine(*p0, *p1); }
};
struct CColModel_ : public CColModel
{
CColModel *ctor(void) { return ::new (this) CColModel(); }
void dtor(void) { this->CColModel::~CColModel(); }
};
STARTPATCHES
InjectHook(0x4B9C30, (CMatrix& (*)(const CMatrix &src, CMatrix &dst))Invert, PATCH_JUMP);
@ -2099,15 +2112,15 @@ STARTPATCHES
InjectHook(0x411E40, (void (CColSphere::*)(float, const CVector&, uint8, uint8))&CColSphere::Set, PATCH_JUMP);
InjectHook(0x40B2A0, &CColBox::Set, PATCH_JUMP);
InjectHook(0x40B320, &CColLine::ctor, PATCH_JUMP);
InjectHook(0x40B320, &CColLine_::ctor, PATCH_JUMP);
InjectHook(0x40B350, &CColLine::Set, PATCH_JUMP);
InjectHook(0x411E70, &CColTriangle::Set, PATCH_JUMP);
InjectHook(0x411EA0, &CColTrianglePlane::Set, PATCH_JUMP);
InjectHook(0x412140, &CColTrianglePlane::GetNormal, PATCH_JUMP);
InjectHook(0x411680, &CColModel::ctor, PATCH_JUMP);
InjectHook(0x4116E0, &CColModel::dtor, PATCH_JUMP);
InjectHook(0x411680, &CColModel_::ctor, PATCH_JUMP);
InjectHook(0x4116E0, &CColModel_::dtor, PATCH_JUMP);
InjectHook(0x411D80, &CColModel::RemoveCollisionVolumes, PATCH_JUMP);
InjectHook(0x411CB0, &CColModel::CalculateTrianglePlanes, PATCH_JUMP);
InjectHook(0x411D10, &CColModel::RemoveTrianglePlanes, PATCH_JUMP);

View file

@ -35,8 +35,6 @@ struct CColLine
CColLine(void) { };
CColLine(const CVector &p0, const CVector &p1) { this->p0 = p0; this->p1 = p1; };
void Set(const CVector &p0, const CVector &p1);
CColLine *ctor(CVector *p0, CVector *p1) { return ::new (this) CColLine(*p0, *p1); }
};
struct CColTriangle
@ -106,8 +104,6 @@ struct CColModel
void SetLinkPtr(CLink<CColModel*>*);
void GetTrianglePoint(CVector &v, int i) const;
CColModel *ctor(void) { return ::new (this) CColModel(); }
void dtor(void) { this->CColModel::~CColModel(); }
CColModel& operator=(const CColModel& other);
};

View file

@ -417,6 +417,11 @@ void CControllerConfigManager::UpdateJoyInConfigMenus_ButtonDown(int32 button, i
case 13:
pad->PCTempJoyState.DPadUp = 255;
break;
#ifdef REGISTER_START_BUTTON
case 12:
pad->PCTempJoyState.Start = 255;
break;
#endif
case 11:
pad->PCTempJoyState.RightShock = 255;
break;
@ -839,6 +844,11 @@ void CControllerConfigManager::UpdateJoyInConfigMenus_ButtonUp(int32 button, int
case 13:
pad->PCTempJoyState.DPadUp = 0;
break;
#ifdef REGISTER_START_BUTTON
case 12:
pad->PCTempJoyState.Start = 0;
break;
#endif
case 11:
pad->PCTempJoyState.RightShock = 0;
break;

View file

@ -1,3 +1,4 @@
#define WITHWINDOWS // just for VK_SPACE
#include "common.h"
#include "patcher.h"
#include "General.h"
@ -8,12 +9,14 @@
#include "FileMgr.h"
#include "main.h"
#include "AnimManager.h"
#include "AnimBlendAssociation.h"
#include "AnimBlendAssocGroup.h"
#include "AnimBlendClumpData.h"
#include "Pad.h"
#include "DMAudio.h"
#include "World.h"
#include "PlayerPed.h"
#include "Wanted.h"
#include "CutsceneHead.h"
#include "RpAnimBlend.h"
#include "ModelIndices.h"
@ -180,7 +183,7 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR");
CStreaming::RemoveUnusedModelsInLoadedList();
CGame::DrasticTidyUpMemory();
CGame::DrasticTidyUpMemory(true);
strcpy(ms_cutsceneName, szCutsceneName);
file = CFileMgr::OpenFile("ANIM\\CUTS.IMG", "rb");
@ -371,8 +374,7 @@ CCutsceneMgr::DeleteCutsceneData(void)
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
}
CTimer::Stop();
//TheCamera.GetScreenFadeStatus() == 2; // what for??
CGame::DrasticTidyUpMemory();
CGame::DrasticTidyUpMemory(TheCamera.GetScreenFadeStatus() == 2);
CTimer::Update();
}

View file

@ -29,6 +29,7 @@ public:
static void SetRunning(bool running) { ms_running = running; }
static bool IsRunning(void) { return ms_running; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
static bool UseLodMultiplier(void) { return ms_useLodMultiplier; }
static CCutsceneObject* GetCutsceneObject(int id) { return ms_pCutsceneObjects[id]; }
static int GetCutsceneTimeInMilleseconds(void) { return 1000.0f * ms_cutsceneTimer; }
static char *GetCutsceneName(void) { return ms_cutsceneName; }

View file

@ -1,12 +1,137 @@
#include "common.h"
#include "Debug.h"
#include "Font.h"
#include "main.h"
#include "Text.h"
int CDebug::ms_nCurrentTextLine;
bool gbDebugStuffInRelease = false;
void CDebug::DebugInitTextBuffer()
#define DEBUG_X_POS (300)
#define DEBUG_Y_POS (41)
#define DEBUG_LINE_HEIGHT (22)
int16 CDebug::ms_nCurrentTextLine;
char CDebug::ms_aTextBuffer[MAX_LINES][MAX_STR_LEN];
void
CDebug::DebugInitTextBuffer()
{
ms_nCurrentTextLine = 0;
}
void CDebug::DebugDisplayTextBuffer()
void
CDebug::DebugAddText(const char *str)
{
int32 i = 0;
if (*str != '\0') {
while (i < MAX_STR_LEN) {
ms_aTextBuffer[ms_nCurrentTextLine][i++] = *(str++);
if (*str == '\0')
break;
}
}
ms_aTextBuffer[ms_nCurrentTextLine++][i] = '\0';
if (ms_nCurrentTextLine >= MAX_LINES)
ms_nCurrentTextLine = 0;
}
void
CDebug::DebugDisplayTextBuffer()
{
#ifndef MASTER
if (gbDebugStuffInRelease)
{
int32 i = 0;
int32 y = DEBUG_Y_POS;
#ifdef FIX_BUGS
CFont::SetPropOn();
CFont::SetBackgroundOff();
CFont::SetScale(1.0f, 1.0f);
CFont::SetCentreOff();
CFont::SetRightJustifyOff();
CFont::SetJustifyOn();
CFont::SetRightJustifyWrap(0.0f);
CFont::SetBackGroundOnlyTextOff();
CFont::SetFontStyle(FONT_BANK);
#else
// this is not even readable
CFont::SetPropOff();
CFont::SetBackgroundOff();
CFont::SetScale(1.0f, 1.0f);
CFont::SetCentreOff();
CFont::SetRightJustifyOn();
CFont::SetRightJustifyWrap(0.0f);
CFont::SetBackGroundOnlyTextOff();
CFont::SetFontStyle(FONT_BANK);
CFont::SetPropOff();
#endif
do {
char *line;
while (true) {
line = ms_aTextBuffer[(ms_nCurrentTextLine + i++) % MAX_LINES];
if (*line != '\0')
break;
y += DEBUG_LINE_HEIGHT;
if (i == MAX_LINES) {
CFont::DrawFonts();
return;
}
}
AsciiToUnicode(line, gUString);
CFont::SetColor(CRGBA(0, 0, 0, 255));
CFont::PrintString(DEBUG_X_POS, y-1, gUString);
CFont::SetColor(CRGBA(255, 128, 128, 255));
CFont::PrintString(DEBUG_X_POS+1, y, gUString);
y += DEBUG_LINE_HEIGHT;
} while (i != MAX_LINES);
CFont::DrawFonts();
}
#endif
}
// custom
CDebug::ScreenStr CDebug::ms_aScreenStrs[MAX_SCREEN_STRS];
int CDebug::ms_nScreenStrs;
void
CDebug::DisplayScreenStrings()
{
int i;
CFont::SetPropOn();
CFont::SetBackgroundOff();
CFont::SetScale(1.0f, 1.0f);
CFont::SetCentreOff();
CFont::SetRightJustifyOff();
CFont::SetJustifyOff();
CFont::SetRightJustifyWrap(0.0f);
CFont::SetWrapx(9999.0f);
CFont::SetBackGroundOnlyTextOff();
CFont::SetFontStyle(FONT_BANK);
for(i = 0; i < ms_nScreenStrs; i++){
AsciiToUnicode(ms_aScreenStrs[i].str, gUString);
CFont::SetColor(CRGBA(0, 0, 0, 255));
CFont::PrintString(ms_aScreenStrs[i].x, ms_aScreenStrs[i].y, gUString);
CFont::SetColor(CRGBA(255, 255, 255, 255));
CFont::PrintString(ms_aScreenStrs[i].x+1, ms_aScreenStrs[i].y+1, gUString);
}
CFont::DrawFonts();
ms_nScreenStrs = 0;
}
void
CDebug::PrintAt(const char *str, int x, int y)
{
if(ms_nScreenStrs >= MAX_SCREEN_STRS)
return;
strncpy(ms_aScreenStrs[ms_nScreenStrs].str, str, 256);
ms_aScreenStrs[ms_nScreenStrs].x = x*12;
ms_aScreenStrs[ms_nScreenStrs].y = y*22;
ms_nScreenStrs++;
}

View file

@ -2,10 +2,33 @@
class CDebug
{
static int ms_nCurrentTextLine;
enum
{
MAX_LINES = 15,
MAX_STR_LEN = 80,
MAX_SCREEN_STRS = 100,
};
static int16 ms_nCurrentTextLine;
static char ms_aTextBuffer[MAX_LINES][MAX_STR_LEN];
// custom
struct ScreenStr {
int x, y;
char str[256];
};
static ScreenStr ms_aScreenStrs[MAX_SCREEN_STRS];
static int ms_nScreenStrs;
public:
static void DebugInitTextBuffer();
static void DebugDisplayTextBuffer();
static void DebugAddText(const char *str);
// custom
static void PrintAt(const char *str, int x, int y);
static void DisplayScreenStrings();
};
extern bool gbDebugStuffInRelease;

View file

@ -5,10 +5,13 @@
#include "World.h"
#include "Wanted.h"
#include "EventList.h"
#include "Messages.h"
#include "Text.h"
#include "main.h"
int32 CEventList::ms_nFirstFreeSlotIndex;
//CEvent gaEvent[NUMEVENTS];
CEvent *gaEvent = (CEvent*)0x6EF830;
CEvent gaEvent[NUMEVENTS];
//CEvent *gaEvent = (CEvent*)0x6EF830;
enum
{

View file

@ -63,4 +63,4 @@ public:
static void ReportCrimeForEvent(eEventType type, int32, bool);
};
extern CEvent *gaEvent;
extern CEvent gaEvent[NUMEVENTS];

View file

@ -1,19 +1,291 @@
#include "common.h"
#include "patcher.h"
#include "Vector.h"
#include "PlayerPed.h"
#include "Entity.h"
#include "PointLights.h"
#include "Particle.h"
#include "Timer.h"
#include "Vehicle.h"
#include "Shadows.h"
#include "Automobile.h"
#include "World.h"
#include "General.h"
#include "EventList.h"
#include "DamageManager.h"
#include "Ped.h"
#include "Fire.h"
CFireManager &gFireManager = *(CFireManager*)0x8F31D0;
WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); }
WRAPPER void CFireManager::Update(void) { EAXJMP(0x479310); }
WRAPPER CFire* CFireManager::FindFurthestFire_NeverMindFireMen(CVector coors, float, float) { EAXJMP(0x479430); }
uint32 CFireManager::GetTotalActiveFires() const
CFire::CFire()
{
return m_nTotalFires;
m_bIsOngoing = false;
m_bIsScriptFire = false;
m_bPropagationFlag = true;
m_bAudioSet = true;
m_vecPos = CVector(0.0f, 0.0f, 0.0f);
m_pEntity = nil;
m_pSource = nil;
m_nFiremenPuttingOut = 0;
m_nExtinguishTime = 0;
m_nStartTime = 0;
field_20 = 1;
m_nNextTimeToAddFlames = 0;
m_fStrength = 0.8f;
}
CFire* CFireManager::FindNearestFire(CVector vecPos, float* pDistance)
CFire::~CFire() {}
void
CFire::ProcessFire(void)
{
float fDamagePlayer;
float fDamagePeds;
float fDamageVehicle;
int8 nRandNumber;
float fGreen;
float fRed;
CVector lightpos;
CVector firePos;
CPed *ped = (CPed *)m_pEntity;
CVehicle *veh = (CVehicle*)m_pEntity;
if (m_pEntity) {
m_vecPos = m_pEntity->GetPosition();
if (((CPed *)m_pEntity)->IsPed()) {
if (ped->m_pFire != this) {
Extinguish();
return;
}
if (ped->m_nMoveState != PEDMOVE_RUN)
m_vecPos.z -= 1.0f;
if (ped->bInVehicle && ped->m_pMyVehicle) {
if (ped->m_pMyVehicle->IsCar())
ped->m_pMyVehicle->m_fHealth = 75.0f;
} else if (m_pEntity == (CPed *)FindPlayerPed()) {
fDamagePlayer = 1.2f * CTimer::GetTimeStep();
((CPlayerPed *)m_pEntity)->InflictDamage(
(CPlayerPed *)m_pSource, WEAPONTYPE_FLAMETHROWER,
fDamagePlayer, PEDPIECE_TORSO, 0);
} else {
fDamagePeds = 1.2f * CTimer::GetTimeStep();
if (((CPlayerPed *)m_pEntity)->InflictDamage(
(CPlayerPed *)m_pSource, WEAPONTYPE_FLAMETHROWER,
fDamagePeds, PEDPIECE_TORSO, 0)) {
m_pEntity->bRenderScorched = true;
}
}
} else if (m_pEntity->IsVehicle()) {
if (veh->m_pCarFire != this) {
Extinguish();
return;
}
if (!m_bIsScriptFire) {
fDamageVehicle = 1.2f * CTimer::GetTimeStep();
veh->InflictDamage((CVehicle *)m_pSource, WEAPONTYPE_FLAMETHROWER, fDamageVehicle);
}
}
}
if (!FindPlayerVehicle() && !FindPlayerPed()->m_pFire && !(FindPlayerPed()->bFireProof)
&& ((FindPlayerPed()->GetPosition() - m_vecPos).MagnitudeSqr() < 2.0f)) {
FindPlayerPed()->DoStuffToGoOnFire();
gFireManager.StartFire(FindPlayerPed(), m_pSource, 0.8f, 1);
}
if (CTimer::GetTimeInMilliseconds() > m_nNextTimeToAddFlames) {
m_nNextTimeToAddFlames = CTimer::GetTimeInMilliseconds() + 80;
firePos = m_vecPos;
if (veh && veh->IsVehicle() && veh->IsCar()) {
CVehicleModelInfo *mi = ((CVehicleModelInfo*)CModelInfo::GetModelInfo(veh->GetModelIndex()));
CVector ModelInfo = mi->m_positions[CAR_POS_HEADLIGHTS];
ModelInfo = m_pEntity->GetMatrix() * ModelInfo;
firePos.x = ModelInfo.x;
firePos.y = ModelInfo.y;
firePos.z = ModelInfo.z + 0.15f;
}
CParticle::AddParticle(PARTICLE_CARFLAME, firePos,
CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.0125f, 0.1f) * m_fStrength),
0, m_fStrength, 0, 0, 0, 0);
CGeneral::GetRandomNumber(); CGeneral::GetRandomNumber(); CGeneral::GetRandomNumber(); /* unsure why these three rands are called */
CParticle::AddParticle(PARTICLE_CARFLAME_SMOKE, firePos,
CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0);
}
if (CTimer::GetTimeInMilliseconds() < m_nExtinguishTime || m_bIsScriptFire) {
if (CTimer::GetTimeInMilliseconds() > m_nStartTime)
m_nStartTime = CTimer::GetTimeInMilliseconds() + 400;
nRandNumber = CGeneral::GetRandomNumber() & 127;
lightpos.x = m_vecPos.x;
lightpos.y = m_vecPos.y;
lightpos.z = m_vecPos.z + 5.0f;
if (!m_pEntity) {
CShadows::StoreStaticShadow((uint32)this, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &lightpos,
7.0f, 0.0f, 0.0f, -7.0f,
255, // this is 0 on PC which results in no shadow
nRandNumber / 2, nRandNumber / 2, 0,
10.0f, 1.0f, 40.0f, 0, 0.0f);
}
fGreen = nRandNumber / 128;
fRed = nRandNumber / 128;
CPointLights::AddLight(0, m_vecPos, CVector(0.0f, 0.0f, 0.0f),
12.0f, fRed, fGreen, 0, 0, 0);
} else {
Extinguish();
}
}
void
CFire::ReportThisFire(void)
{
gFireManager.m_nTotalFires++;
CEventList::RegisterEvent(EVENT_FIRE, m_vecPos, 1000);
}
void
CFire::Extinguish(void)
{
if (m_bIsOngoing) {
if (!m_bIsScriptFire)
gFireManager.m_nTotalFires--;
m_nExtinguishTime = 0;
m_bIsOngoing = false;
if (m_pEntity) {
if (m_pEntity->IsPed()) {
((CPed *)m_pEntity)->RestorePreviousState();
((CPed *)m_pEntity)->m_pFire = nil;
} else if (m_pEntity->IsVehicle()) {
((CVehicle *)m_pEntity)->m_pCarFire = nil;
}
m_pEntity = nil;
}
}
}
void
CFireManager::StartFire(CVector pos, float size, bool propagation)
{
CFire *fire = GetNextFreeFire();
if (fire) {
fire->m_bIsOngoing = true;
fire->m_bIsScriptFire = false;
fire->m_bPropagationFlag = propagation;
fire->m_bAudioSet = true;
fire->m_vecPos = pos;
fire->m_nExtinguishTime = CTimer::GetTimeInMilliseconds() + 10000;
fire->m_nStartTime = CTimer::GetTimeInMilliseconds() + 400;
fire->m_pEntity = nil;
fire->m_pSource = nil;
fire->m_nNextTimeToAddFlames = 0;
fire->ReportThisFire();
fire->m_fStrength = size;
}
}
CFire *
CFireManager::StartFire(CEntity *entityOnFire, CEntity *fleeFrom, float strength, bool propagation)
{
CPed *ped = (CPed *)entityOnFire;
CVehicle *veh = (CVehicle *)entityOnFire;
if (entityOnFire->IsPed()) {
if (ped->m_pFire)
return nil;
if (!ped->IsPedInControl())
return nil;
} else if (entityOnFire->IsVehicle()) {
if (veh->m_pCarFire)
return nil;
if (veh->IsCar() && ((CAutomobile *)veh)->Damage.GetEngineStatus() >= 225)
return nil;
}
CFire *fire = GetNextFreeFire();
if (fire) {
if (entityOnFire->IsPed()) {
ped->m_pFire = fire;
if (ped != FindPlayerPed()) {
if (fleeFrom) {
ped->SetFlee(fleeFrom, 10000);
} else {
CVector2D pos = entityOnFire->GetPosition();
ped->SetFlee(pos, 10000);
ped->m_fleeFrom = nil;
}
ped->bDrawLast = false;
ped->SetMoveState(PEDMOVE_SPRINT);
ped->SetMoveAnim();
ped->m_nPedState = PED_ON_FIRE;
}
if (fleeFrom) {
if (ped->m_nPedType == PEDTYPE_COP) {
CEventList::RegisterEvent(EVENT_COP_SET_ON_FIRE, EVENT_ENTITY_PED,
entityOnFire, (CPed *)fleeFrom, 10000);
} else {
CEventList::RegisterEvent(EVENT_PED_SET_ON_FIRE, EVENT_ENTITY_PED,
entityOnFire, (CPed *)fleeFrom, 10000);
}
}
} else {
if (entityOnFire->IsVehicle()) {
veh->m_pCarFire = fire;
if (fleeFrom) {
CEventList::RegisterEvent(EVENT_CAR_SET_ON_FIRE, EVENT_ENTITY_VEHICLE,
entityOnFire, (CPed *)fleeFrom, 10000);
}
}
}
fire->m_bIsOngoing = true;
fire->m_bIsScriptFire = false;
fire->m_vecPos = entityOnFire->GetPosition();
if (entityOnFire && entityOnFire->IsPed() && ped->IsPlayer()) {
fire->m_nExtinguishTime = CTimer::GetTimeInMilliseconds() + 3333;
} else if (entityOnFire->IsVehicle()) {
fire->m_nExtinguishTime = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(4000, 5000);
} else {
fire->m_nExtinguishTime = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(10000, 11000);
}
fire->m_nStartTime = CTimer::GetTimeInMilliseconds() + 400;
fire->m_pEntity = entityOnFire;
entityOnFire->RegisterReference(&fire->m_pEntity);
fire->m_pSource = fleeFrom;
if (fleeFrom)
fleeFrom->RegisterReference(&fire->m_pSource);
fire->ReportThisFire();
fire->m_nNextTimeToAddFlames = 0;
fire->m_fStrength = strength;
fire->m_bPropagationFlag = propagation;
fire->m_bAudioSet = true;
}
return fire;
}
void
CFireManager::Update(void)
{
for (int i = 0; i < NUM_FIRES; i++) {
if (m_aFires[i].m_bIsOngoing)
m_aFires[i].ProcessFire();
}
}
CFire* CFireManager::FindNearestFire(CVector vecPos, float *pDistance)
{
for (int i = 0; i < MAX_FIREMEN_ATTENDING; i++) {
int fireId = -1;
@ -38,6 +310,44 @@ CFire* CFireManager::FindNearestFire(CVector vecPos, float* pDistance)
return nil;
}
CFire *
CFireManager::FindFurthestFire_NeverMindFireMen(CVector coords, float minRange, float maxRange)
{
int furthestFire = -1;
float lastFireDist = 0.0f;
float fireDist;
for (int i = 0; i < NUM_FIRES; i++) {
if (m_aFires[i].m_bIsOngoing && !m_aFires[i].m_bIsScriptFire) {
fireDist = (m_aFires[i].m_vecPos - coords).Magnitude2D();
if (fireDist > minRange && fireDist < maxRange && fireDist > lastFireDist) {
lastFireDist = fireDist;
furthestFire = i;
}
}
}
if (furthestFire == -1)
return nil;
else
return &m_aFires[furthestFire];
}
CFire *
CFireManager::GetNextFreeFire(void)
{
for (int i = 0; i < NUM_FIRES; i++) {
if (!m_aFires[i].m_bIsOngoing && !m_aFires[i].m_bIsScriptFire)
return &m_aFires[i];
}
return nil;
}
uint32
CFireManager::GetTotalActiveFires(void) const
{
return m_nTotalFires;
}
void
CFireManager::ExtinguishPoint(CVector point, float range)
{
@ -49,16 +359,100 @@ CFireManager::ExtinguishPoint(CVector point, float range)
}
}
WRAPPER void CFireManager::StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32) { EAXJMP(0x479590); }
WRAPPER void CFireManager::StartFire(CVector, float, uint8) { EAXJMP(0x479500); }
WRAPPER int32 CFireManager::StartScriptFire(const CVector& pos, CEntity* culprit, float, uint8) { EAXJMP(0x479E60); }
WRAPPER bool CFireManager::IsScriptFireExtinguish(int16) { EAXJMP(0x479FC0); }
WRAPPER void CFireManager::RemoveScriptFire(int16) { EAXJMP(0x479FE0); }
WRAPPER void CFireManager::RemoveAllScriptFires(void) { EAXJMP(0x47A000); }
WRAPPER void CFireManager::SetScriptFireAudio(int16, bool) { EAXJMP(0x47A040); }
int32
CFireManager::StartScriptFire(const CVector &pos, CEntity *target, float strength, bool propagation)
{
CFire *fire;
CPed *ped = (CPed *)target;
CVehicle *veh = (CVehicle *)target;
if (target) {
if (target->IsPed()) {
if (ped->m_pFire)
ped->m_pFire->Extinguish();
} else if (target->IsVehicle()) {
if (veh->m_pCarFire)
veh->m_pCarFire->Extinguish();
if (veh->IsCar() && ((CAutomobile *)veh)->Damage.GetEngineStatus() >= 225) {
((CAutomobile *)veh)->Damage.SetEngineStatus(215);
}
}
}
fire = GetNextFreeFire();
fire->m_bIsOngoing = true;
fire->m_bIsScriptFire = true;
fire->m_bPropagationFlag = propagation;
fire->m_bAudioSet = true;
fire->m_vecPos = pos;
fire->m_nStartTime = CTimer::GetTimeInMilliseconds() + 400;
fire->m_pEntity = target;
if (target)
target->RegisterReference(&fire->m_pEntity);
fire->m_pSource = nil;
fire->m_nNextTimeToAddFlames = 0;
fire->m_fStrength = strength;
if (target) {
if (target->IsPed()) {
ped->m_pFire = fire;
if (target != (CVehicle *)FindPlayerPed()) {
CVector2D pos = target->GetPosition();
ped->SetFlee(pos, 10000);
ped->SetMoveAnim();
ped->m_nPedState = PED_ON_FIRE;
}
} else if (target->IsVehicle()) {
veh->m_pCarFire = fire;
}
}
return fire - m_aFires;
}
bool
CFireManager::IsScriptFireExtinguish(int16 index)
{
return !m_aFires[index].m_bIsOngoing;
}
void
CFireManager::RemoveAllScriptFires(void)
{
for (int i = 0; i < NUM_FIRES; i++) {
if (m_aFires[i].m_bIsScriptFire) {
m_aFires[i].Extinguish();
m_aFires[i].m_bIsScriptFire = false;
}
}
}
void
CFireManager::RemoveScriptFire(int16 index)
{
m_aFires[index].Extinguish();
m_aFires[index].m_bIsScriptFire = false;
}
void
CFireManager::SetScriptFireAudio(int16 index, bool state)
{
m_aFires[index].m_bAudioSet = state;
}
STARTPATCHES
InjectHook(0x479DB0, &CFireManager::ExtinguishPoint, PATCH_JUMP);
InjectHook(0x4798D0, &CFire::ProcessFire, PATCH_JUMP);
InjectHook(0x4798B0, &CFire::ReportThisFire, PATCH_JUMP);
InjectHook(0x479D40, &CFire::Extinguish, PATCH_JUMP);
InjectHook(0x479500, (void(CFireManager::*)(CVector pos, float size, bool propagation))&CFireManager::StartFire, PATCH_JUMP);
InjectHook(0x479590, (CFire *(CFireManager::*)(CEntity *, CEntity *, float, bool))&CFireManager::StartFire, PATCH_JUMP);
InjectHook(0x479310, &CFireManager::Update, PATCH_JUMP);
InjectHook(0x479430, &CFireManager::FindFurthestFire_NeverMindFireMen, PATCH_JUMP);
InjectHook(0x479340, &CFireManager::FindNearestFire, PATCH_JUMP);
InjectHook(0x4792E0, &CFireManager::GetNextFreeFire, PATCH_JUMP);
InjectHook(0x479DB0, &CFireManager::ExtinguishPoint, PATCH_JUMP);
InjectHook(0x479E60, &CFireManager::StartScriptFire, PATCH_JUMP);
InjectHook(0x479FC0, &CFireManager::IsScriptFireExtinguish, PATCH_JUMP);
InjectHook(0x47A000, &CFireManager::RemoveAllScriptFires, PATCH_JUMP);
InjectHook(0x479FE0, &CFireManager::RemoveScriptFire, PATCH_JUMP);
InjectHook(0x47A040, &CFireManager::SetScriptFireAudio, PATCH_JUMP);
ENDPATCHES

View file

@ -7,18 +7,22 @@ class CFire
public:
bool m_bIsOngoing;
bool m_bIsScriptFire;
bool m_bPropogationFlag;
bool m_bPropagationFlag;
bool m_bAudioSet;
CVector m_vecPos;
CEntity *m_pEntity;
CEntity *m_pSource;
int m_nExtinguishTime;
int m_nStartTime;
int field_20;
int field_24;
uint32 m_nExtinguishTime;
uint32 m_nStartTime;
int32 field_20;
uint32 m_nNextTimeToAddFlames;
uint32 m_nFiremenPuttingOut;
float field_2C;
float m_fStrength;
CFire();
~CFire();
void ProcessFire(void);
void ReportThisFire(void);
void Extinguish(void);
};
@ -27,20 +31,21 @@ class CFireManager
enum {
MAX_FIREMEN_ATTENDING = 2,
};
uint32 m_nTotalFires;
public:
uint32 m_nTotalFires;
CFire m_aFires[NUM_FIRES];
void StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32);
void StartFire(CVector, float, uint8);
void StartFire(CVector pos, float size, bool propagation);
CFire *StartFire(CEntity *entityOnFire, CEntity *fleeFrom, float strength, bool propagation);
void Update(void);
CFire *FindFurthestFire_NeverMindFireMen(CVector coors, float, float);
CFire *FindNearestFire(CVector, float*);
CFire *FindFurthestFire_NeverMindFireMen(CVector coords, float minRange, float maxRange);
CFire *FindNearestFire(CVector vecPos, float *pDistance);
CFire *GetNextFreeFire(void);
uint32 GetTotalActiveFires() const;
void ExtinguishPoint(CVector, float);
int32 StartScriptFire(const CVector& pos, CEntity* culprit, float, uint8);
bool IsScriptFireExtinguish(int16);
void RemoveScriptFire(int16);
void ExtinguishPoint(CVector point, float range);
int32 StartScriptFire(const CVector &pos, CEntity *target, float strength, bool propagation);
bool IsScriptFireExtinguish(int16 index);
void RemoveAllScriptFires(void);
void SetScriptFireAudio(int16, bool);
void RemoveScriptFire(int16 index);
void SetScriptFireAudio(int16 index, bool state);
};
extern CFireManager &gFireManager;

View file

@ -64,7 +64,6 @@ bool &CMenuManager::m_bShutDownFrontEndRequested = *(bool*)0x95CD6A;
int8 &CMenuManager::m_PrefsUseWideScreen = *(int8*)0x95CD23;
int8 &CMenuManager::m_PrefsRadioStation = *(int8*)0x95CDA4;
int8 &CMenuManager::m_bDisableMouseSteering = *(int8*)0x60252C; // 1
int32 &CMenuManager::m_PrefsBrightness = *(int32*)0x5F2E50; // 256
float &CMenuManager::m_PrefsLOD = *(float*)0x8F42C4;
int8 &CMenuManager::m_bFrontEnd_ReloadObrTxtGxt = *(int8*)0x628CFC;
@ -94,10 +93,14 @@ int32 *&pControlEdit = *(int32**)0x628D08;
bool &DisplayComboButtonErrMsg = *(bool*)0x628D14;
int32 &MouseButtonJustClicked = *(int32*)0x628D0C;
int32 &JoyButtonJustClicked = *(int32*)0x628D10;
uint32 &nTimeForSomething = *(uint32*)0x628D54;
bool &holdingScrollBar = *(bool*)0x628D59;
//int32 *pControlTemp = 0;
#ifndef MASTER
bool CMenuManager::m_PrefsMarketing = false;
bool CMenuManager::m_PrefsDisableTutorials = false;
#endif // !MASTER
// 0x5F311C
const char* FrontendFilenames[][2] = {
{"fe2_mainpanel_ul", "" },
@ -181,6 +184,7 @@ ScaleAndCenterX(float x)
#endif
#define isPlainTextScreen(screen) (screen == MENUPAGE_BRIEFS || screen == MENUPAGE_STATS)
#ifdef PS2_LIKE_MENU
#define ChangeScreen(screen, option, updateDelay, withReverseAlpha) \
do { \
@ -235,67 +239,100 @@ ScaleAndCenterX(float x)
m_nHoverOption = HOVEROPTION_NOT_HOVERING; \
} while(0)
#define ScrollUpListByOne() \
do { \
if (m_nSelectedListRow == m_nFirstVisibleRowOnList) { \
if (m_nFirstVisibleRowOnList > 0) { \
m_nSelectedListRow--; \
m_nFirstVisibleRowOnList--; \
m_nCurListItemY -= LIST_HEIGHT / m_nTotalListRow; \
} \
} else { \
m_nSelectedListRow--; \
} \
} while(0)
// --- Functions not in the game/inlined starts
#define ScrollDownListByOne() \
do { \
if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1) { \
if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) { \
m_nSelectedListRow++; \
m_nFirstVisibleRowOnList++; \
m_nCurListItemY += LIST_HEIGHT / m_nTotalListRow; \
} \
} else { \
if (m_nSelectedListRow < m_nTotalListRow - 1) { \
m_nSelectedListRow++; \
} \
} \
} while(0)
inline void
CMenuManager::ScrollUpListByOne()
{
if (m_nSelectedListRow == m_nFirstVisibleRowOnList) {
if (m_nFirstVisibleRowOnList > 0) {
m_nSelectedListRow--;
m_nFirstVisibleRowOnList--;
m_nCurListItemY -= LIST_HEIGHT / m_nTotalListRow;
}
} else {
m_nSelectedListRow--;
}
}
#define PageUpList(playSoundOnSuccess) \
do { \
if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { \
if (m_nFirstVisibleRowOnList > 0) { \
if(playSoundOnSuccess) \
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0); \
\
m_nFirstVisibleRowOnList = max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_LIST_ROW); \
m_nSelectedListRow = min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1); \
} else { \
m_nFirstVisibleRowOnList = 0; \
m_nSelectedListRow = 0; \
} \
m_nCurListItemY = (LIST_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; \
} \
} while(0)
inline void
CMenuManager::ScrollDownListByOne()
{
if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1) {
if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) {
m_nSelectedListRow++;
m_nFirstVisibleRowOnList++;
m_nCurListItemY += LIST_HEIGHT / m_nTotalListRow;
}
} else {
if (m_nSelectedListRow < m_nTotalListRow - 1) {
m_nSelectedListRow++;
}
}
}
#define PageDownList(playSoundOnSuccess) \
do { \
if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { \
if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) { \
if(playSoundOnSuccess) \
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0); \
\
m_nFirstVisibleRowOnList = min(m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW, m_nTotalListRow - MAX_VISIBLE_LIST_ROW); \
m_nSelectedListRow = max(m_nSelectedListRow, m_nFirstVisibleRowOnList); \
} else { \
m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW; \
m_nSelectedListRow = m_nTotalListRow - 1; \
} \
m_nCurListItemY = (LIST_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; \
} \
} while(0)
inline void
CMenuManager::PageUpList(bool playSoundOnSuccess)
{
if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) {
if (m_nFirstVisibleRowOnList > 0) {
if(playSoundOnSuccess)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
m_nFirstVisibleRowOnList = max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_LIST_ROW);
m_nSelectedListRow = min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1);
} else {
m_nFirstVisibleRowOnList = 0;
m_nSelectedListRow = 0;
}
m_nCurListItemY = (LIST_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
}
}
inline void
CMenuManager::PageDownList(bool playSoundOnSuccess)
{
if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) {
if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) {
if(playSoundOnSuccess)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
m_nFirstVisibleRowOnList = min(m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW, m_nTotalListRow - MAX_VISIBLE_LIST_ROW);
m_nSelectedListRow = max(m_nSelectedListRow, m_nFirstVisibleRowOnList);
} else {
m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW;
m_nSelectedListRow = m_nTotalListRow - 1;
}
m_nCurListItemY = (LIST_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
}
}
inline void
CMenuManager::ThingsToDoBeforeLeavingPage()
{
if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && strcmp(m_aSkinName, m_PrefsSkinFile) != 0) {
CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
} else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) {
if (m_nPrefsAudio3DProviderIndex != -1)
m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex();
#ifdef TIDY_UP_PBP
DMAudio.StopFrontEndTrack();
OutputDebugString("FRONTEND AUDIO TRACK STOPPED");
#endif
} else if (m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) {
m_nDisplayVideoMode = m_nPrefsVideoMode;
}
if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
CPlayerSkin::EndFrontendSkinEdit();
}
if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) || (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS)) {
m_nTotalListRow = 0;
}
}
// ------ Functions not in the game/inlined ends
void
CMenuManager::BuildStatLine(char *text, void *stat, uint8 aFloat, void *stat2)
@ -492,7 +529,7 @@ WRAPPER void CMenuManager::DoSettingsBeforeStartingAGame() { EAXJMP(0x48AB40); }
#else
void CMenuManager::DoSettingsBeforeStartingAGame()
{
CCamera::m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDART;
CCamera::m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD;
if (m_PrefsVsyncDisp != m_PrefsVsync)
m_PrefsVsync = m_PrefsVsyncDisp;
@ -935,7 +972,7 @@ void CMenuManager::Draw()
rightText = TheText.Get(m_PrefsDMA ? "FEM_ON" : "FEM_OFF");
break;
case MENUACTION_MOUSESTEER:
rightText = TheText.Get(m_bDisableMouseSteering ? "FEM_OFF" : "FEM_ON");
rightText = TheText.Get(CVehicle::m_bDisableMouseSteering ? "FEM_OFF" : "FEM_ON");
break;
}
@ -1173,7 +1210,6 @@ void CMenuManager::DrawFrontEnd()
bbNames[5] = { "FESZ_QU",MENUPAGE_EXIT };
bbTabCount = 6;
}
m_nCurrScreen = MENUPAGE_NEW_GAME;
} else {
if (bbTabCount != 8) {
bbNames[0] = { "FEB_STA",MENUPAGE_STATS };
@ -1186,8 +1222,8 @@ void CMenuManager::DrawFrontEnd()
bbNames[7] = { "FESZ_QU",MENUPAGE_EXIT };
bbTabCount = 8;
}
m_nCurrScreen = MENUPAGE_STATS;
}
m_nCurrScreen = bbNames[0].screenId;
bottomBarActive = true;
curBottomBarOption = 0;
}
@ -1285,7 +1321,6 @@ void CMenuManager::DrawFrontEndNormal()
eFrontendSprites currentSprite;
switch (m_nCurrScreen) {
case MENUPAGE_STATS:
case MENUPAGE_NEW_GAME:
case MENUPAGE_START_MENU:
case MENUPAGE_PAUSE_MENU:
case MENUPAGE_EXIT:
@ -1315,7 +1350,7 @@ void CMenuManager::DrawFrontEndNormal()
currentSprite = FE_ICONCONTROLS;
break;
default:
/* actually MENUPAGE_NEW_GAME too*/
/*case MENUPAGE_NEW_GAME: */
/*case MENUPAGE_BRIEFS: */
currentSprite = FE_ICONBRIEF;
break;
@ -1323,23 +1358,39 @@ void CMenuManager::DrawFrontEndNormal()
m_aFrontEndSprites[currentSprite].Draw(CRect(MENU_X_LEFT_ALIGNED(50.0f), MENU_Y(50.0f), MENU_X_RIGHT_ALIGNED(50.0f), SCREEN_SCALE_FROM_BOTTOM(95.0f)), CRGBA(255, 255, 255, m_nMenuFadeAlpha > 255 ? 255 : m_nMenuFadeAlpha));
static float fadeAlpha = 0.0f;
static int lastState = 0;
// reverseAlpha = PS2 fading (wait for 255->0, then change screen)
if (m_nMenuFadeAlpha < 255) {
static int LastFade = 0;
if (lastState == 1 && !reverseAlpha)
fadeAlpha = 0.f;
if (m_nMenuFadeAlpha <= 0 && reverseAlpha) {
reverseAlpha = false;
ChangeScreen(pendingScreen, pendingOption, true, false);
} else if(CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 10){
if (!reverseAlpha)
m_nMenuFadeAlpha += 20;
else
m_nMenuFadeAlpha = max(m_nMenuFadeAlpha - 30, 0);
} else {
float timestep = CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
LastFade = CTimer::GetTimeInMillisecondsPauseMode();
// +20 per every 33 ms (1000.f/30.f - original frame limiter fps)
if (!reverseAlpha)
fadeAlpha += (timestep * 100.f) * 20.f / 33.f;
else
fadeAlpha = max(0.0f, fadeAlpha - (timestep * 100.f) * 30.f / 33.f);
m_nMenuFadeAlpha = fadeAlpha;
}
lastState = 0;
} else {
if (reverseAlpha)
m_nMenuFadeAlpha -= 20;
if (lastState == 0) fadeAlpha = 255.f;
if (reverseAlpha) {
float timestep = CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
fadeAlpha -= (timestep * 100.f) * 30.f / 33.f;
m_nMenuFadeAlpha = fadeAlpha;
}
lastState = 1;
// TODO: what is this? waiting mouse?
if(field_518 == 4){
@ -1537,12 +1588,25 @@ void CMenuManager::DrawFrontEndNormal()
}
if (m_nMenuFadeAlpha < 255) {
static int LastFade = 0;
// Famous transparent menu bug
#ifdef FIX_BUGS
static float fadeAlpha = 0.0f;
if (m_nMenuFadeAlpha == 0 && fadeAlpha > 1.0f) fadeAlpha = 0.0f;
float timestep = CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
// +20 per every 33 ms (1000.f/30.f - original frame limiter fps)
fadeAlpha += (timestep * 100.f) * 20.f / 33.f;
m_nMenuFadeAlpha = fadeAlpha;
#else
static uint32 LastFade = 0;
if(CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 10){
m_nMenuFadeAlpha += 20;
LastFade = CTimer::GetTimeInMillisecondsPauseMode();
}
#endif
if (m_nMenuFadeAlpha > 255){
m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
@ -1657,9 +1721,6 @@ int CMenuManager::GetStartOptionsCntrlConfigScreens()
}
#endif
#if DONT_USE_SUSPICIOUS_FUNCS
WRAPPER void CMenuManager::InitialiseChangedLanguageSettings() { EAXJMP(0x47A4D0); }
#else
void CMenuManager::InitialiseChangedLanguageSettings()
{
if (m_bFrontEnd_ReloadObrTxtGxt) {
@ -1670,6 +1731,17 @@ void CMenuManager::InitialiseChangedLanguageSettings()
CTimer::Update();
CGame::frenchGame = false;
CGame::germanGame = false;
#ifdef MORE_LANGUAGES
switch (CMenuManager::m_PrefsLanguage) {
case LANGUAGE_RUSSIAN:
CFont::ReloadFonts(FONT_LANGSET_RUSSIAN);
break;
default:
CFont::ReloadFonts(FONT_LANGSET_EFIGS);
break;
}
#endif
switch (CMenuManager::m_PrefsLanguage) {
case LANGUAGE_FRENCH:
CGame::frenchGame = true;
@ -1677,12 +1749,16 @@ void CMenuManager::InitialiseChangedLanguageSettings()
case LANGUAGE_GERMAN:
CGame::germanGame = true;
break;
#ifdef MORE_LANGUAGES
case LANGUAGE_RUSSIAN:
CGame::russianGame = true;
break;
#endif
default:
break;
}
}
}
#endif
void CMenuManager::LoadAllTextures()
{
@ -1950,7 +2026,7 @@ WRAPPER void CMenuManager::Process(void) { EAXJMP(0x485100); }
#else
void CMenuManager::Process(void)
{
m_bMenuNotProcessed = false;
m_bMenuStateChanged = false;
if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus() != FADE_0)
return;
@ -1993,7 +2069,7 @@ void CMenuManager::Process(void)
}
if (m_nCurrScreen == MENUPAGE_LOADING_IN_PROGRESS) {
if (CheckSlotDataValid(m_nCurrSaveSlot)) {
TheCamera.m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDART;
TheCamera.m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD;
if (m_PrefsVsyncDisp != m_PrefsVsync)
m_PrefsVsync = m_PrefsVsyncDisp;
DMAudio.Service();
@ -2164,15 +2240,15 @@ CMenuManager::ProcessButtonPresses(void)
field_535 = false;
}
static int nTimeForSomething = 0;
static uint32 lastTimeClickedScrollButton = 0;
if (CTimer::GetTimeInMillisecondsPauseMode() - nTimeForSomething >= 200) {
if (CTimer::GetTimeInMillisecondsPauseMode() - lastTimeClickedScrollButton >= 200) {
m_bPressedPgUpOnList = false;
m_bPressedPgDnOnList = false;
m_bPressedUpOnList = false;
m_bPressedDownOnList = false;
m_bPressedScrollButton = false;
nTimeForSomething = CTimer::GetTimeInMillisecondsPauseMode();
lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
}
if (CPad::GetPad(0)->GetTabJustDown()) {
@ -2211,7 +2287,7 @@ CMenuManager::ProcessButtonPresses(void)
m_nCurrExLayer = 19;
if (!m_bPressedUpOnList) {
m_bPressedUpOnList = true;
nTimeForSomething = CTimer::GetTimeInMillisecondsPauseMode();
lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
ScrollUpListByOne();
}
@ -2233,7 +2309,7 @@ CMenuManager::ProcessButtonPresses(void)
m_nCurrExLayer = 19;
if (!m_bPressedDownOnList) {
m_bPressedDownOnList = true;
nTimeForSomething = CTimer::GetTimeInMillisecondsPauseMode();
lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
ScrollDownListByOne();
}
@ -2248,7 +2324,7 @@ CMenuManager::ProcessButtonPresses(void)
m_nCurrExLayer = 19;
if (!m_bPressedPgUpOnList) {
m_bPressedPgUpOnList = true;
nTimeForSomething = CTimer::GetTimeInMillisecondsPauseMode();
lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
m_bShowMouse = false;
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
PageUpList(false);
@ -2260,7 +2336,7 @@ CMenuManager::ProcessButtonPresses(void)
m_nCurrExLayer = 19;
if (!m_bPressedPgDnOnList) {
m_bPressedPgDnOnList = true;
nTimeForSomething = CTimer::GetTimeInMillisecondsPauseMode();
lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
m_bShowMouse = false;
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
PageDownList(false);
@ -2346,7 +2422,7 @@ CMenuManager::ProcessButtonPresses(void)
case HOVEROPTION_CLICKED_SCROLL_UP:
if (!m_bPressedScrollButton) {
m_bPressedScrollButton = true;
nTimeForSomething = CTimer::GetTimeInMillisecondsPauseMode();
lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
ScrollUpListByOne();
}
break;
@ -2354,7 +2430,7 @@ CMenuManager::ProcessButtonPresses(void)
case HOVEROPTION_CLICKED_SCROLL_DOWN:
if (!m_bPressedScrollButton) {
m_bPressedScrollButton = true;
nTimeForSomething = CTimer::GetTimeInMillisecondsPauseMode();
lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
ScrollDownListByOne();
}
break;
@ -2701,6 +2777,8 @@ CMenuManager::ProcessButtonPresses(void)
if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) {
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
bottomBarActive = false;
// If there's a menu change with fade ongoing, finish it now
if (reverseAlpha)
m_nMenuFadeAlpha = 0;
return;
@ -2877,6 +2955,14 @@ CMenuManager::ProcessButtonPresses(void)
CMenuManager::InitialiseChangedLanguageSettings();
SaveSettings();
break;
#ifdef MORE_LANGUAGES
case MENUACTION_LANG_RUS:
m_PrefsLanguage = LANGUAGE_RUSSIAN;
m_bFrontEnd_ReloadObrTxtGxt = true;
CMenuManager::InitialiseChangedLanguageSettings();
SaveSettings();
break;
#endif
case MENUACTION_POPULATESLOTS_CHANGEMENU:
PcSaveHelper.PopulateSlotInfo();
@ -3080,10 +3166,10 @@ CMenuManager::ProcessButtonPresses(void)
PSGLOBAL(joy1)->GetCapabilities(&devCaps);
ControlsManager.InitDefaultControlConfigJoyPad(devCaps.dwButtons);
}
CMenuManager::m_ControlMethod = CONTROL_STANDART;
CMenuManager::m_ControlMethod = CONTROL_STANDARD;
MousePointerStateHelper.bInvertVertically = false;
TheCamera.m_fMouseAccelHorzntl = 0.0025f;
m_bDisableMouseSteering = true;
CVehicle::m_bDisableMouseSteering = true;
TheCamera.m_bHeadBob = false;
SaveSettings();
}
@ -3093,7 +3179,7 @@ CMenuManager::ProcessButtonPresses(void)
#ifndef TIDY_UP_PBP
if (CMenuManager::m_ControlMethod == CONTROL_CLASSIC) {
CCamera::m_bUseMouse3rdPerson = true;
CMenuManager::m_ControlMethod = CONTROL_STANDART;
CMenuManager::m_ControlMethod = CONTROL_STANDARD;
} else {
CCamera::m_bUseMouse3rdPerson = false;
CMenuManager::m_ControlMethod = CONTROL_CLASSIC;
@ -3116,51 +3202,43 @@ CMenuManager::ProcessButtonPresses(void)
if (goBack) {
CMenuManager::ResetHelperText();
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_EXIT, 0);
if (m_nCurrScreen == MENUPAGE_PAUSE_MENU && !m_bGameNotLoaded && !m_bMenuNotProcessed){
if (CMenuManager::m_PrefsVsyncDisp != CMenuManager::m_PrefsVsync) {
CMenuManager::m_PrefsVsync = CMenuManager::m_PrefsVsyncDisp;
}
CMenuManager::RequestFrontEndShutDown();
} else if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT
#ifdef PS2_SAVE_DIALOG
|| m_nCurrScreen == MENUPAGE_SAVE
#endif
) {
CMenuManager::RequestFrontEndShutDown();
} else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) {
DMAudio.StopFrontEndTrack();
OutputDebugString("FRONTEND AUDIO TRACK STOPPED");
}
int oldScreen = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0];
int oldOption = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : aScreens[m_nCurrScreen].m_ParentEntry[0];
#ifdef PS2_LIKE_MENU
if (bottomBarActive){
bottomBarActive = false;
if (!m_bGameNotLoaded) {
if (m_nCurrScreen == MENUPAGE_PAUSE_MENU || bottomBarActive) {
#else
if (m_nCurrScreen == MENUPAGE_PAUSE_MENU) {
#endif
if (!m_bGameNotLoaded && !m_bMenuStateChanged) {
if (CMenuManager::m_PrefsVsyncDisp != CMenuManager::m_PrefsVsync) {
CMenuManager::m_PrefsVsync = CMenuManager::m_PrefsVsyncDisp;
}
CMenuManager::RequestFrontEndShutDown();
}
// We're already resuming, we don't need further processing.
#if defined(FIX_BUGS) || defined(PS2_LIKE_MENU)
return;
#endif
}
#ifdef PS2_LIKE_MENU
else if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT || m_nCurrScreen == MENUPAGE_SAVE) {
#else
else if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT) {
#endif
CMenuManager::RequestFrontEndShutDown();
}
// It's now in ThingsToDoBeforeLeavingPage()
#ifndef TIDY_UP_PBP
else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) {
DMAudio.StopFrontEndTrack();
OutputDebugString("FRONTEND AUDIO TRACK STOPPED");
}
#endif
int oldScreen = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0];
int oldOption = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : aScreens[m_nCurrScreen].m_ParentEntry[0];
if (oldScreen != -1) {
if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && strcmp(m_aSkinName, m_PrefsSkinFile) != 0) {
CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
}
if ((m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) && (m_nPrefsAudio3DProviderIndex != -1)) {
m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex();
}
if (m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) {
m_nDisplayVideoMode = m_nPrefsVideoMode;
}
if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
CPlayerSkin::EndFrontendSkinEdit();
}
ThingsToDoBeforeLeavingPage();
#ifdef PS2_LIKE_MENU
if (!bottomBarActive &&
@ -3168,10 +3246,8 @@ CMenuManager::ProcessButtonPresses(void)
bottomBarActive = true;
} else
#endif
{
ChangeScreen(oldScreen, oldOption, true, true);
if ((m_nPrevScreen == MENUPAGE_SKIN_SELECT) || (m_nPrevScreen == MENUPAGE_KEYBOARD_CONTROLS)) {
m_nTotalListRow = 0;
}
// We will go back for sure at this point, why process other things?!
@ -3412,7 +3488,7 @@ void CMenuManager::ProcessOnOffMenuOptions()
SaveSettings();
break;
case MENUACTION_MOUSESTEER:
m_bDisableMouseSteering = !m_bDisableMouseSteering;
CVehicle::m_bDisableMouseSteering = !CVehicle::m_bDisableMouseSteering;
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
SaveSettings();
break;
@ -3512,11 +3588,16 @@ WRAPPER void CMenuManager::SwitchMenuOnAndOff() { EAXJMP(0x488790); }
#else
void CMenuManager::SwitchMenuOnAndOff()
{
if (!!(CPad::GetPad(0)->NewState.Start && !CPad::GetPad(0)->OldState.Start)
|| m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested) {
bool menuWasActive = !!m_bMenuActive;
if (!m_bMenuActive)
m_bMenuActive = true;
// Reminder: You need REGISTER_START_BUTTON defined to make it work.
if (CPad::GetPad(0)->GetStartJustDown()
#ifdef FIX_BUGS
&& !m_bGameNotLoaded
#endif
|| m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested) {
m_bMenuActive = !m_bMenuActive;
if (m_bShutDownFrontEndRequested)
m_bMenuActive = false;
@ -3525,8 +3606,13 @@ void CMenuManager::SwitchMenuOnAndOff()
if (m_bMenuActive) {
CTimer::StartUserPause();
}
else {
} else {
#ifdef PS2_LIKE_MENU
bottomBarActive = false;
#endif
#ifdef FIX_BUGS
ThingsToDoBeforeLeavingPage();
#endif
ShutdownJustMenu();
SaveSettings();
m_bStartUpFrontEndRequested = false;
@ -3553,7 +3639,7 @@ void CMenuManager::SwitchMenuOnAndOff()
PcSaveHelper.PopulateSlotInfo();
m_nCurrOption = 0;
}
/* // Unused?
/* // PS2 leftover
if (m_nCurrScreen != MENUPAGE_SOUND_SETTINGS && gMusicPlaying)
{
DMAudio.StopFrontEndTrack();
@ -3561,8 +3647,8 @@ void CMenuManager::SwitchMenuOnAndOff()
gMusicPlaying = 0;
}
*/
if (!m_bMenuActive)
m_bMenuNotProcessed = true;
if (m_bMenuActive != menuWasActive)
m_bMenuStateChanged = true;
m_bStartUpFrontEndRequested = false;
m_bShutDownFrontEndRequested = false;

View file

@ -51,6 +51,9 @@ enum eLanguages
LANGUAGE_GERMAN,
LANGUAGE_ITALIAN,
LANGUAGE_SPANISH,
#ifdef MORE_LANGUAGES
LANGUAGE_RUSSIAN,
#endif
};
enum eFrontendSprites
@ -301,6 +304,9 @@ enum eMenuAction
MENUACTION_UNK108,
MENUACTION_UNK109,
MENUACTION_UNK110,
#ifdef MORE_LANGUAGES
MENUACTION_LANG_RUS,
#endif
};
enum eCheckHover
@ -357,7 +363,7 @@ enum
enum eControlMethod
{
CONTROL_STANDART = 0,
CONTROL_STANDARD = 0,
CONTROL_CLASSIC,
};
@ -403,7 +409,7 @@ public:
int32 m_nHelperTextMsgId;
bool m_bLanguageLoaded;
bool m_bMenuActive;
bool m_bMenuNotProcessed;
bool m_bMenuStateChanged;
bool m_bWaitingForNewKeyBind;
bool m_bStartGameLoading;
bool m_bFirstTime;
@ -473,7 +479,6 @@ public:
static int32 &m_ControlMethod;
static int8 &m_PrefsDMA;
static int32 &m_PrefsLanguage;
static int8 &m_bDisableMouseSteering;
static int32 &m_PrefsBrightness;
static float &m_PrefsLOD;
static int8 &m_bFrontEnd_ReloadObrTxtGxt;
@ -492,6 +497,12 @@ public:
static int32 &sthWithButtons;
static int32 &sthWithButtons2;
#ifndef MASTER
static bool m_PrefsMarketing;
static bool m_PrefsDisableTutorials;
#endif // !MASTER
public:
static void BuildStatLine(char *text, void *stat, uint8 aFloat, void *stat2);
static void CentreMousePointer();
@ -540,8 +551,14 @@ public:
void WaitForUserCD();
void PrintController();
// New content:
uint8 GetNumberOfMenuOptions();
// New (not in function or inlined in the game)
void ThingsToDoBeforeLeavingPage();
void ScrollUpListByOne();
void ScrollDownListByOne();
void PageUpList(bool);
void PageDownList(bool);
// uint8 GetNumberOfMenuOptions();
};
static_assert(sizeof(CMenuManager) == 0x564, "CMenuManager: error");

View file

@ -1,7 +1,14 @@
#pragma warning( push )
#pragma warning( disable : 4005)
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#pragma warning( pop )
#include "common.h"
#include "win.h"
#include "patcher.h"
#include "Game.h"
#include "main.h"
#include "RwHelper.h"
#include "Accident.h"
#include "Antennas.h"
#include "Bridge.h"
@ -17,6 +24,7 @@
#include "Cranes.h"
#include "Credits.h"
#include "CutsceneMgr.h"
#include "DMAudio.h"
#include "Darkel.h"
#include "Debug.h"
#include "EventList.h"
@ -28,24 +36,32 @@
#include "Frontend.h"
#include "GameLogic.h"
#include "Garages.h"
#include "GenericGameStorage.h"
#include "Glass.h"
#include "HandlingMgr.h"
#include "Heli.h"
#include "Hud.h"
#include "IniFile.h"
#include "Lights.h"
#include "MBlur.h"
#include "Messages.h"
#include "Pad.h"
#include "Particle.h"
#include "ParticleObject.h"
#include "PedRoutes.h"
#include "Phones.h"
#include "Pickups.h"
#include "Plane.h"
#include "PlayerSkin.h"
#include "Population.h"
#include "Radar.h"
#include "Record.h"
#include "References.h"
#include "Renderer.h"
#include "Replay.h"
#include "Restart.h"
#include "RoadBlocks.h"
#include "PedRoutes.h"
#include "Rubbish.h"
#include "RwHelper.h"
#include "SceneEdit.h"
#include "Script.h"
#include "Shadows.h"
@ -54,11 +70,14 @@
#include "Sprite2d.h"
#include "Stats.h"
#include "Streaming.h"
#include "SurfaceTable.h"
#include "TempColModels.h"
#include "TimeCycle.h"
#include "TrafficLights.h"
#include "Train.h"
#include "TxdStore.h"
#include "User.h"
#include "VisibilityPlugins.h"
#include "WaterCannon.h"
#include "WaterLevel.h"
#include "Weapon.h"
@ -68,6 +87,10 @@
#include "ZoneCull.h"
#include "Zones.h"
#define DEFAULT_VIEWWINDOW (0.7f)
eLevelName &CGame::currLevel = *(eLevelName*)0x941514;
bool &CGame::bDemoMode = *(bool*)0x5F4DD0;
bool &CGame::nastyGame = *(bool*)0x5F4DD4;
@ -76,7 +99,11 @@ bool &CGame::germanGame = *(bool*)0x95CD1E;
bool &CGame::noProstitutes = *(bool*)0x95CDCF;
bool &CGame::playingIntro = *(bool*)0x95CDC2;
char *CGame::aDatFile = (char*)0x773A48;
#ifdef MORE_LANGUAGES
bool CGame::russianGame = false;
#endif
int &gameTxdSlot = *(int*)0x628D88;
bool
CGame::InitialiseOnceBeforeRW(void)
@ -87,7 +114,139 @@ CGame::InitialiseOnceBeforeRW(void)
return true;
}
int &gameTxdSlot = *(int*)0x628D88;
bool
CGame::InitialiseRenderWare(void)
{
_TexturePoolsInitialise();
CTxdStore::Initialise();
CVisibilityPlugins::Initialise();
/* Create camera */
Scene.camera = CameraCreate(RsGlobal.width, RsGlobal.height, TRUE);
ASSERT(Scene.camera != nil);
if (!Scene.camera)
{
return (false);
}
RwCameraSetFarClipPlane(Scene.camera, 2000.0f);
RwCameraSetNearClipPlane(Scene.camera, 0.9f);
CameraSize(Scene.camera, nil, DEFAULT_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
/* Create a world */
RwBBox bbox;
bbox.sup.x = bbox.sup.y = bbox.sup.z = 10000.0f;
bbox.inf.x = bbox.inf.y = bbox.inf.z = -10000.0f;
Scene.world = RpWorldCreate(&bbox);
ASSERT(Scene.world != nil);
if (!Scene.world)
{
CameraDestroy(Scene.camera);
Scene.camera = nil;
return (false);
}
/* Add the camera to the world */
RpWorldAddCamera(Scene.world, Scene.camera);
LightsCreate(Scene.world);
CreateDebugFont();
CFont::Initialise();
CHud::Initialise();
CPlayerSkin::Initialise();
return (true);
}
void CGame::ShutdownRenderWare(void)
{
CMBlur::MotionBlurClose();
DestroySplashScreen();
CHud::Shutdown();
CFont::Shutdown();
for ( int32 i = 0; i < NUMPLAYERS; i++ )
CWorld::Players[i].DeletePlayerSkin();
CPlayerSkin::Shutdown();
DestroyDebugFont();
/* Destroy world */
LightsDestroy(Scene.world);
RpWorldRemoveCamera(Scene.world, Scene.camera);
RpWorldDestroy(Scene.world);
/* destroy camera */
CameraDestroy(Scene.camera);
Scene.world = nil;
Scene.camera = nil;
CVisibilityPlugins::Shutdown();
_TexturePoolsShutdown();
}
bool CGame::InitialiseOnceAfterRW(void)
{
TheText.Load();
DMAudio.Initialise();
CTimer::Initialise();
CTempColModels::Initialise();
mod_HandlingManager.Initialise();
CSurfaceTable::Initialise("DATA\\SURFACE.DAT");
CPedStats::Initialise();
CTimeCycle::Initialise();
if ( DMAudio.GetNum3DProvidersAvailable() == 0 )
FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = -1;
if ( FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -99 || FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -2 )
{
CMenuManager::m_PrefsSpeakers = 0;
for ( int32 i = 0; i < DMAudio.GetNum3DProvidersAvailable(); i++ )
{
wchar buff[64];
char *name = DMAudio.Get3DProviderName(i);
AsciiToUnicode(name, buff);
char *providername = UnicodeToAscii(buff);
strupr(providername);
if ( !strcmp(providername, "MILES FAST 2D POSITIONAL AUDIO") )
{
FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = i;
break;
}
}
}
DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_nPrefsAudio3DProviderIndex);
DMAudio.SetSpeakerConfig(CMenuManager::m_PrefsSpeakers);
DMAudio.SetDynamicAcousticModelingStatus(CMenuManager::m_PrefsDMA);
DMAudio.SetMusicMasterVolume(CMenuManager::m_PrefsMusicVolume);
DMAudio.SetEffectsMasterVolume(CMenuManager::m_PrefsSfxVolume);
DMAudio.SetEffectsFadeVol(127);
DMAudio.SetMusicFadeVol(127);
CWorld::Players[0].SetPlayerSkin(CMenuManager::m_PrefsSkinFile);
return true;
}
void
CGame::FinalShutdown(void)
{
CTxdStore::Shutdown();
CPedStats::Shutdown();
CdStreamShutdown();
}
bool CGame::Initialise(const char* datFile)
{
@ -158,7 +317,7 @@ bool CGame::Initialise(const char* datFile)
CStreaming::Init();
} else {
CStreaming::Init();
if (ConvertTextures()) {
if (CreateTxdImageForVideoCard()) {
CStreaming::Shutdown();
CdStreamAddImage("MODELS\\TXD.IMG");
CStreaming::Init();
@ -196,7 +355,7 @@ bool CGame::Initialise(const char* datFile)
CSceneEdit::Init();
LoadingScreen("Loading the Game", "Load scripts", nil);
CTheScripts::Init();
CGangs::Initialize();
CGangs::Initialise();
LoadingScreen("Loading the Game", "Setup game variables", nil);
CClock::Initialise(1000);
CHeli::InitHelis();
@ -225,16 +384,227 @@ bool CGame::Initialise(const char* datFile)
CTheScripts::Process();
TheCamera.Process();
LoadingScreen("Loading the Game", "Load scene", nil);
CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
CCollision::ms_collisionInMemory = CGame::currLevel;
CModelInfo::RemoveColModelsFromOtherLevels(currLevel);
CCollision::ms_collisionInMemory = currLevel;
for (int i = 0; i < MAX_PADS; i++)
CPad::GetPad(i)->Clear(true);
return true;
}
#if 0
WRAPPER void CGame::Process(void) { EAXJMP(0x48C850); }
#else
bool CGame::ShutDown(void)
{
CReplay::FinishPlayback();
CPlane::Shutdown();
CTrain::Shutdown();
CSpecialFX::Shutdown();
#ifndef PS2
CGarages::Shutdown();
#endif
CMovingThings::Shutdown();
gPhoneInfo.Shutdown();
CWeapon::ShutdownWeapons();
CPedType::Shutdown();
CMBlur::MotionBlurClose();
for (int32 i = 0; i < NUMPLAYERS; i++)
{
if ( CWorld::Players[i].m_pPed )
{
CWorld::Remove(CWorld::Players[i].m_pPed);
delete CWorld::Players[i].m_pPed;
CWorld::Players[i].m_pPed = nil;
}
CWorld::Players[i].Clear();
}
CRenderer::Shutdown();
CWorld::ShutDown();
DMAudio.DestroyAllGameCreatedEntities();
CModelInfo::ShutDown();
CAnimManager::Shutdown();
CCutsceneMgr::Shutdown();
CVehicleModelInfo::DeleteVehicleColourTextures();
CVehicleModelInfo::ShutdownEnvironmentMaps();
CRadar::Shutdown();
CStreaming::Shutdown();
CTxdStore::GameShutdown();
CCollision::Shutdown();
CWaterLevel::Shutdown();
CRubbish::Shutdown();
CClouds::Shutdown();
CShadows::Shutdown();
CCoronas::Shutdown();
CSkidmarks::Shutdown();
CWeaponEffects::Shutdown();
CParticle::Shutdown();
CPools::ShutDown();
CTxdStore::RemoveTxdSlot(gameTxdSlot);
CdStreamRemoveImages();
return true;
}
void CGame::ReInitGameObjectVariables(void)
{
CGameLogic::InitAtStartOfGame();
TheCamera.CCamera::Init();
TheCamera.SetRwCamera(Scene.camera);
CDebug::DebugInitTextBuffer();
CWeather::Init();
CUserDisplay::Init();
CMessages::Init();
CRestart::Initialise();
CWorld::bDoingCarCollisions = false;
CHud::ReInitialise();
CRadar::Initialise();
CCarCtrl::ReInit();
CTimeCycle::Initialise();
CDraw::SetFOV(120.0f);
CDraw::ms_fLODDistance = 500.0f;
CStreaming::RequestBigBuildings(LEVEL_NONE);
CStreaming::LoadAllRequestedModels(false);
CPed::Initialise();
CEventList::Initialise();
CWeapon::InitialiseWeapons();
CPopulation::Initialise();
for (int i = 0; i < NUMPLAYERS; i++)
CWorld::Players[i].Clear();
CWorld::PlayerInFocus = 0;
CAntennas::Init();
CGlass::Init();
gPhoneInfo.Initialise();
CTheScripts::Init();
CGangs::Initialise();
CTimer::Initialise();
CClock::Initialise(1000);
CTheCarGenerators::Init();
CHeli::InitHelis();
CMovingThings::Init();
CDarkel::Init();
CStats::Init();
CPickups::Init();
CPacManPickups::Init();
CGarages::Init();
CSpecialFX::Init();
CWaterCannons::Init();
CParticle::ReloadConfig();
CCullZones::ResolveVisibilities();
if ( !FrontEndMenuManager.m_bLoadingSavedGame )
{
CCranes::InitCranes();
CTheScripts::StartTestScript();
CTheScripts::Process();
TheCamera.Process();
CTrain::InitTrains();
CPlane::InitPlanes();
}
for (int32 i = 0; i < MAX_PADS; i++)
CPad::GetPad(i)->Clear(true);
}
void CGame::ReloadIPLs(void)
{
CTimer::Stop();
CWorld::RemoveStaticObjects();
ThePaths.Init();
CCullZones::Init();
CFileLoader::ReloadPaths("GTA3.IDE");
CFileLoader::LoadScene("INDUST.IPL");
CFileLoader::LoadScene("COMMER.IPL");
CFileLoader::LoadScene("SUBURBAN.IPL");
CFileLoader::LoadScene("CULL.IPL");
ThePaths.PreparePathData();
CTrafficLights::ScanForLightsOnMap();
CRoadBlocks::Init();
CCranes::InitCranes();
CGarages::Init();
CWorld::RepositionCertainDynamicObjects();
CCullZones::ResolveVisibilities();
CRenderer::SortBIGBuildings();
CTimer::Update();
}
void CGame::ShutDownForRestart(void)
{
CReplay::FinishPlayback();
CReplay::EmptyReplayBuffer();
DMAudio.DestroyAllGameCreatedEntities();
for (int i = 0; i < NUMPLAYERS; i++)
CWorld::Players[i].Clear();
CGarages::SetAllDoorsBackToOriginalHeight();
CTheScripts::UndoBuildingSwaps();
CTheScripts::UndoEntityInvisibilitySettings();
CWorld::ClearForRestart();
CTimer::Shutdown();
CStreaming::FlushRequestList();
CStreaming::DeleteAllRwObjects();
CStreaming::RemoveAllUnusedModels();
CStreaming::ms_disableStreaming = false;
CRadar::RemoveRadarSections();
FrontEndMenuManager.UnloadTextures();
CParticleObject::RemoveAllParticleObjects();
CPedType::Shutdown();
CSpecialFX::Shutdown();
TidyUpMemory(true, false);
}
void CGame::InitialiseWhenRestarting(void)
{
CRect rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
CRGBA color(255, 255, 255, 255);
CTimer::Initialise();
CSprite2d::SetRecipNearClip();
b_FoundRecentSavedGameWantToLoad = false;
TheCamera.Init();
if ( FrontEndMenuManager.m_bLoadingSavedGame == true )
{
RestoreForStartLoad();
CStreaming::LoadScene(TheCamera.GetPosition());
}
ReInitGameObjectVariables();
if ( FrontEndMenuManager.m_bLoadingSavedGame == true )
{
if ( GenericLoad() == true )
{
DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds());
CTrain::InitTrains();
CPlane::InitPlanes();
}
else
{
for ( int32 i = 0; i < 50; i++ )
{
HandleExit();
FrontEndMenuManager.MessageScreen("FED_LFL"); // Loading save game has failed. The game will restart now.
}
ShutDownForRestart();
CTimer::Stop();
CTimer::Initialise();
FrontEndMenuManager.m_bLoadingSavedGame = false;
ReInitGameObjectVariables();
currLevel = LEVEL_INDUSTRIAL;
CCollision::SortOutCollisionAfterLoad();
}
}
CTimer::Update();
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
}
extern void (*DebugMenuProcess)(void);
void CGame::Process(void)
{
@ -310,50 +680,34 @@ void CGame::Process(void)
}
}
}
#endif
void CGame::ReloadIPLs(void)
void CGame::DrasticTidyUpMemory(bool)
{
CTimer::Stop();
CWorld::RemoveStaticObjects();
ThePaths.Init();
CCullZones::Init();
CFileLoader::ReloadPaths("GTA3.IDE");
CFileLoader::LoadScene("INDUST.IPL");
CFileLoader::LoadScene("COMMER.IPL");
CFileLoader::LoadScene("SUBURBAN.IPL");
CFileLoader::LoadScene("CULL.IPL");
ThePaths.PreparePathData();
CTrafficLights::ScanForLightsOnMap();
CRoadBlocks::Init();
CCranes::InitCranes();
CGarages::Init();
CWorld::RepositionCertainDynamicObjects();
CCullZones::ResolveVisibilities();
CRenderer::SortBIGBuildings();
CTimer::Update();
#ifdef PS2
// meow
#endif
}
#if 0
WRAPPER void CGame::FinalShutdown(void) { EAXJMP(0x48BEC0); }
#else
void
CGame::FinalShutdown(void)
void CGame::TidyUpMemory(bool, bool)
{
CTxdStore::Shutdown();
CPedStats::Shutdown();
CdStreamShutdown();
}
#ifdef PS2
// meow
#endif
WRAPPER bool CGame::InitialiseRenderWare(void) { EAXJMP(0x48BBA0); }
WRAPPER void CGame::ShutdownRenderWare(void) { EAXJMP(0x48BCB0); }
WRAPPER void CGame::ShutDown(void) { EAXJMP(0x48C3A0); }
WRAPPER void CGame::ShutDownForRestart(void) { EAXJMP(0x48C6B0); }
WRAPPER void CGame::InitialiseWhenRestarting(void) { EAXJMP(0x48C740); }
WRAPPER bool CGame::InitialiseOnceAfterRW(void) { EAXJMP(0x48BD50); }
}
STARTPATCHES
InjectHook(0x48C850, CGame::Process, PATCH_JUMP);
InjectHook(0x48BB80, CGame::InitialiseOnceBeforeRW, PATCH_JUMP);
InjectHook(0x48BBA0, CGame::InitialiseRenderWare, PATCH_JUMP);
InjectHook(0x48BCB0, CGame::ShutdownRenderWare, PATCH_JUMP);
InjectHook(0x48BD50, CGame::InitialiseOnceAfterRW, PATCH_JUMP);
InjectHook(0x48BEC0, CGame::FinalShutdown, PATCH_JUMP);
InjectHook(0x48BED0, CGame::Initialise, PATCH_JUMP);
InjectHook(0x48C3A0, CGame::ShutDown, PATCH_JUMP);
InjectHook(0x48C4B0, CGame::ReInitGameObjectVariables, PATCH_JUMP);
InjectHook(0x48C620, CGame::ReloadIPLs, PATCH_JUMP);
InjectHook(0x48C6B0, CGame::ShutDownForRestart, PATCH_JUMP);
InjectHook(0x48C740, CGame::InitialiseWhenRestarting, PATCH_JUMP);
InjectHook(0x48C850, CGame::Process, PATCH_JUMP);
InjectHook(0x48CA10, CGame::DrasticTidyUpMemory, PATCH_JUMP);
InjectHook(0x48CA20, CGame::TidyUpMemory, PATCH_JUMP);
ENDPATCHES

View file

@ -16,23 +16,27 @@ public:
static bool &nastyGame;
static bool &frenchGame;
static bool &germanGame;
#ifdef MORE_LANGUAGES
static bool russianGame;
#endif
static bool &noProstitutes;
static bool &playingIntro;
static char *aDatFile; //[32];
static bool Initialise(const char *datFile);
static bool InitialiseOnceBeforeRW(void);
static bool InitialiseRenderWare(void);
static bool InitialiseOnceAfterRW(void);
static void InitialiseWhenRestarting(void);
static void ShutDown(void);
static void ShutdownRenderWare(void);
static bool InitialiseOnceAfterRW(void);
static void FinalShutdown(void);
static void ShutDownForRestart(void);
static void Process(void);
static bool Initialise(const char *datFile);
static bool ShutDown(void);
static void ReInitGameObjectVariables(void);
static void ReloadIPLs(void);
static void ShutDownForRestart(void);
static void InitialiseWhenRestarting(void);
static void Process(void);
// NB: these do something on PS2
static void TidyUpMemory(bool, bool) {}
static void DrasticTidyUpMemory(void) {}
static void TidyUpMemory(bool, bool);
static void DrasticTidyUpMemory(bool);
};

View file

@ -1,5 +1,7 @@
#pragma once
#include <ctype.h>
class CGeneral
{
public:

View file

@ -65,6 +65,9 @@ const CMenuScreen aScreens[] = {
MENUACTION_LANG_GER, "FEL_GER", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_LANG_ITA, "FEL_ITA", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_LANG_SPA, "FEL_SPA", SAVESLOT_NONE, MENUPAGE_NONE,
#ifdef MORE_LANGUAGES
MENUACTION_LANG_RUS, "FEL_RUS", SAVESLOT_NONE, MENUPAGE_NONE,
#endif
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
},

View file

@ -5,6 +5,10 @@
#pragma warning( pop )
#include "common.h"
#ifdef XINPUT
#include <Xinput.h>
#pragma comment( lib, "Xinput9_1_0.lib" )
#endif
#include "patcher.h"
#include "Pad.h"
#include "ControllerConfig.h"
@ -547,12 +551,79 @@ void CPad::AddToPCCheatString(char c)
#undef _CHEATCMP
}
#ifdef XINPUT
void CPad::AffectFromXinput(uint32 pad)
{
XINPUT_STATE xstate;
memset(&xstate, 0, sizeof(XINPUT_STATE));
if (XInputGetState(pad, &xstate) == ERROR_SUCCESS)
{
PCTempJoyState.Circle = (xstate.Gamepad.wButtons & XINPUT_GAMEPAD_B) ? 255 : 0;
PCTempJoyState.Cross = (xstate.Gamepad.wButtons & XINPUT_GAMEPAD_A) ? 255 : 0;
PCTempJoyState.Square = (xstate.Gamepad.wButtons & XINPUT_GAMEPAD_X) ? 255 : 0;
PCTempJoyState.Triangle = (xstate.Gamepad.wButtons & XINPUT_GAMEPAD_Y) ? 255 : 0;
PCTempJoyState.DPadDown = (xstate.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) ? 255 : 0;
PCTempJoyState.DPadLeft = (xstate.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) ? 255 : 0;
PCTempJoyState.DPadRight = (xstate.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) ? 255 : 0;
PCTempJoyState.DPadUp = (xstate.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) ? 255 : 0;
PCTempJoyState.LeftShock = (xstate.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) ? 255 : 0;
PCTempJoyState.LeftShoulder1 = (xstate.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) ? 255 : 0;
PCTempJoyState.LeftShoulder2 = xstate.Gamepad.bLeftTrigger;
PCTempJoyState.RightShock = (xstate.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) ? 255 : 0;
PCTempJoyState.RightShoulder1 = (xstate.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) ? 255 : 0;
PCTempJoyState.RightShoulder2 = xstate.Gamepad.bRightTrigger;
PCTempJoyState.Select = (xstate.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) ? 255 : 0;
#ifdef REGISTER_START_BUTTON
PCTempJoyState.Start = (xstate.Gamepad.wButtons & XINPUT_GAMEPAD_START) ? 255 : 0;
#endif
float lx = (float)xstate.Gamepad.sThumbLX / (float)0x7FFF;
float ly = (float)xstate.Gamepad.sThumbLY / (float)0x7FFF;
float rx = (float)xstate.Gamepad.sThumbRX / (float)0x7FFF;
float ry = (float)xstate.Gamepad.sThumbRY / (float)0x7FFF;
if (Abs(lx) > 0.3f || Abs(ly) > 0.3f) {
PCTempJoyState.LeftStickX = (int32)(lx * 128.0f);
PCTempJoyState.LeftStickY = (int32)(-ly * 128.0f);
}
if (Abs(rx) > 0.3f || Abs(ry) > 0.3f) {
PCTempJoyState.RightStickX = (int32)(rx * 128.0f);
PCTempJoyState.RightStickY = (int32)(ry * 128.0f);
}
XINPUT_VIBRATION VibrationState;
memset(&VibrationState, 0, sizeof(XINPUT_VIBRATION));
uint16 iLeftMotor = (uint16)((float)ShakeFreq / 255.0f * (float)0xffff);
uint16 iRightMotor = (uint16)((float)ShakeFreq / 255.0f * (float)0xffff);
if (ShakeDur < CTimer::GetTimeStepInMilliseconds())
ShakeDur = 0;
else
ShakeDur -= CTimer::GetTimeStepInMilliseconds();
if (ShakeDur == 0) ShakeFreq = 0;
VibrationState.wLeftMotorSpeed = iLeftMotor;
VibrationState.wRightMotorSpeed = iRightMotor;
XInputSetState(pad, &VibrationState);
}
}
#endif
void CPad::UpdatePads(void)
{
bool bUpdate = true;
GetPad(0)->UpdateMouse();
#ifdef XINPUT
GetPad(0)->AffectFromXinput(0);
GetPad(1)->AffectFromXinput(1);
#else
CapturePad(0);
#endif
ControlsManager.ClearSimButtonPressCheckers();
@ -565,10 +636,13 @@ void CPad::UpdatePads(void)
if ( bUpdate )
{
GetPad(0)->Update(0);
GetPad(1)->Update(0);
}
#if defined(MASTER) && !defined(XINPUT)
GetPad(1)->NewState.Clear();
GetPad(1)->OldState.Clear();
#endif
OldKeyState = NewKeyState;
NewKeyState = TempKeyState;

View file

@ -2,9 +2,9 @@
enum {
PLAYERCONTROL_ENABLED = 0,
PLAYERCONTROL_DISABLED_1 = 1,
PLAYERCONTROL_DISABLED_1 = 1, // used by first person camera
PLAYERCONTROL_DISABLED_2 = 2,
PLAYERCONTROL_DISABLED_4 = 4,
PLAYERCONTROL_GARAGE = 4,
PLAYERCONTROL_DISABLED_8 = 8,
PLAYERCONTROL_DISABLED_10 = 16,
PLAYERCONTROL_DISABLED_20 = 32, // used on CPlayerInfo::MakePlayerSafe
@ -247,6 +247,10 @@ public:
static char *EditString(char *pStr, int32 nSize);
static int32 *EditCodesForControls(int32 *pRsKeys, int32 nSize);
#ifdef XINPUT
void AffectFromXinput(uint32 pad);
#endif
// mouse
bool GetLeftMouseJustDown() { return !!(NewMouseControllerState.LMB && !OldMouseControllerState.LMB); }
bool GetRightMouseJustDown() { return !!(NewMouseControllerState.RMB && !OldMouseControllerState.RMB); }
@ -399,6 +403,8 @@ public:
bool GetLeftShoulder2JustDown() { return !!(NewState.LeftShoulder2 && !OldState.LeftShoulder2); }
bool GetRightShoulder1JustDown() { return !!(NewState.RightShoulder1 && !OldState.RightShoulder1); }
bool GetRightShoulder2JustDown() { return !!(NewState.RightShoulder2 && !OldState.RightShoulder2); }
bool GetLeftShockJustDown() { return !!(NewState.LeftShock && !OldState.LeftShock); }
bool GetRightShockJustDown() { return !!(NewState.RightShock && !OldState.RightShock); }
bool GetStartJustDown() { return !!(NewState.Start && !OldState.Start); }
bool GetLeftStickXJustDown() { return !!(NewState.LeftStickX && !OldState.LeftStickX); }
bool GetLeftStickYJustDown() { return !!(NewState.LeftStickY && !OldState.LeftStickY); }
@ -422,8 +428,15 @@ public:
bool GetLeftShoulder2(void) { return !!NewState.LeftShoulder2; }
bool GetRightShoulder1(void) { return !!NewState.RightShoulder1; }
bool GetRightShoulder2(void) { return !!NewState.RightShoulder2; }
int16 GetLeftStickX(void) { return NewState.LeftStickX; }
int16 GetLeftStickY(void) { return NewState.LeftStickY; }
int16 GetRightStickX(void) { return NewState.RightStickX; }
int16 GetRightStickY(void) { return NewState.RightStickY; }
bool ArePlayerControlsDisabled(void) { return DisablePlayerControls != PLAYERCONTROL_ENABLED; }
bool ArePlayerControlsDisabled(void) { return DisablePlayerControls != PLAYERCONTROL_ENABLED; }
void SetDisablePlayerControls(uint8 who) { DisablePlayerControls |= who; }
void SetEnablePlayerControls(uint8 who) { DisablePlayerControls &= ~who; }
bool IsPlayerControlsDisabledBy(uint8 who) { return DisablePlayerControls & who; }
};
VALIDATE_SIZE(CPad, 0xFC);

View file

@ -63,6 +63,8 @@ CPlaceable::IsWithinArea(float x1, float y1, float z1, float x2, float y2, float
z1 <= GetPosition().z && GetPosition().z <= z2;
}
#include <new>
class CPlaceable_ : public CPlaceable
{
public:

View file

@ -2,7 +2,9 @@
#include "patcher.h"
#include "main.h"
#include "PlayerPed.h"
#include "Wanted.h"
#include "PlayerInfo.h"
#include "Fire.h"
#include "Frontend.h"
#include "PlayerSkin.h"
#include "Darkel.h"
@ -12,6 +14,7 @@
#include "Remote.h"
#include "World.h"
#include "Replay.h"
#include "Camera.h"
#include "Pad.h"
#include "ProjectileInfo.h"
#include "Explosion.h"

View file

@ -75,9 +75,6 @@ static_assert(RADAR_TILE_SIZE == (WORLD_SIZE_Y / RADAR_NUM_TILES), "CRadar: not
#define RADAR_MIN_SPEED (0.3f)
#define RADAR_MAX_SPEED (0.9f)
#if 0
WRAPPER void CRadar::CalculateBlipAlpha(float) { EAXJMP(0x4A4F90); }
#else
uint8 CRadar::CalculateBlipAlpha(float dist)
{
if (dist <= 1.0f)
@ -88,55 +85,35 @@ uint8 CRadar::CalculateBlipAlpha(float dist)
return 128;
}
#endif
#if 0
WRAPPER void CRadar::ChangeBlipBrightness(int32, int32) { EAXJMP(0x4A57A0); }
#else
void CRadar::ChangeBlipBrightness(int32 i, int32 bright)
{
int index = GetActualBlipArrayIndex(i);
if (index != -1)
ms_RadarTrace[index].m_bDim = bright != 1;
}
#endif
#if 0
WRAPPER void CRadar::ChangeBlipColour(int32, int32) { EAXJMP(0x4A5770); }
#else
void CRadar::ChangeBlipColour(int32 i, int32 color)
{
int index = GetActualBlipArrayIndex(i);
if (index != -1)
ms_RadarTrace[index].m_nColor = color;
}
#endif
#if 0
WRAPPER void CRadar::ChangeBlipDisplay(int32, eBlipDisplay) { EAXJMP(0x4A5810); }
#else
void CRadar::ChangeBlipDisplay(int32 i, eBlipDisplay display)
{
int index = GetActualBlipArrayIndex(i);
if (index != -1)
ms_RadarTrace[index].m_eBlipDisplay = display;
}
#endif
#if 0
WRAPPER void CRadar::ChangeBlipScale(int32, int32) { EAXJMP(0x4A57E0); }
#else
void CRadar::ChangeBlipScale(int32 i, int32 scale)
{
int index = GetActualBlipArrayIndex(i);
if (index != -1)
ms_RadarTrace[index].m_wScale = scale;
}
#endif
#if 0
WRAPPER void CRadar::ClearBlip(int32) { EAXJMP(0x4A5720); }
#else
void CRadar::ClearBlip(int32 i)
{
int index = GetActualBlipArrayIndex(i);
@ -148,11 +125,7 @@ void CRadar::ClearBlip(int32 i)
ms_RadarTrace[index].m_IconID = RADAR_SPRITE_NONE;
}
}
#endif
#if 0
WRAPPER void CRadar::ClearBlipForEntity(eBlipType, int32) { EAXJMP(0x4A56C0); }
#else
void CRadar::ClearBlipForEntity(eBlipType type, int32 id)
{
for (int i = 0; i < NUMRADARBLIPS; i++) {
@ -165,11 +138,7 @@ void CRadar::ClearBlipForEntity(eBlipType type, int32 id)
}
};
}
#endif
#if 0
WRAPPER int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *in) { EAXJMP(0x4A64A0); }
#else
// Why not a proper clipping algorithm?
int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect)
{
@ -249,7 +218,6 @@ int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect)
return n;
}
#endif
bool CRadar::DisplayThisBlip(int32 counter)
{
@ -263,9 +231,6 @@ bool CRadar::DisplayThisBlip(int32 counter)
}
}
#if 0
WRAPPER void CRadar::Draw3dMarkers() { EAXJMP(0x4A4C70); }
#else
void CRadar::Draw3dMarkers()
{
for (int i = 0; i < NUMRADARBLIPS; i++) {
@ -317,12 +282,7 @@ void CRadar::Draw3dMarkers()
}
}
}
#endif
#if 0
WRAPPER void CRadar::DrawBlips() { EAXJMP(0x4A42F0); }
#else
void CRadar::DrawBlips()
{
if (!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud) {
@ -580,12 +540,7 @@ void CRadar::DrawBlips()
}
}
}
#endif
#if 0
WRAPPER void CRadar::DrawMap () { EAXJMP(0x4A4200); }
#else
void CRadar::DrawMap()
{
if (!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud) {
@ -605,11 +560,7 @@ void CRadar::DrawMap()
DrawRadarMap();
}
}
#endif
#if 0
WRAPPER void CRadar::DrawRadarMap() { EAXJMP(0x4A6C20); }
#else
void CRadar::DrawRadarMap()
{
// Game calculates an unused CRect here
@ -642,11 +593,7 @@ void CRadar::DrawRadarMap()
DrawRadarSection(x, y + 1);
DrawRadarSection(x + 1, y + 1);
}
#endif
#if 0
WRAPPER void CRadar::DrawRadarMask() { EAXJMP(0x4A69C0); }
#else
void CRadar::DrawRadarMask()
{
CVector2D corners[4] = {
@ -690,11 +637,7 @@ void CRadar::DrawRadarMask()
RwD3D8SetRenderState(rwRENDERSTATESTENCILFUNCTION, rwSTENCILFUNCTIONGREATER);
}
#endif
#if 0
WRAPPER void CRadar::DrawRadarSection(int32, int32) { EAXJMP(0x4A67E0); }
#else
void CRadar::DrawRadarSection(int32 x, int32 y)
{
int i;
@ -738,20 +681,12 @@ void CRadar::DrawRadarSection(int32 x, int32 y)
// if(numVertices > 2)
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), numVertices);
}
#endif
#if 0
WRAPPER void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha) { EAXJMP(0x4A5EF0); }
#else
void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha)
{
RadarSprites[sprite]->Draw(CRect(x - SCREEN_SCALE_X(8.0f), y - SCREEN_SCALE_Y(8.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(8.0f)), CRGBA(255, 255, 255, alpha));
}
#endif
#if 0
WRAPPER void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int32 alpha) { EAXJMP(0x4A5D10); }
#else
void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int32 alpha)
{
CVector curPosn[4];
@ -778,11 +713,7 @@ void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float
sprite->Draw(curPosn[2].x, curPosn[2].y, curPosn[3].x, curPosn[3].y, curPosn[0].x, curPosn[0].y, curPosn[1].x, curPosn[1].y, CRGBA(255, 255, 255, alpha));
}
#endif
#if 0
WRAPPER int32 CRadar::GetActualBlipArrayIndex(int32) { EAXJMP(0x4A41C0); }
#else
int32 CRadar::GetActualBlipArrayIndex(int32 i)
{
if (i == -1)
@ -792,11 +723,7 @@ int32 CRadar::GetActualBlipArrayIndex(int32 i)
else
return (uint16)i;
}
#endif
#if 0
WRAPPER int32 CRadar::GetNewUniqueBlipIndex(int32) { EAXJMP(0x4A4180); }
#else
int32 CRadar::GetNewUniqueBlipIndex(int32 i)
{
if (ms_RadarTrace[i].m_BlipIndex >= UINT16_MAX - 1)
@ -805,11 +732,7 @@ int32 CRadar::GetNewUniqueBlipIndex(int32 i)
ms_RadarTrace[i].m_BlipIndex++;
return i | (ms_RadarTrace[i].m_BlipIndex << 16);
}
#endif
#if 0
WRAPPER uint32 CRadar::GetRadarTraceColour(uint32 color, bool bright) { EAXJMP(0x4A5BB0); }
#else
uint32 CRadar::GetRadarTraceColour(uint32 color, bool bright)
{
int32 c;
@ -862,7 +785,6 @@ uint32 CRadar::GetRadarTraceColour(uint32 color, bool bright)
};
return c;
}
#endif
const char* gRadarTexNames[] = {
"radar00", "radar01", "radar02", "radar03", "radar04", "radar05", "radar06", "radar07",
@ -875,9 +797,6 @@ const char* gRadarTexNames[] = {
"radar56", "radar57", "radar58", "radar59", "radar60", "radar61", "radar62", "radar63",
};
#if 0
WRAPPER void CRadar::Initialise() { EAXJMP(0x4A3EF0); }
#else
void
CRadar::Initialise()
{
@ -894,11 +813,7 @@ CRadar::Initialise()
for (int i = 0; i < 64; i++)
gRadarTxdIds[i] = CTxdStore::FindTxdSlot(gRadarTexNames[i]);
}
#endif
#if 0
WRAPPER float CRadar::LimitRadarPoint(CVector2D &point) { EAXJMP(0x4A4F30); }
#else
float CRadar::LimitRadarPoint(CVector2D &point)
{
float dist, invdist;
@ -911,11 +826,7 @@ float CRadar::LimitRadarPoint(CVector2D &point)
}
return dist;
}
#endif
#if 0
WRAPPER void CRadar::LoadAllRadarBlips(int32) { EAXJMP(0x4A6F30); }
#else
void CRadar::LoadAllRadarBlips(uint8 *buf, uint32 size)
{
Initialise();
@ -927,11 +838,7 @@ INITSAVEBUF
VALIDATESAVEBUF(size);
}
#endif
#if 0
WRAPPER void CRadar::LoadTextures() { EAXJMP(0x4A4030); }
#else
void
CRadar::LoadTextures()
{
@ -959,42 +866,26 @@ CRadar::LoadTextures()
WeaponSprite.SetTexture("radar_weapon");
CTxdStore::PopCurrentTxd();
}
#endif
#if 0
WRAPPER void RemoveMapSection(int32, int32) { EAXJMP(0x00); }
#else
void RemoveMapSection(int32 x, int32 y)
{
if (x >= 0 && x <= 7 && y >= 0 && y <= 7)
CStreaming::RemoveTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y]);
}
#endif
#if 0
WRAPPER void CRadar::RemoveRadarSections() { EAXJMP(0x4A60E0); }
#else
void CRadar::RemoveRadarSections()
{
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
RemoveMapSection(i, j);
}
#endif
#if 0
WRAPPER void CRadar::RequestMapSection(int32, int32) { EAXJMP(0x00); }
#else
void CRadar::RequestMapSection(int32 x, int32 y)
{
ClipRadarTileCoords(x, y);
CStreaming::RequestTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y], STREAMFLAGS_DONT_REMOVE | STREAMFLAGS_DEPENDENCY);
}
#endif
#if 0
WRAPPER void CRadar::SaveAllRadarBlips(uint8 *buf, uint32 *size) { EAXJMP(0x4A6E30); }
#else
void CRadar::SaveAllRadarBlips(uint8 *buf, uint32 *size)
{
*size = SAVE_HEADER_SIZE + sizeof(ms_RadarTrace);
@ -1006,11 +897,7 @@ INITSAVEBUF
VALIDATESAVEBUF(*size);
}
#endif
#if 0
WRAPPER void CRadar::SetBlipSprite(int32, int32) { EAXJMP(0x4A5840); }
#else
void CRadar::SetBlipSprite(int32 i, int32 icon)
{
int index = CRadar::GetActualBlipArrayIndex(i);
@ -1018,11 +905,7 @@ void CRadar::SetBlipSprite(int32 i, int32 icon)
ms_RadarTrace[index].m_IconID = icon;
}
}
#endif
#if 0
WRAPPER int32 CRadar::SetCoordBlip(eBlipType, CVector, int32, eBlipDisplay display) { EAXJMP(0x4A5590); }
#else
int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay display)
{
int nextBlip;
@ -1043,11 +926,7 @@ int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay
ms_RadarTrace[nextBlip].m_IconID = RADAR_SPRITE_NONE;
return CRadar::GetNewUniqueBlipIndex(nextBlip);
}
#endif
#if 0
WRAPPER int CRadar::SetEntityBlip(eBlipType type, int32, int32, eBlipDisplay) { EAXJMP(0x4A5640); }
#else
int CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDisplay display)
{
int nextBlip;
@ -1066,11 +945,7 @@ int CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDispla
ms_RadarTrace[nextBlip].m_IconID = RADAR_SPRITE_NONE;
return GetNewUniqueBlipIndex(nextBlip);
}
#endif
#if 0
WRAPPER void CRadar::SetRadarMarkerState(int32, bool) { EAXJMP(0x4A5C60); }
#else
void CRadar::SetRadarMarkerState(int32 counter, bool flag)
{
CEntity *e;
@ -1091,11 +966,7 @@ void CRadar::SetRadarMarkerState(int32 counter, bool flag)
if (e)
e->bHasBlip = flag;
}
#endif
#if 0
WRAPPER void CRadar::ShowRadarMarker(CVector pos, uint32 color, float radius) { EAXJMP(0x4A59C0); }
#else
void CRadar::ShowRadarMarker(CVector pos, uint32 color, float radius) {
float f1 = radius * 1.4f;
float f2 = radius * 0.5f;
@ -1117,11 +988,7 @@ void CRadar::ShowRadarMarker(CVector pos, uint32 color, float radius) {
p2 = pos - TheCamera.GetRight()*f2;
CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color, color);
}
#endif
#if 0
WRAPPER void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha) { EAXJMP(0x4A5870); }
#else
void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha)
{
if (!CHud::m_Wants_To_Draw_Hud || TheCamera.m_WideScreenOn)
@ -1130,7 +997,6 @@ void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint8 red, uint8 gree
CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size + 1.0f), y - SCREEN_SCALE_Y(size + 1.0f), SCREEN_SCALE_X(size + 1.0f) + x, SCREEN_SCALE_Y(size + 1.0f) + y), CRGBA(0, 0, 0, alpha));
CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size), y - SCREEN_SCALE_Y(size), SCREEN_SCALE_X(size) + x, SCREEN_SCALE_Y(size) + y), CRGBA(red, green, blue, alpha));
}
#endif
void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha, uint8 mode)
{
@ -1156,9 +1022,6 @@ void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red,
}
}
#if 0
WRAPPER void CRadar::Shutdown() { EAXJMP(0x4A3F60); }
#else
void CRadar::Shutdown()
{
AsukaSprite.Delete();
@ -1183,20 +1046,12 @@ void CRadar::Shutdown()
WeaponSprite.Delete();
RemoveRadarSections();
}
#endif
#if 0
WRAPPER void CRadar::StreamRadarSections(const CVector &posn) { EAXJMP(0x4A6B60); }
#else
void CRadar::StreamRadarSections(const CVector &posn)
{
StreamRadarSections(floorf((2000.0f + posn.x) / 500.0f), ceilf(7.0f - (2000.0f + posn.y) / 500.0f));
}
#endif
#if 0
WRAPPER void CRadar::StreamRadarSections(int32 x, int32 y) { EAXJMP(0x4A6100); }
#else
void CRadar::StreamRadarSections(int32 x, int32 y)
{
for (int i = 0; i < RADAR_NUM_TILES; ++i) {
@ -1208,11 +1063,7 @@ void CRadar::StreamRadarSections(int32 x, int32 y)
};
};
}
#endif
#if 0
WRAPPER void CRadar::TransformRealWorldToTexCoordSpace(CVector2D &out, const CVector2D &in, int32 x, int32 y) { EAXJMP(0x4A5530); }
#else
void CRadar::TransformRealWorldToTexCoordSpace(CVector2D &out, const CVector2D &in, int32 x, int32 y)
{
out.x = in.x - (x * RADAR_TILE_SIZE + WORLD_MIN_X);
@ -1220,11 +1071,7 @@ void CRadar::TransformRealWorldToTexCoordSpace(CVector2D &out, const CVector2D &
out.x /= RADAR_TILE_SIZE;
out.y /= RADAR_TILE_SIZE;
}
#endif
#if 0
WRAPPER void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D &in) { EAXJMP(0x4A5300); }
#else
void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D &in)
{
float s, c;
@ -1255,19 +1102,18 @@ void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D
out = out * m_radarRange + vec2DRadarOrigin;
}
#endif
// Radar space goes from -1.0 to 1.0 in x and y, top right is (1.0, 1.0)
void CRadar::TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in)
{
// FIX? scale RADAR_LEFT here somehow
#ifdef FIX_BUGS
out.x = (in.x + 1.0f)*0.5f*SCREEN_SCALE_X(RADAR_WIDTH) + SCREEN_SCALE_X(RADAR_LEFT);
#else
out.x = (in.x + 1.0f)*0.5f*SCREEN_SCALE_X(RADAR_WIDTH) + RADAR_LEFT;
#endif
out.y = (1.0f - in.y)*0.5f*SCREEN_SCALE_Y(RADAR_HEIGHT) + SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT);
}
#if 0
WRAPPER void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in) { EAXJMP(0x4A50D0); }
#else
void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in)
{
float s, c;
@ -1299,11 +1145,7 @@ void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D
out.x = s * y + c * x;
out.y = c * y - s * x;
}
#endif
#if 0
WRAPPER void CRadar::GetTextureCorners(int32 x, int32 y, CVector2D *out) { EAXJMP(0x4A61C0); };
#else
// Transform from section indices to world coordinates
void CRadar::GetTextureCorners(int32 x, int32 y, CVector2D *out)
{
@ -1326,11 +1168,7 @@ void CRadar::GetTextureCorners(int32 x, int32 y, CVector2D *out)
out[3].x = RADAR_TILE_SIZE * (x);
out[3].y = RADAR_TILE_SIZE * (y);
}
#endif
#if 0
WRAPPER void CRadar::ClipRadarTileCoords(int32 &, int32 &) { EAXJMP(0x00); };
#else
void CRadar::ClipRadarTileCoords(int32 &x, int32 &y)
{
if (x < 0)
@ -1342,24 +1180,16 @@ void CRadar::ClipRadarTileCoords(int32 &x, int32 &y)
if (y > RADAR_NUM_TILES-1)
y = RADAR_NUM_TILES-1;
}
#endif
#if 0
WRAPPER bool CRadar::IsPointInsideRadar(const CVector2D &) { EAXJMP(0x4A6160); }
#else
bool CRadar::IsPointInsideRadar(const CVector2D &point)
{
if (point.x < -1.0f || point.x > 1.0f) return false;
if (point.y < -1.0f || point.y > 1.0f) return false;
return true;
}
#endif
// clip line p1,p2 against (-1.0, 1.0) in x and y, set out to clipped point closest to p1
#if 0
WRAPPER int CRadar::LineRadarBoxCollision(CVector2D &, const CVector2D &, const CVector2D &) { EAXJMP(0x4A6250); }
#else
int CRadar::LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D &p2)
{
float d1, d2;
@ -1430,7 +1260,6 @@ int CRadar::LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVe
return edge;
}
#endif
STARTPATCHES
InjectHook(0x4A3EF0, CRadar::Initialise, PATCH_JUMP);

View file

@ -352,7 +352,25 @@ WRAPPER bool CheckVideoCardCaps(void) { EAXJMP(0x592740); }
WRAPPER void WriteVideoCardCapsFile(void) { EAXJMP(0x5927D0); }
WRAPPER void ConvertingTexturesScreen(uint32, uint32, const char*) { EAXJMP(0x592880); }
WRAPPER void DealWithTxdWriteError(uint32, uint32, const char*) { EAXJMP(0x592BF0); }
WRAPPER bool ConvertTextures() { EAXJMP(0x592C70); }
WRAPPER bool CreateTxdImageForVideoCard() { EAXJMP(0x592C70); }
void CreateDebugFont()
{
;
}
void DestroyDebugFont()
{
;
}
void FlushObrsPrintfs()
{
;
}
WRAPPER void _TexturePoolsInitialise() { EAXJMP(0x598B10); }
WRAPPER void _TexturePoolsShutdown() { EAXJMP(0x598B30); }
STARTPATCHES
//InjectHook(0x526450, GetFirstObjectCallback, PATCH_JUMP);

View file

@ -3,6 +3,9 @@
void *RwMallocAlign(RwUInt32 size, RwUInt32 align);
void RwFreeAlign(void *mem);
void CreateDebugFont();
void DestroyDebugFont();
void FlushObrsPrintfs();
void DefinedState(void);
RwFrame *GetFirstChild(RwFrame *frame);
RwObject *GetFirstObject(RwFrame *frame);
@ -17,7 +20,7 @@ bool CheckVideoCardCaps(void);
void WriteVideoCardCapsFile(void);
void ConvertingTexturesScreen(uint32, uint32, const char*);
void DealWithTxdWriteError(uint32, uint32, const char*);
bool ConvertTextures(); // not a real name
bool CreateTxdImageForVideoCard();
bool RpClumpGtaStreamRead1(RwStream *stream);
RpClump *RpClumpGtaStreamRead2(RwStream *stream);
@ -31,3 +34,7 @@ void CameraDestroy(RwCamera *camera);
RwCamera *CameraCreate(RwInt32 width,
RwInt32 height,
RwBool zBuffer);
void _TexturePoolsInitialise();
void _TexturePoolsShutdown();

View file

@ -62,6 +62,8 @@ public:
static int32 &CarsCrushed;
static int32(&FastestTimes)[TOTAL_FASTEST_TIMES];
static int32(&HighestScores)[TOTAL_HIGHEST_SCORES];
static int32 &KgOfExplosivesUsed;
static int32 &CarsCrushed;
public:
static void RegisterFastestTime(int32, int32);

View file

@ -10,6 +10,7 @@
#include "TxdStore.h"
#include "ModelIndices.h"
#include "Pools.h"
#include "Wanted.h"
#include "Directory.h"
#include "RwHelper.h"
#include "World.h"
@ -198,7 +199,7 @@ CStreaming::Init(void)
// PC only, figure out how much memory we got
#ifdef GTA_PC
#define MB (1024*1024)
extern DWORD &_dwMemAvailPhys;
extern unsigned long &_dwMemAvailPhys;
ms_memoryAvailable = (_dwMemAvailPhys - 10*MB)/2;
if(ms_memoryAvailable < 50*MB)
ms_memoryAvailable = 50*MB;

View file

@ -75,9 +75,6 @@ void CTimer::Shutdown(void)
;
}
#if 0
WRAPPER void CTimer::Update(void) { EAXJMP(0x4ACF70); }
#else
void CTimer::Update(void)
{
m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds;
@ -149,7 +146,6 @@ void CTimer::Update(void)
m_FrameCounter++;
}
#endif
void CTimer::Suspend(void)
{
@ -218,6 +214,11 @@ void CTimer::EndUserPause(void)
m_UserPause = false;
}
uint32 CTimer::GetCyclesPerFrame()
{
return 20;
}
#if 1
STARTPATCHES
InjectHook(0x4ACE60, CTimer::Initialise, PATCH_JUMP);

View file

@ -2,7 +2,7 @@
class CTimer
{
public:
static uint32 &m_snTimeInMilliseconds;
static uint32 &m_snTimeInMillisecondsPauseMode;
static uint32 &m_snTimeInMillisecondsNonClipped;
@ -11,19 +11,20 @@ public:
static float &ms_fTimeScale;
static float &ms_fTimeStep;
static float &ms_fTimeStepNonClipped;
public:
static bool &m_UserPause;
static bool &m_CodePause;
static float GetTimeStep(void) { return ms_fTimeStep; }
static const float &GetTimeStep(void) { return ms_fTimeStep; }
static void SetTimeStep(float ts) { ms_fTimeStep = ts; }
static float GetTimeStepInSeconds() { return ms_fTimeStep / 50.0f; }
static float GetTimeStepInMilliseconds() { return ms_fTimeStep / 50.0f * 1000.0f; }
static float GetTimeStepNonClipped(void) { return ms_fTimeStepNonClipped; }
static const float &GetTimeStepNonClipped(void) { return ms_fTimeStepNonClipped; }
static float GetTimeStepNonClippedInSeconds(void) { return ms_fTimeStepNonClipped / 50.0f; }
static void SetTimeStepNonClipped(float ts) { ms_fTimeStepNonClipped = ts; }
static uint32 GetFrameCounter(void) { return m_FrameCounter; }
static const uint32 &GetFrameCounter(void) { return m_FrameCounter; }
static void SetFrameCounter(uint32 fc) { m_FrameCounter = fc; }
static uint32 GetTimeInMilliseconds(void) { return m_snTimeInMilliseconds; }
static const uint32 &GetTimeInMilliseconds(void) { return m_snTimeInMilliseconds; }
static void SetTimeInMilliseconds(uint32 t) { m_snTimeInMilliseconds = t; }
static uint32 GetTimeInMillisecondsNonClipped(void) { return m_snTimeInMillisecondsNonClipped; }
static void SetTimeInMillisecondsNonClipped(uint32 t) { m_snTimeInMillisecondsNonClipped = t; }
@ -31,8 +32,9 @@ public:
static void SetTimeInMillisecondsPauseMode(uint32 t) { m_snTimeInMillisecondsPauseMode = t; }
static uint32 GetPreviousTimeInMilliseconds(void) { return m_snPreviousTimeInMilliseconds; }
static void SetPreviousTimeInMilliseconds(uint32 t) { m_snPreviousTimeInMilliseconds = t; }
static float GetTimeScale(void) { return ms_fTimeScale; }
static const float &GetTimeScale(void) { return ms_fTimeScale; }
static void SetTimeScale(float ts) { ms_fTimeScale = ts; }
static uint32 GetCyclesPerFrame();
static bool GetIsPaused() { return m_UserPause || m_CodePause; }
static bool GetIsUserPaused() { return m_UserPause; }

View file

@ -10,7 +10,7 @@ CPool<TxdDef,TxdDef> *&CTxdStore::ms_pTxdPool = *(CPool<TxdDef,TxdDef>**)0x8F5FB
RwTexDictionary *&CTxdStore::ms_pStoredTxd = *(RwTexDictionary**)0x9405BC;
void
CTxdStore::Initialize(void)
CTxdStore::Initialise(void)
{
if(ms_pTxdPool == nil)
ms_pTxdPool = new CPool<TxdDef,TxdDef>(TXDSTORESIZE);
@ -187,7 +187,7 @@ CTxdStore::RemoveTxd(int slot)
}
STARTPATCHES
InjectHook(0x527440, CTxdStore::Initialize, PATCH_JUMP);
InjectHook(0x527440, CTxdStore::Initialise, PATCH_JUMP);
InjectHook(0x527470, CTxdStore::Shutdown, PATCH_JUMP);
InjectHook(0x527490, CTxdStore::GameShutdown, PATCH_JUMP);
InjectHook(0x5274E0, CTxdStore::AddTxdSlot, PATCH_JUMP);

View file

@ -13,7 +13,7 @@ class CTxdStore
static CPool<TxdDef,TxdDef> *&ms_pTxdPool;
static RwTexDictionary *&ms_pStoredTxd;
public:
static void Initialize(void);
static void Initialise(void);
static void Shutdown(void);
static void GameShutdown(void);
static int AddTxdSlot(const char *name);

View file

@ -7,19 +7,16 @@
#include "ZoneCull.h"
#include "Darkel.h"
#include "DMAudio.h"
#include "CopPed.h"
#include "Wanted.h"
#include "General.h"
int32 &CWanted::MaximumWantedLevel = *(int32*)0x5F7714; // 6
int32 &CWanted::nMaximumWantedLevel = *(int32*)0x5F7718; // 6400
WRAPPER void CWanted::Reset() { EAXJMP(0x4AD790) };
WRAPPER void CWanted::Update() { EAXJMP(0x4AD7B0) };
void
CWanted::Initialise()
{
int i;
m_nChaos = 0;
m_nLastUpdateTime = 0;
m_nLastWantedLevelChange = 0;
@ -34,10 +31,12 @@ CWanted::Initialise()
m_bArmyRequired = false;
m_fCrimeSensitivity = 1.0f;
m_nWantedLevel = 0;
m_CopsBeatingSuspect = 0;
for(i = 0; i < 10; i++)
m_CopsBeatingSuspect = 0;
for (int i = 0; i < ARRAY_SIZE(m_pCops); i++)
m_pCops[i] = nil;
ClearQdCrimes();
ClearQdCrimes();
}
bool
@ -61,7 +60,7 @@ CWanted::AreArmyRequired()
int32
CWanted::NumOfHelisRequired()
{
if (m_bIgnoredByCops)
if (m_bIgnoredByCops || m_bIgnoredByEveryone)
return 0;
switch (m_nWantedLevel) {
@ -79,9 +78,10 @@ CWanted::NumOfHelisRequired()
void
CWanted::SetWantedLevel(int32 level)
{
ClearQdCrimes();
if (level > MaximumWantedLevel)
level = MaximumWantedLevel;
ClearQdCrimes();
switch (level) {
case 0:
m_nChaos = 0;
@ -360,10 +360,107 @@ CWanted::WorkOutPolicePresence(CVector posn, float radius)
return numPolice;
}
void
CWanted::Update(void)
{
if (CTimer::GetTimeInMilliseconds() - m_nLastUpdateTime > 1000) {
if (m_nWantedLevel > 1) {
m_nLastUpdateTime = CTimer::GetTimeInMilliseconds();
} else {
float radius = 18.0f;
CVector playerPos = FindPlayerCoors();
if (WorkOutPolicePresence(playerPos, radius) == 0) {
m_nLastUpdateTime = CTimer::GetTimeInMilliseconds();
m_nChaos = max(0, m_nChaos - 1);
UpdateWantedLevel();
}
}
UpdateCrimesQ();
bool orderMessedUp = false;
int currCopNum = 0;
bool foundEmptySlot = false;
for (int i = 0; i < ARRAY_SIZE(m_pCops); i++) {
if (m_pCops[i]) {
++currCopNum;
if (foundEmptySlot)
orderMessedUp = true;
} else {
foundEmptySlot = true;
}
}
if (currCopNum != m_CurrentCops) {
printf("CopPursuit total messed up: re-setting\n");
m_CurrentCops = currCopNum;
}
if (orderMessedUp) {
printf("CopPursuit pointer list messed up: re-sorting\n");
bool fixed = true;
for (int i = 0; i < ARRAY_SIZE(m_pCops); i++) {
if (!m_pCops[i]) {
for (int j = i; j < ARRAY_SIZE(m_pCops); j++) {
if (m_pCops[j]) {
m_pCops[i] = m_pCops[j];
m_pCops[j] = nil;
fixed = false;
break;
}
}
if (fixed)
break;
}
}
}
}
}
void
CWanted::ResetPolicePursuit(void)
{
for(int i = 0; i < ARRAY_SIZE(m_pCops); i++) {
CCopPed *cop = m_pCops[i];
if (!cop)
continue;
cop->m_bIsInPursuit = false;
cop->m_objective = OBJECTIVE_NONE;
cop->m_prevObjective = OBJECTIVE_NONE;
cop->m_nLastPedState = PED_NONE;
if (!cop->DyingOrDead()) {
cop->SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f));
}
m_pCops[i] = nil;
}
m_CurrentCops = 0;
}
void
CWanted::Reset(void)
{
ResetPolicePursuit();
Initialise();
}
void
CWanted::UpdateCrimesQ(void)
{
for(int i = 0; i < ARRAY_SIZE(m_aCrimes); i++) {
CCrimeBeingQd &crime = m_aCrimes[i];
if (crime.m_nType != CRIME_NONE) {
if (CTimer::GetTimeInMilliseconds() > crime.m_nTime + 500 && !crime.m_bReported) {
ReportCrimeNow(crime.m_nType, crime.m_vecPosn, crime.m_bPoliceDoesntCare);
crime.m_bReported = true;
}
if (CTimer::GetTimeInMilliseconds() > crime.m_nTime + 10000)
crime.m_nType = CRIME_NONE;
}
}
}
STARTPATCHES
InjectHook(0x4AD6E0, &CWanted::Initialise, PATCH_JUMP);
// InjectHook(0x4AD790, &CWanted::Reset, PATCH_JUMP);
// InjectHook(0x4AD7B0, &CWanted::Update, PATCH_JUMP);
InjectHook(0x4AD790, &CWanted::Reset, PATCH_JUMP);
InjectHook(0x4AD7B0, &CWanted::Update, PATCH_JUMP);
InjectHook(0x4AD900, &CWanted::UpdateWantedLevel, PATCH_JUMP);
InjectHook(0x4AD9F0, &CWanted::RegisterCrime, PATCH_JUMP);
InjectHook(0x4ADA10, &CWanted::RegisterCrime_Immediately, PATCH_JUMP);
@ -374,10 +471,10 @@ STARTPATCHES
InjectHook(0x4ADBC0, &CWanted::AreFbiRequired, PATCH_JUMP);
InjectHook(0x4ADBE0, &CWanted::AreArmyRequired, PATCH_JUMP);
InjectHook(0x4ADC00, &CWanted::NumOfHelisRequired, PATCH_JUMP);
// InjectHook(0x4ADC40, &CWanted::ResetPolicePursuit, PATCH_JUMP);
InjectHook(0x4ADC40, &CWanted::ResetPolicePursuit, PATCH_JUMP);
InjectHook(0x4ADD00, &CWanted::WorkOutPolicePresence, PATCH_JUMP);
InjectHook(0x4ADF20, &CWanted::ClearQdCrimes, PATCH_JUMP);
InjectHook(0x4ADFD0, &CWanted::AddCrimeToQ, PATCH_JUMP);
// InjectHook(0x4AE090, &CWanted::UpdateCrimesQ, PATCH_JUMP);
InjectHook(0x4AE090, &CWanted::UpdateCrimesQ, PATCH_JUMP);
InjectHook(0x4AE110, &CWanted::ReportCrimeNow, PATCH_JUMP);
ENDPATCHES

View file

@ -30,7 +30,7 @@ class CCrimeBeingQd
public:
eCrimeType m_nType;
uint32 m_nId;
int32 m_nTime;
uint32 m_nTime;
CVector m_vecPosn;
bool m_bReported;
bool m_bPoliceDoesntCare;
@ -78,6 +78,8 @@ public:
void ReportCrimeNow(eCrimeType type, const CVector &coors, bool policeDoesntCare);
void UpdateWantedLevel();
void Reset();
void ResetPolicePursuit();
void UpdateCrimesQ();
void Update();
bool IsIgnored(void) { return m_bIgnoredByCops || m_bIgnoredByEveryone; }

View file

@ -19,12 +19,14 @@
#include "Messages.h"
#include "Replay.h"
#include "Population.h"
#include "Fire.h"
CColPoint *gaTempSphereColPoints = (CColPoint*)0x6E64C0; // [32]
CPtrList *CWorld::ms_bigBuildingsList = (CPtrList*)0x6FAB60;
CPtrList &CWorld::ms_listMovingEntityPtrs = *(CPtrList*)0x8F433C;
CSector (*CWorld::ms_aSectors)[NUMSECTORS_X] = (CSector (*)[NUMSECTORS_Y])0x665608;
uint16 &CWorld::ms_nCurrentScanCode = *(uint16*)0x95CC64;
CColPoint &CWorld::ms_testSpherePoint = *(CColPoint*)0x6E64C0;
uint8 &CWorld::PlayerInFocus = *(uint8 *)0x95CD61;
CPlayerInfo (&CWorld::Players)[NUMPLAYERS] = *(CPlayerInfo (*)[NUMPLAYERS])*(uintptr*)0x9412F0;
@ -38,6 +40,7 @@ bool &CWorld::bProcessCutsceneOnly = *(bool*)0x95CD8B;
bool &CWorld::bDoingCarCollisions = *(bool*)0x95CD8C;
bool &CWorld::bIncludeCarTyres = *(bool*)0x95CDAA;
WRAPPER void CWorld::ClearForRestart(void) { EAXJMP(0x4AE850); }
WRAPPER void CWorld::AddParticles(void) { EAXJMP(0x4B4010); }
WRAPPER void CWorld::ShutDown(void) { EAXJMP(0x4AE450); }
WRAPPER void CWorld::RepositionCertainDynamicObjects() { EAXJMP(0x4B42B0); }
@ -52,6 +55,7 @@ WRAPPER void CWorld::FindObjectsOfTypeInRangeSectorList(uint32, CPtrList&, CVect
WRAPPER void CWorld::FindMissionEntitiesIntersectingCube(const CVector&, const CVector&, int16*, int16, CEntity**, bool, bool, bool) { EAXJMP(0x4B3680); }
WRAPPER void CWorld::ClearCarsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B50E0); }
WRAPPER void CWorld::ClearPedsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B52B0); }
WRAPPER void CWorld::CallOffChaseForArea(float, float, float, float) { EAXJMP(0x4B5530); }
void
CWorld::Initialise()
@ -609,9 +613,9 @@ CWorld::GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bo
}
void
CWorld::FindObjectsInRangeSectorList(CPtrList &list, CVector &centre, float distance, bool ignoreZ, short *nextObject, short lastObject, CEntity **objects)
CWorld::FindObjectsInRangeSectorList(CPtrList &list, CVector &centre, float radius, bool ignoreZ, short *nextObject, short lastObject, CEntity **objects)
{
float distSqr = distance * distance;
float radiusSqr = radius * radius;
float objDistSqr;
for (CPtrNode *node = list.first; node; node = node->next) {
@ -625,7 +629,7 @@ CWorld::FindObjectsInRangeSectorList(CPtrList &list, CVector &centre, float dist
else
objDistSqr = diff.MagnitudeSqr();
if (objDistSqr < distSqr && *nextObject < lastObject) {
if (objDistSqr < radiusSqr && *nextObject < lastObject) {
if (objects) {
objects[*nextObject] = object;
}
@ -636,22 +640,22 @@ CWorld::FindObjectsInRangeSectorList(CPtrList &list, CVector &centre, float dist
}
void
CWorld::FindObjectsInRange(CVector &centre, float distance, bool ignoreZ, short *nextObject, short lastObject, CEntity **objects, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies)
CWorld::FindObjectsInRange(CVector &centre, float radius, bool ignoreZ, short *nextObject, short lastObject, CEntity **objects, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies)
{
int minX = GetSectorIndexX(centre.x - distance);
int minX = GetSectorIndexX(centre.x - radius);
if (minX <= 0) minX = 0;
int minY = GetSectorIndexY(centre.y - distance);
int minY = GetSectorIndexY(centre.y - radius);
if (minY <= 0) minY = 0;
int maxX = GetSectorIndexX(centre.x + distance);
int maxX = GetSectorIndexX(centre.x + radius);
#ifdef FIX_BUGS
if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
#else
if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X;
#endif
int maxY = GetSectorIndexY(centre.y + distance);
int maxY = GetSectorIndexY(centre.y + radius);
#ifdef FIX_BUGS
if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
#else
@ -665,48 +669,48 @@ CWorld::FindObjectsInRange(CVector &centre, float distance, bool ignoreZ, short
for(int curX = minX; curX <= maxX; curX++) {
CSector *sector = GetSector(curX, curY);
if (checkBuildings) {
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS], centre, distance, ignoreZ, nextObject, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS], centre, radius, ignoreZ, nextObject, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], centre, radius, ignoreZ, nextObject, lastObject, objects);
}
if (checkVehicles) {
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES], centre, distance, ignoreZ, nextObject, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES], centre, radius, ignoreZ, nextObject, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], centre, radius, ignoreZ, nextObject, lastObject, objects);
}
if (checkPeds) {
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS], centre, distance, ignoreZ, nextObject, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS], centre, radius, ignoreZ, nextObject, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_PEDS_OVERLAP], centre, radius, ignoreZ, nextObject, lastObject, objects);
}
if (checkObjects) {
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS], centre, distance, ignoreZ, nextObject, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS], centre, radius, ignoreZ, nextObject, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], centre, radius, ignoreZ, nextObject, lastObject, objects);
}
if (checkDummies) {
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES], centre, distance, ignoreZ, nextObject, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], centre, distance, ignoreZ, nextObject, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES], centre, radius, ignoreZ, nextObject, lastObject, objects);
FindObjectsInRangeSectorList(sector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], centre, radius, ignoreZ, nextObject, lastObject, objects);
}
}
}
}
CEntity*
CWorld::TestSphereAgainstWorld(CVector centre, float distance, CEntity *entityToIgnore, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSomeObjects)
CWorld::TestSphereAgainstWorld(CVector centre, float radius, CEntity *entityToIgnore, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSomeObjects)
{
CEntity* foundE = nil;
int minX = GetSectorIndexX(centre.x - distance);
int minX = GetSectorIndexX(centre.x - radius);
if (minX <= 0) minX = 0;
int minY = GetSectorIndexY(centre.y - distance);
int minY = GetSectorIndexY(centre.y - radius);
if (minY <= 0) minY = 0;
int maxX = GetSectorIndexX(centre.x + distance);
int maxX = GetSectorIndexX(centre.x + radius);
#ifdef FIX_BUGS
if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
#else
if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X;
#endif
int maxY = GetSectorIndexY(centre.y + distance);
int maxY = GetSectorIndexY(centre.y + radius);
#ifdef FIX_BUGS
if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
#else
@ -719,47 +723,47 @@ CWorld::TestSphereAgainstWorld(CVector centre, float distance, CEntity *entityTo
for (int curX = minX; curX <= maxX; curX++) {
CSector* sector = GetSector(curX, curY);
if (checkBuildings) {
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_BUILDINGS], centre, distance, entityToIgnore, false);
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_BUILDINGS], centre, radius, entityToIgnore, false);
if (foundE)
return foundE;
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], centre, distance, entityToIgnore, false);
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], centre, radius, entityToIgnore, false);
if (foundE)
return foundE;
}
if (checkVehicles) {
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_VEHICLES], centre, distance, entityToIgnore, false);
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_VEHICLES], centre, radius, entityToIgnore, false);
if (foundE)
return foundE;
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], centre, distance, entityToIgnore, false);
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], centre, radius, entityToIgnore, false);
if (foundE)
return foundE;
}
if (checkPeds) {
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_PEDS], centre, distance, entityToIgnore, false);
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_PEDS], centre, radius, entityToIgnore, false);
if (foundE)
return foundE;
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_PEDS_OVERLAP], centre, distance, entityToIgnore, false);
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_PEDS_OVERLAP], centre, radius, entityToIgnore, false);
if (foundE)
return foundE;
}
if (checkObjects) {
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_OBJECTS], centre, distance, entityToIgnore, ignoreSomeObjects);
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_OBJECTS], centre, radius, entityToIgnore, ignoreSomeObjects);
if (foundE)
return foundE;
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], centre, distance, entityToIgnore, ignoreSomeObjects);
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], centre, radius, entityToIgnore, ignoreSomeObjects);
if (foundE)
return foundE;
}
if (checkDummies) {
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_DUMMIES], centre, distance, entityToIgnore, false);
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_DUMMIES], centre, radius, entityToIgnore, false);
if (foundE)
return foundE;
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], centre, distance, entityToIgnore, false);
foundE = TestSphereAgainstSectorList(sector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], centre, radius, entityToIgnore, false);
if (foundE)
return foundE;
}
@ -806,7 +810,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
if (e->GetBoundRadius() + radius > distance) {
CColModel *eCol = CModelInfo::GetModelInfo(e->m_modelIndex)->GetColModel();
int collidedSpheres = CCollision::ProcessColModels(sphereMat, sphereCol, e->GetMatrix(),
*eCol, &ms_testSpherePoint, nil, nil);
*eCol, gaTempSphereColPoints, nil, nil);
if (collidedSpheres != 0 ||
(e->IsVehicle() && ((CVehicle*)e)->m_vehType == VEHICLE_TYPE_CAR &&
@ -1050,6 +1054,19 @@ CWorld::ExtinguishAllCarFiresInArea(CVector point, float range)
}
}
void
CWorld::SetCarsOnFire(float x, float y, float z, float radius, CEntity *reason)
{
int poolSize = CPools::GetVehiclePool()->GetSize();
for (int poolIndex = poolSize - 1; poolIndex >= 0; poolIndex--) {
CVehicle *veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
if (veh && veh->m_status != STATUS_WRECKED && !veh->m_pCarFire && !veh->bFireProof) {
if (Abs(veh->GetPosition().z - z) < 5.0f && Abs(veh->GetPosition().x - x) < radius && Abs(veh->GetPosition().y - y) < radius)
gFireManager.StartFire(veh, reason, 0.8f, true);
}
}
}
void
CWorld::Process(void)
{

View file

@ -60,8 +60,6 @@ class CWorld
static uint16 &ms_nCurrentScanCode;
public:
static CColPoint& ms_testSpherePoint;
static uint8 &PlayerInFocus;
static CPlayerInfo (&Players)[NUMPLAYERS];
static CEntity *&pIgnoreEntity;
@ -101,7 +99,7 @@ public:
static bool GetIsLineOfSightSectorClear(CSector &sector, const CColLine &line, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
static bool GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
static CEntity *TestSphereAgainstWorld(CVector centre, float distance, CEntity *entityToIgnore, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSomeObjects);
static CEntity *TestSphereAgainstWorld(CVector centre, float radius, CEntity *entityToIgnore, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSomeObjects);
static CEntity *TestSphereAgainstSectorList(CPtrList&, CVector, float, CEntity*, bool);
static void FindObjectsInRangeSectorList(CPtrList&, CVector&, float, bool, short*, short, CEntity**);
static void FindObjectsInRange(CVector&, float, bool, short*, short, CEntity**, bool, bool, bool, bool, bool);
@ -117,6 +115,7 @@ public:
static void FindMissionEntitiesIntersectingCube(const CVector&, const CVector&, int16*, int16, CEntity**, bool, bool, bool);
static void ClearCarsFromArea(float, float, float, float, float, float);
static void ClearPedsFromArea(float, float, float, float, float, float);
static void CallOffChaseForArea(float, float, float, float);
static float GetSectorX(float f) { return ((f - WORLD_MIN_X)/SECTOR_SIZE_X); }
static float GetSectorY(float f) { return ((f - WORLD_MIN_Y)/SECTOR_SIZE_Y); }
@ -132,15 +131,19 @@ public:
static void StopAllLawEnforcersInTheirTracks();
static void SetAllCarsCanBeDamaged(bool);
static void ExtinguishAllCarFiresInArea(CVector, float);
static void SetCarsOnFire(float, float, float, float, CEntity*);
static void Initialise();
static void AddParticles();
static void ShutDown();
static void ClearForRestart(void);
static void RepositionCertainDynamicObjects();
static void RemoveStaticObjects();
static void Process();
};
extern CColPoint *gaTempSphereColPoints;
class CPlayerPed;
class CVehicle;
CPlayerPed *FindPlayerPed(void);

View file

@ -1,5 +1,6 @@
#include "common.h"
#include "patcher.h"
#include <ctype.h>
#include "Zones.h"

View file

@ -8,9 +8,12 @@
#pragma warning(disable: 4996) // POSIX names
#include <stdint.h>
#include <string.h>
#include <math.h>
//#include <assert.h>
#include <new>
#ifdef WITHWINDOWS
#include <Windows.h>
#endif
#ifdef WITHD3D
#include <windows.h>
@ -30,6 +33,16 @@
#undef near
#endif
#ifndef max
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif
#ifndef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#endif
#ifndef ARRAYSIZE
#define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a)))
#endif
typedef uint8_t uint8;
typedef int8_t int8;
typedef uint16_t uint16;
@ -202,6 +215,7 @@ void re3_assert(const char *expr, const char *filename, unsigned int lineno, con
#define ABS(a) (((a) < 0) ? (-(a)) : (a))
#define norm(value, min, max) (((value) < (min)) ? 0 : (((value) > (max)) ? 1 : (((value) - (min)) / ((max) - (min)))))
#define lerp(norm, min, max) ( (norm) * ((max) - (min)) + (min) )
#define STRINGIFY(x) #x
#define STR(x) STRINGIFY(x)

View file

@ -94,12 +94,17 @@ enum Config {
NUM_GARAGES = 32,
NUM_PROJECTILES = 32,
NUM_GLASSPANES = 45,
NUM_GLASSENTITIES = 32,
NUM_WATERCANNONS = 3,
NUMPEDROUTES = 200,
NUMPHONES = 50,
NUMPEDGROUPS = 31,
NUMMODELSPERPEDGROUP = 8,
NUMSHOTINFOS = 100,
NUMROADBLOCKS = 600,
NUMVISIBLEENTITIES = 2000,
NUMINVISIBLEENTITIES = 150,
@ -114,6 +119,8 @@ enum Config {
NUM_AUDIO_REFLECTIONS = 5,
NUM_SCRIPT_MAX_ENTITIES = 40,
NUM_GARAGE_STORED_CARS = 6
};
// We'll use this once we're ready to become independent of the game
@ -164,15 +171,19 @@ enum Config {
// not in any game
# define NASTY_GAME // nasty game for all languages
# define NO_MOVIES // disable intro videos
# define NO_CDCHECK
# define NO_CDCHECK
# define CHATTYSPLASH // print what the game is loading
//# define TIMEBARS // print debug timers
#endif
#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more
#define TOGGLEABLE_BETA_FEATURES // toggleable from debug menu. doesn't have too many things
#define TOGGLEABLE_BETA_FEATURES // toggleable from debug menu. not too many things
#define MORE_LANGUAGES // Add more translations to the game
// Pad
#define XINPUT
#define KANGAROO_CHEAT
#define REGISTER_START_BUTTON // currently only in menu sadly. resumes the game
// Hud, frontend and radar
#define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios
@ -199,5 +210,9 @@ enum Config {
// Peds
#define ANIMATE_PED_COL_MODEL
#define VC_PED_PORTS // various ports from VC's CPed, mostly subtle
#define NEW_WALK_AROUND_ALGORITHM // to make walking around vehicles/objects less awkward
// #define NEW_WALK_AROUND_ALGORITHM // to make walking around vehicles/objects less awkward
#define CANCELLABLE_CAR_ENTER
// Camera
#define IMPROVED_CAMERA // Better Debug cam, and maybe more in the future
#define FREE_CAM // Rotating cam

View file

@ -51,6 +51,7 @@
#include "Script.h"
#include "Debug.h"
#include "Console.h"
#include "timebars.h"
#define DEFAULT_VIEWWINDOW (Tan(DEGTORAD(CDraw::GetFOV() * 0.5f)))
@ -90,7 +91,6 @@ void DoFade(void);
void Render2dStuffAfterFade(void);
CSprite2d *LoadSplash(const char *name);
void DestroySplashScreen(void);
extern void (*DebugMenuProcess)(void);
@ -142,6 +142,11 @@ Idle(void *arg)
#endif
CTimer::Update();
#ifdef TIMEBARS
tbInit();
#endif
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
@ -156,16 +161,39 @@ Idle(void *arg)
FrontEndMenuManager.Process();
} else {
CPointLights::InitPerFrame();
#ifdef TIMEBARS
tbStartTimer(0, "CGame::Process");
#endif
CGame::Process();
#ifdef TIMEBARS
tbEndTimer("CGame::Process");
tbStartTimer(0, "DMAudio.Service");
#endif
DMAudio.Service();
#ifdef TIMEBARS
tbEndTimer("DMAudio.Service");
#endif
}
if (RsGlobal.quit)
return;
#else
CPointLights::InitPerFrame();
#ifdef TIMEBARS
tbStartTimer(0, "CGame::Process");
#endif
CGame::Process();
#ifdef TIMEBARS
tbEndTimer("CGame::Process");
tbStartTimer(0, "DMAudio.Service");
#endif
DMAudio.Service();
#ifdef TIMEBARS
tbEndTimer("DMAudio.Service");
#endif
#endif
if(CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()){
@ -192,9 +220,19 @@ Idle(void *arg)
pos.y = SCREEN_HEIGHT / 2.0f;
RsMouseSetPos(&pos);
}
#endif
#ifdef TIMEBARS
tbStartTimer(0, "CnstrRenderList");
#endif
CRenderer::ConstructRenderList();
#ifdef TIMEBARS
tbEndTimer("CnstrRenderList");
tbStartTimer(0, "PreRender");
#endif
CRenderer::PreRender();
#ifdef TIMEBARS
tbEndTimer("PreRender");
#endif
if(CWeather::LightningFlash && !CCullZones::CamNoRain()){
if(!DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255))
@ -212,16 +250,31 @@ Idle(void *arg)
RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip());
RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart());
#ifdef TIMEBARS
tbStartTimer(0, "RenderScene");
#endif
RenderScene();
#ifdef TIMEBARS
tbEndTimer("RenderScene");
#endif
RenderDebugShit();
RenderEffects();
#ifdef TIMEBARS
tbStartTimer(0, "RenderMotionBlur");
#endif
if((TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_NORMAL) &&
TheCamera.m_ScreenReductionPercentage > 0.0f)
TheCamera.SetMotionBlurAlpha(150);
TheCamera.RenderMotionBlur();
#ifdef TIMEBARS
tbEndTimer("RenderMotionBlur");
tbStartTimer(0, "Render2dStuff");
#endif
Render2dStuff();
#ifdef TIMEBARS
tbEndTimer("Render2dStuff");
#endif
}else{
float viewWindow = DEFAULT_VIEWWINDOW;
#ifdef ASPECT_RATIO_SCALE
@ -238,11 +291,30 @@ Idle(void *arg)
#ifdef PS2_SAVE_DIALOG
if (FrontEndMenuManager.m_bMenuActive)
DefinedState();
#endif
#ifdef TIMEBARS
tbStartTimer(0, "RenderMenus");
#endif
RenderMenus();
#ifdef TIMEBARS
tbEndTimer("RenderMenus");
tbStartTimer(0, "DoFade");
#endif
DoFade();
#ifdef TIMEBARS
tbEndTimer("DoFade");
tbStartTimer(0, "Render2dStuff-Fade");
#endif
Render2dStuffAfterFade();
#ifdef TIMEBARS
tbEndTimer("Render2dStuff-Fade");
#endif
CCredits::Render();
#ifdef TIMEBARS
tbDisplay();
#endif
DoRWStuffEndOfFrame();
// if(g_SlowMode)
@ -325,8 +397,9 @@ DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16
void
DoRWStuffEndOfFrame(void)
{
CDebug::DisplayScreenStrings(); // custom
CDebug::DebugDisplayTextBuffer();
// FlushObrsPrintfs();
FlushObrsPrintfs();
RwCameraEndUpdate(Scene.camera);
RsCameraShowRaster(Scene.camera);
}

View file

@ -28,6 +28,7 @@ void InitialiseGame(void);
void LoadingScreen(const char *str1, const char *str2, const char *splashscreen);
void LoadingIslandScreen(const char *levelName);
CSprite2d *LoadSplash(const char *name);
void DestroySplashScreen(void);
char *GetLevelSplashScreen(int level);
char *GetRandomSplashScreen(void);
void LittleTest(void);

119
src/core/obrstr.cpp Normal file
View file

@ -0,0 +1,119 @@
#include "common.h"
#include "Debug.h"
#include "obrstr.h"
char obrstr[128];
char obrstr2[128];
void ObrInt(int32 n1)
{
IntToStr(n1, obrstr);
CDebug::DebugAddText(obrstr);
}
void ObrInt2(int32 n1, int32 n2)
{
IntToStr(n1, obrstr);
strcat(obrstr, " ");
IntToStr(n2, obrstr2);
strcat(obrstr, obrstr2);
CDebug::DebugAddText(obrstr);
}
void ObrInt3(int32 n1, int32 n2, int32 n3)
{
IntToStr(n1, obrstr);
strcat(obrstr, " ");
IntToStr(n2, obrstr2);
strcat(obrstr, obrstr2);
strcat(obrstr, " ");
IntToStr(n3, obrstr2);
strcat(obrstr, obrstr2);
CDebug::DebugAddText(obrstr);
}
void ObrInt4(int32 n1, int32 n2, int32 n3, int32 n4)
{
IntToStr(n1, obrstr);
strcat(obrstr, " ");
IntToStr(n2, obrstr2);
strcat(obrstr, obrstr2);
strcat(obrstr, " ");
IntToStr(n3, obrstr2);
strcat(obrstr, obrstr2);
strcat(obrstr, " ");
IntToStr(n4, obrstr2);
strcat(obrstr, obrstr2);
CDebug::DebugAddText(obrstr);
}
void ObrInt5(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5)
{
IntToStr(n1, obrstr);
strcat(obrstr, " ");
IntToStr(n2, obrstr2);
strcat(obrstr, obrstr2);
strcat(obrstr, " ");
IntToStr(n3, obrstr2);
strcat(obrstr, obrstr2);
strcat(obrstr, " ");
IntToStr(n4, obrstr2);
strcat(obrstr, obrstr2);
strcat(obrstr, " ");
IntToStr(n5, obrstr2);
strcat(obrstr, obrstr2);
CDebug::DebugAddText(obrstr);
}
void ObrInt6(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6)
{
IntToStr(n1, obrstr);
strcat(obrstr, " ");
IntToStr(n2, obrstr2);
strcat(obrstr, obrstr2);
strcat(obrstr, " ");
IntToStr(n3, obrstr2);
strcat(obrstr, obrstr2);
strcat(obrstr, " ");
IntToStr(n4, obrstr2);
strcat(obrstr, obrstr2);
strcat(obrstr, " ");
IntToStr(n5, obrstr2);
strcat(obrstr, obrstr2);
strcat(obrstr, " ");
IntToStr(n6, obrstr2);
strcat(obrstr, obrstr2);
CDebug::DebugAddText(obrstr);
}
void IntToStr(int32 inNum, char *outStr)
{
bool isNeg = inNum < 0;
if (isNeg) {
inNum = -inNum;
*outStr = '-';
}
int16 digits = 1;
if (inNum > 9) {
int32 _inNum = inNum;
do {
digits++;
_inNum /= 10;
} while (_inNum > 9);
}
int32 strSize = digits;
if (isNeg)
strSize++;
char *pStr = &outStr[strSize];
int32 i = 0;
do {
*(pStr-- - 1) = (inNum % 10) + '0';
inNum /= 10;
} while (++i < strSize);
outStr[strSize] = '\0';
}

9
src/core/obrstr.h Normal file
View file

@ -0,0 +1,9 @@
#pragma once
void ObrInt(int32 n1);
void ObrInt2(int32 n1, int32 n2);
void ObrInt3(int32 n1, int32 n2, int32 n3);
void ObrInt4(int32 n1, int32 n2, int32 n3, int32 n4);
void ObrInt5(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5);
void ObrInt6(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6);
void IntToStr(int32 inNum, char *outStr);

View file

@ -1,6 +1,11 @@
#include "common.h"
#include "patcher.h"
#include <algorithm>
#include <vector>
#include <Windows.h>
StaticPatcher *StaticPatcher::ms_head;
StaticPatcher::StaticPatcher(Patcher func)
@ -20,3 +25,55 @@ StaticPatcher::Apply()
}
ms_head = nil;
}
std::vector<uint32> usedAddresses;
static DWORD protect[2];
static uint32 protect_address;
static uint32 protect_size;
void
Protect_internal(uint32 address, uint32 size)
{
protect_address = address;
protect_size = size;
VirtualProtect((void*)address, size, PAGE_EXECUTE_READWRITE, &protect[0]);
}
void
Unprotect_internal(void)
{
VirtualProtect((void*)protect_address, protect_size, protect[0], &protect[1]);
}
void
InjectHook_internal(uint32 address, uint32 hook, int type)
{
if(std::any_of(usedAddresses.begin(), usedAddresses.end(),
[address](uint32 value) { return value == address; })) {
debug("Used address %#06x twice when injecting hook\n", address);
}
usedAddresses.push_back(address);
switch(type){
case PATCH_JUMP:
VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &protect[0]);
*(uint8*)address = 0xE9;
break;
case PATCH_CALL:
VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &protect[0]);
*(uint8*)address = 0xE8;
break;
default:
VirtualProtect((void*)(address + 1), 4, PAGE_EXECUTE_READWRITE, &protect[0]);
break;
}
*(ptrdiff_t*)(address + 1) = hook - address - 5;
if(type == PATCH_NOTHING)
VirtualProtect((void*)(address + 1), 4, protect[0], &protect[1]);
else
VirtualProtect((void*)address, 5, protect[0], &protect[1]);
}

View file

@ -6,13 +6,7 @@
#define VARJMP(a) { _asm jmp a }
#define WRAPARG(a) UNREFERENCED_PARAMETER(a)
#define NOVMT __declspec(novtable)
#define SETVMT(a) *((DWORD_PTR*)this) = (DWORD_PTR)a
#include <algorithm>
#include <vector>
#include "common.h"
#include <string.h> //memset
enum
{
@ -103,72 +97,30 @@ isVC(void)
InjectHook(a, func); \
}
void InjectHook_internal(uint32 address, uint32 hook, int type);
void Protect_internal(uint32 address, uint32 size);
void Unprotect_internal(void);
template<typename T, typename AT> inline void
Patch(AT address, T value)
{
DWORD dwProtect[2];
VirtualProtect((void*)address, sizeof(T), PAGE_EXECUTE_READWRITE, &dwProtect[0]);
Protect_internal((uint32)address, sizeof(T));
*(T*)address = value;
VirtualProtect((void*)address, sizeof(T), dwProtect[0], &dwProtect[1]);
Unprotect_internal();
}
template<typename AT> inline void
Nop(AT address, unsigned int nCount)
{
DWORD dwProtect[2];
VirtualProtect((void*)address, nCount, PAGE_EXECUTE_READWRITE, &dwProtect[0]);
Protect_internal((uint32)address, nCount);
memset((void*)address, 0x90, nCount);
VirtualProtect((void*)address, nCount, dwProtect[0], &dwProtect[1]);
Unprotect_internal();
}
template<typename AT> inline void
ClearCC(AT address, unsigned int nCount)
template <typename T> inline void
InjectHook(uintptr_t address, T hook, unsigned int nType = PATCH_NOTHING)
{
DWORD dwProtect[2];
VirtualProtect((void*)address, nCount, PAGE_EXECUTE_READWRITE, &dwProtect[0]);
memset((void*)address, 0xCC, nCount);
VirtualProtect((void*)address, nCount, dwProtect[0], &dwProtect[1]);
}
extern std::vector<int32> usedAddresses;
template<typename AT, typename HT> inline void
InjectHook(AT address, HT hook, unsigned int nType=PATCH_NOTHING)
{
if(std::any_of(usedAddresses.begin(), usedAddresses.end(),
[address](AT value) { return (int32)value == address; })) {
debug("Used address %#06x twice when injecting hook\n", address);
}
usedAddresses.push_back((int32)address);
DWORD dwProtect[2];
switch ( nType )
{
case PATCH_JUMP:
VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &dwProtect[0]);
*(BYTE*)address = 0xE9;
break;
case PATCH_CALL:
VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &dwProtect[0]);
*(BYTE*)address = 0xE8;
break;
default:
VirtualProtect((void*)((DWORD)address + 1), 4, PAGE_EXECUTE_READWRITE, &dwProtect[0]);
break;
}
DWORD dwHook;
_asm
{
mov eax, hook
mov dwHook, eax
}
*(ptrdiff_t*)((DWORD)address + 1) = (DWORD)dwHook - (DWORD)address - 5;
if ( nType == PATCH_NOTHING )
VirtualProtect((void*)((DWORD)address + 1), 4, dwProtect[0], &dwProtect[1]);
else
VirtualProtect((void*)address, 5, dwProtect[0], &dwProtect[1]);
InjectHook_internal(address, reinterpret_cast<uintptr_t>((void *&)hook), nType);
}
inline void ExtractCall(void *dst, uint32_t a)

View file

@ -20,12 +20,10 @@
#include "debugmenu_public.h"
#include "Particle.h"
#include "Console.h"
#include "Debug.h"
#include <vector>
#include <list>
std::vector<int32> usedAddresses;
void **rwengine = *(void***)0x5A10E1;
DebugMenuAPI gDebugMenuAPI;
@ -114,13 +112,16 @@ SpawnCar(int id)
CStreaming::LoadAllRequestedModels(false);
if(CStreaming::HasModelLoaded(id)){
playerpos = FindPlayerCoors();
int node = ThePaths.FindNodeClosestToCoors(playerpos, 0, 100.0f, false, false);
if(node < 0)
return;
int node;
if(!CModelInfo::IsBoatModel(id)){
node = ThePaths.FindNodeClosestToCoors(playerpos, 0, 100.0f, false, false);
if(node < 0)
return;
}
CVehicle *v;
if(CModelInfo::IsBoatModel(id))
return;
v = new CBoat(id, RANDOM_VEHICLE);
else
v = new CAutomobile(id, RANDOM_VEHICLE);
@ -130,7 +131,11 @@ SpawnCar(int id)
if(carCol2)
DebugMenuEntrySetAddress(carCol2, &v->m_currentColour2);
v->GetPosition() = ThePaths.m_pathNodes[node].pos;
if(CModelInfo::IsBoatModel(id))
v->GetPosition() = TheCamera.GetPosition() + TheCamera.GetForward()*15.0f;
else
v->GetPosition() = ThePaths.m_pathNodes[node].pos;
v->GetPosition().z += 4.0f;
v->SetOrientation(0.0f, 0.0f, 3.49f);
v->m_status = STATUS_ABANDONED;
@ -197,6 +202,12 @@ PlaceOnRoad(void)
((CAutomobile*)veh)->PlaceOnRoadProperly();
}
static void
ResetCamStatics(void)
{
TheCamera.Cams[TheCamera.ActiveCam].ResetStatics = true;
}
static const char *carnames[] = {
"landstal", "idaho", "stinger", "linerun", "peren", "sentinel", "patriot", "firetruk", "trash", "stretch", "manana", "infernus", "blista", "pony",
"mule", "cheetah", "ambulan", "fbicar", "moonbeam", "esperant", "taxi", "kuruma", "bobcat", "mrwhoop", "bfinject", "corpse", "police", "enforcer",
@ -359,6 +370,20 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);
DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop);
extern bool PrintDebugCode;
extern int16 &DebugCamMode;
DebugMenuAddVarBool8("Cam", "Use mouse Cam", (int8*)&CCamera::m_bUseMouse3rdPerson, nil);
#ifdef FREE_CAM
DebugMenuAddVarBool8("Cam", "Free Cam", (int8*)&CCamera::bFreeCam, nil);
#endif
DebugMenuAddVarBool8("Cam", "Print Debug Code", (int8*)&PrintDebugCode, nil);
DebugMenuAddVar("Cam", "Cam Mode", &DebugCamMode, nil, 1, 0, CCam::MODE_EDITOR, nil);
DebugMenuAddCmd("Cam", "Normal", []() { DebugCamMode = 0; });
DebugMenuAddCmd("Cam", "Follow Ped With Bind", []() { DebugCamMode = CCam::MODE_FOLLOW_PED_WITH_BIND; });
DebugMenuAddCmd("Cam", "Reaction", []() { DebugCamMode = CCam::MODE_REACTION; });
DebugMenuAddCmd("Cam", "Chris", []() { DebugCamMode = CCam::MODE_CHRIS; });
DebugMenuAddCmd("Cam", "Reset Statics", ResetCamStatics);
CTweakVars::AddDBG("Debug");
}
}
@ -433,7 +458,8 @@ void re3_debug(const char *format, ...)
vsprintf_s(re3_buff, re3_buffsize, format, va);
va_end(va);
printf("%s", re3_buff);
// printf("%s", re3_buff);
CDebug::DebugAddText(re3_buff);
}
void re3_trace(const char *filename, unsigned int lineno, const char *func, const char *format, ...)

121
src/core/timebars.cpp Normal file
View file

@ -0,0 +1,121 @@
#ifndef MASTER
#include "common.h"
#include "Font.h"
#include "Frontend.h"
#include "Timer.h"
#include "Text.h"
#define MAX_TIMERS (50)
#define MAX_MS_COLLECTED (40)
// enables frame time output
#define FRAMETIME
struct sTimeBar
{
char name[20];
float startTime;
float endTime;
int32 unk;
};
struct
{
sTimeBar Timers[MAX_TIMERS];
uint32 count;
} TimerBar;
float MaxTimes[MAX_TIMERS];
float MaxFrameTime;
uint32 curMS;
uint32 msCollected[MAX_MS_COLLECTED];
#ifdef FRAMETIME
float FrameInitTime;
#endif
void tbInit()
{
TimerBar.count = 0;
uint32 i = CTimer::GetFrameCounter() & 0x7F;
if (i == 0) {
do
MaxTimes[i++] = 0.0f;
while (i != MAX_TIMERS);
#ifdef FRAMETIME
MaxFrameTime = 0.0f;
#endif
}
#ifdef FRAMETIME
FrameInitTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
#endif
}
void tbStartTimer(int32 unk, char *name)
{
strcpy(TimerBar.Timers[TimerBar.count].name, name);
TimerBar.Timers[TimerBar.count].unk = unk;
TimerBar.Timers[TimerBar.count].startTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
TimerBar.count++;
}
void tbEndTimer(char* name)
{
uint32 n = 1500;
for (uint32 i = 0; i < TimerBar.count; i++) {
if (strcmp(name, TimerBar.Timers[i].name) == 0)
n = i;
}
assert(n != 1500);
TimerBar.Timers[n].endTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
}
float Diag_GetFPS()
{
return 39000.0f / (msCollected[(curMS - 1) % MAX_MS_COLLECTED] - msCollected[curMS % MAX_MS_COLLECTED]);
}
void tbDisplay()
{
char temp[200];
wchar wtemp[200];
#ifdef FRAMETIME
float FrameEndTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
#endif
msCollected[(curMS++) % MAX_MS_COLLECTED] = RsTimer();
CFont::SetBackgroundOff();
CFont::SetBackgroundColor(CRGBA(0, 0, 0, 128));
CFont::SetScale(0.48f, 1.12f);
CFont::SetCentreOff();
CFont::SetJustifyOff();
CFont::SetWrapx(640.0f);
CFont::SetRightJustifyOff();
CFont::SetPropOn();
CFont::SetFontStyle(FONT_BANK);
sprintf(temp, "FPS: %.2f", Diag_GetFPS());
AsciiToUnicode(temp, wtemp);
CFont::SetColor(CRGBA(255, 255, 255, 255));
if (!CMenuManager::m_PrefsMarketing || !CMenuManager::m_PrefsDisableTutorials) {
CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * (4.0f / DEFAULT_SCREEN_HEIGHT), wtemp);
#ifndef FINAL
// Timers output (my own implementation)
for (uint32 i = 0; i < TimerBar.count; i++) {
MaxTimes[i] = max(MaxTimes[i], TimerBar.Timers[i].endTime - TimerBar.Timers[i].startTime);
sprintf(temp, "%s: %.2f", &TimerBar.Timers[i].name[0], MaxTimes[i]);
AsciiToUnicode(temp, wtemp);
CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * ((8.0f * (i + 2)) / DEFAULT_SCREEN_HEIGHT), wtemp);
}
#ifdef FRAMETIME
MaxFrameTime = max(MaxFrameTime, FrameEndTime - FrameInitTime);
sprintf(temp, "Frame Time: %.2f", MaxFrameTime);
AsciiToUnicode(temp, wtemp);
CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * ((8.0f * (TimerBar.count + 4)) / DEFAULT_SCREEN_HEIGHT), wtemp);
#endif // FRAMETIME
#endif // !FINAL
}
}
#endif // !MASTER

6
src/core/timebars.h Normal file
View file

@ -0,0 +1,6 @@
#pragma once
void tbInit();
void tbStartTimer(int32, char*);
void tbEndTimer(char*);
void tbDisplay();

View file

@ -21,6 +21,8 @@ CBuilding::ReplaceWithNewModel(int32 id)
CStreaming::RequestModel(id, STREAMFLAGS_DONT_REMOVE);
}
#include <new>
class CBuilding_ : public CBuilding
{
public:

View file

@ -865,6 +865,8 @@ CEntity::ModifyMatrixForBannerInWind(void)
UpdateRwFrame();
}
#include <new>
class CEntity_ : public CEntity
{
public:

View file

@ -39,6 +39,14 @@ public:
x = 1.0f;
}
void Normalise(float norm) {
float sq = MagnitudeSqr();
float invsqrt = RecipSqrt(norm, sq);
x *= invsqrt;
y *= invsqrt;
z *= invsqrt;
}
const CVector &operator+=(CVector const &right) {
x += right.x;
y += right.y;

View file

@ -1113,6 +1113,8 @@ public:
};
STARTPATCHES
InjectHook(0x427820, &CVehicleModelInfo::SetComponentsToUse, PATCH_JUMP);
InjectHook(0x51FDC0, &CVehicleModelInfo_::DeleteRwObject_, PATCH_JUMP);
InjectHook(0x51FCB0, &CVehicleModelInfo_::CreateInstance_, PATCH_JUMP);
InjectHook(0x51FC60, &CVehicleModelInfo_::SetClump_, PATCH_JUMP);

View file

@ -132,5 +132,6 @@ public:
static void ShutdownEnvironmentMaps(void);
static int GetMaximumNumberOfPassengersFromNumberOfDoors(int id);
static void SetComponentsToUse(int8 c1, int8 c2) { ms_compsToUse[0] = c1; ms_compsToUse[1] = c2; }
};
static_assert(sizeof(CVehicleModelInfo) == 0x1F8, "CVehicleModelInfo: error");

View file

@ -12,6 +12,8 @@ CDummyObject::CDummyObject(CObject *obj)
m_level = obj->m_level;
}
#include <new>
class CDummyObject_ : public CDummyObject
{
public:

Some files were not shown because too many files have changed in this diff Show more