Merge remote-tracking branch 'upstream/master' into script_dev

This commit is contained in:
Nikolay Korolev 2019-11-09 16:44:36 +03:00
commit 5ef291ddf2
30 changed files with 1620 additions and 489 deletions

124
README.md
View File

@ -1,76 +1,88 @@
# Intro
# re3
[![Build status](https://ci.appveyor.com/api/projects/status/hyiwgegks122h8jg?svg=true)](https://ci.appveyor.com/project/aap/re3/branch/master)
<a href="https://discord.gg/jYpXxTm"><img src="https://img.shields.io/badge/discord-join-7289DA.svg?logo=discord&longCache=true&style=flat" /></a>
<a href="https://ci.appveyor.com/api/projects/aap/re3/artifacts/bin/Debug/re3.dll?branch=master&job=Configuration%3A+Debug"><img src="https://img.shields.io/badge/download-debug-9cf.svg" /></a>
<a href="https://ci.appveyor.com/api/projects/aap/re3/artifacts/bin/Release/re3.dll?branch=master&job=Configuration%3A+Release"><img src="https://img.shields.io/badge/download-release-blue.svg" /></a>
## Intro
The aim of this project is to reverse GTA III for PC by replacing
parts of the game [one by one](https://en.wikipedia.org/wiki/Ship_of_Theseus)
such that we have a working game at all times.
Apparently you can download a binary of the latest version here:
[Debug](https://ci.appveyor.com/api/projects/aap/re3/artifacts/bin/Debug/re3.dll?branch=master&job=Configuration%3A+Debug),
[Release](https://ci.appveyor.com/api/projects/aap/re3/artifacts/bin/Release/re3.dll?branch=master&job=Configuration%3A+Release).
## How can I try it?
Build status:
[![Build status](https://ci.appveyor.com/api/projects/status/hyiwgegks122h8jg?svg=true)](https://ci.appveyor.com/project/aap/re3/branch/master)
- re3 requires game assets to work, so you need to own a copy of GTA III.
- Since re3 is a DLL that works with original GTA III for now, you need Simple DLL Loader. You can get it [here](https://github.com/aap/simpledllloader).
- Build re3 or download it from one of the above links (Debug or Release).
- Make sure you included the re3 in `plugins.cfg` or `dlls.cfg`.
- re3 starts the script `main_freeroam.scm` that comes along with it by default, so you should copy it to from `gamefiles/` to your game's `data/` directory.
Re3 starts the script main_freeroam.scm by default. Make sure you copy it to your data directory.
![#ffa500](https://placehold.it/15/ffa500/000000?text=+) **Notice**
# Strategy
If you want to load original script/story, press and hold G while game is loading.
This includes both starting new game and loading save game.
![#ffa500](https://placehold.it/15/ffa500/000000?text=+) **Notice if you will build it**
There are various settings at the very bottom of `config.h`, you may want to take a look there. i.e. FIX_BUGS define fixes the bugs we've come across.
https://github.com/GTAmodding/re3/tree/master/src/core/config.h
## I want to contribute, where should I start?
A good approach is to start at the fringes of the code base,
i.e. classes that don't depend on code that we don't have reversed yet.
If a function uses only few unreversed functions that would be inconvenient
to reverse at the time, calling the original functions is acceptable.
# Progress
This is a list of some things that have been reversed to some non-trivial extent.
Not everything is listed, check the code.
(TODO: keep this list at least a bit up to date...)
### Unreversed / incomplete classes (at least the ones we know)
```
CPool
CTxdStore
CVector
CVector2D
CMatrix
CModelInfo
CBaseModelInfo
CSimpleModelInfo
CTimeModelInfo
CClumpModelInfo
CPedModelInfo
CVehicleModelInfo
CVisibilityPlugins
CRenderer
CSprite
CSprite2d
CFont
CEntity
CPhysical
CCollision
CCullZones
CTheZones
CPathFind
CAudioManager, cDMAudio, cSampleManager and all audio - being worked on
CAccidentManager
CBoat
CBrightLights
CBulletInfo
CBulletTraces
CCam
CParticle
CParticleMgr
CPointLights
CCoronas
CAntennas
CClouds
CHud
CCamera
CCivilianPed
CCopPed
CCrane
CCranes
CCullZone
CCullZones
CEmergencyPed
CExplosion
CFallingGlassPane
CFire
CFireManager
CGame
CGarage
CGarages
CGlass
CMenuManager
CMotionBlurStreaks
CPacManPickups
CPed - being worked on
CPedIK
CPhoneInfo - one function left
CPlayerInfo
CPlayerPed
CProjectile
CProjectileInfo
CRoadBlocks
CRunningScript - being worked on
CStats
CSpecialFX
CTrafficLights
CWaterCannon
CWaterCannons
CWeapon
CWeaponEffects
```
# Low hanging fruit
There are a couple of things that have been reversed for other projects
already that could probably be put into this project without too much effort.
Again, the list is not complete:
* ~~Animation (https://github.com/aap/iii_anim)~~
* File Loader (https://github.com/aap/librwgta/tree/master/tools/IIItest)
* ...
# Coding style
### Coding style
I started writing in [Plan 9 style](http://man.cat-v.org/plan_9/6/style),
but realize that this is not the most popular style, so I'm willing to compromise.
@ -178,7 +190,7 @@ but here are some observations:
* Generally, try to make the code look as if R* could have written it
# Environment Variables
### Environment Variables
Here you can find a list of variables that you might need to set in windows:
```
"GTA_III_RE_DIR" * path to "gta3_re" game folder usually where this plugin run.

View File

@ -61,9 +61,9 @@ enum AnimationId
ANIM_KD_LEFT,
ANIM_KD_RIGHT,
ANIM_KO_SKID_FRONT,
ANIM_KO_SPIN_R,
ANIM_KO_SPIN_R, // named left in VC
ANIM_KO_SKID_BACK,
ANIM_KO_SPIN_L,
ANIM_KO_SPIN_L, // named right in VC
ANIM_SHOT_FRONT_PARTIAL,
ANIM_SHOT_LEFT_PARTIAL,
ANIM_SHOT_BACK_PARTIAL,

View File

@ -38,11 +38,18 @@
#include "sampman.h"
cAudioManager &AudioManager = *(cAudioManager *)0x880FC0;
uint32 *audioLogicTimers = (uint32 *)0x6508A0;
uint32 &gPornNextTime = *(uint32*)0x6508A0;
uint32 &gSawMillNextTime = *(uint32*)0x6508A4;
uint32 &gShopNextTime = *(uint32*)0x6508A8;
uint32 &gAirportNextTime = *(uint32*)0x6508AC;
uint32 &gCinemaNextTime = *(uint32*)0x6508B0;
uint32 &gDocksNextTime = *(uint32*)0x6508B4;
uint32 &gHomeNextTime = *(uint32*)0x6508B8;
uint32 &gCellNextTime = *(uint32*)0x6508BC;
uint32 &gNextCryTime = *(uint32*)0x6508C0;
uint8 &jumboVolOffset = *(uint8 *)0x6508ED;
uint8 &gJumboVolOffsetPercentage = *(uint8 *)0x6508ED;
char &g_nMissionAudioPlayingStatus = *(char *)0x60ED88;
int32 *BankStartOffset = (int32 *)0x6FAB70; //[2]
int32 &g_nMissionAudioSfx = *(int32 *)0x60ED84;
bool &bPlayerJustEnteredCar = *(bool *)0x6508C4;
bool &g_bMissionAudioLoadFailed = *(bool *)0x95CD8E;
@ -415,47 +422,47 @@ cAudioManager::AddReleasingSounds()
{
bool toProcess[44];
for(int32 i = 0; i < m_bSampleRequestQueuesStatus[m_bActiveSampleQueue]; i++) {
tActiveSample &sample =
m_asSamples[!m_bActiveSampleQueue][m_abSampleQueueIndexTable[!m_bActiveSampleQueue][i]];
if(!m_asSamples[!m_bActiveSampleQueue][m_abSampleQueueIndexTable[!m_bActiveSampleQueue][i]]
.m_bLoopEnded) {
toProcess[i] = false;
for(int32 j = 0; j < m_bSampleRequestQueuesStatus[m_bActiveSampleQueue]; j++) {
if(sample.m_nEntityIndex ==
m_asSamples[m_bActiveSampleQueue]
[m_abSampleQueueIndexTable[m_bActiveSampleQueue][j]]
.m_nEntityIndex &&
sample.m_counter == m_asSamples[m_bActiveSampleQueue]
[m_abSampleQueueIndexTable[m_bActiveSampleQueue][j]]
.m_counter) {
toProcess[i] = true;
break;
}
int8 queue = m_bActiveSampleQueue == 0;
for(int32 i = 0; i < m_bSampleRequestQueuesStatus[queue]; i++) {
tActiveSample &sample = m_asSamples[queue][m_abSampleQueueIndexTable[queue][i]];
if (sample.m_bLoopEnded) continue;
toProcess[i] = false;
for(int32 j = 0; j < m_bSampleRequestQueuesStatus[m_bActiveSampleQueue]; j++) {
if(sample.m_nEntityIndex ==
m_asSamples[m_bActiveSampleQueue]
[m_abSampleQueueIndexTable[m_bActiveSampleQueue][j]]
.m_nEntityIndex &&
sample.m_counter == m_asSamples[m_bActiveSampleQueue]
[m_abSampleQueueIndexTable[m_bActiveSampleQueue][j]]
.m_counter) {
toProcess[i] = true;
break;
}
if(!toProcess[i]) {
if(sample.m_counter <= 255u || !sample.m_bLoopsRemaining) {
if(!sample.field_76) continue;
if(!sample.m_nLoopCount) {
if(sample.field_88 == -1) {
sample.field_88 = sample.m_bVolume / sample.field_76;
if(sample.field_88 <= 0) sample.field_88 = 1;
}
if(sample.m_bVolume <= sample.field_88) {
sample.field_76 = 0;
continue;
}
sample.m_bVolume -= sample.field_88;
}
if(!toProcess[i]) {
if(sample.m_counter <= 255u || !sample.m_bLoopsRemaining) {
if(!sample.field_76) continue;
if(!sample.m_nLoopCount) {
if(sample.field_88 == -1) {
sample.field_88 = sample.m_bVolume / sample.field_76;
if(sample.field_88 <= 0) sample.field_88 = 1;
}
--sample.field_76;
if(field_2) {
if(sample.field_16 < 20) ++sample.field_16;
if(sample.m_bVolume <= sample.field_88) {
sample.field_76 = 0;
continue;
}
sample.field_56 = 0;
sample.m_bVolume -= sample.field_88;
}
memcpy(&m_sQueueSample, &sample, 92);
AddSampleToRequestedQueue();
--sample.field_76;
if(field_2) {
if(sample.field_16 < 20) ++sample.field_16;
}
sample.field_56 = 0;
}
memcpy(&m_sQueueSample, &sample, sizeof(sample));
AddSampleToRequestedQueue();
}
}
}
@ -625,7 +632,7 @@ cAudioManager::ComputeVolume(uint8 emittingVolume, float soundIntensity, float d
}
int32
cAudioManager::CreateEntity(int32 type, CPhysical *entity)
cAudioManager::CreateEntity(int32 type, void *entity)
{
if(!m_bIsInitialised) return -4;
if(!entity) return -2;
@ -635,7 +642,7 @@ cAudioManager::CreateEntity(int32 type, CPhysical *entity)
m_asAudioEntities[i].m_bIsUsed = true;
m_asAudioEntities[i].m_bStatus = 0;
m_asAudioEntities[i].m_nType = (eAudioType)type;
m_asAudioEntities[i].m_pEntity = (void *)entity;
m_asAudioEntities[i].m_pEntity = entity;
m_asAudioEntities[i].m_awAudioEvent[0] = SOUND_TOTAL_PED_SOUNDS;
m_asAudioEntities[i].m_awAudioEvent[1] = SOUND_TOTAL_PED_SOUNDS;
m_asAudioEntities[i].m_awAudioEvent[2] = SOUND_TOTAL_PED_SOUNDS;
@ -2123,16 +2130,16 @@ uint32
cAudioManager::GetSpecialCharacterTalkSfx(int32 modelIndex, int32 sound)
{
char *modelName = CModelInfo::GetModelInfo(modelIndex)->GetName();
if(strcmp(modelName, "eight") == 0 || strcmp(modelName, "eight2") == 0) { return GetEightTalkSfx(sound); }
if(strcmp(modelName, "frankie") == 0) { return GetFrankieTalkSfx(sound); }
if(strcmp(modelName, "misty") == 0) { return GetMistyTalkSfx(sound); }
if(strcmp(modelName, "ojg") == 0 || strcmp(modelName, "ojg_p") == 0) { return GetOJGTalkSfx(sound); }
if(strcmp(modelName, "cat") == 0) { return GetCatatalinaTalkSfx(sound); }
if(strcmp(modelName, "bomber") == 0) { return GetBomberTalkSfx(sound); }
if(strcmp(modelName, "s_guard") == 0) { return GetSecurityGuardTalkSfx(sound); }
if(strcmp(modelName, "chunky") == 0) { return GetChunkyTalkSfx(sound); }
if(strcmp(modelName, "asuka") == 0) { return GetGenericFemaleTalkSfx(sound); }
if(strcmp(modelName, "maria") == 0) { return GetGenericFemaleTalkSfx(sound); }
if(strcmpi(modelName, "eight") == 0 || strcmpi(modelName, "eight2") == 0) { return GetEightTalkSfx(sound); }
if(strcmpi(modelName, "frankie") == 0) { return GetFrankieTalkSfx(sound); }
if(strcmpi(modelName, "misty") == 0) { return GetMistyTalkSfx(sound); }
if(strcmpi(modelName, "ojg") == 0 || strcmpi(modelName, "ojg_p") == 0) { return GetOJGTalkSfx(sound); }
if(strcmpi(modelName, "cat") == 0) { return GetCatatalinaTalkSfx(sound); }
if(strcmpi(modelName, "bomber") == 0) { return GetBomberTalkSfx(sound); }
if(strcmpi(modelName, "s_guard") == 0) { return GetSecurityGuardTalkSfx(sound); }
if(strcmpi(modelName, "chunky") == 0) { return GetChunkyTalkSfx(sound); }
if(strcmpi(modelName, "asuka") == 0) { return GetGenericFemaleTalkSfx(sound); }
if(strcmpi(modelName, "maria") == 0) { return GetGenericFemaleTalkSfx(sound); }
return GetGenericMaleTalkSfx(sound);
}
@ -2610,9 +2617,8 @@ char *SubZo3Label = (char *)0x6E9870;
void
cAudioManager::InitialisePoliceRadioZones()
{
for(int32 i = 0; i < 36; i++) {
for(int32 j = 0; j < 8; j++) { ZoneSfx[i].m_aName[j] = 0; }
}
for(int32 i = 0; i < NUMAUDIOZONES; i++)
memset(ZoneSfx[i].m_aName, 0, 8);
strcpy(ZoneSfx[0].m_aName, "HOSPI_2");
ZoneSfx[0].m_nSampleIndex = SFX_POLICE_RADIO_ROCKFORD;
@ -2988,26 +2994,25 @@ cAudioManager::PlayerJustLeftCar(void) const
void
cAudioManager::PostInitialiseGameSpecificSetup()
{
m_nFireAudioEntity = CreateEntity(AUDIOTYPE_FIRE,
(CPhysical *)0x8F31D0); // last is addr of firemanager @todo change
m_nFireAudioEntity = CreateEntity(AUDIOTYPE_FIRE, &gFireManager);
if(m_nFireAudioEntity >= 0) SetEntityStatus(m_nFireAudioEntity, 1);
m_nCollisionEntity = CreateEntity(AUDIOTYPE_COLLISION, (CPhysical *)1);
m_nCollisionEntity = CreateEntity(AUDIOTYPE_COLLISION, (void*)1);
if(m_nCollisionEntity >= 0) SetEntityStatus(m_nCollisionEntity, 1);
m_nFrontEndEntity = CreateEntity(AUDIOTYPE_FRONTEND, (CPhysical *)1);
m_nFrontEndEntity = CreateEntity(AUDIOTYPE_FRONTEND, (void*)1);
if(m_nFrontEndEntity >= 0) SetEntityStatus(m_nFrontEndEntity, 1);
m_nProjectileEntity = CreateEntity(AUDIOTYPE_PROJECTILE, (CPhysical *)1);
m_nProjectileEntity = CreateEntity(AUDIOTYPE_PROJECTILE, (void*)1);
if(m_nProjectileEntity >= 0) SetEntityStatus(m_nProjectileEntity, 1);
m_nWaterCannonEntity = CreateEntity(AUDIOTYPE_WATERCANNON, (CPhysical *)1);
m_nWaterCannonEntity = CreateEntity(AUDIOTYPE_WATERCANNON, (void*)1);
if(m_nWaterCannonEntity >= 0) SetEntityStatus(m_nWaterCannonEntity, 1);
m_nPoliceChannelEntity = CreateEntity(AUDIOTYPE_POLICERADIO, (CPhysical *)1);
m_nPoliceChannelEntity = CreateEntity(AUDIOTYPE_POLICERADIO, (void*)1);
if(m_nPoliceChannelEntity >= 0) SetEntityStatus(m_nPoliceChannelEntity, 1);
m_nBridgeEntity = CreateEntity(AUDIOTYPE_BRIDGE, (CPhysical *)1);
m_nBridgeEntity = CreateEntity(AUDIOTYPE_BRIDGE, (void*)1);
if(m_nBridgeEntity >= 0) SetEntityStatus(m_nBridgeEntity, 1);
m_sMissionAudio.m_nSampleIndex = NO_SAMPLE;
@ -3017,7 +3022,7 @@ cAudioManager::PostInitialiseGameSpecificSetup()
m_sMissionAudio.m_bIsPlayed = 0;
m_sMissionAudio.field_12 = 1;
m_sMissionAudio.field_24 = 0;
ResetAudioLogicTimers((int32)CTimer::GetTimeInMilliseconds);
ResetAudioLogicTimers(CTimer::GetTimeInMilliseconds());
}
void
@ -3033,11 +3038,92 @@ cAudioManager::PreInitialiseGameSpecificSetup() const
BankStartOffset[1] = SFX_COP_VOICE_1_ARREST_1;
}
WRAPPER
void
cAudioManager::PreloadMissionAudio(char *)
struct MissionAudioData {
const char *m_pName;
int32 m_nId;
};
constexpr MissionAudioData MissionAudioNameSfxAssoc[] = {
{"lib_a1", STREAMED_SOUND_MISSION_LIB_A1}, {"lib_a2", STREAMED_SOUND_MISSION_LIB_A2},
{"lib_a", STREAMED_SOUND_MISSION_LIB_A}, {"lib_b", STREAMED_SOUND_MISSION_LIB_B},
{"lib_c", STREAMED_SOUND_MISSION_LIB_C}, {"lib_d", STREAMED_SOUND_MISSION_LIB_D},
{"l2_a", STREAMED_SOUND_MISSION_L2_A}, {"j4t_1", STREAMED_SOUND_MISSION_J4T_1},
{"j4t_2", STREAMED_SOUND_MISSION_J4T_2}, {"j4t_3", STREAMED_SOUND_MISSION_J4T_3},
{"j4t_4", STREAMED_SOUND_MISSION_J4T_4}, {"j4_a", STREAMED_SOUND_MISSION_J4_A},
{"j4_b", STREAMED_SOUND_MISSION_J4_B}, {"j4_c", STREAMED_SOUND_MISSION_J4_C},
{"j4_d", STREAMED_SOUND_MISSION_J4_D}, {"j4_e", STREAMED_SOUND_MISSION_J4_E},
{"j4_f", STREAMED_SOUND_MISSION_J4_F}, {"j6_1", STREAMED_SOUND_MISSION_J6_1},
{"j6_a", STREAMED_SOUND_MISSION_J6_A}, {"j6_b", STREAMED_SOUND_MISSION_J6_B},
{"j6_c", STREAMED_SOUND_MISSION_J6_C}, {"j6_d", STREAMED_SOUND_MISSION_J6_D},
{"t4_a", STREAMED_SOUND_MISSION_T4_A}, {"s1_a", STREAMED_SOUND_MISSION_S1_A},
{"s1_a1", STREAMED_SOUND_MISSION_S1_A1}, {"s1_b", STREAMED_SOUND_MISSION_S1_B},
{"s1_c", STREAMED_SOUND_MISSION_S1_C}, {"s1_c1", STREAMED_SOUND_MISSION_S1_C1},
{"s1_d", STREAMED_SOUND_MISSION_S1_D}, {"s1_e", STREAMED_SOUND_MISSION_S1_E},
{"s1_f", STREAMED_SOUND_MISSION_S1_F}, {"s1_g", STREAMED_SOUND_MISSION_S1_G},
{"s1_h", STREAMED_SOUND_MISSION_S1_H}, {"s1_i", STREAMED_SOUND_MISSION_S1_I},
{"s1_j", STREAMED_SOUND_MISSION_S1_J}, {"s1_k", STREAMED_SOUND_MISSION_S1_K},
{"s1_l", STREAMED_SOUND_MISSION_S1_L}, {"s3_a", STREAMED_SOUND_MISSION_S3_A},
{"s3_b", STREAMED_SOUND_MISSION_S3_B}, {"el3_a", STREAMED_SOUND_MISSION_EL3_A},
{"mf1_a", STREAMED_SOUND_MISSION_MF1_A}, {"mf2_a", STREAMED_SOUND_MISSION_MF2_A},
{"mf3_a", STREAMED_SOUND_MISSION_MF3_A}, {"mf3_b", STREAMED_SOUND_MISSION_MF3_B},
{"mf3_b1", STREAMED_SOUND_MISSION_MF3_B1}, {"mf3_c", STREAMED_SOUND_MISSION_MF3_C},
{"mf4_a", STREAMED_SOUND_MISSION_MF4_A}, {"mf4_b", STREAMED_SOUND_MISSION_MF4_B},
{"mf4_c", STREAMED_SOUND_MISSION_MF4_C}, {"a1_a", STREAMED_SOUND_MISSION_A1_A},
{"a3_a", STREAMED_SOUND_MISSION_A3_A}, {"a5_a", STREAMED_SOUND_MISSION_A5_A},
{"a4_a", STREAMED_SOUND_MISSION_A4_A}, {"a4_b", STREAMED_SOUND_MISSION_A4_B},
{"a4_c", STREAMED_SOUND_MISSION_A4_C}, {"a4_d", STREAMED_SOUND_MISSION_A4_D},
{"k1_a", STREAMED_SOUND_MISSION_K1_A}, {"k3_a", STREAMED_SOUND_MISSION_K3_A},
{"r1_a", STREAMED_SOUND_MISSION_R1_A}, {"r2_a", STREAMED_SOUND_MISSION_R2_A},
{"r2_b", STREAMED_SOUND_MISSION_R2_B}, {"r2_c", STREAMED_SOUND_MISSION_R2_C},
{"r2_d", STREAMED_SOUND_MISSION_R2_D}, {"r2_e", STREAMED_SOUND_MISSION_R2_E},
{"r2_f", STREAMED_SOUND_MISSION_R2_F}, {"r2_g", STREAMED_SOUND_MISSION_R2_G},
{"r2_h", STREAMED_SOUND_MISSION_R2_H}, {"r5_a", STREAMED_SOUND_MISSION_R5_A},
{"r6_a", STREAMED_SOUND_MISSION_R6_A}, {"r6_a1", STREAMED_SOUND_MISSION_R6_A1},
{"r6_b", STREAMED_SOUND_MISSION_R6_B}, {"lo2_a", STREAMED_SOUND_MISSION_LO2_A},
{"lo6_a", STREAMED_SOUND_MISSION_LO6_A}, {"yd2_a", STREAMED_SOUND_MISSION_YD2_A},
{"yd2_b", STREAMED_SOUND_MISSION_YD2_B}, {"yd2_c", STREAMED_SOUND_MISSION_YD2_C},
{"yd2_c1", STREAMED_SOUND_MISSION_YD2_C1}, {"yd2_d", STREAMED_SOUND_MISSION_YD2_D},
{"yd2_e", STREAMED_SOUND_MISSION_YD2_E}, {"yd2_f", STREAMED_SOUND_MISSION_YD2_F},
{"yd2_g", STREAMED_SOUND_MISSION_YD2_G}, {"yd2_h", STREAMED_SOUND_MISSION_YD2_H},
{"yd2_ass", STREAMED_SOUND_MISSION_YD2_ASS}, {"yd2_ok", STREAMED_SOUND_MISSION_YD2_OK},
{"h5_a", STREAMED_SOUND_MISSION_H5_A}, {"h5_b", STREAMED_SOUND_MISSION_H5_B},
{"h5_c", STREAMED_SOUND_MISSION_H5_C}, {"ammu_a", STREAMED_SOUND_MISSION_AMMU_A},
{"ammu_b", STREAMED_SOUND_MISSION_AMMU_B}, {"ammu_c", STREAMED_SOUND_MISSION_AMMU_C},
{"door_1", STREAMED_SOUND_MISSION_DOOR_1}, {"door_2", STREAMED_SOUND_MISSION_DOOR_2},
{"door_3", STREAMED_SOUND_MISSION_DOOR_3}, {"door_4", STREAMED_SOUND_MISSION_DOOR_4},
{"door_5", STREAMED_SOUND_MISSION_DOOR_5}, {"door_6", STREAMED_SOUND_MISSION_DOOR_6},
{"t3_a", STREAMED_SOUND_MISSION_T3_A}, {"t3_b", STREAMED_SOUND_MISSION_T3_B},
{"t3_c", STREAMED_SOUND_MISSION_T3_C}, {"k1_b", STREAMED_SOUND_MISSION_K1_B},
{"c_1", STREAMED_SOUND_MISSION_CAT1}};
int32
FindMissionAudioSfx(const char *name)
{
EAXJMP(0x579550);
for(uint32 i = 0; i < ARRAY_SIZE(MissionAudioNameSfxAssoc); ++i) {
if(strcmpi(MissionAudioNameSfxAssoc[i].m_pName, name) == 0) return MissionAudioNameSfxAssoc[i].m_nId;
}
debug("Can't find mission audio %s", name);
return NO_SAMPLE;
}
void
cAudioManager::PreloadMissionAudio(const char *name)
{
if(m_bIsInitialised) {
int32 missionAudioSfx = FindMissionAudioSfx(name);
if(missionAudioSfx != NO_SAMPLE) {
m_sMissionAudio.m_nSampleIndex = missionAudioSfx;
m_sMissionAudio.m_bLoadingStatus = 0;
m_sMissionAudio.m_bPlayStatus = 0;
m_sMissionAudio.field_22 = 0;
m_sMissionAudio.field_24 =
field_19192 * SampleManager.GetStreamedFileLength(missionAudioSfx) / 1000;
m_sMissionAudio.field_24 *= 4;
m_sMissionAudio.m_bIsPlayed = 0;
m_sMissionAudio.field_12 = 1;
g_bMissionAudioLoadFailed = 0;
}
}
}
void
@ -3129,7 +3215,7 @@ cAudioManager::ProcessAirportScriptObject(uint8 sound)
static uint8 counter = 0;
uint32 time = CTimer::GetTimeInMilliseconds();
if(time > audioLogicTimers[3]) {
if(time > gAirportNextTime) {
switch(sound) {
case SCRIPT_SOUND_AIRPORT_LOOP_S:
maxDist = 900.f;
@ -3164,7 +3250,7 @@ cAudioManager::ProcessAirportScriptObject(uint8 sound)
m_sQueueSample.m_bReverbFlag = 1;
m_sQueueSample.m_bRequireReflection = 0;
AddSampleToRequestedQueue();
audioLogicTimers[3] = time + 10000 + m_anRandomTable[3] % 20000;
gAirportNextTime = time + 10000 + m_anRandomTable[3] % 20000;
}
}
}
@ -3539,7 +3625,7 @@ cAudioManager::ProcessCinemaScriptObject(uint8 sound)
static uint8 counter = 0;
uint32 time = CTimer::GetTimeInMilliseconds();
if(time > audioLogicTimers[4]) {
if(time > gCinemaNextTime) {
switch(sound) {
case SCRIPT_SOUND_CINEMA_LOOP_S:
maxDist = 900.f;
@ -3575,7 +3661,7 @@ cAudioManager::ProcessCinemaScriptObject(uint8 sound)
m_sQueueSample.m_bReverbFlag = 1;
m_sQueueSample.m_bRequireReflection = 0;
AddSampleToRequestedQueue();
audioLogicTimers[4] = time + 1000 + m_anRandomTable[3] % 4000;
gCinemaNextTime = time + 1000 + m_anRandomTable[3] % 4000;
}
}
}
@ -3599,7 +3685,7 @@ cAudioManager::ProcessDocksScriptObject(uint8 sound)
static uint32 counter = 0;
time = CTimer::GetTimeInMilliseconds();
if(time > audioLogicTimers[5]) {
if(time > gDocksNextTime) {
switch(sound) {
case SCRIPT_SOUND_DOCKS_LOOP_S:
maxDist = 900.f;
@ -3634,7 +3720,7 @@ cAudioManager::ProcessDocksScriptObject(uint8 sound)
m_sQueueSample.m_bReverbFlag = 1;
m_sQueueSample.m_bRequireReflection = 0;
AddSampleToRequestedQueue();
audioLogicTimers[5] = time + 10000 + m_anRandomTable[3] % 40000;
gDocksNextTime = time + 10000 + m_anRandomTable[3] % 40000;
}
}
}
@ -3887,16 +3973,20 @@ void
cAudioManager::ProcessFrontEnd()
{
bool processed;
bool processedPickup;
bool processedMission;
int16 sample;
static uint32 counter = 0;
static uint8 counter = 0;
static uint32 cPickupNextFrame = 0;
static uint32 cPartMisComNextFrame = 0;
for(uint32 i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) {
processedPickup = 0;
processed = 0;
processedMission = 0;
switch(m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i]) {
case SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM:
m_sQueueSample.m_nSampleIndex = SFX_ERROR_FIRE_RIFLE;
break;
case SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM: m_sQueueSample.m_nSampleIndex = SFX_ERROR_FIRE_RIFLE; break;
case SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM:
m_sQueueSample.m_nSampleIndex = SFX_ERROR_FIRE_ROCKET_LAUNCHER;
break;
@ -3904,7 +3994,7 @@ cAudioManager::ProcessFrontEnd()
case SOUND_GARAGE_BAD_VEHICLE:
case SOUND_3C:
m_sQueueSample.m_nSampleIndex = SFX_PICKUP_ERROR_LEFT;
processed = 1;
processed = true;
break;
case SOUND_GARAGE_OPENING:
case SOUND_GARAGE_BOMB1_SET:
@ -3920,16 +4010,19 @@ cAudioManager::ProcessFrontEnd()
case SOUND_EVIDENCE_PICKUP:
case SOUND_UNLOAD_GOLD:
m_sQueueSample.m_nSampleIndex = SFX_PICKUP_2_LEFT;
processed = 1;
processedPickup = true;
processed = true;
break;
case SOUND_PICKUP_WEAPON_BOUGHT:
case SOUND_PICKUP_WEAPON:
m_sQueueSample.m_nSampleIndex = SFX_PICKUP_1_LEFT;
processed = 1;
processedPickup = true;
processed = true;
break;
case SOUND_4A:
m_sQueueSample.m_nSampleIndex = SFX_PICKUP_ERROR_LEFT;
processed = 1;
processedPickup = true;
processed = true;
break;
case SOUND_PICKUP_BONUS:
case SOUND_PICKUP_MONEY:
@ -3938,60 +4031,65 @@ cAudioManager::ProcessFrontEnd()
case SOUND_PICKUP_PACMAN_PACKAGE:
case SOUND_PICKUP_FLOAT_PACKAGE:
m_sQueueSample.m_nSampleIndex = SFX_PICKUP_3_LEFT;
processed = 1;
processedPickup = true;
processed = true;
break;
case SOUND_PAGER: m_sQueueSample.m_nSampleIndex = SFX_PAGER; break;
case SOUND_RACE_START_3:
case SOUND_RACE_START_2:
case SOUND_RACE_START_1:
case SOUND_CLOCK_TICK: m_sQueueSample.m_nSampleIndex = SFX_TIMER_BEEP; break;
case SOUND_RACE_START_GO:
m_sQueueSample.m_nSampleIndex = SFX_PART_MISSION_COMPLETE;
break;
case SOUND_RACE_START_GO: m_sQueueSample.m_nSampleIndex = SFX_PART_MISSION_COMPLETE; break;
case SOUND_PART_MISSION_COMPLETE:
m_sQueueSample.m_nSampleIndex = SFX_PART_MISSION_COMPLETE;
processedMission = true;
break;
case SOUND_FRONTEND_MENU_STARTING:
processed = 1;
m_sQueueSample.m_nSampleIndex = SFX_START_BUTTON_LEFT;
processed = true;
break;
case SOUND_FRONTEND_MENU_COMPLETED:
processed = 1;
m_sQueueSample.m_nSampleIndex = SFX_PAGE_CHANGE_AND_BACK_LEFT;
processed = true;
break;
case SOUND_FRONTEND_MENU_DENIED:
processed = 1;
m_sQueueSample.m_nSampleIndex = SFX_HIGHLIGHT_LEFT;
processed = true;
break;
case SOUND_FRONTEND_MENU_SUCCESS:
processed = 1;
m_sQueueSample.m_nSampleIndex = SFX_SELECT_LEFT;
processed = true;
break;
case SOUND_FRONTEND_EXIT:
processed = 1;
m_sQueueSample.m_nSampleIndex = SFX_SUB_MENU_BACK_LEFT;
processed = true;
break;
case SOUND_9A:
processed = 1;
m_sQueueSample.m_nSampleIndex = SFX_STEREO_LEFT;
processed = true;
break;
case SOUND_9B: m_sQueueSample.m_nSampleIndex = SFX_MONO; break;
case SOUND_FRONTEND_AUDIO_TEST:
m_sQueueSample.m_nSampleIndex =
m_anRandomTable[0] % 3 + SFX_NOISE_BURST_1;
m_sQueueSample.m_nSampleIndex = m_anRandomTable[0] % 3 + SFX_NOISE_BURST_1;
break;
case SOUND_FRONTEND_FAIL:
processed = 1;
m_sQueueSample.m_nSampleIndex = SFX_ERROR_LEFT;
processed = true;
break;
case SOUND_FRONTEND_NO_RADIO:
case SOUND_FRONTEND_RADIO_CHANGE:
m_sQueueSample.m_nSampleIndex = SFX_RADIO_CLICK;
break;
case SOUND_FRONTEND_RADIO_CHANGE: m_sQueueSample.m_nSampleIndex = SFX_RADIO_CLICK; break;
case SOUND_A0: m_sQueueSample.m_nSampleIndex = SFX_INFO; break;
default: continue;
}
if(processedPickup) {
if(m_nTimeOfRecentCrime <= cPickupNextFrame) continue;
cPickupNextFrame = m_nTimeOfRecentCrime + 5;
} else if(processedMission) {
if(m_nTimeOfRecentCrime <= cPartMisComNextFrame) continue;
cPartMisComNextFrame = m_nTimeOfRecentCrime + 5;
}
sample = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i];
if(sample == SFX_RAIN) {
m_sQueueSample.m_nFrequency = 28509;
@ -4106,7 +4204,7 @@ cAudioManager::ProcessHomeScriptObject(uint8 sound)
static uint8 counter = 0;
time = CTimer::GetTimeInMilliseconds();
if(time > audioLogicTimers[6]) {
if(time > gHomeNextTime) {
switch(sound) {
case SCRIPT_SOUND_HOME_LOOP_S:
maxDist = 900.f;
@ -4142,7 +4240,7 @@ cAudioManager::ProcessHomeScriptObject(uint8 sound)
m_sQueueSample.m_bReverbFlag = 1;
m_sQueueSample.m_bRequireReflection = 1;
AddSampleToRequestedQueue();
audioLogicTimers[6] = time + 1000 + m_anRandomTable[3] % 4000;
gHomeNextTime = time + 1000 + m_anRandomTable[3] % 4000;
}
}
}
@ -5507,7 +5605,7 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
static uint8 iSound = 21;
weapon = nil;
for(uint32 i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_Loops; i++) {
for(uint32 i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) {
noReflection = 0;
processed = 0;
m_sQueueSample.m_bRequireReflection = 0;
@ -6666,7 +6764,7 @@ cAudioManager::ProcessPoliceCellBeatingScriptObject(uint8 sound)
static uint8 counter = 0;
if(time > audioLogicTimers[7]) {
if(time > gCellNextTime) {
switch(sound) {
case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_S:
maxDist = 900.f;
@ -6711,7 +6809,7 @@ cAudioManager::ProcessPoliceCellBeatingScriptObject(uint8 sound)
params.m_pPed = 0;
SetupPedComments(&params, SOUND_8A);
}
audioLogicTimers[7] = time + 500 + m_anRandomTable[3] % 1500;
gCellNextTime = time + 500 + m_anRandomTable[3] % 1500;
}
}
}
@ -6800,7 +6898,7 @@ cAudioManager::ProcessPornCinema(uint8 sound)
}
time = CTimer::GetTimeInMilliseconds();
if(time > audioLogicTimers[0]) {
if(time > gPornNextTime) {
m_sQueueSample.m_bVolume =
ComputeVolume(90, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
@ -6820,7 +6918,7 @@ cAudioManager::ProcessPornCinema(uint8 sound)
m_sQueueSample.m_bReverbFlag = 1;
m_sQueueSample.m_bRequireReflection = 0;
AddSampleToRequestedQueue();
audioLogicTimers[0] = time + 2000 + m_anRandomTable[3] % 6000;
gPornNextTime = time + 2000 + m_anRandomTable[3] % 6000;
}
}
}
@ -7025,7 +7123,7 @@ cAudioManager::ProcessSawMillScriptObject(uint8 sound)
AddSampleToRequestedQueue();
}
time = CTimer::GetTimeInMilliseconds();
if(time > audioLogicTimers[1]) {
if(time > gSawMillNextTime) {
m_sQueueSample.m_bVolume =
ComputeVolume(70, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
@ -7044,7 +7142,7 @@ cAudioManager::ProcessSawMillScriptObject(uint8 sound)
m_sQueueSample.m_bReverbFlag = 1;
m_sQueueSample.m_bRequireReflection = 0;
AddSampleToRequestedQueue();
audioLogicTimers[1] = time + 2000 + m_anRandomTable[3] % 4000;
gSawMillNextTime = time + 2000 + m_anRandomTable[3] % 4000;
}
}
}
@ -7103,7 +7201,7 @@ cAudioManager::ProcessShopScriptObject(uint8 sound)
AddSampleToRequestedQueue();
}
time = CTimer::GetTimeInMilliseconds();
if(time > audioLogicTimers[2]) {
if(time > gShopNextTime) {
m_sQueueSample.m_bVolume =
ComputeVolume(70, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
@ -7124,7 +7222,7 @@ cAudioManager::ProcessShopScriptObject(uint8 sound)
m_sQueueSample.m_bReverbFlag = 1;
m_sQueueSample.m_bRequireReflection = 0;
AddSampleToRequestedQueue();
audioLogicTimers[2] = time + 3000 + m_anRandomTable[3] % 7000;
gShopNextTime = time + 3000 + m_anRandomTable[3] % 7000;
}
}
}
@ -7912,17 +8010,17 @@ cAudioManager::ReportCrime(int32 type, const CVector *pos)
}
void
cAudioManager::ResetAudioLogicTimers(int32 timer)
cAudioManager::ResetAudioLogicTimers(uint32 timer)
{
audioLogicTimers[0] = timer;
audioLogicTimers[8] = timer;
audioLogicTimers[1] = timer;
audioLogicTimers[7] = timer;
audioLogicTimers[2] = timer;
audioLogicTimers[6] = timer;
audioLogicTimers[3] = timer;
audioLogicTimers[5] = timer;
audioLogicTimers[4] = timer;
gPornNextTime = timer;
gNextCryTime = timer;
gSawMillNextTime = timer;
gCellNextTime = timer;
gShopNextTime = timer;
gHomeNextTime = timer;
gAirportNextTime = timer;
gDocksNextTime = timer;
gCinemaNextTime = timer;
for(int32 i = 0; i < m_nAudioEntitiesTotal; i++) {
if(m_asAudioEntities[m_anAudioEntityIndices[i]].m_nType == AUDIOTYPE_PHYSICAL) {
CPed *ped = (CPed *)m_asAudioEntities[m_anAudioEntityIndices[i]].m_pEntity;
@ -8207,7 +8305,7 @@ cAudioManager::SetEffectsMasterVolume(uint8 volume) const
}
void
cAudioManager::SetEntityStatus(int32 id, bool status)
cAudioManager::SetEntityStatus(int32 id, uint8 status)
{
if(m_bIsInitialised && id >= 0 && id < totalAudioEntitiesSlots && m_asAudioEntities[id].m_bIsUsed) {
m_asAudioEntities[id].m_bStatus = status;
@ -8811,10 +8909,10 @@ cAudioManager::SetupPedComments(cPedParams *params, uint32 sound)
SFX_POLICE_HELI_1;
break;
case SOUND_PED_BODYCAST_HIT:
if(CTimer::GetTimeInMilliseconds() <= audioLogicTimers[8]) return;
if(CTimer::GetTimeInMilliseconds() <= gNextCryTime) return;
maxDist = 2500.f;
soundIntensity = 50.f;
audioLogicTimers[8] = CTimer::GetTimeInMilliseconds() + 500;
gNextCryTime = CTimer::GetTimeInMilliseconds() + 500;
pedComment.m_nSampleIndex =
(m_anRandomTable[m_sQueueSample.m_nEntityIndex & 3] & 3) + SFX_PLASTER_BLOKE_1;
break;
@ -8869,46 +8967,124 @@ cAudioManager::SetupPedComments(cPedParams *params, uint32 sound)
void
cAudioManager::SetupSuspectLastSeenReport()
{
CAutomobile *automobile;
CVehicle *veh;
uint8 color1;
int32 index;
int32 main_color;
int32 sample;
int32 color_pre_modifier;
int32 color_post_modifier;
constexpr int32 colors[] = {
3032, 248, 3032, 3032, 249, 3032, 3032, 250, 3032, 3032, 251, 3032, 258, 250, 3032, 3032, 252, 3032,
3032, 253, 3032, 260, 250, 3032, 259, 250, 254, 259, 3032, 3032, 258, 3032, 3032, 258, 3032, 3032,
258, 251, 3032, 3032, 251, 3032, 3032, 251, 3032, 3032, 251, 3032, 3032, 251, 3032, 3032, 251, 3032,
3032, 251, 3032, 259, 3032, 3032, 258, 3032, 3032, 258, 3032, 3032, 258, 3032, 3032, 3032, 255, 3032,
3032, 255, 3032, 3032, 255, 3032, 3032, 255, 3032, 3032, 255, 3032, 3032, 255, 3032, 259, 3032, 3032,
258, 3032, 3032, 258, 3032, 3032, 258, 3032, 3032, 3032, 253, 3032, 3032, 253, 3032, 3032, 253, 3032,
3032, 253, 3032, 3032, 253, 3032, 3032, 253, 3032, 259, 3032, 3032, 258, 3032, 3032, 258, 3032, 3032,
258, 3032, 3032, 3032, 256, 3032, 3032, 256, 3032, 3032, 256, 3032, 3032, 256, 3032, 3032, 256, 3032,
3032, 256, 3032, 259, 3032, 3032, 258, 3032, 3032, 258, 3032, 3032, 258, 3032, 3032, 3032, 250, 3032,
3032, 250, 3032, 3032, 250, 3032, 3032, 250, 3032, 3032, 250, 3032, 3032, 250, 3032, 259, 3032, 3032,
258, 3032, 3032, 258, 3032, 3032, 258, 3032, 3032, 3032, 252, 3032, 3032, 252, 3032, 3032, 252, 3032,
3032, 252, 3032, 3032, 252, 3032, 3032, 252, 3032, 259, 3032, 3032, 258, 3032, 3032, 258, 3032, 3032,
258, 3032, 3032, 3032, 257, 3032, 3032, 257, 3032, 3032, 257, 3032, 3032, 257, 3032, 3032, 257, 3032,
3032, 257, 3032, 259, 3032, 3032, 259, 3032, 3032, 259, 3032, 3032, 259, 3032, 3032, 259, 3032, 3032,
259, 3032, 3032, 259, 3032, 3032, 259, 3032, 3032, 259, 3032, 3032, 259, 3032, 3032, 259, 3032, 3032,
258, 3032, 3032, 258, 3032, 3032, 258, 3032, 3032, 258, 3032, 3032, 258, 3032, 3032};
constexpr int32 gCarColourTable[][3] = {
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLACK, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_WHITE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_BRIGHT, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_BLUE, SFX_POLICE_RADIO_GREY},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}
};
if(MusicManager.m_nMusicMode != 2) {
automobile = (CAutomobile *)FindPlayerVehicle();
if(automobile) {
if(MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE) {
veh = FindPlayerVehicle();
if(veh) {
if(60 - policeChannelTimer > 9) {
color1 = automobile->m_currentColour1;
if(color1 >= 95) {
color1 = veh->m_currentColour1;
if(color1 >= ARRAY_SIZE(gCarColourTable)) {
debug("\n *** UNKNOWN CAR COLOUR %d *** ", color1);
} else {
index = 3 * color1;
main_color = colors[index + 1]; // todo refactor struct
color_pre_modifier = colors[index];
color_post_modifier = colors[index + 2];
switch(automobile->m_modelIndex) {
main_color = gCarColourTable[color1][1];
color_pre_modifier = gCarColourTable[color1][0];
color_post_modifier = gCarColourTable[color1][2];
switch(veh->m_modelIndex) {
case MI_LANDSTAL:
case MI_BLISTA: sample = SFX_POLICE_RADIO_CRUISER; break;
case MI_IDAHO:
@ -8959,7 +9135,7 @@ cAudioManager::SetupSuspectLastSeenReport()
break;
default:
debug("\n *** UNKNOWN CAR MODEL INDEX %d *** ",
automobile->m_modelIndex);
veh->m_modelIndex);
return;
}
if(policeChannelTimer != 60) {
@ -8995,17 +9171,17 @@ cAudioManager::SetupSuspectLastSeenReport()
++policeChannelTimer;
policeChannelTimerSeconds = (policeChannelTimerSeconds + 1) % 60;
}
if(color_pre_modifier != 3032 && policeChannelTimer != 60) {
if(color_pre_modifier != TOTAL_AUDIO_SAMPLES && policeChannelTimer != 60) {
crimesSamples[policeChannelTimerSeconds] = color_pre_modifier;
++policeChannelTimer;
policeChannelTimerSeconds = (policeChannelTimerSeconds + 1) % 60;
}
if(main_color != 3032 && policeChannelTimer != 60) {
if(main_color != TOTAL_AUDIO_SAMPLES && policeChannelTimer != 60) {
crimesSamples[policeChannelTimerSeconds] = main_color;
++policeChannelTimer;
policeChannelTimerSeconds = (policeChannelTimerSeconds + 1) % 60;
}
if(color_post_modifier != 3032 && policeChannelTimer != 60) {
if(color_post_modifier != TOTAL_AUDIO_SAMPLES && policeChannelTimer != 60) {
crimesSamples[policeChannelTimerSeconds] = color_post_modifier;
++policeChannelTimer;
policeChannelTimerSeconds = (policeChannelTimerSeconds + 1) % 60;
@ -9113,11 +9289,75 @@ cAudioManager::UpdateGasPedalAudio(CAutomobile *automobile)
automobile->m_fGasPedalAudio = newGasPedalAudio;
}
WRAPPER
void
cAudioManager::UpdateReflections()
{
EAXJMP(0x57B470);
const CVector &camPos = TheCamera.GetPosition();
CColPoint colpoint;
CEntity *ent;
if(m_nTimeOfRecentCrime & 7) {
if(((uint8)m_nTimeOfRecentCrime + 1) & 7) {
if(((uint8)m_nTimeOfRecentCrime + 2) & 7) {
if(((uint8)m_nTimeOfRecentCrime + 3) & 7) {
if(!(((uint8)m_nTimeOfRecentCrime + 4) & 7)) {
m_avecReflectionsPos[4] = camPos;
m_avecReflectionsPos[4].z += 50.f;
if(CWorld::ProcessVerticalLine(
camPos, m_avecReflectionsPos[4].z, colpoint,
ent, true, false, false, false, true, false,
false)) {
m_afReflectionsDistances[4] =
colpoint.point.z - camPos.z;
} else {
m_afReflectionsDistances[4] = 50.0f;
}
}
} else {
m_avecReflectionsPos[3] = camPos;
m_avecReflectionsPos[3].x += 50.f;
if(CWorld::ProcessLineOfSight(
camPos, m_avecReflectionsPos[3], colpoint, ent, true,
false, false, true, false, true, true)) {
m_afReflectionsDistances[3] =
Distance(camPos, colpoint.point);
} else {
m_afReflectionsDistances[3] = 50.0f;
}
}
} else {
m_avecReflectionsPos[2] = camPos;
m_avecReflectionsPos[2].x -= 50.f;
if(CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[2],
colpoint, ent, true, false, false,
true, false, true, true)) {
m_afReflectionsDistances[2] =
Distance(camPos, colpoint.point);
} else {
m_afReflectionsDistances[2] = 50.0f;
}
}
} else {
m_avecReflectionsPos[1] = camPos;
m_avecReflectionsPos[1].y -= 50.f;
if(CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[1], colpoint,
ent, true, false, false, true, false, true,
true)) {
m_afReflectionsDistances[1] = Distance(camPos, colpoint.point);
} else {
m_afReflectionsDistances[1] = 50.0f;
}
}
} else {
m_avecReflectionsPos[0] = camPos;
m_avecReflectionsPos[0].y += 50.f;
if(CWorld::ProcessLineOfSight(camPos, m_avecReflectionsPos[0], colpoint, ent, true,
false, false, true, false, true, true)) {
m_afReflectionsDistances[0] = Distance(camPos, colpoint.point);
} else {
m_afReflectionsDistances[0] = 50.0f;
}
}
}
bool
@ -9299,6 +9539,7 @@ InjectHook(0x580500, &cAudioManager::PlaySuspectLastSeen, PATCH_JUMP);
InjectHook(0x569420, &cAudioManager::PostInitialiseGameSpecificSetup, PATCH_JUMP);
InjectHook(0x569640, &cAudioManager::PostTerminateGameSpecificShutdown, PATCH_JUMP);
InjectHook(0x569400, &cAudioManager::PreInitialiseGameSpecificSetup, PATCH_JUMP);
InjectHook(0x579550, &cAudioManager::PreloadMissionAudio, PATCH_JUMP);
InjectHook(0x569570, &cAudioManager::PreTerminateGameSpecificShutdown, PATCH_JUMP);
// InjectHook(0x57BA60, &cAudioManager::ProcessActiveQueues, PATCH_JUMP);
InjectHook(0x56C940, &cAudioManager::ProcessAirBrakes, PATCH_JUMP);
@ -9393,6 +9634,7 @@ InjectHook(0x57FCC0, &cAudioManager::SetupSuspectLastSeenReport, PATCH_JUMP);
InjectHook(0x57A150, &cAudioManager::Terminate, PATCH_JUMP);
InjectHook(0x57AC60, &cAudioManager::TranslateEntity, PATCH_JUMP);
InjectHook(0x56AC80, &cAudioManager::UpdateGasPedalAudio, PATCH_JUMP);
InjectHook(0x57B470, &cAudioManager::UpdateReflections, PATCH_JUMP);
InjectHook(0x56C600, &cAudioManager::UsesReverseWarning, PATCH_JUMP);
InjectHook(0x56C3C0, &cAudioManager::UsesSiren, PATCH_JUMP);
InjectHook(0x56C3F0, &cAudioManager::UsesSirenSwitching, PATCH_JUMP);

View File

@ -449,7 +449,7 @@ public:
float speedMultiplier) const; /// ok
int32 ComputePan(float, CVector *); /// ok
uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const; /// ok
int32 CreateEntity(int32 type, CPhysical *entity); /// ok
int32 CreateEntity(int32 type, void* entity); /// ok
void DestroyAllGameCreatedEntities(); /// ok
void DestroyEntity(int32 id); /// ok
@ -576,8 +576,8 @@ public:
void PlayerJustLeftCar() const; /// ok
void PostInitialiseGameSpecificSetup(); /// ok
void PostTerminateGameSpecificShutdown(); /// ok
void PreInitialiseGameSpecificSetup() const; // ok
void PreloadMissionAudio(char *); // todo
void PreInitialiseGameSpecificSetup() const; /// ok
void PreloadMissionAudio(const char *name); /// ok
void PreTerminateGameSpecificShutdown(); /// ok
/// processX - main logic of adding new sounds
void ProcessActiveQueues(); // todo
@ -653,7 +653,7 @@ public:
void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2,
float collisionPower, float intensity2); /// ok
void ReportCrime(int32 crime, const CVector *pos); /// ok
void ResetAudioLogicTimers(int32 timer); /// ok
void ResetAudioLogicTimers(uint32 timer); /// ok
void ResetPoliceRadio(); /// ok
void ResetTimers(uint32 time); /// ok
@ -666,7 +666,7 @@ public:
void SetDynamicAcousticModelingStatus(bool status);
void SetEffectsFadeVolume(uint8 volume) const;
void SetEffectsMasterVolume(uint8 volume) const;
void SetEntityStatus(int32 id, bool status);
void SetEntityStatus(int32 id, uint8 status);
uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(cAudioCollision *audioCollision); /// ok
void SetMissionAudioLocation(float x, float y, float z);
void SetMissionScriptPoliceAudio(int32 sfx) const;
@ -689,7 +689,7 @@ public:
void TranslateEntity(CVector *v1, CVector *v2) const;
void UpdateGasPedalAudio(CAutomobile *automobile);
void UpdateReflections(); // todo
void UpdateReflections();
bool UsesReverseWarning(int32 model) const;
bool UsesSiren(int32 model) const;
bool UsesSirenSwitching(int32 model) const;

View File

@ -18,7 +18,7 @@
#pragma comment( lib, "mss32.lib" )
cSampleManager &SampleManager = *(cSampleManager *)0x7341E0;
int32 (&BankStartOffset)[MAX_SAMPLEBANKS] = *(int32 (*)[MAX_SAMPLEBANKS])*(int *)0x6FAB70;
extern int32 (&BankStartOffset)[MAX_SAMPLEBANKS] = *(int32 (*)[MAX_SAMPLEBANKS])*(int *)0x6FAB70;
///////////////////////////////////////////////////////////////

View File

@ -135,6 +135,7 @@ public:
};
extern cSampleManager &SampleManager;
extern int32 (&BankStartOffset)[MAX_SAMPLEBANKS];
static char StreamedNameTable[][25]=
{

View File

@ -660,7 +660,7 @@ CPickups::DoPickUpEffects(CEntity *entity)
if (!entity->m_flagD80) {
float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800));
float modifiedSin = 0.3 * (s + 1.0f);
float modifiedSin = 0.3f * (s + 1.0f);
int16 colorId;

View File

@ -4677,7 +4677,7 @@ int8 CRunningScript::ProcessCommandsFrom500To599(int32 command)
CollectParameters(&m_nIp, 2);
CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
assert(pPed);
pPed->m_fHealth = *(float*)&ScriptParams[1];
pPed->m_fHealth = ScriptParams[1];
return 0;
}
case COMMAND_SET_CHAR_HEALTH:
@ -4685,9 +4685,8 @@ int8 CRunningScript::ProcessCommandsFrom500To599(int32 command)
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
assert(pPed);
float health = *(float*)&ScriptParams[1];
if (health != 0.0f) {
pPed->m_fHealth = *(float*)&ScriptParams[1];
if (ScriptParams[1]) {
pPed->m_fHealth = ScriptParams[1];
}
else if (pPed->bInVehicle) {
pPed->SetDead();
@ -4704,7 +4703,7 @@ int8 CRunningScript::ProcessCommandsFrom500To599(int32 command)
CollectParameters(&m_nIp, 2);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(pVehicle);
pVehicle->m_fHealth = *(float*)&ScriptParams[1];
pVehicle->m_fHealth = ScriptParams[1];
return 0;
}
case COMMAND_GET_PLAYER_HEALTH:
@ -4840,7 +4839,7 @@ int8 CRunningScript::ProcessCommandsFrom500To599(int32 command)
CPed* pSourcePed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
assert(pSourcePed);
pSourcePed->ClearLookFlag();
pSourcePed->bIsRestoringLook = false;
pSourcePed->bKeepTryingToLook = false;
if (pSourcePed->GetPedState() == PED_LOOK_HEADING || pSourcePed->GetPedState() == PED_LOOK_ENTITY)
pSourcePed->RestorePreviousState();
return 0;
@ -4851,7 +4850,7 @@ int8 CRunningScript::ProcessCommandsFrom500To599(int32 command)
CPed* pSourcePed = CWorld::Players[ScriptParams[0]].m_pPed;
assert(pSourcePed);
pSourcePed->ClearLookFlag();
pSourcePed->bIsRestoringLook = false;
pSourcePed->bKeepTryingToLook = false;
if (pSourcePed->GetPedState() == PED_LOOK_HEADING || pSourcePed->GetPedState() == PED_LOOK_ENTITY)
pSourcePed->RestorePreviousState();
return 0;

View File

@ -16,6 +16,7 @@
#include "ModelIndices.h"
#include "Camera.h"
#include "win.h"
#include "PCSave.h"
CControllerConfigManager &ControlsManager = *(CControllerConfigManager*)0x8F43A4;
@ -75,7 +76,7 @@ void CControllerConfigManager::LoadSettings(int32 file)
char buff[29];
CFileMgr::Read(file, buff, sizeof(buff));
if (!strcmp(buff, "THIS FILE IS NOT VALID YET"))
if (!strncmp(buff, TopLineEmptyFile, sizeof(TopLineEmptyFile)-1))
bValid = false;
else
CFileMgr::Seek(file, 0, 0);
@ -109,7 +110,7 @@ void CControllerConfigManager::InitDefaultControlConfiguration()
SetControllerKeyAssociatedWithAction(VEHICLE_HORN, rsRSHIFT, KEYBOARD);
}
else
SetControllerKeyAssociatedWithAction(VEHICLE_HORN, rsSHIFT, OPTIONAL_EXTRA);
SetControllerKeyAssociatedWithAction(VEHICLE_HORN, rsSHIFT, OPTIONAL_EXTRA); // BUG: must be KEYBOARD ?
SetControllerKeyAssociatedWithAction (VEHICLE_HANDBRAKE, rsRCTRL, KEYBOARD);
SetControllerKeyAssociatedWithAction (VEHICLE_HANDBRAKE, ' ', OPTIONAL_EXTRA);
@ -162,11 +163,11 @@ void CControllerConfigManager::InitDefaultControlConfiguration()
#ifndef FIX_BUGS
SetControllerKeyAssociatedWithAction(PED_SPRINT, rsRSHIFT, OPTIONAL_EXTRA); // BUG: must be KEYBOARD
#else
SetControllerKeyAssociatedWithAction(PED_SPRINT, rsRSHIFT, KEYBOARD); // BUG: must be KEYBOARD ?
SetControllerKeyAssociatedWithAction(PED_SPRINT, rsRSHIFT, KEYBOARD);
#endif
}
else
SetControllerKeyAssociatedWithAction(PED_SPRINT, rsSHIFT, OPTIONAL_EXTRA);
SetControllerKeyAssociatedWithAction(PED_SPRINT, rsSHIFT, OPTIONAL_EXTRA); // BUG: must be KEYBOARD ?
SetControllerKeyAssociatedWithAction (PED_CYCLE_TARGET_LEFT, '[', KEYBOARD);
@ -351,115 +352,48 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons)
void CControllerConfigManager::InitialiseControllerActionNameArray()
{
wchar buff[40+2];
wchar buf[ACTIONNAME_LENGTH + 2];
AsciiToUnicode("PED_LOOKBEHIND", buff);
CMessages::WideStringCopy(m_aActionNames[PED_LOOKBEHIND], buff, sizeof(m_aActionNames[PED_LOOKBEHIND]));
#define SETACTIONNAME(name) AsciiToUnicode(#name, buf); CMessages::WideStringCopy(m_aActionNames[name], buf, ACTIONNAME_LENGTH);
AsciiToUnicode("PED_CYCLE_WEAPON_LEFT", buff);
CMessages::WideStringCopy(m_aActionNames[PED_CYCLE_WEAPON_LEFT], buff, sizeof(m_aActionNames[PED_CYCLE_WEAPON_LEFT]));
SETACTIONNAME(PED_LOOKBEHIND);
SETACTIONNAME(PED_CYCLE_WEAPON_LEFT);
SETACTIONNAME(PED_CYCLE_WEAPON_RIGHT);
SETACTIONNAME(PED_LOCK_TARGET);
SETACTIONNAME(PED_JUMPING);
SETACTIONNAME(PED_SPRINT);
SETACTIONNAME(PED_CYCLE_TARGET_LEFT);
SETACTIONNAME(PED_CYCLE_TARGET_RIGHT);
SETACTIONNAME(PED_CENTER_CAMERA_BEHIND_PLAYER);
SETACTIONNAME(VEHICLE_LOOKBEHIND);
SETACTIONNAME(VEHICLE_LOOKLEFT);
SETACTIONNAME(VEHICLE_LOOKRIGHT);
SETACTIONNAME(VEHICLE_HORN);
SETACTIONNAME(VEHICLE_HANDBRAKE);
SETACTIONNAME(VEHICLE_ACCELERATE);
SETACTIONNAME(VEHICLE_BRAKE);
SETACTIONNAME(VEHICLE_CHANGE_RADIO_STATION);
SETACTIONNAME(TOGGLE_SUBMISSIONS);
SETACTIONNAME(PED_SNIPER_ZOOM_IN);
SETACTIONNAME(PED_SNIPER_ZOOM_OUT);
SETACTIONNAME(PED_1RST_PERSON_LOOK_LEFT);
SETACTIONNAME(PED_1RST_PERSON_LOOK_RIGHT);
SETACTIONNAME(PED_1RST_PERSON_LOOK_UP);
SETACTIONNAME(PED_1RST_PERSON_LOOK_DOWN);
SETACTIONNAME(SHOW_MOUSE_POINTER_TOGGLE);
SETACTIONNAME(CAMERA_CHANGE_VIEW_ALL_SITUATIONS);
SETACTIONNAME(PED_FIREWEAPON);
SETACTIONNAME(VEHICLE_ENTER_EXIT);
SETACTIONNAME(GO_LEFT);
SETACTIONNAME(GO_RIGHT);
SETACTIONNAME(GO_FORWARD);
SETACTIONNAME(GO_BACK);
SETACTIONNAME(NETWORK_TALK);
SETACTIONNAME(TOGGLE_DPAD);
SETACTIONNAME(SWITCH_DEBUG_CAM_ON);
SETACTIONNAME(TAKE_SCREEN_SHOT);
AsciiToUnicode("PED_CYCLE_WEAPON_RIGHT", buff);
CMessages::WideStringCopy(m_aActionNames[PED_CYCLE_WEAPON_RIGHT], buff, sizeof(m_aActionNames[PED_CYCLE_WEAPON_RIGHT]));
AsciiToUnicode("PED_LOCK_TARGET", buff);
CMessages::WideStringCopy(m_aActionNames[PED_LOCK_TARGET], buff, sizeof(m_aActionNames[PED_LOCK_TARGET]));
AsciiToUnicode("PED_JUMPING", buff);
CMessages::WideStringCopy(m_aActionNames[PED_JUMPING], buff, sizeof(m_aActionNames[PED_JUMPING]));
AsciiToUnicode("PED_SPRINT", buff);
CMessages::WideStringCopy(m_aActionNames[PED_SPRINT], buff, sizeof(m_aActionNames[PED_SPRINT]));
AsciiToUnicode("PED_CYCLE_TARGET_LEFT", buff);
CMessages::WideStringCopy(m_aActionNames[PED_CYCLE_TARGET_LEFT], buff, sizeof(m_aActionNames[PED_CYCLE_TARGET_LEFT]));
AsciiToUnicode("PED_CYCLE_TARGET_RIGHT", buff);
CMessages::WideStringCopy(m_aActionNames[PED_CYCLE_TARGET_RIGHT], buff, sizeof(m_aActionNames[PED_CYCLE_TARGET_RIGHT]));
AsciiToUnicode("PED_CENTER_CAMERA_BEHIND_PLAYER", buff);
CMessages::WideStringCopy(m_aActionNames[PED_CENTER_CAMERA_BEHIND_PLAYER], buff, sizeof(m_aActionNames[PED_CENTER_CAMERA_BEHIND_PLAYER]));
AsciiToUnicode("VEHICLE_LOOKBEHIND", buff);
CMessages::WideStringCopy(m_aActionNames[VEHICLE_LOOKBEHIND], buff, sizeof(m_aActionNames[VEHICLE_LOOKBEHIND]));
AsciiToUnicode("VEHICLE_LOOKLEFT", buff);
CMessages::WideStringCopy(m_aActionNames[VEHICLE_LOOKLEFT], buff, sizeof(m_aActionNames[VEHICLE_LOOKLEFT]));
AsciiToUnicode("VEHICLE_LOOKRIGHT", buff);
CMessages::WideStringCopy(m_aActionNames[VEHICLE_LOOKRIGHT], buff, sizeof(m_aActionNames[VEHICLE_LOOKRIGHT]));
AsciiToUnicode("VEHICLE_HORN", buff);
CMessages::WideStringCopy(m_aActionNames[VEHICLE_HORN], buff, sizeof(m_aActionNames[VEHICLE_HORN]));
AsciiToUnicode("VEHICLE_HANDBRAKE", buff);
CMessages::WideStringCopy(m_aActionNames[VEHICLE_HANDBRAKE], buff, sizeof(m_aActionNames[VEHICLE_HANDBRAKE]));
AsciiToUnicode("VEHICLE_ACCELERATE", buff);
CMessages::WideStringCopy(m_aActionNames[VEHICLE_ACCELERATE], buff, sizeof(m_aActionNames[VEHICLE_ACCELERATE]));
AsciiToUnicode("VEHICLE_BRAKE", buff);
CMessages::WideStringCopy(m_aActionNames[VEHICLE_BRAKE], buff, sizeof(m_aActionNames[VEHICLE_BRAKE]));
AsciiToUnicode("VEHICLE_CHANGE_RADIO_STATION", buff);
CMessages::WideStringCopy(m_aActionNames[VEHICLE_CHANGE_RADIO_STATION], buff, sizeof(m_aActionNames[VEHICLE_CHANGE_RADIO_STATION]));
AsciiToUnicode("TOGGLE_SUBMISSIONS", buff);
CMessages::WideStringCopy(m_aActionNames[TOGGLE_SUBMISSIONS], buff, sizeof(m_aActionNames[TOGGLE_SUBMISSIONS]));
AsciiToUnicode("PED_SNIPER_ZOOM_IN", buff);
CMessages::WideStringCopy(m_aActionNames[PED_SNIPER_ZOOM_IN], buff, sizeof(m_aActionNames[PED_SNIPER_ZOOM_IN]));
AsciiToUnicode("PED_SNIPER_ZOOM_OUT", buff);
CMessages::WideStringCopy(m_aActionNames[PED_SNIPER_ZOOM_OUT], buff, sizeof(m_aActionNames[PED_SNIPER_ZOOM_OUT]));
AsciiToUnicode("PED_1RST_PERSON_LOOK_LEFT", buff);
CMessages::WideStringCopy(m_aActionNames[PED_1RST_PERSON_LOOK_LEFT], buff, sizeof(m_aActionNames[PED_1RST_PERSON_LOOK_LEFT]));
AsciiToUnicode("PED_1RST_PERSON_LOOK_RIGHT", buff);
CMessages::WideStringCopy(m_aActionNames[PED_1RST_PERSON_LOOK_RIGHT], buff, sizeof(m_aActionNames[PED_1RST_PERSON_LOOK_RIGHT]));
AsciiToUnicode("PED_1RST_PERSON_LOOK_UP", buff);
CMessages::WideStringCopy(m_aActionNames[PED_1RST_PERSON_LOOK_UP], buff, sizeof(m_aActionNames[PED_1RST_PERSON_LOOK_UP]));
AsciiToUnicode("PED_1RST_PERSON_LOOK_DOWN", buff);
CMessages::WideStringCopy(m_aActionNames[PED_1RST_PERSON_LOOK_DOWN], buff, sizeof(m_aActionNames[PED_1RST_PERSON_LOOK_DOWN]));
AsciiToUnicode("SHOW_MOUSE_POINTER_TOGGLE", buff);
CMessages::WideStringCopy(m_aActionNames[SHOW_MOUSE_POINTER_TOGGLE], buff, sizeof(m_aActionNames[SHOW_MOUSE_POINTER_TOGGLE]));
AsciiToUnicode("CAMERA_CHANGE_VIEW_ALL_SITUATIONS", buff);
CMessages::WideStringCopy(m_aActionNames[CAMERA_CHANGE_VIEW_ALL_SITUATIONS], buff, sizeof(m_aActionNames[CAMERA_CHANGE_VIEW_ALL_SITUATIONS]));
AsciiToUnicode("PED_FIREWEAPON", buff);
CMessages::WideStringCopy(m_aActionNames[PED_FIREWEAPON], buff, sizeof(m_aActionNames[PED_FIREWEAPON]));
AsciiToUnicode("VEHICLE_ENTER_EXIT", buff);
CMessages::WideStringCopy(m_aActionNames[VEHICLE_ENTER_EXIT], buff, sizeof(m_aActionNames[VEHICLE_ENTER_EXIT]));
AsciiToUnicode("GO_LEFT", buff);
CMessages::WideStringCopy(m_aActionNames[GO_LEFT], buff, sizeof(m_aActionNames[GO_LEFT]));
AsciiToUnicode("GO_RIGHT", buff);
CMessages::WideStringCopy(m_aActionNames[GO_RIGHT], buff, sizeof(m_aActionNames[GO_RIGHT]));
AsciiToUnicode("GO_FORWARD", buff);
CMessages::WideStringCopy(m_aActionNames[GO_FORWARD], buff, sizeof(m_aActionNames[GO_FORWARD]));
AsciiToUnicode("GO_BACK", buff);
CMessages::WideStringCopy(m_aActionNames[GO_BACK], buff, sizeof(m_aActionNames[GO_BACK]));
AsciiToUnicode("NETWORK_TALK", buff);
CMessages::WideStringCopy(m_aActionNames[NETWORK_TALK], buff, sizeof(m_aActionNames[NETWORK_TALK]));
AsciiToUnicode("TOGGLE_DPAD", buff);
CMessages::WideStringCopy(m_aActionNames[TOGGLE_DPAD], buff, sizeof(m_aActionNames[TOGGLE_DPAD]));
AsciiToUnicode("SWITCH_DEBUG_CAM_ON", buff);
CMessages::WideStringCopy(m_aActionNames[SWITCH_DEBUG_CAM_ON], buff, sizeof(m_aActionNames[SWITCH_DEBUG_CAM_ON]));
AsciiToUnicode("TAKE_SCREEN_SHOT", buff);
CMessages::WideStringCopy(m_aActionNames[TAKE_SCREEN_SHOT], buff, sizeof(m_aActionNames[TAKE_SCREEN_SHOT]));
#undef SETACTIONNAME
}
void CControllerConfigManager::UpdateJoyInConfigMenus_ButtonDown(int32 button, int32 padnumber)
@ -1422,7 +1356,7 @@ bool CControllerConfigManager::GetIsKeyboardKeyJustDown(RsKeyCodes keycode)
return true;
break;
case rsENTER:
if (CPad::GetPad(PAD1)->GetEnterJustDown())
if (CPad::GetPad(PAD1)->GetReturnJustDown())
return true;
break;
case rsLSHIFT:

View File

@ -117,7 +117,7 @@ public:
DIJOYSTATE2 m_OldState;
DIJOYSTATE2 m_NewState;
#endif
wchar m_aActionNames[MAX_CONTROLLERACTIONS][40];
wchar m_aActionNames[MAX_CONTROLLERACTIONS][ACTIONNAME_LENGTH];
bool m_aButtonStates[MAX_BUTTONS];
char _pad1[3];
tControllerConfigBind m_aSettings[MAX_CONTROLLERACTIONS][MAX_CONTROLLERTYPES];

View File

@ -411,7 +411,7 @@ CCutsceneMgr::Update(void)
if (CPad::GetPad(0)->GetCrossJustDown()
|| (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown())
|| CPad::GetPad(0)->GetLeftMouseJustDown()
|| CPad::GetPad(0)->GetPadEnterJustDown() || CPad::GetPad(0)->GetEnterJustDown() // NOTE: In original code it's a single CPad method
|| CPad::GetPad(0)->GetEnterJustDown()
|| CPad::GetPad(0)->GetCharJustDown(VK_SPACE))
FinishCutscene();
}

View File

@ -1148,12 +1148,12 @@ void CMenuManager::LoadSettings()
CMBlur::BlurOn = true;
MousePointerStateHelper.bInvertVertically = true;
static char Ver;
char Ver[50];
int fileHandle = CFileMgr::OpenFile("gta3.set", "r");
if (fileHandle) {
CFileMgr::Read(fileHandle, (char*)&Ver, sizeof(Ver));
CFileMgr::Read(fileHandle, Ver, 29);
if (strncmp(&Ver, "THIS FILE IS NOT VALID YET", 26)) {
if (strncmp(Ver, TopLineEmptyFile, sizeof(TopLineEmptyFile) - 1)) {
CFileMgr::Seek(fileHandle, 0, 0);
ControlsManager.LoadSettings(fileHandle);
CFileMgr::Read(fileHandle, gString, 20);

View File

@ -19,3 +19,5 @@ extern C_PcSave PcSaveHelper;
extern int *Slots;
extern int *SlotFileName;
extern int *SlotSaveDate;
const char TopLineEmptyFile[] = "THIS FILE IS NOT VALID YET";

View File

@ -1855,7 +1855,7 @@ char *CPad::EditString(char *pStr, int32 nSize)
}
// extenter/up/down
if ( GetPad(0)->GetEnterJustDown() || GetPad(0)->GetUpJustDown() || GetPad(0)->GetDownJustDown() )
if ( GetPad(0)->GetReturnJustDown() || GetPad(0)->GetUpJustDown() || GetPad(0)->GetDownJustDown() )
return nil;
return pStr;
@ -1976,7 +1976,7 @@ int32 *CPad::EditCodesForControls(int32 *pRsKeys, int32 nSize)
if ( GetPad(0)->GetCapsLockJustDown() )
*pRsKeys = rsCAPSLK;
if ( GetPad(0)->GetEnterJustDown() )
if ( GetPad(0)->GetReturnJustDown() )
*pRsKeys = rsENTER;
if ( GetPad(0)->GetLeftShiftJustDown() )

View File

@ -299,7 +299,7 @@ public:
bool GetTimesJustDown() { return !!(NewKeyState.MUL && !OldKeyState.MUL); }
bool GetMinusJustDown() { return !!(NewKeyState.SUB && !OldKeyState.SUB); }
bool GetPlusJustDown() { return !!(NewKeyState.ADD && !OldKeyState.ADD); }
bool GetPadEnterJustDown() { return !!(NewKeyState.ENTER && !OldKeyState.ENTER); } // GetEnterJustDown
bool GetPadEnterJustDown() { return !!(NewKeyState.ENTER && !OldKeyState.ENTER); }
bool GetPadDelJustDown() { return !!(NewKeyState.DECIMAL && !OldKeyState.DECIMAL); }
bool GetPad1JustDown() { return !!(NewKeyState.NUM1 && !OldKeyState.NUM1); }
bool GetPad2JustDown() { return !!(NewKeyState.NUM2 && !OldKeyState.NUM2); }
@ -314,7 +314,7 @@ public:
bool GetBackspaceJustDown() { return !!(NewKeyState.BACKSP && !OldKeyState.BACKSP); }
bool GetTabJustDown() { return !!(NewKeyState.TAB && !OldKeyState.TAB); }
bool GetCapsLockJustDown() { return !!(NewKeyState.CAPSLOCK && !OldKeyState.CAPSLOCK); }
bool GetEnterJustDown() { return !!(NewKeyState.EXTENTER && !OldKeyState.EXTENTER); }
bool GetReturnJustDown() { return !!(NewKeyState.EXTENTER && !OldKeyState.EXTENTER); }
bool GetLeftShiftJustDown() { return !!(NewKeyState.LSHIFT && !OldKeyState.LSHIFT); }
bool GetShiftJustDown() { return !!(NewKeyState.SHIFT && !OldKeyState.SHIFT); }
bool GetRightShiftJustDown() { return !!(NewKeyState.RSHIFT && !OldKeyState.RSHIFT); }
@ -325,6 +325,8 @@ public:
bool GetLeftWinJustDown() { return !!(NewKeyState.LWIN && !OldKeyState.LWIN); }
bool GetRightWinJustDown() { return !!(NewKeyState.RWIN && !OldKeyState.RWIN); }
bool GetAppsJustDown() { return !!(NewKeyState.APPS && !OldKeyState.APPS); }
bool GetEnterJustDown() { return GetPadEnterJustDown() || GetReturnJustDown(); }
bool GetAltJustDown() { return GetLeftAltJustDown() || GetRightAltJustDown(); }
bool GetChar(int32 c) { return NewKeyState.VK_KEYS[c]; }
bool GetF(int32 n) { return NewKeyState.F[n]; }

View File

@ -15,7 +15,7 @@
#include "World.h"
#include "Streaming.h"
float &CRadar::m_RadarRange = *(float*)0x8E281C;
float &CRadar::m_radarRange = *(float*)0x8E281C;
CBlip (&CRadar::ms_RadarTrace)[NUMRADARBLIPS] = *(CBlip(*)[NUMRADARBLIPS]) * (uintptr*)0x6ED5E0;
CVector2D &vec2DRadarOrigin = *(CVector2D*)0x6299B8;
int *gRadarTxdIds = (int*)0x6299C0;
@ -288,7 +288,7 @@ void CRadar::DrawBlips()
CVector2D vec2d;
vec2d.x = vec2DRadarOrigin.x;
vec2d.y = M_SQRT2 * m_RadarRange + vec2DRadarOrigin.y;
vec2d.y = M_SQRT2 * m_radarRange + vec2DRadarOrigin.y;
TransformRealWorldPointToRadarSpace(in, vec2d);
LimitRadarPoint(in);
TransformRadarPointToScreenSpace(out, in);
@ -527,14 +527,14 @@ void CRadar::DrawMap()
if (FindPlayerVehicle()) {
float speed = FindPlayerSpeed().Magnitude();
if (speed < RADAR_MIN_SPEED)
m_RadarRange = RADAR_MIN_RANGE;
m_radarRange = RADAR_MIN_RANGE;
else if (speed < RADAR_MAX_SPEED)
m_RadarRange = (speed - RADAR_MIN_SPEED)/(RADAR_MAX_SPEED-RADAR_MIN_SPEED) * (RADAR_MAX_RANGE-RADAR_MIN_RANGE) + RADAR_MIN_RANGE;
m_radarRange = (speed - RADAR_MIN_SPEED)/(RADAR_MAX_SPEED-RADAR_MIN_SPEED) * (RADAR_MAX_RANGE-RADAR_MIN_RANGE) + RADAR_MIN_RANGE;
else
m_RadarRange = RADAR_MAX_RANGE;
m_radarRange = RADAR_MAX_RANGE;
}
else
m_RadarRange = RADAR_MIN_RANGE;
m_radarRange = RADAR_MIN_RANGE;
vec2DRadarOrigin = CVector2D(FindPlayerCentreOfWorld_NoSniperShift());
DrawRadarMap();
@ -795,12 +795,89 @@ uint32 CRadar::GetRadarTraceColour(uint32 color, bool bright)
}
#endif
#if 1
const char* gRadarTexNames[] = {
"radar00",
"radar01",
"radar02",
"radar03",
"radar04",
"radar05",
"radar06",
"radar07",
"radar08",
"radar09",
"radar10",
"radar11",
"radar12",
"radar13",
"radar14",
"radar15",
"radar16",
"radar17",
"radar18",
"radar19",
"radar20",
"radar21",
"radar22",
"radar23",
"radar24",
"radar25",
"radar26",
"radar27",
"radar28",
"radar29",
"radar30",
"radar31",
"radar32",
"radar33",
"radar34",
"radar35",
"radar36",
"radar37",
"radar38",
"radar39",
"radar40",
"radar41",
"radar42",
"radar43",
"radar44",
"radar45",
"radar46",
"radar47",
"radar48",
"radar49",
"radar50",
"radar51",
"radar52",
"radar53",
"radar54",
"radar55",
"radar56",
"radar57",
"radar58",
"radar59",
"radar60",
"radar61",
};
#if 0
WRAPPER void CRadar::Initialise() { EAXJMP(0x4A3EF0); }
#else
void CRadar::Initialise()
void
CRadar::Initialise()
{
for (int i = 0; i < NUMRADARBLIPS; i++) {
ms_RadarTrace[i].m_BlipIndex = 1;
SetRadarMarkerState(i, false);
ms_RadarTrace[i].m_bInUse = false;
ms_RadarTrace[i].m_eBlipType = BLIP_NONE;
ms_RadarTrace[i].m_eBlipDisplay = BLIP_DISPLAY_NEITHER;
ms_RadarTrace[i].m_IconID = RADAR_SPRITE_NONE;
}
m_radarRange = 350.0f;
for (int i = 0; i < 64; i++)
gRadarTxdIds[i] = CTxdStore::FindTxdSlot(gRadarTexNames[i]);
}
#endif
@ -1102,7 +1179,7 @@ void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D
out.x = s * in.y + c * in.x;
out.y = c * in.y - s * in.x;
out = out * m_RadarRange + vec2DRadarOrigin;
out = out * m_radarRange + vec2DRadarOrigin;
}
#endif
@ -1142,8 +1219,8 @@ void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D
c = Cos(forward.Heading());
}
float x = (in.x - vec2DRadarOrigin.x) * (1.0f / m_RadarRange);
float y = (in.y - vec2DRadarOrigin.y) * (1.0f / m_RadarRange);
float x = (in.x - vec2DRadarOrigin.x) * (1.0f / m_radarRange);
float y = (in.y - vec2DRadarOrigin.y) * (1.0f / m_radarRange);
out.x = s * y + c * x;
out.y = c * y - s * x;

View File

@ -55,7 +55,7 @@ enum
struct CBlip
{
uint32 m_nColor;
uint16 m_eBlipType; // eBlipType
uint32 m_eBlipType; // eBlipType
int32 m_nEntityHandle;
CVector2D m_vec2DPos;
CVector m_vecPos;
@ -78,7 +78,7 @@ static_assert(sizeof(CBlip) == 0x30, "CBlip: error");
class CRadar
{
public:
static float &m_RadarRange;
static float &m_radarRange;
static CBlip (&ms_RadarTrace)[NUMRADARBLIPS];
static CSprite2d *AsukaSprite;
static CSprite2d *BombSprite;

View File

@ -87,6 +87,9 @@ enum Config {
NUM_FIRES = 40,
NUMPEDROUTES = 200,
NUMVISIBLEENTITIES = 2000,
NUMINVISIBLEENTITIES = 150,
};
// We'll use this once we're ready to become independent of the game
@ -141,17 +144,17 @@ enum Config {
# define CHATTYSPLASH // print what the game is loading
#endif
#define FIX_BUGS // fix bugs in the game, TODO: use this more
#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more
// Pad
#define KANGAROO_CHEAT
// Hud & radar
#define ASPECT_RATIO_SCALE
#define TRIANGULAR_BLIPS
#define TRIANGULAR_BLIPS // height indicating triangular radar blips, as in VC
// Script
#define USE_DEBUG_SCRIPT_LOADER
#define USE_DEBUG_SCRIPT_LOADER // makes game load main_freeroam.scm by default
// Vehicles
#define EXPLODING_AIRTRAIN // can blow up jumbo jet with rocket launcher
@ -162,6 +165,6 @@ enum Config {
// Peds
#define ANIMATE_PED_COL_MODEL
#define VC_PED_PORTS
#define NEW_WALK_AROUND_ALGORITHM
#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 CANCELLABLE_CAR_ENTER

View File

@ -354,6 +354,7 @@ DebugMenuPopulate(void)
#ifndef MASTER
DebugMenuAddVarBool8("Debug", "Toggle unused fight feature", (int8*)&CPed::bUnusedFightThingOnPlayer, nil);
DebugMenuAddVarBool8("Debug", "Toggle banned particles", (int8*)&CParticle::bEnableBannedParticles, nil);
DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", (int8*)&CPed::bPopHeadsOnHeadshot, nil);
#endif
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);

View File

@ -78,21 +78,6 @@ public:
bool IsZero(void) { return x == 0.0f && y == 0.0f && z == 0.0f; }
};
inline float
DotProduct(const CVector &v1, const CVector &v2)
{
return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
}
inline CVector
CrossProduct(const CVector &v1, const CVector &v2)
{
return CVector(
v1.y*v2.z - v1.z*v2.y,
v1.z*v2.x - v1.x*v2.z,
v1.x*v2.y - v1.y*v2.x);
}
inline CVector operator+(const CVector &left, const CVector &right)
{
return CVector(left.x + right.x, left.y + right.y, left.z + right.z);
@ -117,3 +102,24 @@ inline CVector operator/(const CVector &left, float right)
{
return CVector(left.x / right, left.y / right, left.z / right);
}
inline float
DotProduct(const CVector &v1, const CVector &v2)
{
return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
}
inline CVector
CrossProduct(const CVector &v1, const CVector &v2)
{
return CVector(
v1.y*v2.z - v1.z*v2.y,
v1.z*v2.x - v1.x*v2.z,
v1.x*v2.y - v1.y*v2.x);
}
inline float
Distance(const CVector &v1, const CVector &v2)
{
return (v2 - v1).Magnitude();
}

View File

@ -49,9 +49,6 @@ public:
CVector2D operator+(const CVector2D &rhs) const {
return CVector2D(x+rhs.x, y+rhs.y);
}
CVector2D operator*(float t) const {
return CVector2D(x*t, y*t);
}
CVector2D operator/(float t) const {
return CVector2D(x/t, y/t);
}
@ -91,3 +88,13 @@ NormalizeXY(float &x, float &y)
}else
x = 1.0f;
}
inline CVector2D operator*(const CVector2D &left, float right)
{
return CVector2D(left.x * right, left.y * right);
}
inline CVector2D operator*(float left, const CVector2D &right)
{
return CVector2D(left * right.x, left * right.y);
}

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,7 @@
struct CPathNode;
class CAccident;
class CObject;
struct CPedAudioData
{
@ -58,6 +59,15 @@ enum PedRouteType
PEDROUTE_GO_TO_START_WHEN_DONE
};
enum FightMoveHitLevel
{
HITLEVEL_NULL,
HITLEVEL_GROUND,
HITLEVEL_LOW,
HITLEVEL_MEDIUM,
HITLEVEL_HIGH
};
struct FightMove
{
AnimationId animId;
@ -65,7 +75,7 @@ struct FightMove
float endFireTime;
float comboFollowOnTime;
float strikeRadius;
uint8 hitLevel;
uint8 hitLevel; // FightMoveHitLevel
uint8 damage;
uint8 flags;
};
@ -99,7 +109,8 @@ enum PedFightMoves
FIGHTMOVE_HITBIGSTEP,
FIGHTMOVE_HITONFLOOR,
FIGHTMOVE_HITBEHIND,
FIGHTMOVE_IDLE2NORM
FIGHTMOVE_IDLE2NORM,
NUM_FIGHTMOVES
};
enum ePedPieceTypes
@ -352,7 +363,7 @@ public:
uint8 bShakeFist : 1; // test shake hand at look entity
uint8 bNoCriticalHits : 1; // if set, limbs won't came off
uint8 m_ped_flagI4 : 1; // seems like related with cars
uint8 m_ped_flagI4 : 1; // we've been put to car by script? - related with cars
uint8 bHasAlreadyBeenRecorded : 1;
uint8 bFallenDown : 1;
#ifdef VC_PED_PORTS
@ -420,7 +431,7 @@ public:
float m_headingRate;
uint16 m_vehEnterType; // TODO: this is more like a door, not a type
int16 m_walkAroundType;
CEntity *m_pCurrentPhysSurface;
CPhysical *m_pCurrentPhysSurface;
CVector m_vecOffsetFromPhysSurface;
CEntity *m_pCurSurface;
CVector m_vecSeekPos;
@ -522,7 +533,6 @@ public:
void SetDead(void);
void ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer);
void RemoveBodyPart(PedNode nodeId, int8 direction);
void SpawnFlyingComponent(int, int8);
bool OurPedCanSeeThisOne(CEntity *target);
void Avoid(void);
void Attack(void);
@ -660,7 +670,6 @@ public:
void ProcessBuoyancy(void);
void ServiceTalking(void);
void SetJump(void);
void UpdatePosition(void);
void WanderPath(void);
void ReactToPointGun(CEntity*);
void SeekCar(void);
@ -681,6 +690,7 @@ public:
void ScanForInterestingStuff(void);
void WarpPedIntoCar(CVehicle*);
void SetCarJack(CVehicle*);
void WarpPedToNearLeaderOffScreen(void);
// Static methods
static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset);
@ -756,6 +766,8 @@ public:
void WanderRange(void);
void SetFollowRoute(int16, int16);
void SeekBoatPosition(void);
void UpdatePosition(void);
CObject *SpawnFlyingComponent(int, int8);
#ifdef VC_PED_PORTS
bool CanPedJumpThis(CEntity*, CVector*);
#else
@ -785,9 +797,12 @@ public:
static CPedAudioData (&CommentWaitTime)[38];
#ifndef MASTER
static bool bUnusedFightThingOnPlayer;
static bool bPopHeadsOnHeadshot;
// Mobile things
static void SwitchDebugDisplay(void);
void DebugRenderOnePedText(void);
static bool bUnusedFightThingOnPlayer;
#endif
};

View File

@ -493,6 +493,11 @@ CCredits::Render(void)
bCreditsGoing = false;
}
bool CCredits::AreCreditsDone(void)
{
return !bCreditsGoing;
}
STARTPATCHES
InjectHook(0x4FE7A0, CCredits::Init, PATCH_JUMP);
InjectHook(0x4FE760, CCredits::Start, PATCH_JUMP);

View File

@ -8,7 +8,7 @@ public:
static void Init(void);
static void Start(void);
static void Stop(void);
static bool AreCreditsDone(void) { return bCreditsGoing; }
static bool AreCreditsDone(void);
static void Render(void);
static void PrintCreditSpace(float space, uint32 &line);
static void PrintCreditText(float scaleX, float scaleY, wchar *text, uint32 &lineoffset, float scrolloffset);

View File

@ -40,9 +40,9 @@ struct EntityInfo
CLinkList<EntityInfo> &gSortedVehiclesAndPeds = *(CLinkList<EntityInfo>*)0x629AC0;
int32 &CRenderer::ms_nNoOfVisibleEntities = *(int32*)0x940730;
CEntity **CRenderer::ms_aVisibleEntityPtrs = (CEntity**)0x6E9920;
CEntity *(&CRenderer::ms_aVisibleEntityPtrs)[NUMVISIBLEENTITIES] = *(CEntity * (*)[NUMVISIBLEENTITIES]) * (uintptr*)0x6E9920;
CEntity *(&CRenderer::ms_aInVisibleEntityPtrs)[NUMINVISIBLEENTITIES] = *(CEntity * (*)[NUMINVISIBLEENTITIES]) * (uintptr*)0x880B50;
int32 &CRenderer::ms_nNoOfInVisibleEntities = *(int32*)0x8F1B78;
CEntity **CRenderer::ms_aInVisibleEntityPtrs = (CEntity**)0x880B50;
CVector &CRenderer::ms_vecCameraPosition = *(CVector*)0x8E2C3C;
CVehicle *&CRenderer::m_pFirstPersonVehicle = *(CVehicle**)0x885B80;
@ -73,9 +73,9 @@ CRenderer::PreRender(void)
for(i = 0; i < ms_nNoOfInVisibleEntities; i++)
ms_aInVisibleEntityPtrs[i]->PreRender();
for(node = CVisibilityPlugins::m_alphaEntityList.tail.prev;
node != &CVisibilityPlugins::m_alphaEntityList.head;
node = node->prev)
for(node = CVisibilityPlugins::m_alphaEntityList.head.next;
node != &CVisibilityPlugins::m_alphaEntityList.tail;
node = node->next)
((CEntity*)node->item.entity)->PreRender();
CHeli::SpecialHeliPreRender();
@ -983,7 +983,7 @@ CRenderer::ScanSectorList(CPtrList *lists)
dy = ms_vecCameraPosition.y - ent->GetPosition().y;
if(dx > -65.0f && dx < 65.0f &&
dy > -65.0f && dy < 65.0f &&
ms_nNoOfInVisibleEntities < 150)
ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1)
ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent;
break;
case VIS_STREAMME:
@ -1033,7 +1033,7 @@ CRenderer::ScanSectorList_Priority(CPtrList *lists)
dy = ms_vecCameraPosition.y - ent->GetPosition().y;
if(dx > -65.0f && dx < 65.0f &&
dy > -65.0f && dy < 65.0f &&
ms_nNoOfInVisibleEntities < 150)
ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1)
ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent;
break;
case VIS_STREAMME:
@ -1078,7 +1078,7 @@ CRenderer::ScanSectorList_Subway(CPtrList *lists)
dy = ms_vecCameraPosition.y - ent->GetPosition().y;
if(dx > -65.0f && dx < 65.0f &&
dy > -65.0f && dy < 65.0f &&
ms_nNoOfInVisibleEntities < 150)
ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1)
ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent;
break;
}
@ -1160,8 +1160,12 @@ CRenderer::IsEntityCullZoneVisible(CEntity *ent)
return IsVehicleCullZoneVisible(ent);
case ENTITY_TYPE_PED:
ped = (CPed*)ent;
if(ped->bInVehicle)
return ped->m_pMyVehicle && IsVehicleCullZoneVisible(ped->m_pMyVehicle);
if (ped->bInVehicle) {
if (ped->m_pMyVehicle)
return IsVehicleCullZoneVisible(ped->m_pMyVehicle);
else
return true;
}
return !(ped->m_pCurSurface && ped->m_pCurSurface->bZoneCulled2);
case ENTITY_TYPE_OBJECT:
obj = (CObject*)ent;

View File

@ -19,9 +19,9 @@ class CPtrList;
class CRenderer
{
static int32 &ms_nNoOfVisibleEntities;
static CEntity **ms_aVisibleEntityPtrs; // [2000];
static CEntity *(&ms_aVisibleEntityPtrs)[NUMVISIBLEENTITIES];
static int32 &ms_nNoOfInVisibleEntities;
static CEntity **ms_aInVisibleEntityPtrs; // [150];
static CEntity *(&ms_aInVisibleEntityPtrs)[NUMINVISIBLEENTITIES];
static CVector &ms_vecCameraPosition;
static CVehicle *&m_pFirstPersonVehicle;

View File

@ -1969,11 +1969,11 @@ _WinMain(HINSTANCE instance,
++gGameState;
else if ( CPad::GetPad(0)->GetLeftMouseJustDown() )
++gGameState;
else if ( CPad::GetPad(0)->GetPadEnterJustDown() || CPad::GetPad(0)->GetEnterJustDown() )
else if ( CPad::GetPad(0)->GetEnterJustDown() )
++gGameState;
else if ( CPad::GetPad(0)->GetCharJustDown(' ') )
else if ( CPad::GetPad(0)->GetCharJustDown(VK_SPACE) )
++gGameState;
else if ( CPad::GetPad(0)->GetLeftAltJustDown() || CPad::GetPad(0)->GetRightAltJustDown() )
else if ( CPad::GetPad(0)->GetAltJustDown() )
++gGameState;
else if ( CPad::GetPad(0)->GetTabJustDown() )
++gGameState;
@ -2005,11 +2005,11 @@ _WinMain(HINSTANCE instance,
++gGameState;
else if ( CPad::GetPad(0)->GetLeftMouseJustDown() )
++gGameState;
else if ( CPad::GetPad(0)->GetPadEnterJustDown() || CPad::GetPad(0)->GetEnterJustDown() )
else if ( CPad::GetPad(0)->GetEnterJustDown() )
++gGameState;
else if ( CPad::GetPad(0)->GetCharJustDown(' ') )
else if ( CPad::GetPad(0)->GetCharJustDown(VK_SPACE) )
++gGameState;
else if ( CPad::GetPad(0)->GetLeftAltJustDown() || CPad::GetPad(0)->GetRightAltJustDown() )
else if ( CPad::GetPad(0)->GetAltJustDown() )
++gGameState;
else if ( CPad::GetPad(0)->GetTabJustDown() )
++gGameState;

View File

@ -2474,8 +2474,8 @@ CAutomobile::TankControl(void)
int lifeSpan = 250;
if(m_vecMoveSpeed.Magnitude() > 0.08f){
lifeSpan = 125;
flashPos.x += 0.5f*m_vecMoveSpeed.x;
flashPos.y += 0.5f*m_vecMoveSpeed.y;
flashPos.x += 5.0f*m_vecMoveSpeed.x;
flashPos.y += 5.0f*m_vecMoveSpeed.y;
}
CParticle::AddParticle(PARTICLE_GUNFLASH, flashPos, nullDir, nil, 0.4f, black, 0, 0, 0, lifeSpan);
flashPos += 0.3f*shotDir;
@ -4210,7 +4210,7 @@ CAutomobile::SpawnFlyingComponent(int32 component, uint32 type)
if(atomic == nil)
return nil;
obj = new CObject;
obj = new CObject();
if(obj == nil)
return nil;