diff --git a/premake5.lua b/premake5.lua index 23a9200b..8300dd9a 100644 --- a/premake5.lua +++ b/premake5.lua @@ -19,6 +19,11 @@ newoption { default = "vendor/glfw-3.3.2.bin.WIN32", } +newoption { + trigger = "with-asan", + description = "Build with address sanitizer" +} + newoption { trigger = "with-librw", description = "Build and use librw from this solution" @@ -60,6 +65,11 @@ workspace "reVC" symbols "Full" staticruntime "off" + if _OPTIONS["with-asan"] then + buildoptions { "-fsanitize=address -g3 -fno-omit-frame-pointer" } + linkoptions { "-fsanitize=address" } + end + filter { "system:windows" } platforms { "win-x86-RW34_d3d8-mss", diff --git a/src/audio/oal/channel.cpp b/src/audio/oal/channel.cpp index 731e3581..673a4aed 100644 --- a/src/audio/oal/channel.cpp +++ b/src/audio/oal/channel.cpp @@ -10,17 +10,49 @@ extern bool IsFXSupported(); +ALuint alSources[MAXCHANNELS+MAX2DCHANNELS]; +ALuint alFilters[MAXCHANNELS+MAX2DCHANNELS]; +ALuint alBuffers[MAXCHANNELS+MAX2DCHANNELS]; +bool bChannelsCreated = false; + +void +CChannel::InitChannels() +{ + alGenSources(MAXCHANNELS+MAX2DCHANNELS, alSources); + alGenBuffers(MAXCHANNELS+MAX2DCHANNELS, alBuffers); + if (IsFXSupported()) + alGenFilters(MAXCHANNELS + MAX2DCHANNELS, alFilters); + bChannelsCreated = true; +} + +void +CChannel::DestroyChannels() +{ + if (bChannelsCreated) + { + alDeleteSources(MAXCHANNELS + MAX2DCHANNELS, alSources); + memset(alSources, 0, sizeof(alSources)); + alDeleteBuffers(MAXCHANNELS + MAX2DCHANNELS, alBuffers); + memset(alBuffers, 0, sizeof(alBuffers)); + if (IsFXSupported()) + { + alDeleteFilters(MAXCHANNELS + MAX2DCHANNELS, alFilters); + memset(alFilters, 0, sizeof(alFilters)); + } + bChannelsCreated = false; + } +} + + CChannel::CChannel() { - alSource = AL_NONE; - alFilter = AL_FILTER_NULL; + Data = nil; + DataSize = 0; SetDefault(); } void CChannel::SetDefault() { - alBuffer = AL_NONE; - Pitch = 1.0f; Gain = 1.0f; Mix = 0.0f; @@ -39,25 +71,19 @@ void CChannel::Reset() SetDefault(); } -void CChannel::Init(bool Is2D) +void CChannel::Init(uint32 _id, bool Is2D) { - ASSERT(!HasSource()); - alGenSources(1, &alSource); + id = _id; if ( HasSource() ) { - alSourcei(alSource, AL_SOURCE_RELATIVE, AL_TRUE); + alSourcei(alSources[id], AL_SOURCE_RELATIVE, AL_TRUE); if ( IsFXSupported() ) - alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); + alSource3i(alSources[id], AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); if ( Is2D ) { - alSource3f(alSource, AL_POSITION, 0.0f, 0.0f, 0.0f); - alSourcef (alSource, AL_GAIN, 1.0f); - } - else - { - if ( IsFXSupported() ) - alGenFilters(1,&alFilter); + alSource3f(alSources[id], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSourcef(alSources[id], AL_GAIN, 1.0f); } } } @@ -69,39 +95,34 @@ void CChannel::Term() { if ( IsFXSupported() ) { - alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); - - if(alFilter != AL_FILTER_NULL) - alDeleteFilters(1,&alFilter); + alSource3i(alSources[id], AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); } - - alDeleteSources(1, &alSource); } - alSource = AL_NONE; - alFilter = AL_FILTER_NULL; } void CChannel::Start() { if ( !HasSource() ) return; - + if ( !Data ) return; + + alBufferData(alBuffers[id], AL_FORMAT_MONO16, Data, DataSize, Frequency); if ( LoopPoints[0] != 0 && LoopPoints[0] != -1 ) - alBufferiv(alBuffer, AL_LOOP_POINTS_SOFT, LoopPoints); - alSourcei (alSource, AL_BUFFER, alBuffer); - alSourcePlay(alSource); + alBufferiv(alBuffers[id], AL_LOOP_POINTS_SOFT, LoopPoints); + alSourcei(alSources[id], AL_BUFFER, alBuffers[id]); + alSourcePlay(alSources[id]); } void CChannel::Stop() { if ( HasSource() ) - alSourceStop(alSource); + alSourceStop(alSources[id]); Reset(); } bool CChannel::HasSource() { - return alSource != AL_NONE; + return alSources[id] != AL_NONE; } bool CChannel::IsUsed() @@ -109,7 +130,7 @@ bool CChannel::IsUsed() if ( HasSource() ) { ALint sourceState; - alGetSourcei(alSource, AL_SOURCE_STATE, &sourceState); + alGetSourcei(alSources[id], AL_SOURCE_STATE, &sourceState); return sourceState == AL_PLAYING; } return false; @@ -118,27 +139,24 @@ bool CChannel::IsUsed() void CChannel::SetPitch(float pitch) { if ( !HasSource() ) return; - alSourcef(alSource, AL_PITCH, pitch); + alSourcef(alSources[id], AL_PITCH, pitch); } void CChannel::SetGain(float gain) { if ( !HasSource() ) return; - alSourcef(alSource, AL_GAIN, gain); + alSourcef(alSources[id], AL_GAIN, gain); } void CChannel::SetVolume(int32 vol) { SetGain(ALfloat(vol) / MAX_VOLUME); } - -void CChannel::SetSampleID(uint32 nSfx) -{ - Sample = nSfx; -} - -void CChannel::SetFreq(int32 freq) + +void CChannel::SetSampleData(void *_data, size_t _DataSize, int32 freq) { + Data = _data; + DataSize = _DataSize; Frequency = freq; } @@ -150,7 +168,7 @@ void CChannel::SetCurrentFreq(uint32 freq) void CChannel::SetLoopCount(int32 loopCount) // fake. TODO: { if ( !HasSource() ) return; - alSourcei(alSource, AL_LOOPING, loopCount == 1 ? AL_FALSE : AL_TRUE); + alSourcei(alSources[id], AL_LOOPING, loopCount == 1 ? AL_FALSE : AL_TRUE); } void CChannel::SetLoopPoints(ALint start, ALint end) @@ -162,53 +180,49 @@ void CChannel::SetLoopPoints(ALint start, ALint end) void CChannel::SetPosition(float x, float y, float z) { if ( !HasSource() ) return; - alSource3f(alSource, AL_POSITION, x, y, z); + alSource3f(alSources[id], AL_POSITION, x, y, z); } void CChannel::SetDistances(float max, float min) { if ( !HasSource() ) return; - alSourcef (alSource, AL_MAX_DISTANCE, max); - alSourcef (alSource, AL_REFERENCE_DISTANCE, min); - alSourcef (alSource, AL_MAX_GAIN, 1.0f); - alSourcef (alSource, AL_ROLLOFF_FACTOR, 1.0f); + alSourcef (alSources[id], AL_MAX_DISTANCE, max); + alSourcef (alSources[id], AL_REFERENCE_DISTANCE, min); + alSourcef (alSources[id], AL_MAX_GAIN, 1.0f); + alSourcef (alSources[id], AL_ROLLOFF_FACTOR, 1.0f); } -void CChannel::SetPan(uint32 pan) +void CChannel::SetPan(int32 pan) { SetPosition((pan-63)/64.0f, 0.0f, Sqrt(1.0f-SQR((pan-63)/64.0f))); } -void CChannel::SetBuffer(ALuint buffer) -{ - alBuffer = buffer; -} - void CChannel::ClearBuffer() { if ( !HasSource() ) return; - SetBuffer(AL_NONE); - alSourcei(alSource, AL_BUFFER, AL_NONE); + alSourcei(alSources[id], AL_BUFFER, AL_NONE); + Data = nil; + DataSize = 0; } void CChannel::SetReverbMix(ALuint slot, float mix) { if ( !IsFXSupported() ) return; if ( !HasSource() ) return; - if ( alFilter == AL_FILTER_NULL ) return; + if ( alFilters[id] == AL_FILTER_NULL ) return; Mix = mix; - EAX3_SetReverbMix(alFilter, mix); - alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter); + EAX3_SetReverbMix(alFilters[id], mix); + alSource3i(alSources[id], AL_AUXILIARY_SEND_FILTER, slot, 0, alFilters[id]); } void CChannel::UpdateReverb(ALuint slot) { if ( !IsFXSupported() ) return; if ( !HasSource() ) return; - if ( alFilter == AL_FILTER_NULL ) return; - EAX3_SetReverbMix(alFilter, Mix); - alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter); + if ( alFilters[id] == AL_FILTER_NULL ) return; + EAX3_SetReverbMix(alFilters[id], Mix); + alSource3i(alSources[id], AL_AUXILIARY_SEND_FILTER, slot, 0, alFilters[id]); } #endif diff --git a/src/audio/oal/channel.h b/src/audio/oal/channel.h index 0c86bdc6..81817a32 100644 --- a/src/audio/oal/channel.h +++ b/src/audio/oal/channel.h @@ -9,22 +9,24 @@ class CChannel { - ALuint alSource; - ALuint alFilter; - ALuint alBuffer; + uint32 id; float Pitch, Gain; float Mix; + void *Data; + size_t DataSize; int32 Frequency; float Position[3]; float Distances[2]; int32 LoopCount; ALint LoopPoints[2]; - uint32 Sample; public: + static void InitChannels(); + static void DestroyChannels(); + CChannel(); void SetDefault(); void Reset(); - void Init(bool Is2D = false); + void Init(uint32 _id, bool Is2D = false); void Term(); void Start(); void Stop(); @@ -33,15 +35,13 @@ public: void SetPitch(float pitch); void SetGain(float gain); void SetVolume(int32 vol); - void SetSampleID(uint32 nSfx); - void SetFreq(int32 freq); + void SetSampleData(void *_data, size_t _DataSize, int32 freq); void SetCurrentFreq(uint32 freq); void SetLoopCount(int32 loopCount); // fake void SetLoopPoints(ALint start, ALint end); void SetPosition(float x, float y, float z); void SetDistances(float max, float min); - void SetPan(uint32 pan); - void SetBuffer(ALuint buffer); + void SetPan(int32 pan); void ClearBuffer(); void SetReverbMix(ALuint slot, float mix); void UpdateReverb(ALuint slot); diff --git a/src/audio/sampman.h b/src/audio/sampman.h index 794db8e0..d3e4415f 100644 --- a/src/audio/sampman.h +++ b/src/audio/sampman.h @@ -175,11 +175,7 @@ public: bool Initialise(void); void Terminate (void); - -#ifdef AUDIO_OAL - void UpdateSoundBuffers(void); -#endif - + bool CheckForAnAudioFileOnCD(void); char GetCDAudioDriveLetter (void); @@ -280,7 +276,114 @@ static char StreamedNameTable[][25] = { "AUDIO\\door_2.OPUS", "AUDIO\\door_3.OPUS", "AUDIO\\door_4.OPUS", "AUDIO\\door_5.OPUS", "AUDIO\\door_6.OPUS", "AUDIO\\t3_a.OPUS", "AUDIO\\t3_b.OPUS", "AUDIO\\t3_c.OPUS", "AUDIO\\k1_b.OPUS", "AUDIO\\cat1.OPUS"}; #else -static char StreamedNameTable[][25]= +#ifdef PS2_AUDIO +static char StreamedNameTable[][40] = +{ + "AUDIO\\MUSIC\\WILD.VB", + "AUDIO\\MUSIC\\FLASH.VB", + "AUDIO\\MUSIC\\KCHAT.VB", // 16 khz + "AUDIO\\MUSIC\\FEVER.VB", + "AUDIO\\MUSIC\\VROCK.VB", + "AUDIO\\MUSIC\\VCPR.VB", // 16 khz + "AUDIO\\MUSIC\\ESPANT.VB", + "AUDIO\\MUSIC\\EMOTION.VB", + "AUDIO\\MUSIC\\WAVE.VB", + "AUDIO\\MUSIC\\MISCOM.VB", + "AUDIO\\MUSIC\\CITY.VB", + "AUDIO\\MUSIC\\WATER.VB", + "AUDIO\\MUSIC\\BEACHAMB.VB", + "AUDIO\\MUSIC\\HCITY.VB", + "AUDIO\\MUSIC\\HWATER.VB", + "AUDIO\\MUSIC\\HBEACH.VB", + "AUDIO\\MUSIC\\MALLAMB.VB", + "AUDIO\\MUSIC\\STRIP.VB", + "AUDIO\\MUSIC\\MALIBU.VB", + "AUDIO\\MUSIC\\HOTEL.VB", + "AUDIO\\MUSIC\\DIRTRING.VB", + "AUDIO\\MUSIC\\LAW4RIOT.VB", + "AUDIO\\MUSIC\\AMBSIL.VB", + "AUDIO\\MUSIC\\POLICE.VB", // 16 khz + "AUDIO\\MUSIC\\TAXI.VB", + "AUDIO\\MUSIC\\BCLOSED.VB", + "AUDIO\\MUSIC\\BOPEN.VB", + "AUDIO\\CUTSCENE\\ASS\\ASS_1.VB", + "AUDIO\\CUTSCENE\\ASS\\ASS_2.VB", + "AUDIO\\CUTSCENE\\BANK\\BANK_1.VB", + "AUDIO\\CUTSCENE\\BANK\\BANK_2A.VB", + "AUDIO\\CUTSCENE\\BANK\\BANK_2B.VB", + "AUDIO\\CUTSCENE\\BANK\\BANK_3A.VB", + "AUDIO\\CUTSCENE\\BANK\\BANK_3B.VB", + "AUDIO\\CUTSCENE\\BANK\\BANK_4.VB", + "AUDIO\\CUTSCENE\\BIKE\\BIKE_1.VB", + "AUDIO\\CUTSCENE\\BIKE\\BIKE_2.VB", + "AUDIO\\CUTSCENE\\BIKE\\BIKE_3.VB", + "AUDIO\\CUTSCENE\\BUD\\BUD_1.VB", + "AUDIO\\CUTSCENE\\BUD\\BUD_2.VB", + "AUDIO\\CUTSCENE\\BUD\\BUD_3.VB", + "AUDIO\\CUTSCENE\\CAP\\CAP_1.VB", + "AUDIO\\CUTSCENE\\CAR\\CAR_1.VB", + "AUDIO\\CUTSCENE\\CNT\\CNT_1A.VB", + "AUDIO\\CUTSCENE\\CNT\\CNT_1B.VB", + "AUDIO\\CUTSCENE\\CNT\\CNT_2.VB", + "AUDIO\\CUTSCENE\\COK\\COK_1.VB", + "AUDIO\\CUTSCENE\\COK\\COK_2A.VB", + "AUDIO\\CUTSCENE\\COK\\COK_2B.VB", + "AUDIO\\CUTSCENE\\COK\\COK_3.VB", + "AUDIO\\CUTSCENE\\COK\\COK_4A.VB", + "AUDIO\\CUTSCENE\\COK\\COK_4A2.VB", + "AUDIO\\CUTSCENE\\COK\\COK_4B.VB", + "AUDIO\\CUTSCENE\\COL\\COL_1.VB", + "AUDIO\\CUTSCENE\\COL\\COL_2.VB", + "AUDIO\\CUTSCENE\\COL\\COL_3A.VB", + "AUDIO\\CUTSCENE\\COL\\COL_4A.VB", + "AUDIO\\CUTSCENE\\COL\\COL_5A.VB", + "AUDIO\\CUTSCENE\\COL\\COL_5B.VB", + "AUDIO\\CUTSCENE\\CUB\\CUB_1.VB", + "AUDIO\\CUTSCENE\\CUB\\CUB_2.VB", + "AUDIO\\CUTSCENE\\CUB\\CUB_3.VB", + "AUDIO\\CUTSCENE\\CUB\\CUB_4.VB", + "AUDIO\\CUTSCENE\\DRUG\\DRUG_1.VB", + "AUDIO\\CUTSCENE\\FIN\\FIN.VB", + "AUDIO\\CUTSCENE\\FIN\\FIN2.VB", + "AUDIO\\CUTSCENE\\FINALE\\FINALE.VB", + "AUDIO\\CUTSCENE\\HAT\\HAT_1.VB", + "AUDIO\\CUTSCENE\\HAT\\HAT_2.VB", + "AUDIO\\CUTSCENE\\HAT\\HAT_3.VB", + "AUDIO\\CUTSCENE\\ICE\\ICE_1.VB", + "AUDIO\\CUTSCENE\\INT\\INT_A.VB", + "AUDIO\\CUTSCENE\\INT\\INT_B.VB", + "AUDIO\\CUTSCENE\\INT\\INT_D.VB", + "AUDIO\\CUTSCENE\\INT\\INT_M.VB", + "AUDIO\\CUTSCENE\\LAW\\LAW_1A.VB", + "AUDIO\\CUTSCENE\\LAW\\LAW_1B.VB", + "AUDIO\\CUTSCENE\\LAW\\LAW_2A.VB", + "AUDIO\\CUTSCENE\\LAW\\LAW_2B.VB", + "AUDIO\\CUTSCENE\\LAW\\LAW_2C.VB", + "AUDIO\\CUTSCENE\\LAW\\LAW_3.VB", + "AUDIO\\CUTSCENE\\LAW\\LAW_4.VB", + "AUDIO\\CUTSCENE\\PHIL\\PHIL_1.VB", + "AUDIO\\CUTSCENE\\PHIL\\PHIL_2.VB", + "AUDIO\\CUTSCENE\\PORN\\PORN_1.VB", + "AUDIO\\CUTSCENE\\PORN\\PORN_2.VB", + "AUDIO\\CUTSCENE\\PORN\\PORN_3.VB", + "AUDIO\\CUTSCENE\\PORN\\PORN_4.VB", + "AUDIO\\CUTSCENE\\RESC\\RESC_1A.VB", + "AUDIO\\CUTSCENE\\ROK\\ROK_1.VB", + "AUDIO\\CUTSCENE\\ROK\\ROK_2.VB", + "AUDIO\\CUTSCENE\\ROK\\ROK_3A.VB", + "AUDIO\\CUTSCENE\\STRIPA\\STRIPA.VB", + "AUDIO\\CUTSCENE\\TAX\\TAX_1.VB", + "AUDIO\\CUTSCENE\\TEX\\TEX_1.VB", + "AUDIO\\CUTSCENE\\TEX\\TEX_2.VB", + "AUDIO\\CUTSCENE\\TEX\\TEX_3.VB", + "AUDIO\\MUSIC\\GLIGHT.VB", + "AUDIO\\MUSIC\\FIST.VB", + "AUDIO\\MUSIC\\MISCOM.VB", + "AUDIO\\MUSIC\\MISCOM.VB", + "AUDIO\\MUSIC\\MISCOM.VB", + "AUDIO\\MUSIC\\MISCOM.VB", +#else +static char StreamedNameTable[][25] = { "AUDIO\\WILD.ADF", "AUDIO\\FLASH.ADF", @@ -385,6 +488,7 @@ static char StreamedNameTable[][25]= "AUDIO\\MISCOM.MP3", "AUDIO\\MISCOM.MP3", "AUDIO\\MISCOM.MP3", +#endif "AUDIO\\MOBR1.WAV", "AUDIO\\PAGER.WAV", "AUDIO\\CARREV.WAV", diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp index ce81439b..80f19e50 100644 --- a/src/audio/sampman_oal.cpp +++ b/src/audio/sampman_oal.cpp @@ -98,45 +98,12 @@ int32 nPedSlotSfx [MAX_PEDSFX]; int32 nPedSlotSfxAddr[MAX_PEDSFX]; uint8 nCurrentPedSlot; -ALuint pedBuffers[MAX_PEDSFX]; - CChannel aChannel[MAXCHANNELS+MAX2DCHANNELS]; uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS]; uint32 nStreamLength[TOTAL_STREAMED_SOUNDS]; ALuint ALStreamSources[MAX_STREAMS]; ALuint ALStreamBuffers[MAX_STREAMS][NUM_STREAMBUFFERS]; -struct -{ - ALuint buffer; - ALuint timer; - - bool IsEmpty() { return timer == 0; } - void Set(ALuint buf) { buffer = buf; } - void Wait() { timer = 10000; } - void Init() - { - buffer = 0; - timer = 0; - } - void Term() - { - if ( buffer != 0 && alIsBuffer(buffer) ) - alDeleteBuffers(1, &buffer); - timer = 0; - } - void Update() - { - if ( !(timer > 0) ) return; - timer -= ALuint(CTimer::GetTimeStepInMilliseconds()); - if ( timer > 0 ) return; - if ( buffer != 0 && alIsBuffer(buffer) ) - { - alDeleteBuffers(1, &buffer); - timer = ( alGetError() == AL_NO_ERROR ) ? 0 : 10000; - } - } -}ALBuffers[SAMPLEBANK_MAX]; struct tMP3Entry { @@ -282,12 +249,7 @@ release_existing() alDeleteBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]); } - alDeleteBuffers(MAX_PEDSFX, pedBuffers); - - for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ ) - { - ALBuffers[i].Term(); - } + CChannel::DestroyChannels(); if ( ALContext ) { @@ -368,13 +330,6 @@ set_new_provider(int index) stream->ProviderInit(); } - for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ ) - { - ALBuffers[i].Init(); - } - - alGenBuffers(MAX_PEDSFX, pedBuffers); - usingEAX = 0; usingEAX3 = 0; _usingEFX = false; @@ -406,10 +361,12 @@ set_new_provider(int index) } //SampleManager.SetSpeakerConfig(speaker_type); - + + CChannel::InitChannels(); + for ( int32 i = 0; i < MAXCHANNELS; i++ ) - aChannel[i].Init(); - aChannel[CHANNEL2D].Init(true); + aChannel[i].Init(i); + aChannel[CHANNEL2D].Init(CHANNEL2D, true); if ( IsFXSupported() ) { @@ -1178,7 +1135,7 @@ cSampleManager::Terminate(void) _DeleteMP3Entries(); CStream::Terminate(); - + if ( nSampleBankMemoryStartAddress[SFX_BANK_0] != 0 ) { free((void *)nSampleBankMemoryStartAddress[SFX_BANK_0]); @@ -1194,15 +1151,6 @@ cSampleManager::Terminate(void) _bSampmanInitialised = false; } -void -cSampleManager::UpdateSoundBuffers(void) -{ - for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ ) - { - ALBuffers[i].Update(); - } -} - bool cSampleManager::CheckForAnAudioFileOnCD(void) { return true; @@ -1409,13 +1357,7 @@ cSampleManager::LoadPedComment(uint32 nComment) #endif nPedSlotSfx[nCurrentPedSlot] = nComment; - - alBufferData(pedBuffers[nCurrentPedSlot], - AL_FORMAT_MONO16, - (void *)(nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] + PED_BLOCKSIZE*nCurrentPedSlot), - m_aSamples[nComment].nSize, - m_aSamples[nComment].nFrequency); - + if ( ++nCurrentPedSlot >= MAX_PEDSFX ) nCurrentPedSlot = 0; @@ -1553,25 +1495,14 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) { ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); - ALuint buffer; + uintptr addr; if ( nSfx < SAMPLEBANK_MAX ) { if ( !IsSampleBankLoaded(nBank) ) return false; - uintptr addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset; - - if ( ALBuffers[nSfx].IsEmpty() ) - { - ALuint buf; - alGenBuffers(1, &buf); - alBufferData(buf, AL_FORMAT_MONO16, (void *)addr, m_aSamples[nSfx].nSize, m_aSamples[nSfx].nFrequency); - ALBuffers[nSfx].Set(buf); - } - ALBuffers[nSfx].Wait(); - - buffer = ALBuffers[nSfx].buffer; + addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset; } else { @@ -1579,14 +1510,7 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) return false; int32 slot = _GetPedCommentSlot(nSfx); - - buffer = pedBuffers[slot]; - } - - if ( buffer == 0 ) - { - TRACE("No buffer to play id %d", nSfx); - return false; + addr = (nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] + PED_BLOCKSIZE * slot); } if ( GetChannelUsedFlag(nChannel) ) @@ -1598,10 +1522,8 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) aChannel[nChannel].Reset(); if ( aChannel[nChannel].HasSource() ) { - aChannel[nChannel].SetSampleID (nSfx); - aChannel[nChannel].SetFreq (m_aSamples[nSfx].nFrequency); + aChannel[nChannel].SetSampleData ((void*)addr, m_aSamples[nSfx].nSize, m_aSamples[nSfx].nFrequency); aChannel[nChannel].SetLoopPoints (0, -1); - aChannel[nChannel].SetBuffer (buffer); aChannel[nChannel].SetPitch (1.0f); return true; } @@ -2059,8 +1981,6 @@ cSampleManager::Service(void) if ( stream ) stream->Update(); } - - UpdateSoundBuffers(); } bool diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp index 8b8bc1a3..2a5863f1 100644 --- a/src/control/Pickups.cpp +++ b/src/control/Pickups.cpp @@ -1014,8 +1014,11 @@ CPickups::DoPickUpEffects(CEntity *entity) float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800)); float modifiedSin = 0.3f * (s + 1.0f); - +#ifdef FIX_BUGS + int16 colorId = 0; +#else int16 colorId; +#endif bool doInnerGlow = false; bool doOuterGlow = true; @@ -1029,7 +1032,6 @@ CPickups::DoPickUpEffects(CEntity *entity) doInnerGlow = true; doOuterGlow = false; } else if (entity->GetModelIndex() == MI_PICKUP_INFO || entity->GetModelIndex() == MI_PICKUP_KILLFRENZY) { - colorId = WEAPONTYPE_TOTALWEAPONS + 2; doInnerGlow = true; doOuterGlow = false; } else if (entity->GetModelIndex() == MI_PICKUP_HEALTH || entity->GetModelIndex() == MI_PICKUP_BONUS) { diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 86c9e86e..f85fc076 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -2488,7 +2488,7 @@ int8 CRunningScript::ProcessOneCommand() if (commands[command].position == -1) strcat(commandInfo, commands[command].name + sizeof("COMMAND_") - 1); for (int i = 0; commands[command].input[i] != ARGTYPE_NONE; i++) { - char tmp[16]; + char tmp[32]; bool var = false; int value; switch (commands[command].input[i]) { @@ -2552,7 +2552,7 @@ int8 CRunningScript::ProcessOneCommand() m_nIp = ip; ip = t; for (int i = 0; commands[command].output[i] != ARGTYPE_NONE; i++) { - char tmp[16]; + char tmp[32]; switch (commands[command].output[i]) { case ARGTYPE_INT: case ARGTYPE_PED_HANDLE: @@ -5171,7 +5171,12 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CollectParameters(&m_nIp, 1); CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; float angle = pPed->bInVehicle ? pPed->m_pMyVehicle->GetForward().Heading() : pPed->GetForward().Heading(); - *(float*)&ScriptParams[0] = CGeneral::LimitAngle(RADTODEG(angle)); + angle = RADTODEG(angle); + if (angle < 0.0f) + angle += 360.0f; + if (angle > 360.0f) + angle -= 360.0f; + *(float*)&ScriptParams[0] = angle; StoreParameters(&m_nIp, 1); return 0; } @@ -5192,7 +5197,12 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); script_assert(pPed); float angle = pPed->bInVehicle ? pPed->m_pMyVehicle->GetForward().Heading() : pPed->GetForward().Heading(); - *(float*)&ScriptParams[0] = CGeneral::LimitAngle(RADTODEG(angle)); + angle = RADTODEG(angle); + if (angle < 0.0f) + angle += 360.0f; + if (angle > 360.0f) + angle -= 360.0f; + *(float*)&ScriptParams[0] = angle; StoreParameters(&m_nIp, 1); return 0; } @@ -5213,7 +5223,12 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); script_assert(pVehicle); float angle = pVehicle->GetForward().Heading(); - *(float*)&ScriptParams[0] = CGeneral::LimitAngle(RADTODEG(angle)); + angle = RADTODEG(angle); + if (angle < 0.0f) + angle += 360.0f; + if (angle > 360.0f) + angle -= 360.0f; + *(float*)&ScriptParams[0] = angle; StoreParameters(&m_nIp, 1); return 0; } @@ -5231,7 +5246,12 @@ int8 CRunningScript::ProcessCommands300To399(int32 command) CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); script_assert(pObject); float angle = pObject->GetForward().Heading(); - *(float*)&ScriptParams[0] = CGeneral::LimitAngle(RADTODEG(angle)); + angle = RADTODEG(angle); + if (angle < 0.0f) + angle += 360.0f; + if (angle > 360.0f) + angle -= 360.0f; + *(float*)&ScriptParams[0] = angle; StoreParameters(&m_nIp, 1); return 0; } @@ -13225,7 +13245,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) } case COMMAND_CLEAR_CHAR_FOLLOW_PATH: { - CollectParameters(&m_nIp, 2); + CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); script_assert(pPed); if (pPed->GetPedState() == PED_FOLLOW_PATH) { diff --git a/src/core/config.h b/src/core/config.h index 0ef921ca..ce77391c 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -167,6 +167,22 @@ enum Config { // any debug stuff that is only left in mobile, is not in MASTER //#define MASTER +// once and for all: +// pc: FINAL & MASTER +// mobile: FINAL + +// MASTER builds must be FINAL +#ifdef MASTER +#define FINAL +#endif + +// quality of life fixes that should also be in FINAL +#define NASTY_GAME // nasty game for all languages +#define NO_CDCHECK + +// those infamous texts +#define DRAW_GAME_VERSION_TEXT + #if defined GTA_PS2 # define GTA_PS2_STUFF # define RANDOMSPLASH @@ -188,9 +204,13 @@ enum Config { #ifdef MASTER // only in master builds + #undef DRAW_GAME_VERSION_TEXT #else // not in master builds #define VALIDATE_SAVE_SIZE + + #define NO_MOVIES // disable intro videos + #define DEBUGMENU #endif #ifdef FINAL @@ -198,11 +218,7 @@ enum Config { # define USE_MY_DOCUMENTS // use my documents directory for user files #else // not in any game -# define NASTY_GAME // nasty game for all languages -# define NO_MOVIES // disable intro videos -# define NO_CDCHECK # define CHATTYSPLASH // print what the game is loading -# define DEBUGMENU # define TIMEBARS // print debug timers #endif @@ -223,7 +239,7 @@ enum Config { #define USE_TXD_CDIMAGE // generate and load textures from txd.img #define PS2_ALPHA_TEST // emulate ps2 alpha test #define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number -//#define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time +#define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time //#define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU //#define USE_TEXTURE_POOL //#define CUTSCENE_BORDERS_SWITCH diff --git a/src/core/main.cpp b/src/core/main.cpp index b1f1ea50..64b3a63f 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -757,6 +757,8 @@ DisplayGameDebugText() char str[200]; wchar ustr[200]; + +#ifdef DRAW_GAME_VERSION_TEXT wchar ver[200]; AsciiToUnicode(version_name, ver); @@ -772,6 +774,7 @@ DisplayGameDebugText() CFont::SetBackGroundOnlyTextOff(); CFont::SetColor(CRGBA(255, 108, 0, 255)); CFont::PrintString(SCREEN_SCALE_X(10.0f), SCREEN_SCALE_Y(10.0f), ver); +#endif FrameSamples++; FramesPerSecondCounter += 1000.0f / (CTimer::GetTimeStepNonClippedInSeconds() * 1000.0f); diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 2e112442..318b1d47 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -441,9 +441,12 @@ DebugMenuPopulate(void) DebugMenuEntrySetWrap(e, true); DebugMenuAddVar("Render", "Neo Vehicle Shininess", &CustomPipes::VehicleShininess, nil, 0.1f, 0, 1.0f); DebugMenuAddVar("Render", "Neo Vehicle Specularity", &CustomPipes::VehicleSpecularity, nil, 0.1f, 0, 1.0f); - DebugMenuAddVar("Render", "Neo Ped Rim light", &CustomPipes::RimlightMult, nil, 0.1f, 0, 1.0f); - DebugMenuAddVar("Render", "Neo World Lightmaps", &CustomPipes::LightmapMult, nil, 0.1f, 0, 1.0f); - DebugMenuAddVar("Render", "Neo Road Gloss", &CustomPipes::GlossMult, nil, 0.1f, 0, 1.0f); + DebugMenuAddVarBool8("Render", "Neo Ped Rim light enable", &CustomPipes::RimlightEnable, nil); + DebugMenuAddVar("Render", "Mult", &CustomPipes::RimlightMult, nil, 0.1f, 0, 1.0f); + DebugMenuAddVarBool8("Render", "Neo World Lightmaps enable", &CustomPipes::LightmapEnable, nil); + DebugMenuAddVar("Render", "Mult", &CustomPipes::LightmapMult, nil, 0.1f, 0, 1.0f); + DebugMenuAddVarBool8("Render", "Neo Road Gloss enable", &CustomPipes::GlossEnable, nil); + DebugMenuAddVar("Render", "Mult", &CustomPipes::GlossMult, nil, 0.1f, 0, 1.0f); #endif DebugMenuAddVarBool8("Render", "Show Ped Paths", &gbShowPedPaths, nil); DebugMenuAddVarBool8("Render", "Show Car Paths", &gbShowCarPaths, nil); diff --git a/src/extras/custompipes.cpp b/src/extras/custompipes.cpp index 2b4745e3..2ae87950 100644 --- a/src/extras/custompipes.cpp +++ b/src/extras/custompipes.cpp @@ -365,6 +365,7 @@ AttachVehiclePipe(rw::Clump *clump) * Neo World pipe */ +bool LightmapEnable; float LightmapMult = 1.0f; InterpolatedFloat WorldLightmapBlend(1.0f); rw::ObjPipeline *worldPipe; @@ -389,6 +390,7 @@ AttachWorldPipe(rw::Clump *clump) * Neo Gloss pipe */ +bool GlossEnable; float GlossMult = 1.0f; rw::ObjPipeline *glossPipe; @@ -427,6 +429,7 @@ AttachGlossPipe(rw::Clump *clump) * Neo Rim pipes */ +bool RimlightEnable; float RimlightMult = 1.0f; InterpolatedColor RampStart(Color(0.0f, 0.0f, 0.0f, 1.0f)); InterpolatedColor RampEnd(Color(1.0f, 1.0f, 1.0f, 1.0f)); diff --git a/src/extras/custompipes.h b/src/extras/custompipes.h index 4ebe586f..6e9c6517 100644 --- a/src/extras/custompipes.h +++ b/src/extras/custompipes.h @@ -98,6 +98,7 @@ void DestroyVehiclePipe(void); void AttachVehiclePipe(rw::Atomic *atomic); void AttachVehiclePipe(rw::Clump *clump); +extern bool LightmapEnable; extern float LightmapMult; extern InterpolatedFloat WorldLightmapBlend; extern rw::ObjPipeline *worldPipe; @@ -106,6 +107,7 @@ void DestroyWorldPipe(void); void AttachWorldPipe(rw::Atomic *atomic); void AttachWorldPipe(rw::Clump *clump); +extern bool GlossEnable; extern float GlossMult; extern rw::ObjPipeline *glossPipe; void CreateGlossPipe(void); @@ -114,6 +116,7 @@ void AttachGlossPipe(rw::Atomic *atomic); void AttachGlossPipe(rw::Clump *clump); rw::Texture *GetGlossTex(rw::Material *mat); +extern bool RimlightEnable; extern float RimlightMult; extern InterpolatedColor RampStart; extern InterpolatedColor RampEnd; diff --git a/src/extras/custompipes_d3d9.cpp b/src/extras/custompipes_d3d9.cpp index 63e91063..06ce1461 100644 --- a/src/extras/custompipes_d3d9.cpp +++ b/src/extras/custompipes_d3d9.cpp @@ -190,6 +190,11 @@ worldRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header) using namespace rw::d3d; using namespace rw::d3d9; + if(!LightmapEnable){ + defaultRenderCB_Shader(atomic, header); + return; + } + int vsBits; setStreamSource(0, header->vertexStream[0].vertexBuffer, 0, header->vertexStream[0].stride); setIndices(header->indexBuffer); @@ -297,6 +302,9 @@ glossRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header) using namespace rw::d3d; using namespace rw::d3d9; + if(!GlossEnable) + return; + setVertexShader(neoGloss_VS); setPixelShader(neoGloss_PS); @@ -395,6 +403,11 @@ rimRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header) using namespace rw::d3d; using namespace rw::d3d9; + if(!RimlightEnable){ + defaultRenderCB_Shader(atomic, header); + return; + } + int vsBits; setStreamSource(0, header->vertexStream[0].vertexBuffer, 0, header->vertexStream[0].stride); setIndices(header->indexBuffer); @@ -433,6 +446,11 @@ rimSkinRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header) using namespace rw::d3d; using namespace rw::d3d9; + if(!RimlightEnable){ + skinRenderCB(atomic, header); + return; + } + int vsBits; setStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer, diff --git a/src/extras/custompipes_gl.cpp b/src/extras/custompipes_gl.cpp index cb434ea1..dbd4d7d6 100644 --- a/src/extras/custompipes_gl.cpp +++ b/src/extras/custompipes_gl.cpp @@ -203,6 +203,11 @@ worldRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header) using namespace rw; using namespace rw::gl3; + if(!LightmapEnable){ + gl3::defaultRenderCB(atomic, header); + return; + } + Material *m; setWorldMatrix(atomic->getFrame()->getLTM()); @@ -315,6 +320,8 @@ glossRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header) using namespace rw::gl3; worldRenderCB(atomic, header); + if(!GlossEnable) + return; Material *m; @@ -442,6 +449,11 @@ rimSkinRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header) using namespace rw; using namespace rw::gl3; + if(!RimlightEnable){ + gl3::skinRenderCB(atomic, header); + return; + } + Material *m; setWorldMatrix(atomic->getFrame()->getLTM()); @@ -487,6 +499,11 @@ rimRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header) using namespace rw; using namespace rw::gl3; + if(!RimlightEnable){ + gl3::defaultRenderCB(atomic, header); + return; + } + Material *m; setWorldMatrix(atomic->getFrame()->getLTM()); diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp index 8b78bdbd..293e5274 100644 --- a/src/objects/Object.cpp +++ b/src/objects/Object.cpp @@ -12,6 +12,8 @@ #include "World.h" #include "Floater.h" #include "soundlist.h" +#include "WaterLevel.h" +#include "Timecycle.h" int16 CObject::nNoTempObjects; //int16 CObject::nBodyCastHealth = 1000; @@ -128,15 +130,115 @@ CObject::Teleport(CVector vecPos) void CObject::Render(void) { - if(bDoNotRender) + if (bDoNotRender) return; - if(m_nRefModelIndex != -1 && ObjectCreatedBy == TEMP_OBJECT && bUseVehicleColours){ + if (m_nRefModelIndex != -1 && ObjectCreatedBy == TEMP_OBJECT && bUseVehicleColours) { CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(m_nRefModelIndex); assert(mi->GetModelType() == MITYPE_VEHICLE); mi->SetVehicleColour(m_colour1, m_colour2); } + float red = (0.8f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed_Obj()) * 165.75f; + float green = (0.8f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen_Obj()) * 165.75f; + float blue = (0.8f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue_Obj()) * 165.75f; + + red = clamp(red, 0.0f, 255.0f); + green = clamp(green, 0.0f, 255.0f); + blue = clamp(blue, 0.0f, 255.0f); + + int alpha = CGeneral::GetRandomNumberInRange(196, 225); + + RwRGBA color = { (uint8)red, (uint8)green, (uint8)blue, (uint8)alpha }; + + if (this->GetModelIndex() == MI_YT_MAIN_BODY) { + float moveSpeedMagnitude = this->GetMoveSpeed().Magnitude(); + if (moveSpeedMagnitude > 0.0f) { + float scaleMax = GetColModel()->boundingBox.max.y * 0.85f; + + CVector dir = this->GetMoveSpeed() + 0.3f * this->GetRight() - 0.5f * this->GetForward(); + dir.z += 0.05f * moveSpeedMagnitude; + + CVector pos = scaleMax * this->GetForward() + 2.25f * this->GetRight() + this->GetPosition(); + + float fWaterLevel; + CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true); + pos.z = fWaterLevel + 0.75f; + + CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 1.2f * moveSpeedMagnitude, color, + CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0); + + float scaleMin = GetColModel()->boundingBox.min.y; + + dir = this->GetMoveSpeed() - 0.5f * this->GetForward(); + dir.z += 0.05f * moveSpeedMagnitude; + + pos = scaleMin * this->GetForward() + 4.5f * this->GetRight() + this->GetPosition(); + + CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true); + pos.z = fWaterLevel + 0.55f; + + CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 0.9f, color, + CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0); + + pos = scaleMin * 1.1f * this->GetForward() + 2.25f * this->GetRight() + this->GetPosition(); + + CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true); + pos.z = fWaterLevel + 0.55f; + + CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 0.9f, color, + CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0); + + pos = scaleMin * 1.1f * this->GetForward() - 0.05f * this->GetRight() + this->GetPosition(); + + CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true); + pos.z = fWaterLevel + 0.55f; + + CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 0.9f, color, + CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0); + } + } + + if (this->GetModelIndex() == MI_YT_MAIN_BODY2) { + float moveSpeedMagnitude = this->GetMoveSpeed().Magnitude(); + if (moveSpeedMagnitude > 0.0f) { + float scaleMax = GetColModel()->boundingBox.max.y * 0.85f; + + CVector dir = this->GetMoveSpeed() - 0.3f * this->GetRight() - 0.5f * this->GetForward(); + dir.z += 0.05f * moveSpeedMagnitude; + + CVector pos = scaleMax * this->GetForward() - 2.25f * this->GetRight() + this->GetPosition(); + + float fWaterLevel; + CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true); + pos.z = fWaterLevel + 0.75f; + + CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 1.2f * moveSpeedMagnitude, color, + CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0); + + float scaleMin = GetColModel()->boundingBox.min.y; + + dir = this->GetMoveSpeed() - 0.5f * this->GetForward(); + dir.z += 0.05f * moveSpeedMagnitude; + + pos = scaleMin * this->GetForward() - 4.5f * this->GetRight() + this->GetPosition(); + + CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true); + pos.z = fWaterLevel + 0.55f; + + CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 0.9f, color, + CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0); + + pos = scaleMin * 1.1f * this->GetForward() - 2.25f * this->GetRight() + this->GetPosition(); + + CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &fWaterLevel, true); + pos.z = fWaterLevel + 0.55f; + + CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, 0.9f, color, + CGeneral::GetRandomNumberInRange(0.0f, 0.4f), CGeneral::GetRandomNumberInRange(0.0f, 45.0f), 0, 0); + } + } + CEntity::Render(); } diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 82298e74..03c0bf2c 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -2524,7 +2524,7 @@ CPed::PlayFootSteps(void) CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &adjustedFootPos, top.x, top.y, right.x, right.y, - 255, 255, 0, 0, 4.0f, 3000.0f, 1.0f); + 255, 255, 0, 0, 4.0f, 3000, 1.0f); if (m_bloodyFootprintCountOrDeathTime <= 20) { m_bloodyFootprintCountOrDeathTime = 0; @@ -2537,10 +2537,10 @@ CPed::PlayFootSteps(void) CVector2D top(forward * -0.26f); CVector2D right(GetRight() * (stepPart == 1 ? 0.1f : 0.14f)); - CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &adjustedFootPos, + CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpShadowPedTex, &adjustedFootPos, top.x, top.y, right.x, right.y, - 120, 250, 250, 50, 4.0f, 5000.0f, 1.0f); + 120, 250, 250, 50, 4.0f, 5000, 1.0f); } if (CWeather::Rain <= 0.1f || CCullZones::CamNoRain() || CCullZones::PlayerNoRain()) { if (IsPlayer()) @@ -2569,7 +2569,7 @@ CPed::PlayFootSteps(void) CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &adjustedFootPosL, top.x, top.y, right.x, right.y, - 255, 255, 0, 0, 4.0f, 3000.0f, 1.0f); + 255, 255, 0, 0, 4.0f, 3000, 1.0f); if (m_bloodyFootprintCountOrDeathTime <= 20) { m_bloodyFootprintCountOrDeathTime = 0; @@ -2584,10 +2584,10 @@ CPed::PlayFootSteps(void) CVector2D top(forward * -0.26f); CVector2D right(GetRight() * 0.14f); - CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &adjustedFootPosL, + CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpShadowPedTex, &adjustedFootPosL, top.x, top.y, right.x, right.y, - 120, 250, 250, 50, 4.0f, 5000.0f, 1.0f); + 120, 250, 250, 50, 4.0f, 5000, 1.0f); } } if(!footPosRok) @@ -2604,7 +2604,7 @@ CPed::PlayFootSteps(void) CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &adjustedFootPosR, top.x, top.y, right.x, right.y, - 255, 255, 0, 0, 4.0f, 3000.0f, 1.0f); + 255, 255, 0, 0, 4.0f, 3000, 1.0f); if (m_bloodyFootprintCountOrDeathTime <= 20) { m_bloodyFootprintCountOrDeathTime = 0; @@ -2618,10 +2618,10 @@ CPed::PlayFootSteps(void) CVector2D top(forward * -0.26f); CVector2D right(GetRight() * 0.14f); - CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &adjustedFootPosR, + CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpShadowPedTex, &adjustedFootPosR, top.x, top.y, right.x, right.y, - 120, 250, 250, 50, 4.0f, 5000.0f, 1.0f); + 120, 250, 250, 50, 4.0f, 5000, 1.0f); } } } @@ -19094,7 +19094,7 @@ CPed::WarpPedIntoCar(CVehicle *car) m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle); m_carInObjective = car; m_carInObjective->RegisterReference((CEntity **) &m_carInObjective); - SetPedState(m_nPedState); + SetPedState(PED_DRIVING); bUsesCollision = false; bIsInTheAir = false; bVehExitWillBeInstant = true; diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp index b765675f..4874bf04 100644 --- a/src/render/Fluff.cpp +++ b/src/render/Fluff.cpp @@ -398,7 +398,7 @@ void CMovingThings::Init() for (int32 i = 0; i < NUMMOVINGTHINGS; i++) { aMovingThings[i].m_nType = 0; - aMovingThings[i].m_nHidden = 0; + aMovingThings[i].m_farAway = 0; } for (int i = 0; i < NUMSECTORS_X; i++) { @@ -434,19 +434,19 @@ void CMovingThings::Update() CPlaneTrails::Update(); CEscalators::Update(); - const int TIME_SPAN = 64; // frames to process all aMovingThings + const int TIME_SPAN = 8; // frames to process all aMovingThings int16 i; int block = CTimer::GetFrameCounter() % TIME_SPAN; for (i = (block * NUMMOVINGTHINGS) / TIME_SPAN; i < ((block + 1) * NUMMOVINGTHINGS) / TIME_SPAN; i++) { - if (aMovingThings[i].m_nHidden == 1) + if (aMovingThings[i].m_farAway == 1) aMovingThings[i].Update(); } for (i = 0; i < CMovingThings::Num; i++) { - if (aMovingThings[i].m_nHidden == 0) + if (aMovingThings[i].m_farAway == 0) aMovingThings[i].Update(); } @@ -473,27 +473,57 @@ void CMovingThings::Render() CPlaneBanners::Render(); } +void CMovingThings::RegisterOne(CEntity *pEnt, uint16 nType) { + if (Num >= NUMMOVINGTHINGS) + return; + + aMovingThings[Num].m_pEntity = pEnt; + aMovingThings[Num].m_nType = nType; + aMovingThings[Num].m_farAway = 0; + aMovingThings[Num].m_vecPosn = pEnt->GetPosition(); + aMovingThings[Num].AddToList(&CMovingThings::StartCloseList); + Num++; +} + +void CMovingThings::PossiblyAddThisEntity(CEntity *pEnt) { + if (pEnt->GetModelIndex() == MI_LIGHTBEAM) { + RegisterOne(pEnt, 1); + } + else if (pEnt->GetModelIndex() == MI_AIRPORTRADAR) { + RegisterOne(pEnt, 2); + } + else if (pEnt->GetModelIndex() == MI_MALLFAN || pEnt->GetModelIndex() == MI_HOTELFAN_NIGHT + || pEnt->GetModelIndex() == MI_HOTELFAN_DAY || pEnt->GetModelIndex() == MI_HOTROOMFAN) { + RegisterOne(pEnt, 3); + } + else if (pEnt->GetModelIndex() == MI_BLIMP_NIGHT || pEnt->GetModelIndex() == MI_BLIMP_DAY) { + RegisterOne(pEnt, 4); + } +} + // ---------- CMovingThing ---------- -float lengths[5] = { 100.0f, 1500.0f, 400.0f, 100.0f, 2000.0f }; +static float maxUpdateDists[5] = { 100.0f, 1500.0f, 400.0f, 100.0f, 2000.0f }; void CMovingThing::Update() { switch (m_nType) { case 1: { float angle = (CTimer::GetTimeInMilliseconds() % 0x3FFF) * TWOPI / 0x3FFF; - m_pEntity->GetRight() = CVector(-Sin(angle), Cos(angle), 0.0f); + float s = Sin(angle); + float c = Cos(angle); + m_pEntity->GetRight() = CVector(-s, c, 0.0f); m_pEntity->GetForward() = CVector(0.0f, 0.0f, 1.0f); - m_pEntity->GetUp() = CVector(Cos(angle), Sin(angle), 0.0f); + m_pEntity->GetUp() = CVector(c, s, 0.0f); if (CClock::GetHours() >= 20 || CClock::GetHours() < 5) { if (Abs(TheCamera.GetPosition().x - m_pEntity->GetPosition().x) < 600.0f && Abs(TheCamera.GetPosition().y - m_pEntity->GetPosition().y) < 600.0f) { CVector delta = m_pEntity->GetPosition() - TheCamera.GetPosition(); - delta.Normalise(); + delta /= delta.Magnitude(); - if (delta.x * Cos(angle) + delta.y * Sin(angle) < -0.92f) { + if (DotProduct(delta, CVector(c, s, 0.0f)) < -0.92f) { CVector coors = m_pEntity->GetPosition() - 10.0f * delta; - CCoronas::RegisterCorona(43, 128, 128, 100, 255, coors, 70.0f, 600.0f, 0.0f, CCoronas::TYPE_STAR, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f, false, 1.5f); + CCoronas::RegisterCorona(43, 128, 128, 100, 255, coors, 70.0f, 600.0f, 0.0f, CCoronas::TYPE_STAR, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); } } } @@ -501,24 +531,30 @@ void CMovingThing::Update() break; case 2: { float angle = (CTimer::GetTimeInMilliseconds() % 0x7FF) * TWOPI / 0x7FF; - m_pEntity->GetRight() = CVector(Cos(angle), Sin(angle), 0.0f); - m_pEntity->GetForward() = CVector(-Sin(angle), Cos(angle), 0.0f); + float s = Sin(angle); + float c = Cos(angle); + m_pEntity->GetRight() = CVector(c, s, 0.0f); + m_pEntity->GetForward() = CVector(-s, c, 0.0f); m_pEntity->GetUp() = CVector(0.0f, 0.0f, 1.0f); } break; case 3: { float angle = (CTimer::GetTimeInMilliseconds() % 0x3FF) * TWOPI / 0x3FF; - m_pEntity->GetRight() = CVector(Cos(angle), Sin(angle), 0.0f); - m_pEntity->GetForward() = CVector(-Sin(angle), Cos(angle), 0.0f); + float s = Sin(angle); + float c = Cos(angle); + m_pEntity->GetRight() = CVector(c, s, 0.0f); + m_pEntity->GetForward() = CVector(-s, c, 0.0f); m_pEntity->GetUp() = CVector(0.0f, 0.0f, 1.0f); } break; case 4: { float angle = (CTimer::GetTimeInMilliseconds() % 0x3FFFF) * TWOPI / 0x3FFFF; - m_pEntity->GetRight() = CVector(-Cos(angle), -Sin(angle), 0.0f); - m_pEntity->GetForward() = CVector(Sin(angle), -Cos(angle), 0.0f); + float s = Sin(angle); + float c = Cos(angle); + m_pEntity->GetRight() = CVector(-c, -s, 0.0f); + m_pEntity->GetForward() = CVector(s, -c, 0.0f); m_pEntity->GetUp() = CVector(0.0f, 0.0f, 1.0f); - m_pEntity->SetPosition(CVector(350.0f * Cos(angle) - 465.0f, 350.0f * Sin(angle) + 1163.0f, 260.0f)); + m_pEntity->SetPosition(CVector(350.0f * c - 465.0f, 350.0f * s + 1163.0f, 260.0f)); } break; default: @@ -528,16 +564,16 @@ void CMovingThing::Update() m_pEntity->GetMatrix().UpdateRW(); m_pEntity->UpdateRwFrame(); - if (SQR(m_pEntity->GetPosition().x - TheCamera.GetPosition().x) + SQR(m_pEntity->GetPosition().y - TheCamera.GetPosition().y) >= SQR(lengths[m_nType])) { - if (m_nHidden == 0) { - RemoveFromList(); - m_nHidden = 1; + if (SQR(m_pEntity->GetPosition().x - TheCamera.GetPosition().x) + SQR(m_pEntity->GetPosition().y - TheCamera.GetPosition().y) < SQR(maxUpdateDists[m_nType])) { + if (m_farAway == 1) { + AddToList(&CMovingThings::StartCloseList); + m_farAway = 0; } } else { - if (m_nHidden == 1) { - AddToList(&CMovingThings::StartCloseList); - m_nHidden = 0; + if (m_farAway == 0) { + RemoveFromList(); + m_farAway = 1; } } } @@ -569,34 +605,6 @@ int16 CMovingThing::SizeList() return count; } -void CMovingThings::RegisterOne(CEntity *pEnt, uint16 nType) { - if (Num >= NUMMOVINGTHINGS) - return; - - aMovingThings[Num].m_pEntity = pEnt; - aMovingThings[Num].m_nType = nType; - aMovingThings[Num].m_nHidden = 0; - aMovingThings[Num].m_vecPosn = pEnt->GetPosition(); - aMovingThings[Num].AddToList(&CMovingThings::StartCloseList); - Num++; -} - -void CMovingThings::PossiblyAddThisEntity(CEntity *pEnt) { - if (pEnt->GetModelIndex() == MI_LIGHTBEAM) { - RegisterOne(pEnt, 1); - } - else if (pEnt->GetModelIndex() == MI_AIRPORTRADAR) { - RegisterOne(pEnt, 2); - } - else if (pEnt->GetModelIndex() == MI_MALLFAN || pEnt->GetModelIndex() == MI_HOTELFAN_NIGHT - || pEnt->GetModelIndex() == MI_HOTELFAN_DAY || pEnt->GetModelIndex() == MI_HOTROOMFAN) { - RegisterOne(pEnt, 3); - } - else if (pEnt->GetModelIndex() == MI_BLIMP_NIGHT || pEnt->GetModelIndex() == MI_BLIMP_DAY) { - RegisterOne(pEnt, 4); - } -} - char String_Time[] = "THE TIME IS 12:34 "; const char* FindTimeMessage() { diff --git a/src/render/Fluff.h b/src/render/Fluff.h index 98fb9f92..58c8410c 100644 --- a/src/render/Fluff.h +++ b/src/render/Fluff.h @@ -125,7 +125,7 @@ public: CMovingThing *m_pNext; CMovingThing *m_pPrev; int16 m_nType; - int16 m_nHidden; + int16 m_farAway; CVector m_vecPosn; CEntity* m_pEntity; diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index 94e09044..cf0e2b70 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -351,7 +351,7 @@ void CHud::Draw() rect.right = SCREEN_WIDTH/2 + xOffset; rect.bottom = SCREEN_HEIGHT/2 + yOffset; Sprites[sprite].Draw(CRect(rect), CRGBA(255, 255, 255, 255), - 0.99f, 0.99f, 0.01f, 0.99f, 0.99f, 0.01f, 0.1f, 0.01f); + 0.99f, 0.99f, 0.01f, 0.99f, 0.99f, 0.01f, 0.01f, 0.01f); CVector dotPos; float size = 25.0f; diff --git a/src/render/WaterCreatures.cpp b/src/render/WaterCreatures.cpp index 90f24183..d3bd2701 100644 --- a/src/render/WaterCreatures.cpp +++ b/src/render/WaterCreatures.cpp @@ -11,70 +11,70 @@ int CWaterCreatures::nNumActiveSeaLifeForms; CWaterCreature CWaterCreatures::aWaterCreatures[NUM_WATER_CREATURES]; struct WaterCreatureProperties aProperties[65] = { - { &MI_FISH1SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH2SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH3SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH1SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH2SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH3SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f }, { &MI_JELLYFISH, 0.01f, 2.2f, 0.0005f, 3.5f }, { &MI_JELLYFISH01, 0.01f, 2.2f, 0.0005f, 3.5f }, - { &MI_FISH1SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH2SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH3SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH1SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH2SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH3SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f }, { &MI_TURTLE, 0.01f, 2.0f, 0.0005f, 4.0f }, - { &MI_FISH1SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH2SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH3SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH1SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH2SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH3SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f }, { &MI_DOLPHIN, 0.03f, 1.5f, 0.0005f, 4.0f }, - { &MI_FISH1SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH2SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH3SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH1SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH2SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH3SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f }, { &MI_SHARK, 0.03f, 0.4f, 0.0005f, 4.0f }, - { &MI_FISH1SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH2SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH3SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH1SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH1SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH2SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH2SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH2S, 0.04f, 1.5f, 0.0008f, 3.0f }, - { &MI_FISH3SINGLE, 0.04f, 3.0f, 0.0008f, 3.0f }, + { &MI_FISH3SINGLE, 0.04f, 1.0f, 0.0008f, 3.0f }, { &MI_FISH3S, 0.04f, 1.5f, 0.0008f, 3.0f }, }; @@ -82,21 +82,17 @@ CWaterCreature::CWaterCreature() { Free(); } -CWaterCreature::~CWaterCreature() { - //looks like unused -} - -void CWaterCreature::Initialise(CObject *pObj, float fRightMult, float fZTurnSpeed, float fWaterDepth, uint32 alpha, eFishSlotState state) { +void CWaterCreature::Initialise(CObject *pObj, float fFwdSpeed, float fZTurnSpeed, float fWaterDepth, uint32 alpha, eFishSlotState state) { this->m_pObj = pObj; - this->m_fRightMult = fRightMult; + this->m_fFwdSpeed = fFwdSpeed; this->m_fZTurnSpeed = fZTurnSpeed; this->m_fWaterDepth = fWaterDepth; this->m_alpha = alpha; this->m_state = state; } -void CWaterCreature::Allocate(CObject *pObj, float fRightMult, float fZTurnSpeed, float fWaterDepth, uint32 alpha, eFishSlotState state) { - CWaterCreature::Initialise(pObj, fRightMult, fZTurnSpeed, fWaterDepth, alpha, state); +void CWaterCreature::Allocate(CObject *pObj, float fFwdSpeed, float fZTurnSpeed, float fWaterDepth, uint32 alpha, eFishSlotState state) { + CWaterCreature::Initialise(pObj, fFwdSpeed, fZTurnSpeed, fWaterDepth, alpha, state); } void CWaterCreature::Free() { @@ -112,14 +108,14 @@ CWaterCreature *CWaterCreatures::GetFishStructSlot() { } CObject *CWaterCreatures::CreateSeaLifeForm(CVector const& pos, int16 modelID, int32 zRotAngle) { - if (CObject::nNoTempObjects >= 40) + if (CObject::nNoTempObjects >= NUMTEMPOBJECTS) return nil; CObject *pObj = new CObject(modelID, true); if (!pObj) return nil; - pObj->GetMatrix().GetPosition() = pos; + pObj->SetPosition(pos); pObj->GetMatrix().UpdateRW(); pObj->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); pObj->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f); @@ -148,32 +144,34 @@ float CWaterCreatures::CalculateFishHeading(CVector const& pos1, CVector const& CVector delta = pos1 - pos2; delta.Normalise(); - return Atan2(-delta.x, delta.y); + return CGeneral::GetRandomNumberInRange(-90, 90) + + RADTODEG(delta.Heading() + HALFPI + PI); } void CWaterCreatures::CreateOne(CVector const& pos, int32 modelID) { if (!IsSpaceForMoreWaterCreatures()) return; - CVector storedPos = pos; + CVector playerPos = FindPlayerPed()->GetPosition(); + CVector fishPos = pos; float fDepth, fLevelNoWaves; - if (!TheCamera.IsSphereVisible(storedPos, 3.0f) - && CWaterLevel::GetWaterDepth(storedPos, &fDepth, &fLevelNoWaves, nil) && fDepth > 4.5f) { + if (!TheCamera.IsSphereVisible(fishPos, 3.0f) + && CWaterLevel::GetWaterDepth(fishPos, &fDepth, &fLevelNoWaves, nil) && fDepth > 4.5f) { if (modelID == -1 || modelID < 0 || modelID > 64) modelID = CGeneral::GetRandomNumberInRange(0, 64); WaterCreatureProperties *creature = &aProperties[modelID]; - storedPos.z = fLevelNoWaves - creature->fLevel; - float fRightMult = CGeneral::GetRandomNumberInRange(0.0f, creature->fRightMult) + 0.01f; - float angle = CWaterCreatures::CalculateFishHeading(FindPlayerPed()->GetPosition(), storedPos); + fishPos.z = fLevelNoWaves - creature->fLevel; + float fFwdSpeed = CGeneral::GetRandomNumberInRange(0.0f, creature->fFwdSpeed) + 0.01f; + float angle = CWaterCreatures::CalculateFishHeading(playerPos, fishPos); - CObject *fish = CreateSeaLifeForm(storedPos, *(int16*)creature->modelID, angle); + CObject *fish = CreateSeaLifeForm(fishPos, *creature->modelID, angle); if (!fish) return; fish->SetRwObjectAlpha(255); CWaterCreature *wc = GetFishStructSlot(); - wc->Allocate(fish, fRightMult, 0.0f, creature->fWaterDepth, 255, WATER_CREATURE_ALLOCATED); + wc->Allocate(fish, fFwdSpeed, 0.0f, creature->fWaterDepth, 255, WATER_CREATURE_INIT); nNumActiveSeaLifeForms++; } } @@ -189,62 +187,68 @@ void CWaterCreatures::UpdateAll() { CVector playerPos = FindPlayerPed()->GetPosition(); for (int i = 0; i < NUM_WATER_CREATURES; i++) { switch (aWaterCreatures[i].m_state) { - case WATER_CREATURE_ACTIVE: + case WATER_CREATURE_ACTIVE: + // is this even reachable? aWaterCreatures[i].m_pObj->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 40000; if (!aWaterCreatures[i].m_pObj->GetIsOnScreen()) { aWaterCreatures[i].m_pObj->SetRwObjectAlpha(0); - aWaterCreatures[i].m_state = WATER_CREATURE_TO_REMOVE; + aWaterCreatures[i].m_state = WATER_CREATURE_REMOVE; break; } - case WATER_CREATURE_ALLOCATED: { - if ((playerPos - aWaterCreatures[i].m_pObj->GetPosition()).Magnitude() < SQR(75.0f)) { + // fall through + case WATER_CREATURE_INIT: { + if ((playerPos - aWaterCreatures[i].m_pObj->GetPosition()).MagnitudeSqr() < SQR(75.0f)) { if (aWaterCreatures[i].m_alpha < 255) aWaterCreatures[i].m_alpha = Min(aWaterCreatures[i].m_alpha + 4, 255); aWaterCreatures[i].m_pObj->SetRwObjectAlpha(aWaterCreatures[i].m_alpha); - CVector newRight = aWaterCreatures[i].m_pObj->GetRight(); - newRight.Normalise(); - aWaterCreatures[i].m_pObj->m_vecMoveSpeed = newRight * aWaterCreatures[i].m_fRightMult; + CVector fwd = aWaterCreatures[i].m_pObj->GetRight(); // for some reason they used x for forward + fwd.Normalise(); + aWaterCreatures[i].m_pObj->m_vecMoveSpeed = fwd * aWaterCreatures[i].m_fFwdSpeed; aWaterCreatures[i].m_pObj->m_vecTurnSpeed = CVector(0.0f, 0.0f, aWaterCreatures[i].m_fZTurnSpeed); aWaterCreatures[i].m_pObj->bIsStatic = false; float fDepth = 0.0; CWaterLevel::GetWaterDepth(aWaterCreatures[i].m_pObj->GetPosition(), &fDepth, nil, nil); if (aWaterCreatures[i].m_fWaterDepth < fDepth) { + // it looks like this can never be true initially, looks like a BUG if (aWaterCreatures[i].m_pObj->m_nEndOfLifeTime - 40000 <= CTimer::GetTimeInMilliseconds()) aWaterCreatures[i].m_state = WATER_CREATURE_ACTIVE; } else { - aWaterCreatures[i].m_state = WATER_CREATURE_UPDATE; + // creature is deeper than water + aWaterCreatures[i].m_state = WATER_CREATURE_FADE_OUT; } } else { - aWaterCreatures[i].m_state = WATER_CREATURE_TO_REMOVE; + aWaterCreatures[i].m_state = WATER_CREATURE_REMOVE; } break; } - case WATER_CREATURE_UPDATE: { + case WATER_CREATURE_FADE_OUT: { aWaterCreatures[i].m_pObj->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 40000; if (aWaterCreatures[i].m_alpha <= 0) { - aWaterCreatures[i].m_state = WATER_CREATURE_TO_REMOVE; + aWaterCreatures[i].m_state = WATER_CREATURE_REMOVE; } else { aWaterCreatures[i].m_alpha = Max(aWaterCreatures[i].m_alpha - 6, 0); aWaterCreatures[i].m_pObj->SetRwObjectAlpha(aWaterCreatures[i].m_alpha); - CVector newRight = aWaterCreatures[i].m_pObj->GetRight(); - newRight.Normalise(); - newRight.x *= aWaterCreatures[i].m_fRightMult; - newRight.y *= aWaterCreatures[i].m_fRightMult; - newRight.z -= 0.015f; - aWaterCreatures[i].m_pObj->m_vecMoveSpeed = newRight; + CVector speed = aWaterCreatures[i].m_pObj->GetRight(); + speed.Normalise(); + speed.x *= aWaterCreatures[i].m_fFwdSpeed; + speed.y *= aWaterCreatures[i].m_fFwdSpeed; + speed.z = -0.015f; + aWaterCreatures[i].m_pObj->m_vecMoveSpeed = speed; if (!aWaterCreatures[i].m_pObj->GetIsOnScreen()) - aWaterCreatures[i].m_state = WATER_CREATURE_TO_REMOVE; + aWaterCreatures[i].m_state = WATER_CREATURE_REMOVE; } break; } - case WATER_CREATURE_TO_REMOVE: - if (aWaterCreatures[i].m_pObj) + case WATER_CREATURE_REMOVE: + if (aWaterCreatures[i].m_pObj){ CWorld::Remove(aWaterCreatures[i].m_pObj); + delete aWaterCreatures[i].m_pObj; + } FreeFishStructSlot(&aWaterCreatures[i]); nNumActiveSeaLifeForms--; aWaterCreatures[i].m_state = WATER_CREATURE_DISABLED; @@ -258,7 +262,10 @@ void CWaterCreatures::UpdateAll() { void CWaterCreatures::RemoveAll() { for (int i = 0; i < NUM_WATER_CREATURES; i++) { if (aWaterCreatures[i].m_state != WATER_CREATURE_DISABLED) { - CWorld::Remove(aWaterCreatures[i].m_pObj); + if (aWaterCreatures[i].m_pObj){ + CWorld::Remove(aWaterCreatures[i].m_pObj); + delete aWaterCreatures[i].m_pObj; + } FreeFishStructSlot(&aWaterCreatures[i]); aWaterCreatures[i].m_state = WATER_CREATURE_DISABLED; nNumActiveSeaLifeForms--; diff --git a/src/render/WaterCreatures.h b/src/render/WaterCreatures.h index 7dcaa288..9ef8198c 100644 --- a/src/render/WaterCreatures.h +++ b/src/render/WaterCreatures.h @@ -2,27 +2,26 @@ #include "Object.h" enum eFishSlotState { - WATER_CREATURE_ALLOCATED = 0, + WATER_CREATURE_INIT = 0, WATER_CREATURE_ACTIVE, - WATER_CREATURE_UPDATE, - WATER_CREATURE_TO_REMOVE, + WATER_CREATURE_FADE_OUT, + WATER_CREATURE_REMOVE, WATER_CREATURE_DISABLED }; class CWaterCreature { public: CObject *m_pObj; - float m_fRightMult; + float m_fFwdSpeed; float m_fZTurnSpeed; int32 m_alpha; float m_fWaterDepth; int32 m_state; CWaterCreature(); - ~CWaterCreature(); - void Allocate(CObject *pObj, float fRightMult, float fZTurnSpeed, float fWaterDepth, uint32 alpha, eFishSlotState state); + void Allocate(CObject *pObj, float fFwdSpeed, float fZTurnSpeed, float fWaterDepth, uint32 alpha, eFishSlotState state); void Free(); - void Initialise(CObject *pObj, float fRightMult, float fZTurnSpeed, float fWaterDepth, uint32 alpha, eFishSlotState state); + void Initialise(CObject *pObj, float fFwdSpeed, float fZTurnSpeed, float fWaterDepth, uint32 alpha, eFishSlotState state); }; class CWaterCreatures { @@ -42,7 +41,7 @@ public: struct WaterCreatureProperties { int16 *modelID; - float fRightMult; + float fFwdSpeed; float fLevel; float fUnknown; //unused float fWaterDepth; diff --git a/src/render/WaterLevel.cpp b/src/render/WaterLevel.cpp index 530e0e85..88c45c79 100644 --- a/src/render/WaterLevel.cpp +++ b/src/render/WaterLevel.cpp @@ -2963,7 +2963,7 @@ CWaterLevel::HandleBeachToysStuff(void) CEntity * CWaterLevel::CreateBeachToy(CVector const &vec, eBeachToy beachtoy) { - if (CObject::nNoTempObjects >= 40) + if (CObject::nNoTempObjects >= NUMTEMPOBJECTS) return nil; int finalToy = beachtoy; diff --git a/src/render/WindModifiers.cpp b/src/render/WindModifiers.cpp index b72e362e..3bd6ac9c 100644 --- a/src/render/WindModifiers.cpp +++ b/src/render/WindModifiers.cpp @@ -33,8 +33,9 @@ CWindModifiers::FindWindModifier(CVector pos, float *x, float *y) float dist = (pos - Array[i].m_pos).Magnitude(); if (dist < MAX_FADE_DIST) { float distFade = dist < MIN_FADE_DIST ? 1.0f : 1.0f - (dist - MIN_FADE_DIST) / (MAX_FADE_DIST - MIN_FADE_DIST); - float heightFade = distFade * ((1.0f - zDist / MAX_HEIGHT_DIST) / 2.0f); - dir = (pos - Array[i].m_pos) * heightFade / dist; + float heightFade = 1.0f - zDist / MAX_HEIGHT_DIST; + float fade = distFade * heightFade * 0.5f; + dir = (pos - Array[i].m_pos) * fade / dist; bWasWindModifierFound = true; } } diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp index 503027af..4c4fc434 100644 --- a/src/rw/RwHelper.cpp +++ b/src/rw/RwHelper.cpp @@ -6,8 +6,10 @@ #include "Timecycle.h" #include "skeleton.h" #include "Debug.h" -#ifndef FINAL +#if !defined(FINAL) || defined(DEBUGMENU) #include "rtcharse.h" +#endif +#ifndef FINAL RtCharset *debugCharset; #endif @@ -18,7 +20,7 @@ bool gPS2alphaTest = false; #endif bool gBackfaceCulling; -#ifndef FINAL +#if !defined(FINAL) || defined(DEBUGMENU) static bool charsetOpen; void OpenCharsetSafe() { diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index cba465b7..f083e0f6 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -1859,9 +1859,9 @@ CVehicle::SetDriver(CPed *driver) } if(IsBike()) - ApplyMoveForce(-0.2f*driver->m_fMass * GetUp()); + ApplyMoveForce(-0.02f*driver->m_fMass * GetUp()); else - ApplyTurnForce(0.0f, 0.0f, -0.2f*driver->m_fMass, + ApplyTurnForce(0.0f, 0.0f, -0.02f*driver->m_fMass, driver->GetPosition().x - GetPosition().x, driver->GetPosition().y - GetPosition().y, 0.0f); diff --git a/vendor/librw b/vendor/librw index 5e5a6246..e68ef137 160000 --- a/vendor/librw +++ b/vendor/librw @@ -1 +1 @@ -Subproject commit 5e5a624681a268e759df53edc15a73f587fda6df +Subproject commit e68ef1374d20071887348e9031f5fa38a2e4f7ed diff --git a/vendor/ogg b/vendor/ogg index 684c7377..36f969bb 160000 --- a/vendor/ogg +++ b/vendor/ogg @@ -1 +1 @@ -Subproject commit 684c73773e7e2683245ffd6aa75f04115b51123a +Subproject commit 36f969bb37559345ee03796ed625a9abd42c6db9