Merge branch 'miami' into lcs

# Conflicts:
#	src/audio/AudioLogic.cpp
#	src/audio/AudioSamples.h
#	src/audio/sampman_miles.cpp
This commit is contained in:
Sergeanur 2021-09-01 17:09:12 +03:00
commit 29383a6a11
8 changed files with 244 additions and 64 deletions

View File

@ -43,6 +43,7 @@
#include "Fluff.h" #include "Fluff.h"
#include "Script.h" #include "Script.h"
#include "Wanted.h" #include "Wanted.h"
#include "debugmenu.h"
#include "KeyGen.h" #include "KeyGen.h"
#include "Ferry.h" #include "Ferry.h"
@ -8242,6 +8243,20 @@ cAudioManager::DebugPlayPedComment(int32 sound)
m_sPedComments.Add(&pedComment); m_sPedComments.Add(&pedComment);
} }
#ifdef DEBUGMENU
uint32 nDebugPlayPedComment = SAMPLEBANK_PED_START;
void DebugMenuPlayPedComment()
{
AudioManager.DebugPlayPedComment(nDebugPlayPedComment);
}
SETTWEAKPATH("Audio");
TWEAKUINT32N(nDebugPlayPedComment, SAMPLEBANK_PED_START, SAMPLEBANK_PED_END, 1, "Ped Comment ID");
TWEAKFUNCN(DebugMenuPlayPedComment, "Play Ped Comment");
#endif
void void
cPedComments::Add(tPedComment *com) cPedComments::Add(tPedComment *com)
{ {
@ -8278,6 +8293,7 @@ cPedComments::Process()
{ {
uint32 sampleIndex; uint32 sampleIndex;
uint8 queue; uint8 queue;
bool8 bIsPlayerComment;
static uint8 counter = 0; static uint8 counter = 0;
static uint32 prevSamples[10] = { NO_SAMPLE, NO_SAMPLE, NO_SAMPLE, NO_SAMPLE, NO_SAMPLE, NO_SAMPLE, NO_SAMPLE, NO_SAMPLE, NO_SAMPLE, NO_SAMPLE }; static uint32 prevSamples[10] = { NO_SAMPLE, NO_SAMPLE, NO_SAMPLE, NO_SAMPLE, NO_SAMPLE, NO_SAMPLE, NO_SAMPLE, NO_SAMPLE, NO_SAMPLE, NO_SAMPLE };
@ -8291,13 +8307,30 @@ cPedComments::Process()
goto PedCommentAlreadyAdded; goto PedCommentAlreadyAdded;
} }
} }
#if defined(GTA_PS2) || defined(FIX_BUGS)
bool8 IsLoadedResult;
sampleIndex = m_aPedCommentQueue[m_nActiveQueue][m_aPedCommentOrderList[m_nActiveQueue][0]].m_nSampleIndex; sampleIndex = m_aPedCommentQueue[m_nActiveQueue][m_aPedCommentOrderList[m_nActiveQueue][0]].m_nSampleIndex;
if (sampleIndex >= PLAYER_COMMENTS_START && sampleIndex <= PLAYER_COMMENTS_END) {
IsLoadedResult = SampleManager.IsMissionAudioLoaded(MISSION_AUDIO_PLAYER_COMMENT, sampleIndex);
bIsPlayerComment = TRUE;
} else {
IsLoadedResult = SampleManager.IsPedCommentLoaded(sampleIndex);
bIsPlayerComment = FALSE;
}
switch(IsLoadedResult) { // yes, this was a switch
#else
switch(SampleManager.IsPedCommentLoaded(sampleIndex)) { // yes, this was a switch switch(SampleManager.IsPedCommentLoaded(sampleIndex)) { // yes, this was a switch
#endif
case FALSE: case FALSE:
#if defined(GTA_PC) && !defined(FIX_BUGS) #if defined(GTA_PC) && !defined(FIX_BUGS)
if(!m_bDelay) if(!m_bDelay)
#endif #endif
SampleManager.LoadPedComment(sampleIndex); #if defined(GTA_PS2) || defined(FIX_BUGS)
if (bIsPlayerComment)
SampleManager.LoadMissionAudio(MISSION_AUDIO_PLAYER_COMMENT, sampleIndex);
else
#endif
SampleManager.LoadPedComment(sampleIndex);
break; break;
case TRUE: case TRUE:
AudioManager.m_sQueueSample.m_nEntityIndex = m_aPedCommentQueue[m_nActiveQueue][m_aPedCommentOrderList[m_nActiveQueue][0]].m_nEntityIndex; AudioManager.m_sQueueSample.m_nEntityIndex = m_aPedCommentQueue[m_nActiveQueue][m_aPedCommentOrderList[m_nActiveQueue][0]].m_nEntityIndex;
@ -8338,7 +8371,7 @@ cPedComments::Process()
AudioManager.m_sQueueSample.m_bIs2D = FALSE; AudioManager.m_sQueueSample.m_bIs2D = FALSE;
#ifdef FIX_BUGS #ifdef FIX_BUGS
#ifndef ATTACH_RELEASING_SOUNDS_TO_ENTITIES #ifndef ATTACH_RELEASING_SOUNDS_TO_ENTITIES
else if (sampleIndex >= SFX_TONI_ANGRY_BUSTED_01 && sampleIndex <= SFX_TONI_WISECRACKING_SHOOT_26) { // check if player sfx else if (sampleIndex >= PLAYER_COMMENTS_START && sampleIndex <= PLAYER_COMMENTS_END) { // check if player sfx
AudioManager.m_sQueueSample.m_bIs2D = TRUE; AudioManager.m_sQueueSample.m_bIs2D = TRUE;
AudioManager.m_sQueueSample.m_nPan = 63; AudioManager.m_sQueueSample.m_nPan = 63;
} }

View File

@ -2,6 +2,9 @@
#include "common.h" #include "common.h"
#define FIRST_PLAYER_COMMENT(e) PLAYER_COMMENTS_START, e = PLAYER_COMMENTS_START
#define LAST_PLAYER_COMMENT(e) e, PLAYER_COMMENTS_END = e
enum eSfxSample enum eSfxSample
{ {
SFX_AIR_BRAKES, SFX_AIR_BRAKES,
@ -4421,7 +4424,7 @@ enum eSfxSample
SFX_TAN3_AG, SFX_TAN3_AG,
SFX_TAN3_AH, SFX_TAN3_AH,
SFX_TING, SFX_TING,
SFX_TONI_ANGRY_BUSTED_01, FIRST_PLAYER_COMMENT(SFX_TONI_ANGRY_BUSTED_01),
SFX_TONI_ANGRY_BUSTED_02, SFX_TONI_ANGRY_BUSTED_02,
SFX_TONI_ANGRY_BUSTED_03, SFX_TONI_ANGRY_BUSTED_03,
SFX_TONI_ANGRY_BUSTED_04, SFX_TONI_ANGRY_BUSTED_04,
@ -5347,7 +5350,7 @@ enum eSfxSample
SFX_TONI_WISECRACKING_SHOOT_23, SFX_TONI_WISECRACKING_SHOOT_23,
SFX_TONI_WISECRACKING_SHOOT_24, SFX_TONI_WISECRACKING_SHOOT_24,
SFX_TONI_WISECRACKING_SHOOT_25, SFX_TONI_WISECRACKING_SHOOT_25,
SFX_TONI_WISECRACKING_SHOOT_26, LAST_PLAYER_COMMENT(SFX_TONI_WISECRACKING_SHOOT_26),
SFX_TOSH1AA, SFX_TOSH1AA,
SFX_TOSH1AB, SFX_TOSH1AB,
SFX_TOSH1AC, SFX_TOSH1AC,
@ -5718,8 +5721,4 @@ enum eSfxSample
SAMPLEBANK_PED_START = SFX_FOOTSTEP_SAND_4 + 1, SAMPLEBANK_PED_START = SFX_FOOTSTEP_SAND_4 + 1,
SAMPLEBANK_PED_END = SFX_WORKER2_SPECIAL_CASE_3, SAMPLEBANK_PED_END = SFX_WORKER2_SPECIAL_CASE_3,
SAMPLEBANK_PED_MAX = SAMPLEBANK_PED_END + 1, SAMPLEBANK_PED_MAX = SAMPLEBANK_PED_END + 1,
// LCS: TODO
SFX_TRAIN_FAR = NO_SAMPLE,
SFX_TRAIN_NEAR = NO_SAMPLE,
}; };

View File

@ -168,3 +168,13 @@ enum
NUM_CHANNELS NUM_CHANNELS
}; };
#endif #endif
enum
{
MISSION_AUDIO_SLOT_1,
MISSION_AUDIO_SLOT_2,
MISSION_AUDIO_POLRADIO_CRIME_OR_COLOR,
MISSION_AUDIO_POLRADIO_AREA_OR_CAR,
MISSION_AUDIO_PLAYER_COMMENT,
MISSION_AUDIO_COUNT
};

View File

@ -206,6 +206,11 @@ public:
bool8 LoadSampleBank (uint8 nBank); bool8 LoadSampleBank (uint8 nBank);
void UnloadSampleBank (uint8 nBank); void UnloadSampleBank (uint8 nBank);
bool8 IsSampleBankLoaded(uint8 nBank); bool8 IsSampleBankLoaded(uint8 nBank);
#if defined (GTA_PS2) || defined (FIX_BUGS)
bool8 IsMissionAudioLoaded(uint8 nSlot, uint32 nSample);
bool8 LoadMissionAudio (uint8 nSlot, uint32 nSample);
#endif
bool8 IsPedCommentLoaded(uint32 nComment); bool8 IsPedCommentLoaded(uint32 nComment);
bool8 LoadPedComment (uint32 nComment); bool8 LoadPedComment (uint32 nComment);

View File

@ -39,6 +39,11 @@ int32 nPedSlotSfx [MAX_PEDSFX];
int32 nPedSlotSfxAddr[MAX_PEDSFX]; int32 nPedSlotSfxAddr[MAX_PEDSFX];
uint8 nCurrentPedSlot; uint8 nCurrentPedSlot;
#ifdef FIX_BUGS
uint32 gPlayerTalkSfx = UINT32_MAX;
void *gPlayerTalkData = 0;
#endif
uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS]; uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
uint32 nStreamLength[TOTAL_STREAMED_SOUNDS]; uint32 nStreamLength[TOTAL_STREAMED_SOUNDS];
@ -1318,6 +1323,20 @@ cSampleManager::Initialise(void)
nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX); nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX);
#ifdef FIX_BUGS
// Find biggest player comment
uint32 nMaxPedSize = 0;
for (uint32 i = PLAYER_COMMENTS_START; i <= PLAYER_COMMENTS_END; i++)
nMaxPedSize = Max(nMaxPedSize, m_aSamples[i].nSize);
gPlayerTalkData = AIL_mem_alloc_lock(nMaxPedSize);
if ( !gPlayerTalkData )
{
Terminate();
return FALSE;
}
#endif
LoadSampleBank(SFX_BANK_0); LoadSampleBank(SFX_BANK_0);
TRACE("stream"); TRACE("stream");
@ -1471,6 +1490,14 @@ cSampleManager::Terminate(void)
AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS]); AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS]);
nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = 0; nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = 0;
} }
#ifdef FIX_BUGS
if ( gPlayerTalkData != 0)
{
AIL_mem_free_lock(gPlayerTalkData);
gPlayerTalkData = 0;
}
#endif
if ( DIG ) if ( DIG )
{ {
@ -1636,6 +1663,33 @@ cSampleManager::IsSampleBankLoaded(uint8 nBank)
return bSampleBankLoaded[nBank]; return bSampleBankLoaded[nBank];
} }
#ifdef FIX_BUGS
bool8
cSampleManager::IsMissionAudioLoaded(uint8 nSlot, uint32 nSample)
{
ASSERT(nSlot == MISSION_AUDIO_PLAYER_COMMENT); // only MISSION_AUDIO_PLAYER_COMMENT is supported on PC
return nSample == gPlayerTalkSfx;
}
bool8
cSampleManager::LoadMissionAudio(uint8 nSlot, uint32 nSample)
{
ASSERT(nSlot == MISSION_AUDIO_PLAYER_COMMENT); // only MISSION_AUDIO_PLAYER_COMMENT is supported on PC
ASSERT(nSample < TOTAL_AUDIO_SAMPLES);
if (fseek(fpSampleDataHandle, m_aSamples[nSample].nOffset, SEEK_SET) != 0)
return FALSE;
if (fread(gPlayerTalkData, 1, m_aSamples[nSample].nSize, fpSampleDataHandle) != m_aSamples[nSample].nSize)
return FALSE;
gPlayerTalkSfx = nSample;
return TRUE;
}
#endif
bool8 bool8
cSampleManager::IsPedCommentLoaded(uint32 nComment) cSampleManager::IsPedCommentLoaded(uint32 nComment)
{ {
@ -1863,6 +1917,15 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset; addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset;
} }
#ifdef FIX_BUGS
else if ( nSfx >= PLAYER_COMMENTS_START && nSfx <= PLAYER_COMMENTS_END )
{
if ( !IsMissionAudioLoaded(MISSION_AUDIO_PLAYER_COMMENT, nSfx) )
return FALSE;
addr = (uintptr)gPlayerTalkData;
}
#endif
else else
{ {
if ( !IsPedCommentLoaded(nSfx) ) if ( !IsPedCommentLoaded(nSfx) )
@ -2565,7 +2628,7 @@ cSampleManager::InitialiseSampleBanks(void)
fclose(fpSampleDescHandle); fclose(fpSampleDescHandle);
fpSampleDescHandle = NULL; fpSampleDescHandle = NULL;
for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) for ( uint32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
{ {
#ifdef FIX_BUGS #ifdef FIX_BUGS
if (nBank >= MAX_SFX_BANKS) break; if (nBank >= MAX_SFX_BANKS) break;

View File

@ -156,6 +156,22 @@ cSampleManager::IsSampleBankLoaded(uint8 nBank)
return FALSE; return FALSE;
} }
bool8
cSampleManager::IsMissionAudioLoaded(uint8 nSlot, uint32 nSample)
{
ASSERT(nSlot < MISSION_AUDIO_COUNT);
return FALSE;
}
bool8
cSampleManager::LoadMissionAudio(uint8 nSlot, uint32 nSample)
{
ASSERT(nSlot < MISSION_AUDIO_COUNT);
return FALSE;
}
bool8 bool8
cSampleManager::IsPedCommentLoaded(uint32 nComment) cSampleManager::IsPedCommentLoaded(uint32 nComment)
{ {

View File

@ -102,6 +102,11 @@ int32 nPedSlotSfx [MAX_PEDSFX];
int32 nPedSlotSfxAddr[MAX_PEDSFX]; int32 nPedSlotSfxAddr[MAX_PEDSFX];
uint8 nCurrentPedSlot; uint8 nCurrentPedSlot;
#ifdef FIX_BUGS
uint32 gPlayerTalkSfx = UINT32_MAX;
void *gPlayerTalkData = 0;
#endif
CChannel aChannel[NUM_CHANNELS]; CChannel aChannel[NUM_CHANNELS];
uint8 nChannelVolume[NUM_CHANNELS]; uint8 nChannelVolume[NUM_CHANNELS];
@ -1047,7 +1052,17 @@ cSampleManager::Initialise(void)
nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = (uintptr)malloc(PED_BLOCKSIZE*MAX_PEDSFX); nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = (uintptr)malloc(PED_BLOCKSIZE*MAX_PEDSFX);
ASSERT(nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] != 0); ASSERT(nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] != 0);
#ifdef FIX_BUGS
// Find biggest player comment
uint32 nMaxPedSize = 0;
for (uint32 i = PLAYER_COMMENTS_START; i <= PLAYER_COMMENTS_END; i++)
nMaxPedSize = Max(nMaxPedSize, m_aSamples[i].nSize);
gPlayerTalkData = malloc(nMaxPedSize);
ASSERT(gPlayerTalkData != 0);
#endif
LoadSampleBank(SFX_BANK_0); LoadSampleBank(SFX_BANK_0);
} }
@ -1207,6 +1222,14 @@ cSampleManager::Terminate(void)
free((void *)nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS]); free((void *)nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS]);
nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = 0; nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = 0;
} }
#ifdef FIX_BUGS
if ( gPlayerTalkData != 0 )
{
free(gPlayerTalkData);
gPlayerTalkData = 0;
}
#endif
_bSampmanInitialised = FALSE; _bSampmanInitialised = FALSE;
} }
@ -1332,6 +1355,33 @@ cSampleManager::IsSampleBankLoaded(uint8 nBank)
return bSampleBankLoaded[nBank]; return bSampleBankLoaded[nBank];
} }
#ifdef FIX_BUGS
bool8
cSampleManager::IsMissionAudioLoaded(uint8 nSlot, uint32 nSample)
{
ASSERT(nSlot == MISSION_AUDIO_PLAYER_COMMENT); // only MISSION_AUDIO_PLAYER_COMMENT is supported on PC
return nSample == gPlayerTalkSfx;
}
bool8
cSampleManager::LoadMissionAudio(uint8 nSlot, uint32 nSample)
{
ASSERT(nSlot == MISSION_AUDIO_PLAYER_COMMENT); // only MISSION_AUDIO_PLAYER_COMMENT is supported on PC
ASSERT(nSample < TOTAL_AUDIO_SAMPLES);
if (fseek(fpSampleDataHandle, m_aSamples[nSample].nOffset, SEEK_SET) != 0)
return FALSE;
if (fread(gPlayerTalkData, 1, m_aSamples[nSample].nSize, fpSampleDataHandle) != m_aSamples[nSample].nSize)
return FALSE;
gPlayerTalkSfx = nSample;
return TRUE;
}
#endif
bool8 bool8
cSampleManager::IsPedCommentLoaded(uint32 nComment) cSampleManager::IsPedCommentLoaded(uint32 nComment)
{ {
@ -1566,6 +1616,15 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset; addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset;
} }
#ifdef FIX_BUGS
else if ( nSfx >= PLAYER_COMMENTS_START && nSfx <= PLAYER_COMMENTS_END )
{
if ( !IsMissionAudioLoaded(MISSION_AUDIO_PLAYER_COMMENT, nSfx) )
return FALSE;
addr = (uintptr)gPlayerTalkData;
}
#endif
else else
{ {
if ( !IsPedCommentLoaded(nSfx) ) if ( !IsPedCommentLoaded(nSfx) )
@ -2087,7 +2146,7 @@ cSampleManager::InitialiseSampleBanks(void)
fclose(fpSampleDescHandle); fclose(fpSampleDescHandle);
fpSampleDescHandle = NULL; fpSampleDescHandle = NULL;
for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) for ( uint32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
{ {
#ifdef FIX_BUGS #ifdef FIX_BUGS
if (nBank >= MAX_SFX_BANKS) break; if (nBank >= MAX_SFX_BANKS) break;

View File

@ -536,61 +536,56 @@ CShadows::StoreShadowForVehicle(CVehicle *pCar, VEH_SHD_TYPE type)
float size = 1.0f; float size = 1.0f;
if ( pCar->GetModelIndex() == MI_HUNTER ) switch ( pCar->GetModelIndex() )
{ {
fVehicleWidth *= 3.0f; case MI_PIZZABOY:
fVehicleHeight *= 1.4f; case MI_PCJ600:
size *= 0.5f; case MI_FAGGIO:
} {
else if ( pCar->GetModelIndex() == MI_ANGEL ) fVehicleHeight *= 1.2f;
{ size = 0.05f;
fVehicleHeight = fVehicleHeight * 1.5f; break;
size = 0.03f; }
}
else if ( pCar->GetModelIndex() == MI_SEASPAR ) case MI_ANGEL:
{ case MI_FREEWAY:
fVehicleWidth *= 3.0f; case MI_SANCHEZ:
fVehicleHeight *= 1.4f; {
size *= 0.5f; fVehicleHeight *= 1.5f;
} size *= 0.03f;
else if ( pCar->GetModelIndex() == MI_PIZZABOY || pCar->GetModelIndex() == MI_PCJ600 || pCar->GetModelIndex() == MI_FAGGIO ) break;
{ }
fVehicleHeight *= 1.2f;
size = 0.05f; case MI_HUNTER:
} case MI_SEASPAR:
else if ( pCar->GetModelIndex() == MI_FREEWAY ) case MI_SPARROW:
{ case MI_MAVERICK:
fVehicleHeight *= 1.5f; case MI_VCNMAV:
size = 0.03f; case MI_POLMAV:
} {
else if ( pCar->GetModelIndex() == MI_RCRAIDER ) fVehicleWidth *= 3.0f;
{ fVehicleHeight *= 1.4f;
fVehicleHeight *= 1.5f; size *= 0.5f;
fVehicleWidth *= 2.0f; break;
size = 0.2f; }
}
else if ( pCar->GetModelIndex() == MI_SANCHEZ ) case MI_RCGOBLIN:
{ case MI_RCRAIDER:
fVehicleHeight *= 1.5f; {
size = 0.03f; fVehicleHeight *= 1.5f;
} fVehicleWidth *= 2.0f;
else if ( pCar->GetModelIndex() == MI_SPARROW || pCar->GetModelIndex() == MI_MAVERICK || pCar->GetModelIndex() == MI_VCNMAV || pCar->GetModelIndex() == MI_POLMAV ) size *= 0.2f;
{ break;
fVehicleWidth *= 3.0f; }
fVehicleHeight *= 1.4f;
size *= 0.5f; case MI_DODO:
} {
else if ( pCar->GetModelIndex() == MI_RCGOBLIN ) fVehicleHeight *= 0.9f;
{ fVehicleWidth *= 0.4f;
fVehicleHeight *= 1.5f; break;
fVehicleWidth *= 2.0f; }
size = 0.2f;
}
else if ( pCar->GetModelIndex() == MI_DODO )
{
fVehicleHeight *= 0.9f;
fVehicleWidth *= 0.4f;
} }
CarPos.x -= pCar->GetForward().x * (((fVehicleHeight/2) - pCar->GetColModel()->boundingBox.max.y)*size); CarPos.x -= pCar->GetForward().x * (((fVehicleHeight/2) - pCar->GetColModel()->boundingBox.max.y)*size);
CarPos.y -= pCar->GetForward().y * (((fVehicleHeight/2) - pCar->GetColModel()->boundingBox.max.y)*size); CarPos.y -= pCar->GetForward().y * (((fVehicleHeight/2) - pCar->GetColModel()->boundingBox.max.y)*size);