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) ### Unreversed / incomplete classes (at least the ones we know)
``` ```
cAudioManager - being worked on cAudioManager - WIP
CBoat CBoat
CBrightLights CBrightLights
CBulletInfo CBulletInfo
CBulletTraces
CCam
CCamera
CCopPed
CCrane CCrane
CCranes CCranes
CCullZone CCullZone
CCullZones CCullZones
CExplosion CExplosion
CFallingGlassPane CFallingGlassPane
CFire
CFireManager
CGame
CGarage
CGarages
CGlass CGlass
CMenuManager CMenuManager - WIP
CMotionBlurStreaks CMotionBlurStreaks
CObject CObject
CPacManPickups CPacManPickups
@ -68,15 +59,10 @@ CRoadBlocks
CRubbish CRubbish
CSceneEdit CSceneEdit
CSkidmarks CSkidmarks
CShotInfo
CSpecialFX CSpecialFX
CStats CStats
CTrafficLights CTrafficLights
CWanted
CWaterCannon
CWaterCannons
CWeapon CWeapon
CWeaponEffects
CWeather CWeather
CWorld 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 ) #pragma warning( disable : 344 )
#endif /* (defined(__ICL)) */ #endif /* (defined(__ICL)) */
//nobody needed that - AAP
#include <windows.h> //#include <windows.h>
#if (defined(RWDEBUG)) #if (defined(RWDEBUG))
#if (defined(RWMEMDEBUG) && !defined(_CRTDBG_MAP_ALLOC)) #if (defined(RWMEMDEBUG) && !defined(_CRTDBG_MAP_ALLOC))

View File

@ -203,6 +203,15 @@ CAnimBlendAssociation::UpdateBlend(float timeDelta)
return true; 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 STARTPATCHES
InjectHook(0x4016A0, &CAnimBlendAssociation::AllocateAnimBlendNodeArray, PATCH_JUMP); InjectHook(0x4016A0, &CAnimBlendAssociation::AllocateAnimBlendNodeArray, PATCH_JUMP);
@ -219,7 +228,7 @@ STARTPATCHES
InjectHook(0x4031F0, &CAnimBlendAssociation::UpdateTime, PATCH_JUMP); InjectHook(0x4031F0, &CAnimBlendAssociation::UpdateTime, PATCH_JUMP);
InjectHook(0x4032B0, &CAnimBlendAssociation::UpdateBlend, PATCH_JUMP); InjectHook(0x4032B0, &CAnimBlendAssociation::UpdateBlend, PATCH_JUMP);
InjectHook(0x401460, &CAnimBlendAssociation::ctor1, PATCH_JUMP); InjectHook(0x401460, &CAnimBlendAssociation_::ctor1, PATCH_JUMP);
InjectHook(0x4014C0, &CAnimBlendAssociation::ctor2, PATCH_JUMP); InjectHook(0x4014C0, &CAnimBlendAssociation_::ctor2, PATCH_JUMP);
InjectHook(0x401520, &CAnimBlendAssociation::dtor, PATCH_JUMP); InjectHook(0x401520, &CAnimBlendAssociation_::dtor, PATCH_JUMP);
ENDPATCHES ENDPATCHES

View File

@ -85,9 +85,5 @@ public:
static CAnimBlendAssociation *FromLink(CAnimBlendLink *l) { static CAnimBlendAssociation *FromLink(CAnimBlendLink *l) {
return (CAnimBlendAssociation*)((uint8*)l - offsetof(CAnimBlendAssociation, link)); 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"); static_assert(sizeof(CAnimBlendAssociation) == 0x40, "CAnimBlendAssociation: error");

View File

@ -36,9 +36,19 @@ CAnimBlendClumpData::ForAllFrames(void (*cb)(AnimBlendFrameData*, void*), void *
cb(&frames[i], arg); 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 STARTPATCHES
InjectHook(0x401880, &CAnimBlendClumpData::ctor, PATCH_JUMP); InjectHook(0x401880, &CAnimBlendClumpData_::ctor, PATCH_JUMP);
InjectHook(0x4018B0, &CAnimBlendClumpData::dtor, PATCH_JUMP); InjectHook(0x4018B0, &CAnimBlendClumpData_::dtor, PATCH_JUMP);
InjectHook(0x4018F0, &CAnimBlendClumpData::SetNumberOfFrames, PATCH_JUMP); InjectHook(0x4018F0, &CAnimBlendClumpData::SetNumberOfFrames, PATCH_JUMP);
InjectHook(0x401930, &CAnimBlendClumpData::ForAllFrames, PATCH_JUMP); InjectHook(0x401930, &CAnimBlendClumpData::ForAllFrames, PATCH_JUMP);
ENDPATCHES ENDPATCHES

View File

@ -49,9 +49,5 @@ public:
void SetNumberOfBones(int n) { SetNumberOfFrames(n); } void SetNumberOfBones(int n) { SetNumberOfFrames(n); }
#endif #endif
void ForAllFrames(void (*cb)(AnimBlendFrameData*, void*), void *arg); 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"); static_assert(sizeof(CAnimBlendClumpData) == 0x14, "CAnimBlendClumpData: error");

View File

@ -20,6 +20,7 @@
#include "MusicManager.h" #include "MusicManager.h"
#include "Pad.h" #include "Pad.h"
#include "Ped.h" #include "Ped.h"
#include "Fire.h"
#include "Physical.h" #include "Physical.h"
#include "Placeable.h" #include "Placeable.h"
#include "Plane.h" #include "Plane.h"
@ -67,6 +68,7 @@ const int molotovVolume = 50;
const int rainOnVehicleIntensity = 22; const int rainOnVehicleIntensity = 22;
const int reverseGearIntensity = 30; const int reverseGearIntensity = 30;
const int engineDamageIntensity = 40;
const bool hornPatternsArray[8][44] = { const bool hornPatternsArray[8][44] = {
@ -416,7 +418,7 @@ cAudioManager::AddReleasingSounds()
} }
sample.field_56 = 0; sample.field_56 = 0;
} }
memcpy(&m_sQueueSample, &sample, sizeof(sample)); memcpy(&m_sQueueSample, &sample, sizeof(tSound));
AddSampleToRequestedQueue(); AddSampleToRequestedQueue();
} }
} }
@ -2742,11 +2744,215 @@ cAudioManager::PreTerminateGameSpecificShutdown()
} }
} }
WRAPPER
void void
cAudioManager::ProcessActiveQueues() 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 bool
@ -3056,7 +3262,7 @@ cAudioManager::ProcessBridgeMotor()
m_sQueueSample.m_bVolume = ComputeVolume(maxVolume, bridgeIntensity, m_sQueueSample.m_fDistance); m_sQueueSample.m_bVolume = ComputeVolume(maxVolume, bridgeIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) { if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_counter = 1; 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_bBankIndex = SAMPLEBANK_MAIN;
m_sQueueSample.m_bIsDistant = false; m_sQueueSample.m_bIsDistant = false;
m_sQueueSample.field_16 = 1; m_sQueueSample.field_16 = 1;
@ -3127,7 +3333,7 @@ cAudioManager::ProcessBridgeWarning()
m_sQueueSample.m_bVolume = ComputeVolume(100, 450.f, m_sQueueSample.m_fDistance); m_sQueueSample.m_bVolume = ComputeVolume(100, 450.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) { if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_counter = 0; 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_bBankIndex = SAMPLEBANK_MAIN;
m_sQueueSample.m_bIsDistant = false; m_sQueueSample.m_bIsDistant = false;
m_sQueueSample.field_16 = 1; m_sQueueSample.field_16 = 1;
@ -3153,7 +3359,7 @@ cAudioManager::ProcessCarBombTick(cVehicleParams *params)
{ {
CAutomobile *automobile; CAutomobile *automobile;
if(params->m_fDistance >= 1600.f) return false; if(params->m_fDistance >= SQR(40.f)) return false;
automobile = (CAutomobile *)params->m_pVehicle; automobile = (CAutomobile *)params->m_pVehicle;
if(automobile->bEngineOn && automobile->m_bombType == CARBOMB_TIMEDACTIVE) { if(automobile->bEngineOn && automobile->m_bombType == CARBOMB_TIMEDACTIVE) {
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
@ -3410,11 +3616,11 @@ cAudioManager::ProcessEngineDamage(cVehicleParams *params)
uint8 engineStatus; uint8 engineStatus;
uint8 emittingVolume; uint8 emittingVolume;
if(params->m_fDistance >= 1600.f) return false; if(params->m_fDistance >= SQR(engineDamageIntensity)) return false;
veh = (CAutomobile *)params->m_pVehicle; veh = (CAutomobile *)params->m_pVehicle;
if(veh->bEngineOn) { if(veh->bEngineOn) {
engineStatus = veh->Damage.GetEngineStatus(); engineStatus = veh->Damage.GetEngineStatus();
if(engineStatus > 250u || engineStatus < 100) return true; if(engineStatus > 250 || engineStatus < 100) return true;
if(engineStatus < 225) { if(engineStatus < 225) {
m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI; m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI;
emittingVolume = 6; emittingVolume = 6;
@ -3427,7 +3633,7 @@ cAudioManager::ProcessEngineDamage(cVehicleParams *params)
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE); m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE);
} }
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); 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) { if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_counter = 28; m_sQueueSample.m_counter = 28;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
@ -3438,7 +3644,7 @@ cAudioManager::ProcessEngineDamage(cVehicleParams *params)
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex); m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.field_48 = 2.0f; 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_56 = 0;
m_sQueueSample.field_76 = 3; m_sQueueSample.field_76 = 3;
m_sQueueSample.m_bReverbFlag = true; m_sQueueSample.m_bReverbFlag = true;
@ -3534,7 +3740,7 @@ cAudioManager::ProcessExplosions(int32 explosion)
CVector *pos; CVector *pos;
float distSquared; float distSquared;
for(uint8 i = 0; i < 48; i++) { for(uint8 i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
if(CExplosion::GetExplosionActiveCounter(i) == 1) { if(CExplosion::GetExplosionActiveCounter(i) == 1) {
CExplosion::ResetExplosionActiveCounter(i); CExplosion::ResetExplosionActiveCounter(i);
type = CExplosion::GetExplosionType(i); type = CExplosion::GetExplosionType(i);
@ -3732,7 +3938,7 @@ cAudioManager::ProcessFrontEnd()
break; break;
case SOUND_GARAGE_NO_MONEY: case SOUND_GARAGE_NO_MONEY:
case SOUND_GARAGE_BAD_VEHICLE: case SOUND_GARAGE_BAD_VEHICLE:
case SOUND_3C: case SOUND_GARAGE_BOMB_ALREADY_SET:
m_sQueueSample.m_nSampleIndex = SFX_PICKUP_ERROR_LEFT; m_sQueueSample.m_nSampleIndex = SFX_PICKUP_ERROR_LEFT;
stereo = true; stereo = true;
break; break;
@ -3889,7 +4095,7 @@ cAudioManager::ProcessGarages()
CalculateDistance(distCalculated, distSquared); \ CalculateDistance(distCalculated, distSquared); \
m_sQueueSample.m_bVolume = ComputeVolume(60, 80.f, m_sQueueSample.m_fDistance); \ m_sQueueSample.m_bVolume = ComputeVolume(60, 80.f, m_sQueueSample.m_fDistance); \
if(m_sQueueSample.m_bVolume) { \ 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_nSampleIndex = SFX_COL_CAR_PANEL_2; \
m_sQueueSample.m_nFrequency = 6735; \ m_sQueueSample.m_nFrequency = 6735; \
} else if(m_asAudioEntities[m_sQueueSample.m_nEntityIndex] \ } else if(m_asAudioEntities[m_sQueueSample.m_nEntityIndex] \
@ -3905,7 +4111,7 @@ cAudioManager::ProcessGarages()
m_sQueueSample.m_bEmittingVolume = 60; \ m_sQueueSample.m_bEmittingVolume = 60; \
m_sQueueSample.field_48 = 0.0f; \ m_sQueueSample.field_48 = 0.0f; \
m_sQueueSample.m_fSoundIntensity = 80.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_bReverbFlag = true;*/ \ /*m_sQueueSample.m_bReverbFlag = true;*/ \
m_sQueueSample.m_bIsDistant = false; \ m_sQueueSample.m_bIsDistant = false; \
@ -3915,7 +4121,7 @@ cAudioManager::ProcessGarages()
m_sQueueSample.m_nLoopEnd = -1; \ m_sQueueSample.m_nLoopEnd = -1; \
m_sQueueSample.m_counter = iSound++; \ m_sQueueSample.m_counter = iSound++; \
if(iSound < 32) iSound = 32; \ if(iSound < 32) iSound = 32; \
m_sQueueSample.m_bRequireReflection = 1; \ m_sQueueSample.m_bRequireReflection = true; \
AddSampleToRequestedQueue(); \ AddSampleToRequestedQueue(); \
} \ } \
} \ } \
@ -3925,20 +4131,20 @@ cAudioManager::ProcessGarages()
} }
for(uint32 i = 0; i < CGarages::NumGarages; ++i) { for(uint32 i = 0; i < CGarages::NumGarages; ++i) {
if(CGarages::Garages[i].m_eGarageType == GARAGE_NONE) continue; if(CGarages::aGarages[i].m_eGarageType == GARAGE_NONE) continue;
entity = CGarages::Garages[i].m_pDoor1; entity = CGarages::aGarages[i].m_pDoor1;
if(!entity) continue; if(!entity) continue;
m_sQueueSample.m_vecPos = entity->GetPosition(); m_sQueueSample.m_vecPos = entity->GetPosition();
distCalculated = false; distCalculated = false;
distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos); distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(distSquared < 6400.f) { 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) { if(state == GS_OPENING || state == GS_CLOSING || state == GS_AFTERDROPOFF) {
CalculateDistance(distCalculated, distSquared); 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(m_sQueueSample.m_bVolume) {
if(CGarages::Garages[i].m_eGarageType == GARAGE_CRUSHER) { if(CGarages::aGarages[i].m_eGarageType == GARAGE_CRUSHER) {
if(CGarages::Garages[i].m_eGarageState == GS_AFTERDROPOFF) { if(CGarages::aGarages[i].m_eGarageState == GS_AFTERDROPOFF) {
if(!(m_FrameCounter & 1)) { if(!(m_FrameCounter & 1)) {
LOOP_HELPER LOOP_HELPER
continue; continue;
@ -3955,11 +4161,11 @@ cAudioManager::ProcessGarages()
m_sQueueSample.m_nSampleIndex) >> m_sQueueSample.m_nSampleIndex) >>
1; 1;
m_sQueueSample.m_nFrequency += m_sQueueSample.m_nFrequency +=
RandomDisplacement((int32)m_sQueueSample.m_nFrequency >> 4); RandomDisplacement(m_sQueueSample.m_nFrequency >> 4);
m_sQueueSample.m_nLoopCount = 1; m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.field_56 = 1; m_sQueueSample.field_56 = 1;
m_sQueueSample.m_counter = iSound++; m_sQueueSample.m_counter = iSound++;
if(iSound < 32u) iSound = 32; if(iSound < 32) iSound = 32;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
m_sQueueSample.m_bIsDistant = false; m_sQueueSample.m_bIsDistant = false;
m_sQueueSample.field_16 = 3; m_sQueueSample.field_16 = 3;
@ -4001,11 +4207,11 @@ cAudioManager::ProcessGarages()
m_sQueueSample.m_bReverbFlag = true; m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false; m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue(); AddSampleToRequestedQueue();
}
}
LOOP_HELPER LOOP_HELPER
} }
} }
}
}
#undef LOOP_HELPER #undef LOOP_HELPER
} }
@ -4183,11 +4389,8 @@ cAudioManager::ProcessJumboAccel(CPlane *plane)
void void
cAudioManager::ProcessJumboDecel(CPlane *plane) cAudioManager::ProcessJumboDecel(CPlane *plane)
{ {
float modificator;
if(SetupJumboFlySound(20) && SetupJumboTaxiSound(75)) { if(SetupJumboFlySound(20) && SetupJumboTaxiSound(75)) {
modificator = (plane->m_fSpeed - 0.10334f) * 1.676f; const float modificator = min(1.f, (plane->m_fSpeed - 0.10334f) * 1.676f);
if(modificator > 1.0f) modificator = 1.0f;
SetupJumboEngineSound(maxVolume * modificator, 6050.f * modificator + 16000); SetupJumboEngineSound(maxVolume * modificator, 6050.f * modificator + 16000);
SetupJumboWhineSound(18, 29500); SetupJumboWhineSound(18, 29500);
} }
@ -4202,7 +4405,7 @@ cAudioManager::ProcessJumboFlying()
void void
cAudioManager::ProcessJumboLanding(CPlane *plane) 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(SetupJumboFlySound(107.f * modificator + 20)) {
if(SetupJumboTaxiSound(75.f * (1.f - modificator))) { if(SetupJumboTaxiSound(75.f * (1.f - modificator))) {
SetupJumboEngineSound(maxVolume, 22050); SetupJumboEngineSound(maxVolume, 22050);
@ -4214,7 +4417,7 @@ cAudioManager::ProcessJumboLanding(CPlane *plane)
void void
cAudioManager::ProcessJumboTakeOff(CPlane *plane) 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(SetupJumboFlySound((107.f * modificator) + 20) && SetupJumboRumbleSound(maxVolume * (1.f - modificator))) {
if(SetupJumboEngineSound(maxVolume, 22050)) SetupJumboWhineSound(18.f * (1.f - modificator), 44100); if(SetupJumboEngineSound(maxVolume, 22050)) SetupJumboWhineSound(18.f * (1.f - modificator), 44100);
@ -5003,13 +5206,11 @@ cAudioManager::ProcessMissionAudio()
void void
cAudioManager::ProcessModelCarEngine(cVehicleParams *params) cAudioManager::ProcessModelCarEngine(cVehicleParams *params)
{ {
cAudioManager *v2;
CAutomobile *automobile; CAutomobile *automobile;
float allowedVelocity; float allowedVelocity;
int32 emittingVol; int32 emittingVol;
float velocityChange; float velocityChange;
v2 = this;
if(params->m_fDistance < 900.f) { if(params->m_fDistance < 900.f) {
automobile = (CAutomobile *)params->m_pVehicle; automobile = (CAutomobile *)params->m_pVehicle;
if(automobile->bEngineOn) { if(automobile->bEngineOn) {
@ -5311,13 +5512,13 @@ cAudioManager::ProcessPed(CPhysical *ped)
{ {
cPedParams params; cPedParams params;
params.m_pPed = 0; params.m_pPed = nil;
params.m_bDistanceCalculated = 0; params.m_bDistanceCalculated = false;
params.m_fDistance = 0.0f; params.m_fDistance = 0.0f;
m_sQueueSample.m_vecPos = ped->GetPosition(); m_sQueueSample.m_vecPos = ped->GetPosition();
params.m_bDistanceCalculated = 0; //params.m_bDistanceCalculated = false;
params.m_pPed = (CPed *)ped; params.m_pPed = (CPed *)ped;
params.m_fDistance = GetDistanceSquared(&m_sQueueSample.m_vecPos); params.m_fDistance = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(ped->m_modelIndex == MI_FATMALE02) ProcessPedHeadphones(&params); if(ped->m_modelIndex == MI_FATMALE02) ProcessPedHeadphones(&params);
@ -5328,7 +5529,7 @@ void
cAudioManager::ProcessPedHeadphones(cPedParams *params) cAudioManager::ProcessPedHeadphones(cPedParams *params)
{ {
CPed *ped; CPed *ped;
CVehicle *veh; CAutomobile *veh;
uint8 emittingVol; uint8 emittingVol;
if(params->m_fDistance < 49.f) { if(params->m_fDistance < 49.f) {
@ -5337,9 +5538,9 @@ cAudioManager::ProcessPedHeadphones(cPedParams *params)
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance); CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
if(ped->bInVehicle && ped->m_nPedState == PED_DRIVING) { if(ped->bInVehicle && ped->m_nPedState == PED_DRIVING) {
emittingVol = 10; emittingVol = 10;
veh = ped->m_pMyVehicle; veh = (CAutomobile*)ped->m_pMyVehicle;
if(veh && veh->IsCar()) { 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)) { if(!veh->IsDoorClosed((eDoors)i) || veh->IsDoorMissing((eDoors)i)) {
emittingVol = 42; emittingVol = 42;
break; break;
@ -7234,11 +7435,224 @@ cAudioManager::ProcessVehicleDoors(cVehicleParams *params)
return true; return true;
} }
WRAPPER void
bool
cAudioManager::ProcessVehicleEngine(cVehicleParams* params) 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 void
@ -7358,7 +7772,7 @@ cAudioManager::ProcessVehicleRoadNoise(cVehicleParams *params)
freq = 6050 * emittingVol / 30 + 16000; freq = 6050 * emittingVol / 30 + 16000;
} else { } else {
m_sQueueSample.m_nSampleIndex = SFX_ROAD_NOISE; 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( sampleFreq = SampleManager.GetSampleBaseFrequency(
SFX_ROAD_NOISE); SFX_ROAD_NOISE);
freq = (sampleFreq * modificator) + ((3 * sampleFreq) >> 2); freq = (sampleFreq * modificator) + ((3 * sampleFreq) >> 2);
@ -7533,8 +7947,8 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams *params)
void cAudioManager::ProcessWaterCannon(int32) void cAudioManager::ProcessWaterCannon(int32)
{ {
for(int32 i = 0; i < NUM_WATERCANNONS; i++) { for(int32 i = 0; i < NUM_WATERCANNONS; i++) {
if(aCannons[i].m_nId) { if(CWaterCannons::aCannons[i].m_nId) {
m_sQueueSample.m_vecPos = aCannons[0].m_avecPos[aCannons[i].m_wIndex]; m_sQueueSample.m_vecPos = CWaterCannons::aCannons[0].m_avecPos[CWaterCannons::aCannons[i].m_nCur];
float distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos); float distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(distSquared < 900.f) { if(distSquared < 900.f) {
m_sQueueSample.m_fDistance = Sqrt(distSquared); m_sQueueSample.m_fDistance = Sqrt(distSquared);
@ -7647,7 +8061,7 @@ cAudioManager::ProcessWetRoadNoise(cVehicleParams *params)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN; m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
m_sQueueSample.m_bIsDistant = false; m_sQueueSample.m_bIsDistant = false;
m_sQueueSample.field_16 = 3; 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); freq = SampleManager.GetSampleBaseFrequency(SFX_ROAD_NOISE);
m_sQueueSample.m_nFrequency = freq + freq * modificator; m_sQueueSample.m_nFrequency = freq + freq * modificator;
m_sQueueSample.m_nLoopCount = 0; m_sQueueSample.m_nLoopCount = 0;

View File

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

View File

@ -2,13 +2,12 @@
#include "patcher.h" #include "patcher.h"
#include "AudioScriptObject.h" #include "AudioScriptObject.h"
#include "Pools.h" #include "Pools.h"
#include "DMAudio.h"
WRAPPER void cAudioScriptObject::SaveAllAudioScriptObjects(uint8 *buf, uint32 *size) { EAXJMP(0x57c460); }
void void
cAudioScriptObject::Reset() cAudioScriptObject::Reset()
{ {
AudioId = 125; AudioId = SCRSOUND_INVALID;
Posn = CVector(0.0f, 0.0f, 0.0f); Posn = CVector(0.0f, 0.0f, 0.0f);
AudioEntity = AEHANDLE_NONE; AudioEntity = AEHANDLE_NONE;
} }
@ -18,22 +17,66 @@ cAudioScriptObject::operator new(size_t sz)
{ {
return CPools::GetAudioScriptObjectPool()->New(); return CPools::GetAudioScriptObjectPool()->New();
} }
void * void *
cAudioScriptObject::operator new(size_t sz, int handle) cAudioScriptObject::operator new(size_t sz, int handle)
{ {
return CPools::GetAudioScriptObjectPool()->New(handle); return CPools::GetAudioScriptObjectPool()->New(handle);
} }
void void
cAudioScriptObject::operator delete(void *p, size_t sz) cAudioScriptObject::operator delete(void *p, size_t sz)
{ {
CPools::GetAudioScriptObjectPool()->Delete((cAudioScriptObject *)p); CPools::GetAudioScriptObjectPool()->Delete((cAudioScriptObject *)p);
} }
void void
cAudioScriptObject::operator delete(void *p, int handle) cAudioScriptObject::operator delete(void *p, int handle)
{ {
CPools::GetAudioScriptObjectPool()->Delete((cAudioScriptObject *)p); 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 void
PlayOneShotScriptObject(uint8 id, CVector const &pos) PlayOneShotScriptObject(uint8 id, CVector const &pos)
{ {
@ -47,4 +90,6 @@ PlayOneShotScriptObject(uint8 id, CVector const &pos)
STARTPATCHES STARTPATCHES
InjectHook(0x57C430, &cAudioScriptObject::Reset, PATCH_JUMP); InjectHook(0x57C430, &cAudioScriptObject::Reset, PATCH_JUMP);
InjectHook(0x57C5F0, &PlayOneShotScriptObject, PATCH_JUMP); InjectHook(0x57C5F0, &PlayOneShotScriptObject, PATCH_JUMP);
InjectHook(0x57C560, &cAudioScriptObject::LoadAllAudioScriptObjects, PATCH_JUMP);
InjectHook(0x57c460, &cAudioScriptObject::SaveAllAudioScriptObjects, PATCH_JUMP);
ENDPATCHES ENDPATCHES

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -19,6 +19,7 @@
#include "Ped.h" #include "Ped.h"
#include "PlayerInfo.h" #include "PlayerInfo.h"
#include "PlayerPed.h" #include "PlayerPed.h"
#include "Wanted.h"
#include "Pools.h" #include "Pools.h"
#include "Renderer.h" #include "Renderer.h"
#include "RoadBlocks.h" #include "RoadBlocks.h"
@ -27,7 +28,7 @@
#include "Streaming.h" #include "Streaming.h"
#include "VisibilityPlugins.h" #include "VisibilityPlugins.h"
#include "Vehicle.h" #include "Vehicle.h"
#include "Wanted.h" #include "Fire.h"
#include "World.h" #include "World.h"
#include "Zones.h" #include "Zones.h"
@ -880,9 +881,7 @@ CCarCtrl::SlowCarOnRailsDownForTrafficAndLights(CVehicle* pVehicle)
pVehicle->AutoPilot.ModifySpeed(max(maxSpeed, curSpeed - 0.5f * CTimer::GetTimeStep())); 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) 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; 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) 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) float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle* pVehicleB, float projectionX, float projectionY, CVector* pForwardA, CVector* pForwardB, uint8 id)
{ {
CVector2D vecBToA = pVehicleA->GetPosition() - pVehicleB->GetPosition(); CVector2D vecBToA = pVehicleA->GetPosition() - pVehicleB->GetPosition();
@ -1179,7 +1174,6 @@ float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle*
} }
return proximity; return proximity;
} }
#endif
float CCarCtrl::FindAngleToWeaveThroughTraffic(CVehicle* pVehicle, CPhysical* pTarget, float angleToTarget, float angleForward) float CCarCtrl::FindAngleToWeaveThroughTraffic(CVehicle* pVehicle, CPhysical* pTarget, float angleToTarget, float angleForward)
{ {

View File

@ -2,9 +2,6 @@
#include "patcher.h" #include "patcher.h"
#include "Curves.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) float CCurves::CalcSpeedScaleFactor(CVector* pPoint1, CVector* pPoint2, float dir1X, float dir1Y, float dir2X, float dir2Y)
{ {
CVector2D dir1(dir1X, dir1Y); CVector2D dir1(dir1X, dir1Y);
@ -16,11 +13,7 @@ float CCurves::CalcSpeedScaleFactor(CVector* pPoint1, CVector* pPoint2, float di
else else
return ((1.0f - dp) * 0.2f + 1.0f) * distance; 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) 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); 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), (dir1.y * (1.0f - curveCoef) + dir2.y * curveCoef) / (timeOnCurve * 0.001f),
0.0f); 0.0f);
} }
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,11 @@
#pragma once #pragma once
#include "Automobile.h" #include "Automobile.h"
#include "audio_enums.h" #include "audio_enums.h"
#include "Camera.h"
#include "config.h" #include "config.h"
class CVehicle; class CVehicle;
class CCamera;
enum eGarageState : int8 enum eGarageState : int8
{ {
@ -44,7 +46,8 @@ enum eGarageType : int8
enum 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 class CStoredCar
@ -63,34 +66,43 @@ class CStoredCar
int8 m_nVariationA; int8 m_nVariationA;
int8 m_nVariationB; int8 m_nVariationB;
int8 m_nCarBombType; 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"); static_assert(sizeof(CStoredCar) == 0x28, "CStoredCar");
#define SWITCH_GARAGE_DISTANCE_CLOSE 40.0f
class CGarage class CGarage
{ {
public:
eGarageType m_eGarageType; eGarageType m_eGarageType;
eGarageState m_eGarageState; eGarageState m_eGarageState;
char field_2; bool field_2; // unused
char m_bClosingWithoutTargetCar; bool m_bClosingWithoutTargetCar;
char m_bDeactivated; bool m_bDeactivated;
char m_bResprayHappened; bool m_bResprayHappened;
char field_6;
char field_7;
int m_nTargetModelIndex; int m_nTargetModelIndex;
CEntity *m_pDoor1; CEntity *m_pDoor1;
CEntity *m_pDoor2; CEntity *m_pDoor2;
char m_bDoor1PoolIndex; uint8 m_bDoor1PoolIndex;
char m_bDoor2PoolIndex; uint8 m_bDoor2PoolIndex;
char m_bIsDoor1Object; bool m_bDoor1IsDummy;
char m_bIsDoor2Object; bool m_bDoor2IsDummy;
char field_24; bool m_bRecreateDoorOnNextRefresh;
char m_bRotatedDoor; bool m_bRotatedDoor;
char m_bCameraFollowsPlayer; bool m_bCameraFollowsPlayer;
char field_27; float m_fX1;
CVector m_vecInf; float m_fX2;
CVector m_vecSup; float m_fY1;
float m_fY2;
float m_fZ1;
float m_fZ2;
float m_fDoorPos; float m_fDoorPos;
float m_fDoorHeight; float m_fDoorHeight;
float m_fDoor1X; float m_fDoor1X;
@ -99,26 +111,74 @@ public:
float m_fDoor2Y; float m_fDoor2Y;
float m_fDoor1Z; float m_fDoor1Z;
float m_fDoor2Z; float m_fDoor2Z;
int m_nDoorOpenTime; uint32 m_nTimeToStartAction;
char m_bCollectedCarsState; uint8 m_bCollectedCarsState;
char field_89;
char field_90;
char field_91;
CVehicle *m_pTarget; CVehicle *m_pTarget;
int field_96; void* field_96; // unused
CStoredCar m_sStoredCar; CStoredCar m_sStoredCar; // not needed
void OpenThisGarage(); void OpenThisGarage();
void CloseThisGarage(); void CloseThisGarage();
bool IsOpen() { return m_eGarageState == GS_OPENED || m_eGarageState == GS_OPENEDCONTAINSCAR; } bool IsOpen() { return m_eGarageState == GS_OPENED || m_eGarageState == GS_OPENEDCONTAINSCAR; }
bool IsClosed() { return m_eGarageState == GS_FULLYCLOSED; } 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"); static_assert(sizeof(CGarage) == 140, "CGarage");
class CGarages class CGarages
{ {
public: enum {
MESSAGE_LENGTH = 8
};
static int32 &BankVansCollected; static int32 &BankVansCollected;
static bool &BombsAreFree; static bool &BombsAreFree;
static bool &RespraysAreFree; static bool &RespraysAreFree;
@ -127,7 +187,7 @@ public:
static int32 &CrushedCarId; static int32 &CrushedCarId;
static uint32 &LastTimeHelpMessage; static uint32 &LastTimeHelpMessage;
static int32 &MessageNumberInString; static int32 &MessageNumberInString;
static const char *MessageIDString; static char(&MessageIDString)[MESSAGE_LENGTH];
static int32 &MessageNumberInString2; static int32 &MessageNumberInString2;
static uint32 &MessageStartTime; static uint32 &MessageStartTime;
static uint32 &MessageEndTime; static uint32 &MessageEndTime;
@ -135,36 +195,62 @@ public:
static bool &PlayerInGarage; static bool &PlayerInGarage;
static int32 &PoliceCarsCollected; static int32 &PoliceCarsCollected;
static uint32 &GarageToBeTidied; 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: 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); static void Init(void);
#ifndef PS2
static void Shutdown(void);
#endif
static void Update(void); static void Update(void);
static void Load(uint8 *buf, uint32 size);
static void Save(uint8 *buf, uint32 *size); static int16 AddOne(float X1, float Y1, float Z1, float X2, float Y2, float Z2, eGarageType type, int32 targetId);
static int16 AddOne(float, float, float, float, float, float, uint8, uint32); 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 void SetTargetCarForMissonGarage(int16, CVehicle*);
static bool HasCarBeenDroppedOffYet(int16); static bool HasCarBeenDroppedOffYet(int16);
static void ActivateGarage(int16);
static void DeActivateGarage(int16); static void DeActivateGarage(int16);
static void ActivateGarage(int16);
static int32 QueryCarsCollected(int16); static int32 QueryCarsCollected(int16);
static bool HasThisCarBeenCollected(int16, uint8); static bool HasImportExportGarageCollectedThisCar(int16, int8);
static void ChangeGarageType(int16, eGarageType, int32);
static bool HasResprayHappened(int16);
static void GivePlayerDetonator();
static bool IsGarageOpen(int16); static bool IsGarageOpen(int16);
static bool IsGarageClosed(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 void SetGarageDoorToRotate(int16);
static bool HasImportExportGarageCollectedThisCar(int16, int8);
static void SetLeaveCameraForThisGarage(int16); static void SetLeaveCameraForThisGarage(int16);
static bool IsThisCarWithinGarageArea(int16, CEntity*); 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); } WRAPPER bool CPedPath::CalcPedRoute(uint8, CVector, CVector, CVector*, int16*, int16) { EAXJMP(0x42E680); }
enum #define MAX_DIST INT16_MAX-1
{
NodeTypeExtern = 1,
NodeTypeIntern = 2,
ObjectFlag1 = 1,
ObjectEastWest = 2,
MAX_DIST = INT16_MAX-1
};
// object flags: // object flags:
// 1 // 1 UseInRoadBlock
// 2 east/west road(?) // 2 east/west road(?)
CPathInfoForObject *&InfoForTileCars = *(CPathInfoForObject**)0x8F1A8C; CPathInfoForObject *&InfoForTileCars = *(CPathInfoForObject**)0x8F1A8C;
@ -218,14 +209,14 @@ CPathFind::PreparePathData(void)
if(numIntern == 1 && numExtern == 2){ if(numIntern == 1 && numExtern == 2){
if(numLanes < 4){ if(numLanes < 4){
if((i & 7) == 4){ // WHAT? if((i & 7) == 4){ // WHAT?
m_objectFlags[i] |= ObjectFlag1; m_objectFlags[i] |= UseInRoadBlock;
if(maxX > maxY) if(maxX > maxY)
m_objectFlags[i] |= ObjectEastWest; m_objectFlags[i] |= ObjectEastWest;
else else
m_objectFlags[i] &= ~ObjectEastWest; m_objectFlags[i] &= ~ObjectEastWest;
} }
}else{ }else{
m_objectFlags[i] |= ObjectFlag1; m_objectFlags[i] |= UseInRoadBlock;
if(maxX > maxY) if(maxX > maxY)
m_objectFlags[i] |= ObjectEastWest; m_objectFlags[i] |= ObjectEastWest;
else else

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,37 @@
#include "common.h" #include "common.h"
#include "patcher.h" #include "patcher.h"
#include "RoadBlocks.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::GenerateRoadBlockCopsForCar(CVehicle*, int32, int16) { EAXJMP(0x4376A0); }
WRAPPER void CRoadBlocks::GenerateRoadBlocks(void) { EAXJMP(0x436FA0); } 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 class CRoadBlocks
{ {
public: public:
static int16 (&NumRoadBlocks);
static int16 (&RoadBlockObjects)[NUMROADBLOCKS];
static bool (&InOrOut)[NUMROADBLOCKS];
static void Init(void); static void Init(void);
static void GenerateRoadBlockCopsForCar(CVehicle*, int32, int16); static void GenerateRoadBlockCopsForCar(CVehicle*, int32, int16);
static void GenerateRoadBlocks(void); static void GenerateRoadBlocks(void);

View File

@ -2,5 +2,11 @@
#include "patcher.h" #include "patcher.h"
#include "SceneEdit.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::Update(void) { EAXJMP(0x585570); }
WRAPPER void CSceneEdit::Init(void) { EAXJMP(0x585170); } WRAPPER void CSceneEdit::Init(void) { EAXJMP(0x585170); }

View File

@ -3,6 +3,12 @@
class CSceneEdit class CSceneEdit
{ {
public: 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 Update(void);
static void Init(void); static void Init(void);
}; };

View File

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

View File

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

View File

@ -33,6 +33,7 @@
#include "Clock.h" #include "Clock.h"
#include "Timecycle.h" #include "Timecycle.h"
#include "RpAnimBlend.h" #include "RpAnimBlend.h"
#include "AnimBlendAssociation.h"
#include "Shadows.h" #include "Shadows.h"
#include "Radar.h" #include "Radar.h"
#include "Hud.h" #include "Hud.h"
@ -207,6 +208,7 @@ PlayAnimation(RpClump *clump, AssocGroupId animGroup, AnimationId anim)
animAssoc->SetRun(); animAssoc->SetRun();
} }
extern void (*DebugMenuProcess)(void);
void void
CAnimViewer::Update(void) CAnimViewer::Update(void)
{ {
@ -246,6 +248,9 @@ CAnimViewer::Update(void)
} }
CPad::UpdatePads(); CPad::UpdatePads();
CPad* pad = CPad::GetPad(0); CPad* pad = CPad::GetPad(0);
DebugMenuProcess();
CStreaming::UpdateForAnimViewer(); CStreaming::UpdateForAnimViewer();
CStreaming::RequestModel(modelId, 0); CStreaming::RequestModel(modelId, 0);
if (CStreaming::HasModelLoaded(modelId)) { if (CStreaming::HasModelLoaded(modelId)) {
@ -289,7 +294,7 @@ CAnimViewer::Update(void)
} }
newEntity->GetPosition() = CVector(0.0f, 0.0f, 0.0f); newEntity->GetPosition() = CVector(0.0f, 0.0f, 0.0f);
CWorld::Add(newEntity); 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) { 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); ((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 CEntity;
class CPed; class CPed;
class CAutomobile; 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 enum
{ {
MODE_NONE = 0, MODE_NONE = 0,
@ -66,17 +83,17 @@ struct CCam
bool m_bTheHeightFixerVehicleIsATrain; bool m_bTheHeightFixerVehicleIsATrain;
bool LookBehindCamWasInFront; bool LookBehindCamWasInFront;
bool LookingBehind; bool LookingBehind;
bool LookingLeft; // 32 bool LookingLeft;
bool LookingRight; bool LookingRight;
bool ResetStatics; //for interpolation type stuff to work bool ResetStatics; //for interpolation type stuff to work
bool Rotating; bool Rotating;
int16 Mode; // CameraMode int16 Mode; // CameraMode
uint32 m_uiFinishTime; // 52 uint32 m_uiFinishTime;
int m_iDoCollisionChecksOnFrameNum; int m_iDoCollisionChecksOnFrameNum;
int m_iDoCollisionCheckEveryNumOfFrames; int m_iDoCollisionCheckEveryNumOfFrames;
int m_iFrameNumWereAt; // 64 int m_iFrameNumWereAt;
int m_iRunningVectorArrayPos; int m_iRunningVectorArrayPos;
int m_iRunningVectorCounter; int m_iRunningVectorCounter;
int DirectionWasLooking; int DirectionWasLooking;
@ -85,9 +102,9 @@ struct CCam
float f_Roll; //used for adding a slight roll to the camera in the float f_Roll; //used for adding a slight roll to the camera in the
float f_rollSpeed; float f_rollSpeed;
float m_fSyphonModeTargetZOffSet; float m_fSyphonModeTargetZOffSet;
float m_fUnknownZOffSet; float m_fRoadOffSet;
float m_fAmountFractionObscured; float m_fAmountFractionObscured;
float m_fAlphaSpeedOverOneFrame; // 100 float m_fAlphaSpeedOverOneFrame;
float m_fBetaSpeedOverOneFrame; float m_fBetaSpeedOverOneFrame;
float m_fBufferedTargetBeta; float m_fBufferedTargetBeta;
float m_fBufferedTargetOrientation; float m_fBufferedTargetOrientation;
@ -95,7 +112,7 @@ struct CCam
float m_fCamBufferedHeight; float m_fCamBufferedHeight;
float m_fCamBufferedHeightSpeed; float m_fCamBufferedHeightSpeed;
float m_fCloseInPedHeightOffset; float m_fCloseInPedHeightOffset;
float m_fCloseInPedHeightOffsetSpeed; // 132 float m_fCloseInPedHeightOffsetSpeed;
float m_fCloseInCarHeightOffset; float m_fCloseInCarHeightOffset;
float m_fCloseInCarHeightOffsetSpeed; float m_fCloseInCarHeightOffsetSpeed;
float m_fDimensionOfHighestNearCar; float m_fDimensionOfHighestNearCar;
@ -103,7 +120,7 @@ struct CCam
float m_fFovSpeedOverOneFrame; float m_fFovSpeedOverOneFrame;
float m_fMinDistAwayFromCamWhenInterPolating; float m_fMinDistAwayFromCamWhenInterPolating;
float m_fPedBetweenCameraHeightOffset; float m_fPedBetweenCameraHeightOffset;
float m_fPlayerInFrontSyphonAngleOffSet; // 164 float m_fPlayerInFrontSyphonAngleOffSet;
float m_fRadiusForDead; float m_fRadiusForDead;
float m_fRealGroundDist; //used for follow ped mode float m_fRealGroundDist; //used for follow ped mode
float m_fTargetBeta; float m_fTargetBeta;
@ -111,7 +128,7 @@ struct CCam
float m_fTransitionBeta; float m_fTransitionBeta;
float m_fTrueBeta; float m_fTrueBeta;
float m_fTrueAlpha; // 200 float m_fTrueAlpha;
float m_fInitialPlayerOrientation; //used for first person float m_fInitialPlayerOrientation; //used for first person
float Alpha; float Alpha;
@ -120,34 +137,25 @@ struct CCam
float FOVSpeed; float FOVSpeed;
float Beta; float Beta;
float BetaSpeed; float BetaSpeed;
float Distance; // 232 float Distance;
float DistanceSpeed; float DistanceSpeed;
float CA_MIN_DISTANCE; float CA_MIN_DISTANCE;
float CA_MAX_DISTANCE; float CA_MAX_DISTANCE;
float SpeedVar; float SpeedVar;
// ped onfoot zoom distance CVector m_cvecSourceSpeedOverOneFrame;
float m_fTargetZoomGroundOne; CVector m_cvecTargetSpeedOverOneFrame;
float m_fTargetZoomGroundTwo; // 256 CVector m_cvecUpOverOneFrame;
float m_fTargetZoomGroundThree;
// ped onfoot alpha angle offset
float m_fTargetZoomOneZExtra;
float m_fTargetZoomTwoZExtra;
float m_fTargetZoomThreeZExtra;
float m_fTargetZoomZCloseIn; CVector m_cvecTargetCoorsForFudgeInter;
float m_fMinRealGroundDist; CVector m_cvecCamFixedModeVector;
float m_fTargetCloseInDist; CVector m_cvecCamFixedModeSource;
CVector m_cvecCamFixedModeUpOffSet;
CVector m_cvecTargetCoorsForFudgeInter; // 360 CVector m_vecLastAboveWaterCamPosition; //helper for when the player has gone under the water
CVector m_cvecCamFixedModeVector; // 372 CVector m_vecBufferedPlayerBodyOffset;
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
// The three vectors that determine this camera for this frame // 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 Source; // Coors in world space
CVector SourceBeforeLookBehind; CVector SourceBeforeLookBehind;
CVector Up; // Just that CVector Up; // Just that
@ -162,6 +170,10 @@ struct CCam
bool m_bFirstPersonRunAboutActive; bool m_bFirstPersonRunAboutActive;
CCam(void) { Init(); }
void Init(void);
void Process(void);
void ProcessSpecialHeightRoutines(void);
void GetVectorsReadyForRW(void); void GetVectorsReadyForRW(void);
CVector DoAverageOnVector(const CVector &vec); CVector DoAverageOnVector(const CVector &vec);
float GetPedBetaAngleForClearView(const CVector &Target, float Dist, float BetaOffset, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies); 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); bool FixCamIfObscured(CVector &TargetCoors, float TargetHeight, float TargetOrientation);
void Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist); void Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist);
void FixCamWhenObscuredByVehicle(const CVector &TargetCoors); void FixCamWhenObscuredByVehicle(const CVector &TargetCoors);
bool Using3rdPersonMouseCam(); void LookBehind(void);
bool GetWeaponFirstPersonOn(); 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_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_BehindCar(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_Cam_On_A_String(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(sizeof(CCam) == 0x1A4, "CCam: wrong size");
static_assert(offsetof(CCam, Alpha) == 0xA8, "CCam: error"); static_assert(offsetof(CCam, Alpha) == 0xA8, "CCam: error");
static_assert(offsetof(CCam, Front) == 0x140, "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 struct CTrainCamNode
@ -223,6 +288,7 @@ enum
FADE_OUT = 0, FADE_OUT = 0,
FADE_IN, FADE_IN,
FADE_NONE
}; };
enum enum
@ -248,13 +314,14 @@ enum
enum enum
{ {
CAM_CONTROLLER_0, CAMCONTROL_GAME,
CAM_CONTROLLER_1, CAMCONTROL_SCRIPT,
CAM_CONTROLLER_2 CAMCONTROL_OBBE
}; };
struct CCamera : public CPlaceable class CCamera : public CPlaceable
{ {
public:
bool m_bAboveGroundTrainNodesLoaded; bool m_bAboveGroundTrainNodesLoaded;
bool m_bBelowGroundTrainNodesLoaded; bool m_bBelowGroundTrainNodesLoaded;
bool m_bCamDirectlyBehind; bool m_bCamDirectlyBehind;
@ -302,10 +369,6 @@ bool m_FadeTargetIsSplashScreen;
uint8 ActiveCam; uint8 ActiveCam;
uint32 m_uiCamShakeStart; uint32 m_uiCamShakeStart;
uint32 m_uiFirstPersonCamLastInputTime; uint32 m_uiFirstPersonCamLastInputTime;
// where are those?
//bool m_bVehicleSuspenHigh;
//bool m_bEnable1rstPersonCamCntrlsScript;
//bool m_bAllow1rstPersonWeaponsCamera;
uint32 m_uiLongestTimeInMill; uint32 m_uiLongestTimeInMill;
uint32 m_uiNumberOfTrainCamNodes; uint32 m_uiNumberOfTrainCamNodes;
@ -321,7 +384,7 @@ bool m_FadeTargetIsSplashScreen;
int m_BlurRed; int m_BlurRed;
int m_BlurType; int m_BlurType;
uint32 unknown; uint32 unknown; // some counter having to do with music
int m_iWorkOutSpeedThisNumFrames; int m_iWorkOutSpeedThisNumFrames;
int m_iNumFramesSoFar; int m_iNumFramesSoFar;
@ -387,8 +450,8 @@ uint32 unknown;
CCam Cams[3]; CCam Cams[3];
void *pToGarageWeAreIn; CGarage *pToGarageWeAreIn;
void *pToGarageWeAreInForHackAvoidFirstPerson; CGarage *pToGarageWeAreInForHackAvoidFirstPerson;
CQueuedMode m_PlayerMode; CQueuedMode m_PlayerMode;
CQueuedMode PlayerWeaponMode; CQueuedMode PlayerWeaponMode;
CVector m_PreviousCameraPosition; CVector m_PreviousCameraPosition;
@ -399,7 +462,6 @@ uint32 unknown;
CVector m_vecFixedModeUpOffSet; CVector m_vecFixedModeUpOffSet;
CVector m_vecCutSceneOffset; CVector m_vecCutSceneOffset;
// one of those has to go
CVector m_cvecStartingSourceForInterPol; CVector m_cvecStartingSourceForInterPol;
CVector m_cvecStartingTargetForInterPol; CVector m_cvecStartingTargetForInterPol;
CVector m_cvecStartingUpForInterPol; CVector m_cvecStartingUpForInterPol;
@ -409,7 +471,6 @@ uint32 unknown;
CVector m_vecSourceWhenInterPol; CVector m_vecSourceWhenInterPol;
CVector m_vecTargetWhenInterPol; CVector m_vecTargetWhenInterPol;
CVector m_vecUpWhenInterPol; CVector m_vecUpWhenInterPol;
//CVector m_vecClearGeometryVec;
CVector m_vecGameCamPos; CVector m_vecGameCamPos;
CVector SourceDuringInter; CVector SourceDuringInter;
@ -417,8 +478,8 @@ uint32 unknown;
CVector UpDuringInter; CVector UpDuringInter;
RwCamera *m_pRwCamera; RwCamera *m_pRwCamera;
CEntity *pTargetEntity; CEntity *pTargetEntity;
CCamPathSplines m_arrPathArray[4]; CCamPathSplines m_arrPathArray[MAX_NUM_OF_SPLINETYPES];
CTrainCamNode m_arrTrainCamNode[800]; CTrainCamNode m_arrTrainCamNode[MAX_NUM_OF_NODES];
CMatrix m_cameraMatrix; CMatrix m_cameraMatrix;
bool m_bGarageFixedCamPositionSet; bool m_bGarageFixedCamPositionSet;
bool m_vecDoingSpecialInterPolation; bool m_vecDoingSpecialInterPolation;
@ -455,67 +516,97 @@ int m_iModeObbeCamIsInForCar;
uint32 m_uiFadeTimeStartedMusic; uint32 m_uiFadeTimeStartedMusic;
static bool &m_bUseMouse3rdPerson; 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; } 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; } 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 IsPointVisible(const CVector &center, const CMatrix *mat);
bool IsSphereVisible(const CVector &center, float radius, const CMatrix *mat); bool IsSphereVisible(const CVector &center, float radius, const CMatrix *mat);
bool IsSphereVisible(const CVector &center, float radius); bool IsSphereVisible(const CVector &center, float radius);
bool IsBoxVisible(RwV3d *box, const CMatrix *mat); 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, DistanceToWater) == 0xe4, "CCamera: error");
static_assert(offsetof(CCamera, m_WideScreenOn) == 0x70, "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_uiTimeTransitionStart) == 0x94, "CCamera: error");
static_assert(offsetof(CCamera, m_BlurBlue) == 0x9C, "CCamera: error"); static_assert(offsetof(CCamera, m_BlurBlue) == 0x9C, "CCamera: error");
static_assert(offsetof(CCamera, Cams) == 0x1A4, "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_vecCutSceneOffset) == 0x6F8, "CCamera: error");
static_assert(offsetof(CCamera, m_arrPathArray) == 0x7a8, "CCamera: error");
static_assert(sizeof(CCamera) == 0xE9D8, "CCamera: wrong size"); static_assert(sizeof(CCamera) == 0xE9D8, "CCamera: wrong size");
extern CCamera &TheCamera; extern CCamera &TheCamera;
void CamShakeNoPos(CCamera*, float); 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; BOOL _gbCdStreamAsync;
DWORD _gdwCdStreamFlags; DWORD _gdwCdStreamFlags;
DWORD WINAPI CdStreamThread(LPVOID lpThreadParameter);
void void
CdStreamInitThread(void) CdStreamInitThread(void)

View File

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

View File

@ -2061,6 +2061,19 @@ CColModel::operator=(const CColModel &other)
return *this; 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 STARTPATCHES
InjectHook(0x4B9C30, (CMatrix& (*)(const CMatrix &src, CMatrix &dst))Invert, PATCH_JUMP); 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(0x411E40, (void (CColSphere::*)(float, const CVector&, uint8, uint8))&CColSphere::Set, PATCH_JUMP);
InjectHook(0x40B2A0, &CColBox::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(0x40B350, &CColLine::Set, PATCH_JUMP);
InjectHook(0x411E70, &CColTriangle::Set, PATCH_JUMP); InjectHook(0x411E70, &CColTriangle::Set, PATCH_JUMP);
InjectHook(0x411EA0, &CColTrianglePlane::Set, PATCH_JUMP); InjectHook(0x411EA0, &CColTrianglePlane::Set, PATCH_JUMP);
InjectHook(0x412140, &CColTrianglePlane::GetNormal, PATCH_JUMP); InjectHook(0x412140, &CColTrianglePlane::GetNormal, PATCH_JUMP);
InjectHook(0x411680, &CColModel::ctor, PATCH_JUMP); InjectHook(0x411680, &CColModel_::ctor, PATCH_JUMP);
InjectHook(0x4116E0, &CColModel::dtor, PATCH_JUMP); InjectHook(0x4116E0, &CColModel_::dtor, PATCH_JUMP);
InjectHook(0x411D80, &CColModel::RemoveCollisionVolumes, PATCH_JUMP); InjectHook(0x411D80, &CColModel::RemoveCollisionVolumes, PATCH_JUMP);
InjectHook(0x411CB0, &CColModel::CalculateTrianglePlanes, PATCH_JUMP); InjectHook(0x411CB0, &CColModel::CalculateTrianglePlanes, PATCH_JUMP);
InjectHook(0x411D10, &CColModel::RemoveTrianglePlanes, PATCH_JUMP); InjectHook(0x411D10, &CColModel::RemoveTrianglePlanes, PATCH_JUMP);

View File

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

View File

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

View File

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

View File

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

View File

@ -1,12 +1,137 @@
#include "common.h"
#include "Debug.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; 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 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: public:
static void DebugInitTextBuffer(); static void DebugInitTextBuffer();
static void DebugDisplayTextBuffer(); 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 "World.h"
#include "Wanted.h" #include "Wanted.h"
#include "EventList.h" #include "EventList.h"
#include "Messages.h"
#include "Text.h"
#include "main.h"
int32 CEventList::ms_nFirstFreeSlotIndex; int32 CEventList::ms_nFirstFreeSlotIndex;
//CEvent gaEvent[NUMEVENTS]; CEvent gaEvent[NUMEVENTS];
CEvent *gaEvent = (CEvent*)0x6EF830; //CEvent *gaEvent = (CEvent*)0x6EF830;
enum enum
{ {

View File

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

View File

@ -1,16 +1,288 @@
#include "common.h" #include "common.h"
#include "patcher.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" #include "Fire.h"
CFireManager &gFireManager = *(CFireManager*)0x8F31D0; CFireManager &gFireManager = *(CFireManager*)0x8F31D0;
WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); } CFire::CFire()
WRAPPER void CFireManager::Update(void) { EAXJMP(0x479310); }
WRAPPER CFire* CFireManager::FindFurthestFire_NeverMindFireMen(CVector coors, float, float) { EAXJMP(0x479430); }
uint32 CFireManager::GetTotalActiveFires() const
{ {
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::~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) CFire* CFireManager::FindNearestFire(CVector vecPos, float *pDistance)
@ -38,6 +310,44 @@ CFire* CFireManager::FindNearestFire(CVector vecPos, float* pDistance)
return nil; 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 void
CFireManager::ExtinguishPoint(CVector point, float range) 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); } int32
WRAPPER void CFireManager::StartFire(CVector, float, uint8) { EAXJMP(0x479500); } CFireManager::StartScriptFire(const CVector &pos, CEntity *target, float strength, bool propagation)
WRAPPER int32 CFireManager::StartScriptFire(const CVector& pos, CEntity* culprit, float, uint8) { EAXJMP(0x479E60); } {
WRAPPER bool CFireManager::IsScriptFireExtinguish(int16) { EAXJMP(0x479FC0); } CFire *fire;
WRAPPER void CFireManager::RemoveScriptFire(int16) { EAXJMP(0x479FE0); } CPed *ped = (CPed *)target;
WRAPPER void CFireManager::RemoveAllScriptFires(void) { EAXJMP(0x47A000); } CVehicle *veh = (CVehicle *)target;
WRAPPER void CFireManager::SetScriptFireAudio(int16, bool) { EAXJMP(0x47A040); }
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 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(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 ENDPATCHES

View File

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

View File

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

View File

@ -51,6 +51,9 @@ enum eLanguages
LANGUAGE_GERMAN, LANGUAGE_GERMAN,
LANGUAGE_ITALIAN, LANGUAGE_ITALIAN,
LANGUAGE_SPANISH, LANGUAGE_SPANISH,
#ifdef MORE_LANGUAGES
LANGUAGE_RUSSIAN,
#endif
}; };
enum eFrontendSprites enum eFrontendSprites
@ -301,6 +304,9 @@ enum eMenuAction
MENUACTION_UNK108, MENUACTION_UNK108,
MENUACTION_UNK109, MENUACTION_UNK109,
MENUACTION_UNK110, MENUACTION_UNK110,
#ifdef MORE_LANGUAGES
MENUACTION_LANG_RUS,
#endif
}; };
enum eCheckHover enum eCheckHover
@ -357,7 +363,7 @@ enum
enum eControlMethod enum eControlMethod
{ {
CONTROL_STANDART = 0, CONTROL_STANDARD = 0,
CONTROL_CLASSIC, CONTROL_CLASSIC,
}; };
@ -403,7 +409,7 @@ public:
int32 m_nHelperTextMsgId; int32 m_nHelperTextMsgId;
bool m_bLanguageLoaded; bool m_bLanguageLoaded;
bool m_bMenuActive; bool m_bMenuActive;
bool m_bMenuNotProcessed; bool m_bMenuStateChanged;
bool m_bWaitingForNewKeyBind; bool m_bWaitingForNewKeyBind;
bool m_bStartGameLoading; bool m_bStartGameLoading;
bool m_bFirstTime; bool m_bFirstTime;
@ -473,7 +479,6 @@ public:
static int32 &m_ControlMethod; static int32 &m_ControlMethod;
static int8 &m_PrefsDMA; static int8 &m_PrefsDMA;
static int32 &m_PrefsLanguage; static int32 &m_PrefsLanguage;
static int8 &m_bDisableMouseSteering;
static int32 &m_PrefsBrightness; static int32 &m_PrefsBrightness;
static float &m_PrefsLOD; static float &m_PrefsLOD;
static int8 &m_bFrontEnd_ReloadObrTxtGxt; static int8 &m_bFrontEnd_ReloadObrTxtGxt;
@ -492,6 +497,12 @@ public:
static int32 &sthWithButtons; static int32 &sthWithButtons;
static int32 &sthWithButtons2; static int32 &sthWithButtons2;
#ifndef MASTER
static bool m_PrefsMarketing;
static bool m_PrefsDisableTutorials;
#endif // !MASTER
public: public:
static void BuildStatLine(char *text, void *stat, uint8 aFloat, void *stat2); static void BuildStatLine(char *text, void *stat, uint8 aFloat, void *stat2);
static void CentreMousePointer(); static void CentreMousePointer();
@ -540,8 +551,14 @@ public:
void WaitForUserCD(); void WaitForUserCD();
void PrintController(); void PrintController();
// New content: // New (not in function or inlined in the game)
uint8 GetNumberOfMenuOptions(); void ThingsToDoBeforeLeavingPage();
void ScrollUpListByOne();
void ScrollDownListByOne();
void PageUpList(bool);
void PageDownList(bool);
// uint8 GetNumberOfMenuOptions();
}; };
static_assert(sizeof(CMenuManager) == 0x564, "CMenuManager: error"); 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 "common.h"
#include "win.h"
#include "patcher.h" #include "patcher.h"
#include "Game.h" #include "Game.h"
#include "main.h" #include "main.h"
#include "RwHelper.h"
#include "Accident.h" #include "Accident.h"
#include "Antennas.h" #include "Antennas.h"
#include "Bridge.h" #include "Bridge.h"
@ -17,6 +24,7 @@
#include "Cranes.h" #include "Cranes.h"
#include "Credits.h" #include "Credits.h"
#include "CutsceneMgr.h" #include "CutsceneMgr.h"
#include "DMAudio.h"
#include "Darkel.h" #include "Darkel.h"
#include "Debug.h" #include "Debug.h"
#include "EventList.h" #include "EventList.h"
@ -28,24 +36,32 @@
#include "Frontend.h" #include "Frontend.h"
#include "GameLogic.h" #include "GameLogic.h"
#include "Garages.h" #include "Garages.h"
#include "GenericGameStorage.h"
#include "Glass.h" #include "Glass.h"
#include "HandlingMgr.h"
#include "Heli.h" #include "Heli.h"
#include "Hud.h"
#include "IniFile.h" #include "IniFile.h"
#include "Lights.h"
#include "MBlur.h"
#include "Messages.h" #include "Messages.h"
#include "Pad.h" #include "Pad.h"
#include "Particle.h" #include "Particle.h"
#include "ParticleObject.h"
#include "PedRoutes.h"
#include "Phones.h" #include "Phones.h"
#include "Pickups.h" #include "Pickups.h"
#include "Plane.h" #include "Plane.h"
#include "PlayerSkin.h"
#include "Population.h" #include "Population.h"
#include "Radar.h"
#include "Record.h" #include "Record.h"
#include "References.h"
#include "Renderer.h" #include "Renderer.h"
#include "Replay.h" #include "Replay.h"
#include "Restart.h" #include "Restart.h"
#include "RoadBlocks.h" #include "RoadBlocks.h"
#include "PedRoutes.h"
#include "Rubbish.h" #include "Rubbish.h"
#include "RwHelper.h"
#include "SceneEdit.h" #include "SceneEdit.h"
#include "Script.h" #include "Script.h"
#include "Shadows.h" #include "Shadows.h"
@ -54,11 +70,14 @@
#include "Sprite2d.h" #include "Sprite2d.h"
#include "Stats.h" #include "Stats.h"
#include "Streaming.h" #include "Streaming.h"
#include "SurfaceTable.h"
#include "TempColModels.h"
#include "TimeCycle.h" #include "TimeCycle.h"
#include "TrafficLights.h" #include "TrafficLights.h"
#include "Train.h" #include "Train.h"
#include "TxdStore.h" #include "TxdStore.h"
#include "User.h" #include "User.h"
#include "VisibilityPlugins.h"
#include "WaterCannon.h" #include "WaterCannon.h"
#include "WaterLevel.h" #include "WaterLevel.h"
#include "Weapon.h" #include "Weapon.h"
@ -68,6 +87,10 @@
#include "ZoneCull.h" #include "ZoneCull.h"
#include "Zones.h" #include "Zones.h"
#define DEFAULT_VIEWWINDOW (0.7f)
eLevelName &CGame::currLevel = *(eLevelName*)0x941514; eLevelName &CGame::currLevel = *(eLevelName*)0x941514;
bool &CGame::bDemoMode = *(bool*)0x5F4DD0; bool &CGame::bDemoMode = *(bool*)0x5F4DD0;
bool &CGame::nastyGame = *(bool*)0x5F4DD4; bool &CGame::nastyGame = *(bool*)0x5F4DD4;
@ -76,7 +99,11 @@ bool &CGame::germanGame = *(bool*)0x95CD1E;
bool &CGame::noProstitutes = *(bool*)0x95CDCF; bool &CGame::noProstitutes = *(bool*)0x95CDCF;
bool &CGame::playingIntro = *(bool*)0x95CDC2; bool &CGame::playingIntro = *(bool*)0x95CDC2;
char *CGame::aDatFile = (char*)0x773A48; char *CGame::aDatFile = (char*)0x773A48;
#ifdef MORE_LANGUAGES
bool CGame::russianGame = false;
#endif
int &gameTxdSlot = *(int*)0x628D88;
bool bool
CGame::InitialiseOnceBeforeRW(void) CGame::InitialiseOnceBeforeRW(void)
@ -87,7 +114,139 @@ CGame::InitialiseOnceBeforeRW(void)
return true; 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) bool CGame::Initialise(const char* datFile)
{ {
@ -158,7 +317,7 @@ bool CGame::Initialise(const char* datFile)
CStreaming::Init(); CStreaming::Init();
} else { } else {
CStreaming::Init(); CStreaming::Init();
if (ConvertTextures()) { if (CreateTxdImageForVideoCard()) {
CStreaming::Shutdown(); CStreaming::Shutdown();
CdStreamAddImage("MODELS\\TXD.IMG"); CdStreamAddImage("MODELS\\TXD.IMG");
CStreaming::Init(); CStreaming::Init();
@ -196,7 +355,7 @@ bool CGame::Initialise(const char* datFile)
CSceneEdit::Init(); CSceneEdit::Init();
LoadingScreen("Loading the Game", "Load scripts", nil); LoadingScreen("Loading the Game", "Load scripts", nil);
CTheScripts::Init(); CTheScripts::Init();
CGangs::Initialize(); CGangs::Initialise();
LoadingScreen("Loading the Game", "Setup game variables", nil); LoadingScreen("Loading the Game", "Setup game variables", nil);
CClock::Initialise(1000); CClock::Initialise(1000);
CHeli::InitHelis(); CHeli::InitHelis();
@ -225,16 +384,227 @@ bool CGame::Initialise(const char* datFile)
CTheScripts::Process(); CTheScripts::Process();
TheCamera.Process(); TheCamera.Process();
LoadingScreen("Loading the Game", "Load scene", nil); LoadingScreen("Loading the Game", "Load scene", nil);
CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); CModelInfo::RemoveColModelsFromOtherLevels(currLevel);
CCollision::ms_collisionInMemory = CGame::currLevel; CCollision::ms_collisionInMemory = currLevel;
for (int i = 0; i < MAX_PADS; i++) for (int i = 0; i < MAX_PADS; i++)
CPad::GetPad(i)->Clear(true); CPad::GetPad(i)->Clear(true);
return true; return true;
} }
#if 0 bool CGame::ShutDown(void)
WRAPPER void CGame::Process(void) { EAXJMP(0x48C850); } {
#else 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); extern void (*DebugMenuProcess)(void);
void CGame::Process(void) void CGame::Process(void)
{ {
@ -310,50 +680,34 @@ void CGame::Process(void)
} }
} }
} }
#endif
void CGame::ReloadIPLs(void) void CGame::DrasticTidyUpMemory(bool)
{ {
CTimer::Stop(); #ifdef PS2
CWorld::RemoveStaticObjects(); // meow
ThePaths.Init(); #endif
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();
} }
#if 0 void CGame::TidyUpMemory(bool, bool)
WRAPPER void CGame::FinalShutdown(void) { EAXJMP(0x48BEC0); }
#else
void
CGame::FinalShutdown(void)
{ {
CTxdStore::Shutdown(); #ifdef PS2
CPedStats::Shutdown(); // meow
CdStreamShutdown();
}
#endif #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 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(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 ENDPATCHES

View File

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

View File

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

View File

@ -65,6 +65,9 @@ const CMenuScreen aScreens[] = {
MENUACTION_LANG_GER, "FEL_GER", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_LANG_GER, "FEL_GER", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_LANG_ITA, "FEL_ITA", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_LANG_ITA, "FEL_ITA", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_LANG_SPA, "FEL_SPA", 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, MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
}, },

View File

@ -5,6 +5,10 @@
#pragma warning( pop ) #pragma warning( pop )
#include "common.h" #include "common.h"
#ifdef XINPUT
#include <Xinput.h>
#pragma comment( lib, "Xinput9_1_0.lib" )
#endif
#include "patcher.h" #include "patcher.h"
#include "Pad.h" #include "Pad.h"
#include "ControllerConfig.h" #include "ControllerConfig.h"
@ -547,12 +551,79 @@ void CPad::AddToPCCheatString(char c)
#undef _CHEATCMP #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) void CPad::UpdatePads(void)
{ {
bool bUpdate = true; bool bUpdate = true;
GetPad(0)->UpdateMouse(); GetPad(0)->UpdateMouse();
#ifdef XINPUT
GetPad(0)->AffectFromXinput(0);
GetPad(1)->AffectFromXinput(1);
#else
CapturePad(0); CapturePad(0);
#endif
ControlsManager.ClearSimButtonPressCheckers(); ControlsManager.ClearSimButtonPressCheckers();
@ -565,10 +636,13 @@ void CPad::UpdatePads(void)
if ( bUpdate ) if ( bUpdate )
{ {
GetPad(0)->Update(0); GetPad(0)->Update(0);
GetPad(1)->Update(0);
} }
#if defined(MASTER) && !defined(XINPUT)
GetPad(1)->NewState.Clear(); GetPad(1)->NewState.Clear();
GetPad(1)->OldState.Clear(); GetPad(1)->OldState.Clear();
#endif
OldKeyState = NewKeyState; OldKeyState = NewKeyState;
NewKeyState = TempKeyState; NewKeyState = TempKeyState;

View File

@ -2,9 +2,9 @@
enum { enum {
PLAYERCONTROL_ENABLED = 0, PLAYERCONTROL_ENABLED = 0,
PLAYERCONTROL_DISABLED_1 = 1, PLAYERCONTROL_DISABLED_1 = 1, // used by first person camera
PLAYERCONTROL_DISABLED_2 = 2, PLAYERCONTROL_DISABLED_2 = 2,
PLAYERCONTROL_DISABLED_4 = 4, PLAYERCONTROL_GARAGE = 4,
PLAYERCONTROL_DISABLED_8 = 8, PLAYERCONTROL_DISABLED_8 = 8,
PLAYERCONTROL_DISABLED_10 = 16, PLAYERCONTROL_DISABLED_10 = 16,
PLAYERCONTROL_DISABLED_20 = 32, // used on CPlayerInfo::MakePlayerSafe PLAYERCONTROL_DISABLED_20 = 32, // used on CPlayerInfo::MakePlayerSafe
@ -247,6 +247,10 @@ public:
static char *EditString(char *pStr, int32 nSize); static char *EditString(char *pStr, int32 nSize);
static int32 *EditCodesForControls(int32 *pRsKeys, int32 nSize); static int32 *EditCodesForControls(int32 *pRsKeys, int32 nSize);
#ifdef XINPUT
void AffectFromXinput(uint32 pad);
#endif
// mouse // mouse
bool GetLeftMouseJustDown() { return !!(NewMouseControllerState.LMB && !OldMouseControllerState.LMB); } bool GetLeftMouseJustDown() { return !!(NewMouseControllerState.LMB && !OldMouseControllerState.LMB); }
bool GetRightMouseJustDown() { return !!(NewMouseControllerState.RMB && !OldMouseControllerState.RMB); } bool GetRightMouseJustDown() { return !!(NewMouseControllerState.RMB && !OldMouseControllerState.RMB); }
@ -399,6 +403,8 @@ public:
bool GetLeftShoulder2JustDown() { return !!(NewState.LeftShoulder2 && !OldState.LeftShoulder2); } bool GetLeftShoulder2JustDown() { return !!(NewState.LeftShoulder2 && !OldState.LeftShoulder2); }
bool GetRightShoulder1JustDown() { return !!(NewState.RightShoulder1 && !OldState.RightShoulder1); } bool GetRightShoulder1JustDown() { return !!(NewState.RightShoulder1 && !OldState.RightShoulder1); }
bool GetRightShoulder2JustDown() { return !!(NewState.RightShoulder2 && !OldState.RightShoulder2); } 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 GetStartJustDown() { return !!(NewState.Start && !OldState.Start); }
bool GetLeftStickXJustDown() { return !!(NewState.LeftStickX && !OldState.LeftStickX); } bool GetLeftStickXJustDown() { return !!(NewState.LeftStickX && !OldState.LeftStickX); }
bool GetLeftStickYJustDown() { return !!(NewState.LeftStickY && !OldState.LeftStickY); } bool GetLeftStickYJustDown() { return !!(NewState.LeftStickY && !OldState.LeftStickY); }
@ -422,8 +428,15 @@ public:
bool GetLeftShoulder2(void) { return !!NewState.LeftShoulder2; } bool GetLeftShoulder2(void) { return !!NewState.LeftShoulder2; }
bool GetRightShoulder1(void) { return !!NewState.RightShoulder1; } bool GetRightShoulder1(void) { return !!NewState.RightShoulder1; }
bool GetRightShoulder2(void) { return !!NewState.RightShoulder2; } 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); 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; z1 <= GetPosition().z && GetPosition().z <= z2;
} }
#include <new>
class CPlaceable_ : public CPlaceable class CPlaceable_ : public CPlaceable
{ {
public: public:

View File

@ -2,7 +2,9 @@
#include "patcher.h" #include "patcher.h"
#include "main.h" #include "main.h"
#include "PlayerPed.h" #include "PlayerPed.h"
#include "Wanted.h"
#include "PlayerInfo.h" #include "PlayerInfo.h"
#include "Fire.h"
#include "Frontend.h" #include "Frontend.h"
#include "PlayerSkin.h" #include "PlayerSkin.h"
#include "Darkel.h" #include "Darkel.h"
@ -12,6 +14,7 @@
#include "Remote.h" #include "Remote.h"
#include "World.h" #include "World.h"
#include "Replay.h" #include "Replay.h"
#include "Camera.h"
#include "Pad.h" #include "Pad.h"
#include "ProjectileInfo.h" #include "ProjectileInfo.h"
#include "Explosion.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_MIN_SPEED (0.3f)
#define RADAR_MAX_SPEED (0.9f) #define RADAR_MAX_SPEED (0.9f)
#if 0
WRAPPER void CRadar::CalculateBlipAlpha(float) { EAXJMP(0x4A4F90); }
#else
uint8 CRadar::CalculateBlipAlpha(float dist) uint8 CRadar::CalculateBlipAlpha(float dist)
{ {
if (dist <= 1.0f) if (dist <= 1.0f)
@ -88,55 +85,35 @@ uint8 CRadar::CalculateBlipAlpha(float dist)
return 128; return 128;
} }
#endif
#if 0
WRAPPER void CRadar::ChangeBlipBrightness(int32, int32) { EAXJMP(0x4A57A0); }
#else
void CRadar::ChangeBlipBrightness(int32 i, int32 bright) void CRadar::ChangeBlipBrightness(int32 i, int32 bright)
{ {
int index = GetActualBlipArrayIndex(i); int index = GetActualBlipArrayIndex(i);
if (index != -1) if (index != -1)
ms_RadarTrace[index].m_bDim = bright != 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) void CRadar::ChangeBlipColour(int32 i, int32 color)
{ {
int index = GetActualBlipArrayIndex(i); int index = GetActualBlipArrayIndex(i);
if (index != -1) if (index != -1)
ms_RadarTrace[index].m_nColor = color; 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) void CRadar::ChangeBlipDisplay(int32 i, eBlipDisplay display)
{ {
int index = GetActualBlipArrayIndex(i); int index = GetActualBlipArrayIndex(i);
if (index != -1) if (index != -1)
ms_RadarTrace[index].m_eBlipDisplay = display; 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) void CRadar::ChangeBlipScale(int32 i, int32 scale)
{ {
int index = GetActualBlipArrayIndex(i); int index = GetActualBlipArrayIndex(i);
if (index != -1) if (index != -1)
ms_RadarTrace[index].m_wScale = scale; ms_RadarTrace[index].m_wScale = scale;
} }
#endif
#if 0
WRAPPER void CRadar::ClearBlip(int32) { EAXJMP(0x4A5720); }
#else
void CRadar::ClearBlip(int32 i) void CRadar::ClearBlip(int32 i)
{ {
int index = GetActualBlipArrayIndex(i); int index = GetActualBlipArrayIndex(i);
@ -148,11 +125,7 @@ void CRadar::ClearBlip(int32 i)
ms_RadarTrace[index].m_IconID = RADAR_SPRITE_NONE; 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) void CRadar::ClearBlipForEntity(eBlipType type, int32 id)
{ {
for (int i = 0; i < NUMRADARBLIPS; i++) { 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? // Why not a proper clipping algorithm?
int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect) int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect)
{ {
@ -249,7 +218,6 @@ int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect)
return n; return n;
} }
#endif
bool CRadar::DisplayThisBlip(int32 counter) 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() void CRadar::Draw3dMarkers()
{ {
for (int i = 0; i < NUMRADARBLIPS; i++) { 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() void CRadar::DrawBlips()
{ {
if (!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud) { 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() void CRadar::DrawMap()
{ {
if (!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud) { if (!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud) {
@ -605,11 +560,7 @@ void CRadar::DrawMap()
DrawRadarMap(); DrawRadarMap();
} }
} }
#endif
#if 0
WRAPPER void CRadar::DrawRadarMap() { EAXJMP(0x4A6C20); }
#else
void CRadar::DrawRadarMap() void CRadar::DrawRadarMap()
{ {
// Game calculates an unused CRect here // Game calculates an unused CRect here
@ -642,11 +593,7 @@ void CRadar::DrawRadarMap()
DrawRadarSection(x, y + 1); DrawRadarSection(x, y + 1);
DrawRadarSection(x + 1, y + 1); DrawRadarSection(x + 1, y + 1);
} }
#endif
#if 0
WRAPPER void CRadar::DrawRadarMask() { EAXJMP(0x4A69C0); }
#else
void CRadar::DrawRadarMask() void CRadar::DrawRadarMask()
{ {
CVector2D corners[4] = { CVector2D corners[4] = {
@ -690,11 +637,7 @@ void CRadar::DrawRadarMask()
RwD3D8SetRenderState(rwRENDERSTATESTENCILFUNCTION, rwSTENCILFUNCTIONGREATER); RwD3D8SetRenderState(rwRENDERSTATESTENCILFUNCTION, rwSTENCILFUNCTIONGREATER);
} }
#endif
#if 0
WRAPPER void CRadar::DrawRadarSection(int32, int32) { EAXJMP(0x4A67E0); }
#else
void CRadar::DrawRadarSection(int32 x, int32 y) void CRadar::DrawRadarSection(int32 x, int32 y)
{ {
int i; int i;
@ -738,20 +681,12 @@ void CRadar::DrawRadarSection(int32 x, int32 y)
// if(numVertices > 2) // if(numVertices > 2)
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), numVertices); 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) 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)); 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) void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int32 alpha)
{ {
CVector curPosn[4]; 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)); 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) int32 CRadar::GetActualBlipArrayIndex(int32 i)
{ {
if (i == -1) if (i == -1)
@ -792,11 +723,7 @@ int32 CRadar::GetActualBlipArrayIndex(int32 i)
else else
return (uint16)i; return (uint16)i;
} }
#endif
#if 0
WRAPPER int32 CRadar::GetNewUniqueBlipIndex(int32) { EAXJMP(0x4A4180); }
#else
int32 CRadar::GetNewUniqueBlipIndex(int32 i) int32 CRadar::GetNewUniqueBlipIndex(int32 i)
{ {
if (ms_RadarTrace[i].m_BlipIndex >= UINT16_MAX - 1) if (ms_RadarTrace[i].m_BlipIndex >= UINT16_MAX - 1)
@ -805,11 +732,7 @@ int32 CRadar::GetNewUniqueBlipIndex(int32 i)
ms_RadarTrace[i].m_BlipIndex++; ms_RadarTrace[i].m_BlipIndex++;
return i | (ms_RadarTrace[i].m_BlipIndex << 16); 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) uint32 CRadar::GetRadarTraceColour(uint32 color, bool bright)
{ {
int32 c; int32 c;
@ -862,7 +785,6 @@ uint32 CRadar::GetRadarTraceColour(uint32 color, bool bright)
}; };
return c; return c;
} }
#endif
const char* gRadarTexNames[] = { const char* gRadarTexNames[] = {
"radar00", "radar01", "radar02", "radar03", "radar04", "radar05", "radar06", "radar07", "radar00", "radar01", "radar02", "radar03", "radar04", "radar05", "radar06", "radar07",
@ -875,9 +797,6 @@ const char* gRadarTexNames[] = {
"radar56", "radar57", "radar58", "radar59", "radar60", "radar61", "radar62", "radar63", "radar56", "radar57", "radar58", "radar59", "radar60", "radar61", "radar62", "radar63",
}; };
#if 0
WRAPPER void CRadar::Initialise() { EAXJMP(0x4A3EF0); }
#else
void void
CRadar::Initialise() CRadar::Initialise()
{ {
@ -894,11 +813,7 @@ CRadar::Initialise()
for (int i = 0; i < 64; i++) for (int i = 0; i < 64; i++)
gRadarTxdIds[i] = CTxdStore::FindTxdSlot(gRadarTexNames[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 CRadar::LimitRadarPoint(CVector2D &point)
{ {
float dist, invdist; float dist, invdist;
@ -911,11 +826,7 @@ float CRadar::LimitRadarPoint(CVector2D &point)
} }
return dist; return dist;
} }
#endif
#if 0
WRAPPER void CRadar::LoadAllRadarBlips(int32) { EAXJMP(0x4A6F30); }
#else
void CRadar::LoadAllRadarBlips(uint8 *buf, uint32 size) void CRadar::LoadAllRadarBlips(uint8 *buf, uint32 size)
{ {
Initialise(); Initialise();
@ -927,11 +838,7 @@ INITSAVEBUF
VALIDATESAVEBUF(size); VALIDATESAVEBUF(size);
} }
#endif
#if 0
WRAPPER void CRadar::LoadTextures() { EAXJMP(0x4A4030); }
#else
void void
CRadar::LoadTextures() CRadar::LoadTextures()
{ {
@ -959,42 +866,26 @@ CRadar::LoadTextures()
WeaponSprite.SetTexture("radar_weapon"); WeaponSprite.SetTexture("radar_weapon");
CTxdStore::PopCurrentTxd(); CTxdStore::PopCurrentTxd();
} }
#endif
#if 0
WRAPPER void RemoveMapSection(int32, int32) { EAXJMP(0x00); }
#else
void RemoveMapSection(int32 x, int32 y) void RemoveMapSection(int32 x, int32 y)
{ {
if (x >= 0 && x <= 7 && y >= 0 && y <= 7) if (x >= 0 && x <= 7 && y >= 0 && y <= 7)
CStreaming::RemoveTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y]); CStreaming::RemoveTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y]);
} }
#endif
#if 0
WRAPPER void CRadar::RemoveRadarSections() { EAXJMP(0x4A60E0); }
#else
void CRadar::RemoveRadarSections() void CRadar::RemoveRadarSections()
{ {
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++) for (int j = 0; j < 8; j++)
RemoveMapSection(i, j); RemoveMapSection(i, j);
} }
#endif
#if 0
WRAPPER void CRadar::RequestMapSection(int32, int32) { EAXJMP(0x00); }
#else
void CRadar::RequestMapSection(int32 x, int32 y) void CRadar::RequestMapSection(int32 x, int32 y)
{ {
ClipRadarTileCoords(x, y); ClipRadarTileCoords(x, y);
CStreaming::RequestTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y], STREAMFLAGS_DONT_REMOVE | STREAMFLAGS_DEPENDENCY); 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) void CRadar::SaveAllRadarBlips(uint8 *buf, uint32 *size)
{ {
*size = SAVE_HEADER_SIZE + sizeof(ms_RadarTrace); *size = SAVE_HEADER_SIZE + sizeof(ms_RadarTrace);
@ -1006,11 +897,7 @@ INITSAVEBUF
VALIDATESAVEBUF(*size); VALIDATESAVEBUF(*size);
} }
#endif
#if 0
WRAPPER void CRadar::SetBlipSprite(int32, int32) { EAXJMP(0x4A5840); }
#else
void CRadar::SetBlipSprite(int32 i, int32 icon) void CRadar::SetBlipSprite(int32 i, int32 icon)
{ {
int index = CRadar::GetActualBlipArrayIndex(i); int index = CRadar::GetActualBlipArrayIndex(i);
@ -1018,11 +905,7 @@ void CRadar::SetBlipSprite(int32 i, int32 icon)
ms_RadarTrace[index].m_IconID = 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 CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay display)
{ {
int nextBlip; int nextBlip;
@ -1043,11 +926,7 @@ int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay
ms_RadarTrace[nextBlip].m_IconID = RADAR_SPRITE_NONE; ms_RadarTrace[nextBlip].m_IconID = RADAR_SPRITE_NONE;
return CRadar::GetNewUniqueBlipIndex(nextBlip); 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 CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDisplay display)
{ {
int nextBlip; int nextBlip;
@ -1066,11 +945,7 @@ int CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDispla
ms_RadarTrace[nextBlip].m_IconID = RADAR_SPRITE_NONE; ms_RadarTrace[nextBlip].m_IconID = RADAR_SPRITE_NONE;
return GetNewUniqueBlipIndex(nextBlip); return GetNewUniqueBlipIndex(nextBlip);
} }
#endif
#if 0
WRAPPER void CRadar::SetRadarMarkerState(int32, bool) { EAXJMP(0x4A5C60); }
#else
void CRadar::SetRadarMarkerState(int32 counter, bool flag) void CRadar::SetRadarMarkerState(int32 counter, bool flag)
{ {
CEntity *e; CEntity *e;
@ -1091,11 +966,7 @@ void CRadar::SetRadarMarkerState(int32 counter, bool flag)
if (e) if (e)
e->bHasBlip = flag; 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) { void CRadar::ShowRadarMarker(CVector pos, uint32 color, float radius) {
float f1 = radius * 1.4f; float f1 = radius * 1.4f;
float f2 = radius * 0.5f; float f2 = radius * 0.5f;
@ -1117,11 +988,7 @@ void CRadar::ShowRadarMarker(CVector pos, uint32 color, float radius) {
p2 = pos - TheCamera.GetRight()*f2; p2 = pos - TheCamera.GetRight()*f2;
CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color, color); 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) 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) 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 + 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)); 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) 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() void CRadar::Shutdown()
{ {
AsukaSprite.Delete(); AsukaSprite.Delete();
@ -1183,20 +1046,12 @@ void CRadar::Shutdown()
WeaponSprite.Delete(); WeaponSprite.Delete();
RemoveRadarSections(); RemoveRadarSections();
} }
#endif
#if 0
WRAPPER void CRadar::StreamRadarSections(const CVector &posn) { EAXJMP(0x4A6B60); }
#else
void CRadar::StreamRadarSections(const CVector &posn) void CRadar::StreamRadarSections(const CVector &posn)
{ {
StreamRadarSections(floorf((2000.0f + posn.x) / 500.0f), ceilf(7.0f - (2000.0f + posn.y) / 500.0f)); 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) void CRadar::StreamRadarSections(int32 x, int32 y)
{ {
for (int i = 0; i < RADAR_NUM_TILES; ++i) { 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) void CRadar::TransformRealWorldToTexCoordSpace(CVector2D &out, const CVector2D &in, int32 x, int32 y)
{ {
out.x = in.x - (x * RADAR_TILE_SIZE + WORLD_MIN_X); 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.x /= RADAR_TILE_SIZE;
out.y /= 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) void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D &in)
{ {
float s, c; float s, c;
@ -1255,19 +1102,18 @@ void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D
out = out * m_radarRange + vec2DRadarOrigin; 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) // 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) 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; 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); 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) void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in)
{ {
float s, c; float s, c;
@ -1299,11 +1145,7 @@ void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D
out.x = s * y + c * x; out.x = s * y + c * x;
out.y = c * y - s * 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 // Transform from section indices to world coordinates
void CRadar::GetTextureCorners(int32 x, int32 y, CVector2D *out) 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].x = RADAR_TILE_SIZE * (x);
out[3].y = RADAR_TILE_SIZE * (y); 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) void CRadar::ClipRadarTileCoords(int32 &x, int32 &y)
{ {
if (x < 0) if (x < 0)
@ -1342,24 +1180,16 @@ void CRadar::ClipRadarTileCoords(int32 &x, int32 &y)
if (y > RADAR_NUM_TILES-1) if (y > RADAR_NUM_TILES-1)
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) bool CRadar::IsPointInsideRadar(const CVector2D &point)
{ {
if (point.x < -1.0f || point.x > 1.0f) return false; if (point.x < -1.0f || point.x > 1.0f) return false;
if (point.y < -1.0f || point.y > 1.0f) return false; if (point.y < -1.0f || point.y > 1.0f) return false;
return true; return true;
} }
#endif
// clip line p1,p2 against (-1.0, 1.0) in x and y, set out to clipped point closest to p1 // 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) int CRadar::LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D &p2)
{ {
float d1, d2; float d1, d2;
@ -1430,7 +1260,6 @@ int CRadar::LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVe
return edge; return edge;
} }
#endif
STARTPATCHES STARTPATCHES
InjectHook(0x4A3EF0, CRadar::Initialise, PATCH_JUMP); 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 WriteVideoCardCapsFile(void) { EAXJMP(0x5927D0); }
WRAPPER void ConvertingTexturesScreen(uint32, uint32, const char*) { EAXJMP(0x592880); } WRAPPER void ConvertingTexturesScreen(uint32, uint32, const char*) { EAXJMP(0x592880); }
WRAPPER void DealWithTxdWriteError(uint32, uint32, const char*) { EAXJMP(0x592BF0); } 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 STARTPATCHES
//InjectHook(0x526450, GetFirstObjectCallback, PATCH_JUMP); //InjectHook(0x526450, GetFirstObjectCallback, PATCH_JUMP);

View File

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

View File

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

View File

@ -10,6 +10,7 @@
#include "TxdStore.h" #include "TxdStore.h"
#include "ModelIndices.h" #include "ModelIndices.h"
#include "Pools.h" #include "Pools.h"
#include "Wanted.h"
#include "Directory.h" #include "Directory.h"
#include "RwHelper.h" #include "RwHelper.h"
#include "World.h" #include "World.h"
@ -198,7 +199,7 @@ CStreaming::Init(void)
// PC only, figure out how much memory we got // PC only, figure out how much memory we got
#ifdef GTA_PC #ifdef GTA_PC
#define MB (1024*1024) #define MB (1024*1024)
extern DWORD &_dwMemAvailPhys; extern unsigned long &_dwMemAvailPhys;
ms_memoryAvailable = (_dwMemAvailPhys - 10*MB)/2; ms_memoryAvailable = (_dwMemAvailPhys - 10*MB)/2;
if(ms_memoryAvailable < 50*MB) if(ms_memoryAvailable < 50*MB)
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) void CTimer::Update(void)
{ {
m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds; m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds;
@ -149,7 +146,6 @@ void CTimer::Update(void)
m_FrameCounter++; m_FrameCounter++;
} }
#endif
void CTimer::Suspend(void) void CTimer::Suspend(void)
{ {
@ -218,6 +214,11 @@ void CTimer::EndUserPause(void)
m_UserPause = false; m_UserPause = false;
} }
uint32 CTimer::GetCyclesPerFrame()
{
return 20;
}
#if 1 #if 1
STARTPATCHES STARTPATCHES
InjectHook(0x4ACE60, CTimer::Initialise, PATCH_JUMP); InjectHook(0x4ACE60, CTimer::Initialise, PATCH_JUMP);

View File

@ -2,7 +2,7 @@
class CTimer class CTimer
{ {
public:
static uint32 &m_snTimeInMilliseconds; static uint32 &m_snTimeInMilliseconds;
static uint32 &m_snTimeInMillisecondsPauseMode; static uint32 &m_snTimeInMillisecondsPauseMode;
static uint32 &m_snTimeInMillisecondsNonClipped; static uint32 &m_snTimeInMillisecondsNonClipped;
@ -11,19 +11,20 @@ public:
static float &ms_fTimeScale; static float &ms_fTimeScale;
static float &ms_fTimeStep; static float &ms_fTimeStep;
static float &ms_fTimeStepNonClipped; static float &ms_fTimeStepNonClipped;
public:
static bool &m_UserPause; static bool &m_UserPause;
static bool &m_CodePause; 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 void SetTimeStep(float ts) { ms_fTimeStep = ts; }
static float GetTimeStepInSeconds() { return ms_fTimeStep / 50.0f; } static float GetTimeStepInSeconds() { return ms_fTimeStep / 50.0f; }
static float GetTimeStepInMilliseconds() { return ms_fTimeStep / 50.0f * 1000.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 float GetTimeStepNonClippedInSeconds(void) { return ms_fTimeStepNonClipped / 50.0f; }
static void SetTimeStepNonClipped(float ts) { ms_fTimeStepNonClipped = ts; } 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 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 void SetTimeInMilliseconds(uint32 t) { m_snTimeInMilliseconds = t; }
static uint32 GetTimeInMillisecondsNonClipped(void) { return m_snTimeInMillisecondsNonClipped; } static uint32 GetTimeInMillisecondsNonClipped(void) { return m_snTimeInMillisecondsNonClipped; }
static void SetTimeInMillisecondsNonClipped(uint32 t) { m_snTimeInMillisecondsNonClipped = t; } static void SetTimeInMillisecondsNonClipped(uint32 t) { m_snTimeInMillisecondsNonClipped = t; }
@ -31,8 +32,9 @@ public:
static void SetTimeInMillisecondsPauseMode(uint32 t) { m_snTimeInMillisecondsPauseMode = t; } static void SetTimeInMillisecondsPauseMode(uint32 t) { m_snTimeInMillisecondsPauseMode = t; }
static uint32 GetPreviousTimeInMilliseconds(void) { return m_snPreviousTimeInMilliseconds; } static uint32 GetPreviousTimeInMilliseconds(void) { return m_snPreviousTimeInMilliseconds; }
static void SetPreviousTimeInMilliseconds(uint32 t) { m_snPreviousTimeInMilliseconds = t; } 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 void SetTimeScale(float ts) { ms_fTimeScale = ts; }
static uint32 GetCyclesPerFrame();
static bool GetIsPaused() { return m_UserPause || m_CodePause; } static bool GetIsPaused() { return m_UserPause || m_CodePause; }
static bool GetIsUserPaused() { return m_UserPause; } 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; RwTexDictionary *&CTxdStore::ms_pStoredTxd = *(RwTexDictionary**)0x9405BC;
void void
CTxdStore::Initialize(void) CTxdStore::Initialise(void)
{ {
if(ms_pTxdPool == nil) if(ms_pTxdPool == nil)
ms_pTxdPool = new CPool<TxdDef,TxdDef>(TXDSTORESIZE); ms_pTxdPool = new CPool<TxdDef,TxdDef>(TXDSTORESIZE);
@ -187,7 +187,7 @@ CTxdStore::RemoveTxd(int slot)
} }
STARTPATCHES STARTPATCHES
InjectHook(0x527440, CTxdStore::Initialize, PATCH_JUMP); InjectHook(0x527440, CTxdStore::Initialise, PATCH_JUMP);
InjectHook(0x527470, CTxdStore::Shutdown, PATCH_JUMP); InjectHook(0x527470, CTxdStore::Shutdown, PATCH_JUMP);
InjectHook(0x527490, CTxdStore::GameShutdown, PATCH_JUMP); InjectHook(0x527490, CTxdStore::GameShutdown, PATCH_JUMP);
InjectHook(0x5274E0, CTxdStore::AddTxdSlot, PATCH_JUMP); InjectHook(0x5274E0, CTxdStore::AddTxdSlot, PATCH_JUMP);

View File

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

View File

@ -7,19 +7,16 @@
#include "ZoneCull.h" #include "ZoneCull.h"
#include "Darkel.h" #include "Darkel.h"
#include "DMAudio.h" #include "DMAudio.h"
#include "CopPed.h"
#include "Wanted.h" #include "Wanted.h"
#include "General.h"
int32 &CWanted::MaximumWantedLevel = *(int32*)0x5F7714; // 6 int32 &CWanted::MaximumWantedLevel = *(int32*)0x5F7714; // 6
int32 &CWanted::nMaximumWantedLevel = *(int32*)0x5F7718; // 6400 int32 &CWanted::nMaximumWantedLevel = *(int32*)0x5F7718; // 6400
WRAPPER void CWanted::Reset() { EAXJMP(0x4AD790) };
WRAPPER void CWanted::Update() { EAXJMP(0x4AD7B0) };
void void
CWanted::Initialise() CWanted::Initialise()
{ {
int i;
m_nChaos = 0; m_nChaos = 0;
m_nLastUpdateTime = 0; m_nLastUpdateTime = 0;
m_nLastWantedLevelChange = 0; m_nLastWantedLevelChange = 0;
@ -35,8 +32,10 @@ CWanted::Initialise()
m_fCrimeSensitivity = 1.0f; m_fCrimeSensitivity = 1.0f;
m_nWantedLevel = 0; m_nWantedLevel = 0;
m_CopsBeatingSuspect = 0; m_CopsBeatingSuspect = 0;
for(i = 0; i < 10; i++)
for (int i = 0; i < ARRAY_SIZE(m_pCops); i++)
m_pCops[i] = nil; m_pCops[i] = nil;
ClearQdCrimes(); ClearQdCrimes();
} }
@ -61,7 +60,7 @@ CWanted::AreArmyRequired()
int32 int32
CWanted::NumOfHelisRequired() CWanted::NumOfHelisRequired()
{ {
if (m_bIgnoredByCops) if (m_bIgnoredByCops || m_bIgnoredByEveryone)
return 0; return 0;
switch (m_nWantedLevel) { switch (m_nWantedLevel) {
@ -79,9 +78,10 @@ CWanted::NumOfHelisRequired()
void void
CWanted::SetWantedLevel(int32 level) CWanted::SetWantedLevel(int32 level)
{ {
ClearQdCrimes();
if (level > MaximumWantedLevel) if (level > MaximumWantedLevel)
level = MaximumWantedLevel; level = MaximumWantedLevel;
ClearQdCrimes();
switch (level) { switch (level) {
case 0: case 0:
m_nChaos = 0; m_nChaos = 0;
@ -360,10 +360,107 @@ CWanted::WorkOutPolicePresence(CVector posn, float radius)
return numPolice; 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 STARTPATCHES
InjectHook(0x4AD6E0, &CWanted::Initialise, PATCH_JUMP); InjectHook(0x4AD6E0, &CWanted::Initialise, PATCH_JUMP);
// InjectHook(0x4AD790, &CWanted::Reset, PATCH_JUMP); InjectHook(0x4AD790, &CWanted::Reset, PATCH_JUMP);
// InjectHook(0x4AD7B0, &CWanted::Update, PATCH_JUMP); InjectHook(0x4AD7B0, &CWanted::Update, PATCH_JUMP);
InjectHook(0x4AD900, &CWanted::UpdateWantedLevel, PATCH_JUMP); InjectHook(0x4AD900, &CWanted::UpdateWantedLevel, PATCH_JUMP);
InjectHook(0x4AD9F0, &CWanted::RegisterCrime, PATCH_JUMP); InjectHook(0x4AD9F0, &CWanted::RegisterCrime, PATCH_JUMP);
InjectHook(0x4ADA10, &CWanted::RegisterCrime_Immediately, PATCH_JUMP); InjectHook(0x4ADA10, &CWanted::RegisterCrime_Immediately, PATCH_JUMP);
@ -374,10 +471,10 @@ STARTPATCHES
InjectHook(0x4ADBC0, &CWanted::AreFbiRequired, PATCH_JUMP); InjectHook(0x4ADBC0, &CWanted::AreFbiRequired, PATCH_JUMP);
InjectHook(0x4ADBE0, &CWanted::AreArmyRequired, PATCH_JUMP); InjectHook(0x4ADBE0, &CWanted::AreArmyRequired, PATCH_JUMP);
InjectHook(0x4ADC00, &CWanted::NumOfHelisRequired, 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(0x4ADD00, &CWanted::WorkOutPolicePresence, PATCH_JUMP);
InjectHook(0x4ADF20, &CWanted::ClearQdCrimes, PATCH_JUMP); InjectHook(0x4ADF20, &CWanted::ClearQdCrimes, PATCH_JUMP);
InjectHook(0x4ADFD0, &CWanted::AddCrimeToQ, 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); InjectHook(0x4AE110, &CWanted::ReportCrimeNow, PATCH_JUMP);
ENDPATCHES ENDPATCHES

View File

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

View File

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

View File

@ -60,8 +60,6 @@ class CWorld
static uint16 &ms_nCurrentScanCode; static uint16 &ms_nCurrentScanCode;
public: public:
static CColPoint& ms_testSpherePoint;
static uint8 &PlayerInFocus; static uint8 &PlayerInFocus;
static CPlayerInfo (&Players)[NUMPLAYERS]; static CPlayerInfo (&Players)[NUMPLAYERS];
static CEntity *&pIgnoreEntity; 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 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 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 CEntity *TestSphereAgainstSectorList(CPtrList&, CVector, float, CEntity*, bool);
static void FindObjectsInRangeSectorList(CPtrList&, CVector&, float, bool, short*, short, CEntity**); static void FindObjectsInRangeSectorList(CPtrList&, CVector&, float, bool, short*, short, CEntity**);
static void FindObjectsInRange(CVector&, float, bool, short*, short, CEntity**, bool, bool, bool, bool, bool); 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 FindMissionEntitiesIntersectingCube(const CVector&, const CVector&, int16*, int16, CEntity**, bool, bool, bool);
static void ClearCarsFromArea(float, float, float, float, float, float); static void ClearCarsFromArea(float, float, float, float, float, float);
static void ClearPedsFromArea(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 GetSectorX(float f) { return ((f - WORLD_MIN_X)/SECTOR_SIZE_X); }
static float GetSectorY(float f) { return ((f - WORLD_MIN_Y)/SECTOR_SIZE_Y); } static float GetSectorY(float f) { return ((f - WORLD_MIN_Y)/SECTOR_SIZE_Y); }
@ -132,15 +131,19 @@ public:
static void StopAllLawEnforcersInTheirTracks(); static void StopAllLawEnforcersInTheirTracks();
static void SetAllCarsCanBeDamaged(bool); static void SetAllCarsCanBeDamaged(bool);
static void ExtinguishAllCarFiresInArea(CVector, float); static void ExtinguishAllCarFiresInArea(CVector, float);
static void SetCarsOnFire(float, float, float, float, CEntity*);
static void Initialise(); static void Initialise();
static void AddParticles(); static void AddParticles();
static void ShutDown(); static void ShutDown();
static void ClearForRestart(void);
static void RepositionCertainDynamicObjects(); static void RepositionCertainDynamicObjects();
static void RemoveStaticObjects(); static void RemoveStaticObjects();
static void Process(); static void Process();
}; };
extern CColPoint *gaTempSphereColPoints;
class CPlayerPed; class CPlayerPed;
class CVehicle; class CVehicle;
CPlayerPed *FindPlayerPed(void); CPlayerPed *FindPlayerPed(void);

View File

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

View File

@ -8,9 +8,12 @@
#pragma warning(disable: 4996) // POSIX names #pragma warning(disable: 4996) // POSIX names
#include <stdint.h> #include <stdint.h>
#include <string.h>
#include <math.h> #include <math.h>
//#include <assert.h>
#include <new> #ifdef WITHWINDOWS
#include <Windows.h>
#endif
#ifdef WITHD3D #ifdef WITHD3D
#include <windows.h> #include <windows.h>
@ -30,6 +33,16 @@
#undef near #undef near
#endif #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 uint8_t uint8;
typedef int8_t int8; typedef int8_t int8;
typedef uint16_t uint16; 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 ABS(a) (((a) < 0) ? (-(a)) : (a))
#define norm(value, min, max) (((value) < (min)) ? 0 : (((value) > (max)) ? 1 : (((value) - (min)) / ((max) - (min))))) #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 STRINGIFY(x) #x
#define STR(x) STRINGIFY(x) #define STR(x) STRINGIFY(x)

View File

@ -94,12 +94,17 @@ enum Config {
NUM_GARAGES = 32, NUM_GARAGES = 32,
NUM_PROJECTILES = 32, NUM_PROJECTILES = 32,
NUM_GLASSPANES = 45,
NUM_GLASSENTITIES = 32,
NUM_WATERCANNONS = 3, NUM_WATERCANNONS = 3,
NUMPEDROUTES = 200, NUMPEDROUTES = 200,
NUMPHONES = 50, NUMPHONES = 50,
NUMPEDGROUPS = 31, NUMPEDGROUPS = 31,
NUMMODELSPERPEDGROUP = 8, NUMMODELSPERPEDGROUP = 8,
NUMSHOTINFOS = 100,
NUMROADBLOCKS = 600,
NUMVISIBLEENTITIES = 2000, NUMVISIBLEENTITIES = 2000,
NUMINVISIBLEENTITIES = 150, NUMINVISIBLEENTITIES = 150,
@ -114,6 +119,8 @@ enum Config {
NUM_AUDIO_REFLECTIONS = 5, NUM_AUDIO_REFLECTIONS = 5,
NUM_SCRIPT_MAX_ENTITIES = 40, NUM_SCRIPT_MAX_ENTITIES = 40,
NUM_GARAGE_STORED_CARS = 6
}; };
// We'll use this once we're ready to become independent of the game // We'll use this once we're ready to become independent of the game
@ -166,13 +173,17 @@ enum Config {
# define NO_MOVIES // disable intro videos # define NO_MOVIES // disable intro videos
# define NO_CDCHECK # define NO_CDCHECK
# define CHATTYSPLASH // print what the game is loading # define CHATTYSPLASH // print what the game is loading
//# define TIMEBARS // print debug timers
#endif #endif
#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more #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 // Pad
#define XINPUT
#define KANGAROO_CHEAT #define KANGAROO_CHEAT
#define REGISTER_START_BUTTON // currently only in menu sadly. resumes the game
// Hud, frontend and radar // Hud, frontend and radar
#define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios #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 // Peds
#define ANIMATE_PED_COL_MODEL #define ANIMATE_PED_COL_MODEL
#define VC_PED_PORTS // various ports from VC's CPed, mostly subtle #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 #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 "Script.h"
#include "Debug.h" #include "Debug.h"
#include "Console.h" #include "Console.h"
#include "timebars.h"
#define DEFAULT_VIEWWINDOW (Tan(DEGTORAD(CDraw::GetFOV() * 0.5f))) #define DEFAULT_VIEWWINDOW (Tan(DEGTORAD(CDraw::GetFOV() * 0.5f)))
@ -90,7 +91,6 @@ void DoFade(void);
void Render2dStuffAfterFade(void); void Render2dStuffAfterFade(void);
CSprite2d *LoadSplash(const char *name); CSprite2d *LoadSplash(const char *name);
void DestroySplashScreen(void);
extern void (*DebugMenuProcess)(void); extern void (*DebugMenuProcess)(void);
@ -142,6 +142,11 @@ Idle(void *arg)
#endif #endif
CTimer::Update(); CTimer::Update();
#ifdef TIMEBARS
tbInit();
#endif
CSprite2d::InitPerFrame(); CSprite2d::InitPerFrame();
CFont::InitPerFrame(); CFont::InitPerFrame();
@ -156,16 +161,39 @@ Idle(void *arg)
FrontEndMenuManager.Process(); FrontEndMenuManager.Process();
} else { } else {
CPointLights::InitPerFrame(); CPointLights::InitPerFrame();
#ifdef TIMEBARS
tbStartTimer(0, "CGame::Process");
#endif
CGame::Process(); CGame::Process();
#ifdef TIMEBARS
tbEndTimer("CGame::Process");
tbStartTimer(0, "DMAudio.Service");
#endif
DMAudio.Service(); DMAudio.Service();
#ifdef TIMEBARS
tbEndTimer("DMAudio.Service");
#endif
} }
if (RsGlobal.quit) if (RsGlobal.quit)
return; return;
#else #else
CPointLights::InitPerFrame(); CPointLights::InitPerFrame();
#ifdef TIMEBARS
tbStartTimer(0, "CGame::Process");
#endif
CGame::Process(); CGame::Process();
#ifdef TIMEBARS
tbEndTimer("CGame::Process");
tbStartTimer(0, "DMAudio.Service");
#endif
DMAudio.Service(); DMAudio.Service();
#ifdef TIMEBARS
tbEndTimer("DMAudio.Service");
#endif
#endif #endif
if(CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()){ if(CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()){
@ -192,9 +220,19 @@ Idle(void *arg)
pos.y = SCREEN_HEIGHT / 2.0f; pos.y = SCREEN_HEIGHT / 2.0f;
RsMouseSetPos(&pos); RsMouseSetPos(&pos);
} }
#endif
#ifdef TIMEBARS
tbStartTimer(0, "CnstrRenderList");
#endif #endif
CRenderer::ConstructRenderList(); CRenderer::ConstructRenderList();
#ifdef TIMEBARS
tbEndTimer("CnstrRenderList");
tbStartTimer(0, "PreRender");
#endif
CRenderer::PreRender(); CRenderer::PreRender();
#ifdef TIMEBARS
tbEndTimer("PreRender");
#endif
if(CWeather::LightningFlash && !CCullZones::CamNoRain()){ if(CWeather::LightningFlash && !CCullZones::CamNoRain()){
if(!DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255)) if(!DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255))
@ -212,16 +250,31 @@ Idle(void *arg)
RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip()); RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip());
RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart()); RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart());
#ifdef TIMEBARS
tbStartTimer(0, "RenderScene");
#endif
RenderScene(); RenderScene();
#ifdef TIMEBARS
tbEndTimer("RenderScene");
#endif
RenderDebugShit(); RenderDebugShit();
RenderEffects(); RenderEffects();
#ifdef TIMEBARS
tbStartTimer(0, "RenderMotionBlur");
#endif
if((TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_NORMAL) && if((TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_NORMAL) &&
TheCamera.m_ScreenReductionPercentage > 0.0f) TheCamera.m_ScreenReductionPercentage > 0.0f)
TheCamera.SetMotionBlurAlpha(150); TheCamera.SetMotionBlurAlpha(150);
TheCamera.RenderMotionBlur(); TheCamera.RenderMotionBlur();
#ifdef TIMEBARS
tbEndTimer("RenderMotionBlur");
tbStartTimer(0, "Render2dStuff");
#endif
Render2dStuff(); Render2dStuff();
#ifdef TIMEBARS
tbEndTimer("Render2dStuff");
#endif
}else{ }else{
float viewWindow = DEFAULT_VIEWWINDOW; float viewWindow = DEFAULT_VIEWWINDOW;
#ifdef ASPECT_RATIO_SCALE #ifdef ASPECT_RATIO_SCALE
@ -238,11 +291,30 @@ Idle(void *arg)
#ifdef PS2_SAVE_DIALOG #ifdef PS2_SAVE_DIALOG
if (FrontEndMenuManager.m_bMenuActive) if (FrontEndMenuManager.m_bMenuActive)
DefinedState(); DefinedState();
#endif
#ifdef TIMEBARS
tbStartTimer(0, "RenderMenus");
#endif #endif
RenderMenus(); RenderMenus();
#ifdef TIMEBARS
tbEndTimer("RenderMenus");
tbStartTimer(0, "DoFade");
#endif
DoFade(); DoFade();
#ifdef TIMEBARS
tbEndTimer("DoFade");
tbStartTimer(0, "Render2dStuff-Fade");
#endif
Render2dStuffAfterFade(); Render2dStuffAfterFade();
#ifdef TIMEBARS
tbEndTimer("Render2dStuff-Fade");
#endif
CCredits::Render(); CCredits::Render();
#ifdef TIMEBARS
tbDisplay();
#endif
DoRWStuffEndOfFrame(); DoRWStuffEndOfFrame();
// if(g_SlowMode) // if(g_SlowMode)
@ -325,8 +397,9 @@ DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16
void void
DoRWStuffEndOfFrame(void) DoRWStuffEndOfFrame(void)
{ {
CDebug::DisplayScreenStrings(); // custom
CDebug::DebugDisplayTextBuffer(); CDebug::DebugDisplayTextBuffer();
// FlushObrsPrintfs(); FlushObrsPrintfs();
RwCameraEndUpdate(Scene.camera); RwCameraEndUpdate(Scene.camera);
RsCameraShowRaster(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 LoadingScreen(const char *str1, const char *str2, const char *splashscreen);
void LoadingIslandScreen(const char *levelName); void LoadingIslandScreen(const char *levelName);
CSprite2d *LoadSplash(const char *name); CSprite2d *LoadSplash(const char *name);
void DestroySplashScreen(void);
char *GetLevelSplashScreen(int level); char *GetLevelSplashScreen(int level);
char *GetRandomSplashScreen(void); char *GetRandomSplashScreen(void);
void LittleTest(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 "common.h"
#include "patcher.h" #include "patcher.h"
#include <algorithm>
#include <vector>
#include <Windows.h>
StaticPatcher *StaticPatcher::ms_head; StaticPatcher *StaticPatcher::ms_head;
StaticPatcher::StaticPatcher(Patcher func) StaticPatcher::StaticPatcher(Patcher func)
@ -20,3 +25,55 @@ StaticPatcher::Apply()
} }
ms_head = nil; 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 VARJMP(a) { _asm jmp a }
#define WRAPARG(a) UNREFERENCED_PARAMETER(a) #define WRAPARG(a) UNREFERENCED_PARAMETER(a)
#define NOVMT __declspec(novtable) #include <string.h> //memset
#define SETVMT(a) *((DWORD_PTR*)this) = (DWORD_PTR)a
#include <algorithm>
#include <vector>
#include "common.h"
enum enum
{ {
@ -103,72 +97,30 @@ isVC(void)
InjectHook(a, func); \ 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 template<typename T, typename AT> inline void
Patch(AT address, T value) Patch(AT address, T value)
{ {
DWORD dwProtect[2]; Protect_internal((uint32)address, sizeof(T));
VirtualProtect((void*)address, sizeof(T), PAGE_EXECUTE_READWRITE, &dwProtect[0]);
*(T*)address = value; *(T*)address = value;
VirtualProtect((void*)address, sizeof(T), dwProtect[0], &dwProtect[1]); Unprotect_internal();
} }
template<typename AT> inline void template<typename AT> inline void
Nop(AT address, unsigned int nCount) Nop(AT address, unsigned int nCount)
{ {
DWORD dwProtect[2]; Protect_internal((uint32)address, nCount);
VirtualProtect((void*)address, nCount, PAGE_EXECUTE_READWRITE, &dwProtect[0]);
memset((void*)address, 0x90, nCount); memset((void*)address, 0x90, nCount);
VirtualProtect((void*)address, nCount, dwProtect[0], &dwProtect[1]); Unprotect_internal();
} }
template<typename AT> inline void template <typename T> inline void
ClearCC(AT address, unsigned int nCount) InjectHook(uintptr_t address, T hook, unsigned int nType = PATCH_NOTHING)
{ {
DWORD dwProtect[2]; InjectHook_internal(address, reinterpret_cast<uintptr_t>((void *&)hook), nType);
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]);
} }
inline void ExtractCall(void *dst, uint32_t a) inline void ExtractCall(void *dst, uint32_t a)

View File

@ -20,12 +20,10 @@
#include "debugmenu_public.h" #include "debugmenu_public.h"
#include "Particle.h" #include "Particle.h"
#include "Console.h" #include "Console.h"
#include "Debug.h"
#include <vector>
#include <list> #include <list>
std::vector<int32> usedAddresses;
void **rwengine = *(void***)0x5A10E1; void **rwengine = *(void***)0x5A10E1;
DebugMenuAPI gDebugMenuAPI; DebugMenuAPI gDebugMenuAPI;
@ -114,13 +112,16 @@ SpawnCar(int id)
CStreaming::LoadAllRequestedModels(false); CStreaming::LoadAllRequestedModels(false);
if(CStreaming::HasModelLoaded(id)){ if(CStreaming::HasModelLoaded(id)){
playerpos = FindPlayerCoors(); playerpos = FindPlayerCoors();
int node = ThePaths.FindNodeClosestToCoors(playerpos, 0, 100.0f, false, false); int node;
if(!CModelInfo::IsBoatModel(id)){
node = ThePaths.FindNodeClosestToCoors(playerpos, 0, 100.0f, false, false);
if(node < 0) if(node < 0)
return; return;
}
CVehicle *v; CVehicle *v;
if(CModelInfo::IsBoatModel(id)) if(CModelInfo::IsBoatModel(id))
return; v = new CBoat(id, RANDOM_VEHICLE);
else else
v = new CAutomobile(id, RANDOM_VEHICLE); v = new CAutomobile(id, RANDOM_VEHICLE);
@ -130,7 +131,11 @@ SpawnCar(int id)
if(carCol2) if(carCol2)
DebugMenuEntrySetAddress(carCol2, &v->m_currentColour2); DebugMenuEntrySetAddress(carCol2, &v->m_currentColour2);
if(CModelInfo::IsBoatModel(id))
v->GetPosition() = TheCamera.GetPosition() + TheCamera.GetForward()*15.0f;
else
v->GetPosition() = ThePaths.m_pathNodes[node].pos; v->GetPosition() = ThePaths.m_pathNodes[node].pos;
v->GetPosition().z += 4.0f; v->GetPosition().z += 4.0f;
v->SetOrientation(0.0f, 0.0f, 3.49f); v->SetOrientation(0.0f, 0.0f, 3.49f);
v->m_status = STATUS_ABANDONED; v->m_status = STATUS_ABANDONED;
@ -197,6 +202,12 @@ PlaceOnRoad(void)
((CAutomobile*)veh)->PlaceOnRoadProperly(); ((CAutomobile*)veh)->PlaceOnRoadProperly();
} }
static void
ResetCamStatics(void)
{
TheCamera.Cams[TheCamera.ActiveCam].ResetStatics = true;
}
static const char *carnames[] = { static const char *carnames[] = {
"landstal", "idaho", "stinger", "linerun", "peren", "sentinel", "patriot", "firetruk", "trash", "stretch", "manana", "infernus", "blista", "pony", "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", "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", "Start Credits", CCredits::Start);
DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop); 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"); CTweakVars::AddDBG("Debug");
} }
} }
@ -433,7 +458,8 @@ void re3_debug(const char *format, ...)
vsprintf_s(re3_buff, re3_buffsize, format, va); vsprintf_s(re3_buff, re3_buffsize, format, va);
va_end(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, ...) 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); CStreaming::RequestModel(id, STREAMFLAGS_DONT_REMOVE);
} }
#include <new>
class CBuilding_ : public CBuilding class CBuilding_ : public CBuilding
{ {
public: public:

View File

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

View File

@ -39,6 +39,14 @@ public:
x = 1.0f; 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) { const CVector &operator+=(CVector const &right) {
x += right.x; x += right.x;
y += right.y; y += right.y;

View File

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

View File

@ -132,5 +132,6 @@ public:
static void ShutdownEnvironmentMaps(void); static void ShutdownEnvironmentMaps(void);
static int GetMaximumNumberOfPassengersFromNumberOfDoors(int id); 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"); static_assert(sizeof(CVehicleModelInfo) == 0x1F8, "CVehicleModelInfo: error");

View File

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

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