diff options
80 files changed, 3246 insertions, 1656 deletions
diff --git a/premake5.lua b/premake5.lua index 334c9c53..23a9200b 100644 --- a/premake5.lua +++ b/premake5.lua @@ -332,14 +332,12 @@ project "reVC" links { "rw" } filter "platforms:*d3d9*" + defines { "USE_D3D9" } links { "d3d9" } filter "platforms:*x86*d3d*" includedirs { "sdk/dx8sdk/include" } libdirs { "sdk/dx8sdk/lib" } - - filter "platforms:*amd64*d3d9*" - defines { "USE_D3D9" } filter "platforms:win-x86*gl3_glfw*" libdirs { path.join(_OPTIONS["glewdir"], "lib/Release/Win32") } diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp index 9a8dda28..6ea93f6d 100644 --- a/src/audio/AudioLogic.cpp +++ b/src/audio/AudioLogic.cpp @@ -1,4 +1,4 @@ -#include "common.h" +#include "common.h" #include "AudioManager.h" #include "audio_enums.h" @@ -993,7 +993,7 @@ cAudioManager::ProcessVehicleRoadNoise(cVehicleParams *params) int32 emittingVol; uint32 freq; - float modificator; + float multiplier; int sampleFreq; float velocity; @@ -1016,9 +1016,9 @@ cAudioManager::ProcessVehicleRoadNoise(cVehicleParams *params) freq = 6050 * emittingVol / 30 + 16000; } else { m_sQueueSample.m_nSampleIndex = SFX_ROAD_NOISE; - modificator = m_sQueueSample.m_fDistance / 190.f; + multiplier = (m_sQueueSample.m_fDistance / SOUND_INTENSITY) * 0.5f; sampleFreq = SampleManager.GetSampleBaseFrequency(SFX_ROAD_NOISE); - freq = (sampleFreq * modificator) + ((3 * sampleFreq) / 4); + freq = (sampleFreq * multiplier) + ((3 * sampleFreq) / 4); } m_sQueueSample.m_nFrequency = freq; m_sQueueSample.m_nLoopCount = 0; @@ -1046,7 +1046,7 @@ cAudioManager::ProcessWetRoadNoise(cVehicleParams *params) float relativeVelocity; int32 emittingVol; - float modificator; + float multiplier; int freq; float velChange; @@ -1066,9 +1066,13 @@ cAudioManager::ProcessWetRoadNoise(cVehicleParams *params) m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_bIs2D = false; m_sQueueSample.m_nReleasingVolumeModificator = 3; - modificator = m_sQueueSample.m_fDistance / 6.f; +#ifdef FIX_BUGS + multiplier = (m_sQueueSample.m_fDistance / SOUND_INTENSITY) * 0.5f; +#else + multiplier = (m_sQueueSample.m_fDistance / 3.0f) * 0.5f; +#endif freq = SampleManager.GetSampleBaseFrequency(SFX_ROAD_NOISE); - m_sQueueSample.m_nFrequency = freq + freq * modificator; + m_sQueueSample.m_nFrequency = freq + freq * multiplier; m_sQueueSample.m_nLoopCount = 0; m_sQueueSample.m_nEmittingVolume = emittingVol; m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex); @@ -4923,17 +4927,25 @@ cAudioManager::ProcessFires(int32) void cAudioManager::ProcessWaterCannon(int32) { - const float SOUND_INTENSITY = 900.0f; + const float SOUND_INTENSITY = 30.0f; for (int32 i = 0; i < NUM_WATERCANNONS; i++) { if (CWaterCannons::aCannons[i].m_nId) { m_sQueueSample.m_vecPos = CWaterCannons::aCannons[0].m_avecPos[CWaterCannons::aCannons[i].m_nCur]; float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos); - if (distSquared < SOUND_INTENSITY) { + if (distSquared < SQR(SOUND_INTENSITY)) { m_sQueueSample.m_fDistance = Sqrt(distSquared); +#ifdef FIX_BUGS + m_sQueueSample.m_nVolume = ComputeVolume(50, SOUND_INTENSITY, m_sQueueSample.m_fDistance); +#else m_sQueueSample.m_nVolume = ComputeVolume(50, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); +#endif if (m_sQueueSample.m_nVolume != 0) { +#ifdef FIX_BUGS m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY; +#else + m_sQueueSample.m_fSoundIntensity = SQR(SOUND_INTENSITY); +#endif m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI; m_sQueueSample.m_nBankIndex = SFX_BANK_0; m_sQueueSample.m_nFrequency = 15591; diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index 93ac8857..d36316eb 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -328,8 +328,13 @@ cAudioManager::Get3DProviderName(uint8 id) const { if (!m_bIsInitialised) return nil; +#ifdef AUDIO_OAL + id = clamp(id, 0, SampleManager.GetNum3DProvidersAvailable() - 1); +#else + // We don't want that either since it will crash the game, but skipping for now if (id >= SampleManager.GetNum3DProvidersAvailable()) return nil; +#endif return SampleManager.Get3DProviderName(id); } @@ -618,29 +623,56 @@ cAudioManager::AddDetailsToRequestedOrderList(uint8 sample) m_abSampleQueueIndexTable[m_nActiveSampleQueue][i] = sample; } +// --MIAMI: Done void cAudioManager::AddReflectionsToRequestedQueue() { +#ifdef FIX_BUGS + uint32 oldFreq = 0; +#else + uint32 oldFreq; +#endif float reflectionDistance; int32 noise; - uint8 emittingVolume = (m_sQueueSample.m_nVolume / 2) + (m_sQueueSample.m_nVolume / 8); + uint8 emittingVolume; + + uint32 oldCounter = m_sQueueSample.m_nCounter; + float oldDist = m_sQueueSample.m_fDistance; + CVector oldPos = m_sQueueSample.m_vecPos; + if ( CTimer::GetIsSlowMotionActive() ) { + emittingVolume = m_sQueueSample.m_nVolume; + oldFreq = m_sQueueSample.m_nFrequency; + } else { + emittingVolume = (m_sQueueSample.m_nVolume / 2) + (m_sQueueSample.m_nVolume / 16); + } + m_sQueueSample.m_fSoundIntensity = m_sQueueSample.m_fSoundIntensity / 2.f; + + int halfOldFreq = oldFreq >> 1; for (uint32 i = 0; i < ARRAY_SIZE(m_afReflectionsDistances); i++) { + if ( CTimer::GetIsSlowMotionActive() ) + m_afReflectionsDistances[i] = GetRandomNumberInRange(i % 4, 0, 2) * 100.f / 8.f; + reflectionDistance = m_afReflectionsDistances[i]; if (reflectionDistance > 0.0f && reflectionDistance < 100.f && reflectionDistance < m_sQueueSample.m_fSoundIntensity) { - m_sQueueSample.m_nLoopsRemaining = (reflectionDistance * 500.f / 1029.f); - if (m_sQueueSample.m_nLoopsRemaining > 5) { + m_sQueueSample.m_nLoopsRemaining = CTimer::GetIsSlowMotionActive() ? (reflectionDistance * 800.f / 1029.f) : (reflectionDistance * 500.f / 1029.f); + if (m_sQueueSample.m_nLoopsRemaining > 3) { m_sQueueSample.m_fDistance = m_afReflectionsDistances[i]; m_sQueueSample.m_nEmittingVolume = emittingVolume; m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance); + if (m_sQueueSample.m_nVolume > emittingVolume / 16) { - m_sQueueSample.m_nCounter += (i + 1) * 256; + m_sQueueSample.m_nCounter = oldCounter + (i + 1) * 256; if (m_sQueueSample.m_nLoopCount) { - noise = RandomDisplacement(m_sQueueSample.m_nFrequency / 32); - if (noise <= 0) - m_sQueueSample.m_nFrequency += noise; - else - m_sQueueSample.m_nFrequency -= noise; + if ( CTimer::GetIsSlowMotionActive() ) { + m_sQueueSample.m_nFrequency = halfOldFreq + ((halfOldFreq * i) / ARRAY_SIZE(m_afReflectionsDistances)); + } else { + noise = RandomDisplacement(m_sQueueSample.m_nFrequency / 32); + if (noise <= 0) + m_sQueueSample.m_nFrequency += noise; + else + m_sQueueSample.m_nFrequency -= noise; + } } m_sQueueSample.m_nReleasingVolumeModificator += 20; m_sQueueSample.m_vecPos = m_avecReflectionsPos[i]; @@ -649,50 +681,85 @@ cAudioManager::AddReflectionsToRequestedQueue() } } } + m_sQueueSample.m_vecPos = oldPos; + m_sQueueSample.m_fDistance = oldDist; } +// --MIAMI: Done void cAudioManager::UpdateReflections() { - const CVector &camPos = TheCamera.GetPosition(); + CVector camPos = TheCamera.GetPosition(); CColPoint colpoint; CEntity *ent; if (m_FrameCounter % 8 == 0) { m_avecReflectionsPos[0] = camPos; - m_avecReflectionsPos[0].y += 50.f; + m_avecReflectionsPos[0].y += 100.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; + m_afReflectionsDistances[0] = 100.0f; + } else if ((m_FrameCounter + 1) % 8 == 0) { m_avecReflectionsPos[1] = camPos; - m_avecReflectionsPos[1].y -= 50.0f; + m_avecReflectionsPos[1].y -= 100.0f; 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; + m_afReflectionsDistances[1] = 100.0f; + } else if ((m_FrameCounter + 2) % 8 == 0) { m_avecReflectionsPos[2] = camPos; - m_avecReflectionsPos[2].x -= 50.0f; + m_avecReflectionsPos[2].x -= 100.0f; 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; + m_afReflectionsDistances[2] = 100.0f; + } else if ((m_FrameCounter + 3) % 8 == 0) { m_avecReflectionsPos[3] = camPos; - m_avecReflectionsPos[3].x += 50.0f; + m_avecReflectionsPos[3].x += 100.0f; 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; + m_afReflectionsDistances[3] = 100.0f; + } else if ((m_FrameCounter + 4) % 8 == 0) { + camPos.y += 1.0f; m_avecReflectionsPos[4] = camPos; - m_avecReflectionsPos[4].z += 50.0f; + m_avecReflectionsPos[4].z += 100.0f; if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[4].z, colpoint, ent, true, false, false, false, true, false, nil)) m_afReflectionsDistances[4] = colpoint.point.z - camPos.z; else - m_afReflectionsDistances[4] = 50.0f; + m_afReflectionsDistances[4] = 100.0f; + + } else if ((m_FrameCounter + 5) % 8 == 0) { + camPos.y -= 1.0f; + m_avecReflectionsPos[5] = camPos; + m_avecReflectionsPos[5].z += 100.0f; + if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[5].z, colpoint, ent, true, false, false, false, true, false, nil)) + m_afReflectionsDistances[5] = colpoint.point.z - camPos.z; + else + m_afReflectionsDistances[5] = 100.0f; + + } else if ((m_FrameCounter + 6) % 8 == 0) { + camPos.x -= 1.0f; + m_avecReflectionsPos[6] = camPos; + m_avecReflectionsPos[6].z += 100.0f; + if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[6].z, colpoint, ent, true, false, false, false, true, false, nil)) + m_afReflectionsDistances[6] = colpoint.point.z - camPos.z; + else + m_afReflectionsDistances[6] = 100.0f; + + } else if ((m_FrameCounter + 7) % 8 == 0) { + camPos.x += 1.0f; + m_avecReflectionsPos[7] = camPos; + m_avecReflectionsPos[7].z += 100.0f; + if (CWorld::ProcessVerticalLine(camPos, m_avecReflectionsPos[7].z, colpoint, ent, true, false, false, false, true, false, nil)) + m_afReflectionsDistances[7] = colpoint.point.z - camPos.z; + else + m_afReflectionsDistances[7] = 100.0f; } } @@ -1009,4 +1076,4 @@ cAudioManager::ComputeEmittingVolume(uint8 emittingVolume, float intensity, floa return (quatIntensity - (dist - diffIntensity)) * (float)emittingVolume / quatIntensity; return emittingVolume; } -#endif
\ No newline at end of file +#endif diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h index a43b4309..ae130b85 100644 --- a/src/audio/AudioManager.h +++ b/src/audio/AudioManager.h @@ -156,19 +156,14 @@ public: VALIDATE_SIZE(cVehicleParams, 0x18); enum { - /* - REFLECTION_YMAX = 0, top - REFLECTION_YMIN = 1, bottom - REFLECTION_XMIN = 2, left - REFLECTION_XMAX = 3, right - REFLECTION_ZMAX = 4, - */ - - REFLECTION_TOP = 0, - REFLECTION_BOTTOM, - REFLECTION_LEFT, - REFLECTION_RIGHT, - REFLECTION_UP, + REFLECTION_NORTH = 0, + REFLECTION_SOUTH, + REFLECTION_WEST, + REFLECTION_EAST, + REFLECTION_CEIL_NORTH, + REFLECTION_CEIL_SOUTH, + REFLECTION_CEIL_WEST, + REFLECTION_CEIL_EAST, MAX_REFLECTIONS, }; diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp index 2f392264..58b5dc02 100644 --- a/src/audio/oal/stream.cpp +++ b/src/audio/oal/stream.cpp @@ -377,8 +377,8 @@ CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUF #endif else m_pSoundFile = nil; - ASSERT(m_pSoundFile != nil); - if (m_pSoundFile && m_pSoundFile->IsOpened() ) + + if ( IsOpened() ) { m_pBuffer = malloc(m_pSoundFile->GetBufferSize()); ASSERT(m_pBuffer!=nil); @@ -425,14 +425,14 @@ bool CStream::HasSource() bool CStream::IsOpened() { - return m_pSoundFile->IsOpened(); + return m_pSoundFile && m_pSoundFile->IsOpened(); } bool CStream::IsPlaying() { if ( !HasSource() || !IsOpened() ) return false; - if ( m_pSoundFile->IsOpened() && !m_bPaused ) + if ( !m_bPaused ) { ALint sourceState; alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); @@ -500,7 +500,7 @@ void CStream::SetPan(uint8 nPan) void CStream::SetPosMS(uint32 nPos) { - if ( !m_pSoundFile->IsOpened() ) return; + if ( !IsOpened() ) return; m_pSoundFile->Seek(nPos); ClearBuffers(); } @@ -508,7 +508,7 @@ void CStream::SetPosMS(uint32 nPos) uint32 CStream::GetPosMS() { if ( !HasSource() ) return 0; - if ( !m_pSoundFile->IsOpened() ) return 0; + if ( !IsOpened() ) return 0; ALint offset; //alGetSourcei(m_alSource, AL_SAMPLE_OFFSET, &offset); @@ -521,7 +521,7 @@ uint32 CStream::GetPosMS() uint32 CStream::GetLengthMS() { - if ( !m_pSoundFile->IsOpened() ) return 0; + if ( !IsOpened() ) return 0; return m_pSoundFile->GetLength(); } @@ -529,7 +529,7 @@ bool CStream::FillBuffer(ALuint alBuffer) { if ( !HasSource() ) return false; - if ( !m_pSoundFile->IsOpened() ) + if ( !IsOpened() ) return false; if ( !(alBuffer != AL_NONE && alIsBuffer(alBuffer)) ) return false; @@ -571,7 +571,7 @@ void CStream::ClearBuffers() bool CStream::Setup() { - if ( m_pSoundFile->IsOpened() ) + if ( IsOpened() ) { m_pSoundFile->Seek(0); alSourcei(m_alSource, AL_SOURCE_RELATIVE, AL_TRUE); diff --git a/src/audio/sampman.h b/src/audio/sampman.h index dc4a8e3e..794db8e0 100644 --- a/src/audio/sampman.h +++ b/src/audio/sampman.h @@ -143,8 +143,8 @@ class cSampleManager char *m_aAudioProviders[MAXPROVIDERS]; tSample m_aSamples[TOTAL_AUDIO_SAMPLES]; char m_MiscomPath[260]; - char m_SfxPath[260]; - char m_StreamedAudioPath[188]; + char m_WavFilesPath[260]; + char m_MP3FilesPath[188]; void *m_aChannels[18]; public: diff --git a/src/audio/sampman_miles.cpp b/src/audio/sampman_miles.cpp index 6a7850d8..f7c4d7a6 100644 --- a/src/audio/sampman_miles.cpp +++ b/src/audio/sampman_miles.cpp @@ -16,10 +16,12 @@ #include "MusicManager.h" #include "Frontend.h" #include "Timer.h" - +#include "crossplatform.h" #pragma comment( lib, "mss32.lib" ) +// --MIAMI: file done + cSampleManager SampleManager; uint32 BankStartOffset[MAX_SFX_BANKS]; /////////////////////////////////////////////////////////////// @@ -65,11 +67,6 @@ uint8 nStreamLoopedFlag[MAX_STREAMS]; uint32 _CurMP3Index; int32 _CurMP3Pos; bool _bIsMp3Active; - -#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) -bool _bUseHDDAudio; -char _aHDDPath[MAX_PATH]; -#endif /////////////////////////////////////////////////////////////// @@ -560,15 +557,6 @@ _FindMP3s(void) FindClose(hFind); return; } - - FILE *f = fopen("MP3\\MP3Report.txt", "w"); - - if ( f ) - { - fprintf(f, "MP3 Report File\n\n"); - fprintf(f, "\"%s\"", fd.cFileName); - } - if ( filepathlen > 4 ) { @@ -578,12 +566,6 @@ _FindMP3s(void) { OutputDebugString("Resolving Link"); OutputDebugString(filepath); - - if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); - } - else - { - if ( f ) fprintf(f, " - couldn't resolve shortcut"); } bShortcut = true; @@ -607,10 +589,6 @@ _FindMP3s(void) if ( _pMP3List == NULL ) { FindClose(hFind); - - if ( f ) - fclose(f); - return; } @@ -633,9 +611,6 @@ _FindMP3s(void) { _pMP3List->pLinkPath = NULL; } - - if ( f ) fprintf(f, " - OK\n"); - bInitFirstEntry = false; } else @@ -644,8 +619,6 @@ _FindMP3s(void) OutputDebugString(filepath); - if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); - bInitFirstEntry = true; } @@ -661,8 +634,6 @@ _FindMP3s(void) int32 filepathlen = strlen(filepath); - if ( f ) fprintf(f, "\"%s\"", fd.cFileName); - if ( filepathlen > 0 ) { if ( filepathlen > 4 ) @@ -673,12 +644,6 @@ _FindMP3s(void) { OutputDebugString("Resolving Link"); OutputDebugString(filepath); - - if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); - } - else - { - if ( f ) fprintf(f, " - couldn't resolve shortcut"); } bShortcut = true; @@ -689,8 +654,6 @@ _FindMP3s(void) if ( filepathlen > MAX_PATH ) { - if ( f ) fprintf(f, " - Filename and path too long - %s - IGNORED)\n", filepath); - continue; } } @@ -729,17 +692,13 @@ _FindMP3s(void) } pList = _pMP3List; - - if ( f ) fprintf(f, " - OK\n"); - + bInitFirstEntry = false; } else { strcat(filepath, " - NOT A VALID MP3"); OutputDebugString(filepath); - - if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); } } } @@ -752,8 +711,6 @@ _FindMP3s(void) if ( filepathlen > 0 ) { - if ( f ) fprintf(f, "\"%s\"", fd.cFileName); - if ( filepathlen > 4 ) { if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) @@ -762,12 +719,6 @@ _FindMP3s(void) { OutputDebugString("Resolving Link"); OutputDebugString(filepath); - - if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); - } - else - { - if ( f ) fprintf(f, " - couldn't resolve shortcut"); } bShortcut = true; @@ -812,26 +763,16 @@ _FindMP3s(void) nNumMP3s++; OutputDebugString(fd.cFileName); - - if ( f ) fprintf(f, " - OK\n"); } else { strcat(filepath, " - NOT A VALID MP3"); OutputDebugString(filepath); - - if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); } } } } - - if ( f ) - { - fprintf(f, "\nTOTAL SUPPORTED MP3s: %d\n", nNumMP3s); - fclose(f); - } - + FindClose(hFind); } @@ -1043,54 +984,37 @@ cSampleManager::Initialise(void) AIL_set_preference(DIG_MIXER_CHANNELS, MAX_DIGITAL_MIXER_CHANNELS); - DIG = AIL_open_digital_driver(DIGITALRATE, DIGITALBITS, DIGITALCHANNELS, 0); - if ( DIG == NULL ) - { - OutputDebugString(AIL_last_error()); - Terminate(); - return false; - } - - add_providers(); - - if ( !InitialiseSampleBanks() ) - { - Terminate(); - return false; - } - - nSampleBankMemoryStartAddress[SFX_BANK_0] = (int32)AIL_mem_alloc_lock(nSampleBankSize[SFX_BANK_0]); - if ( !nSampleBankMemoryStartAddress[SFX_BANK_0] ) - { - Terminate(); - return false; - } - - nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX); + DIG = AIL_open_digital_driver(DIGITALRATE, DIGITALBITS, DIGITALCHANNELS, 0); } #ifdef AUDIO_CACHE TRACE("cache"); - FILE *cacheFile = fopen("audio\\sound.cache", "rb"); + FILE *cacheFile = fcaseopen("audio\\sound.cache", "rb"); + bool CreateCache = false; if (cacheFile) { fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); fclose(cacheFile); - m_bInitialised = true; - }else { + }else + CreateCache = true; #endif - TRACE("cdrom"); - S32 tatalms; char filepath[MAX_PATH]; + bool bFileNotFound; + S32 tatalms; + TRACE("cdrom"); { m_bInitialised = false; + while (true) { + + // Find path of WAVs (originally in HDD) int32 drive = 'C'; +#ifndef NO_CDCHECK do { char latter[2]; @@ -1111,93 +1035,35 @@ cSampleManager::Initialise(void) if ( f ) { fclose(f); - - bool bFileNotFound = false; - - for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) - { - strcpy(filepath, m_szCDRomRootPath); - strcat(filepath, StreamedNameTable[i]); - - mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); - - if ( mp3Stream[0] ) - { - AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); - - AIL_close_stream(mp3Stream[0]); - mp3Stream[0] = NULL; - - nStreamLength[i] = tatalms; - } - else - { - bFileNotFound = true; - break; - } - } - - if ( !bFileNotFound ) - { - m_bInitialised = true; - break; - } - else - { - m_bInitialised = false; - continue; - } + strcpy(m_MiscomPath, m_szCDRomRootPath); + break; } } - + } while ( ++drive <= 'Z' ); - - if ( !m_bInitialised ) - { -#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) - FrontEndMenuManager.WaitForUserCD(); - if ( FrontEndMenuManager.m_bQuitGameNoCD ) - { - Terminate(); - return false; - } - continue; #else - m_bInitialised = true; + m_MiscomPath[0] = '\0'; #endif + + if ( DIG == NULL ) + { + OutputDebugString(AIL_last_error()); + Terminate(); + return false; } - break; - } - } + add_providers(); -#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) - // hddaudio - /** - Option for user to play audio files directly from hard disk. - Copy the contents of the PLAY discs Audio directory into your installed Grand Theft Auto III Audio directory. - Grand Theft Auto III still requires the presence of the PLAY disc when started. - This may give better performance on some machines (though worse on others). - **/ - TRACE("hddaudio 1.1 patch"); - { - int32 streamLength[TOTAL_STREAMED_SOUNDS]; - - bool bFileNotFound = false; - char rootpath[MAX_PATH]; - - strcpy(_aHDDPath, m_szCDRomRootPath); - rootpath[0] = '\0'; - - FILE *f = fopen(StreamedNameTable[0], "rb"); - - if ( f ) - { - fclose(f); - - for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) + m_szCDRomRootPath[0] = '\0'; + + strcpy(m_WavFilesPath, m_szCDRomRootPath); + +#ifdef AUDIO_CACHE + if ( CreateCache ) +#endif + for ( int32 i = STREAMED_SOUND_MISSION_MOBR1; i < TOTAL_STREAMED_SOUNDS; i++ ) { - strcpy(filepath, rootpath); + strcpy(filepath, m_szCDRomRootPath); strcat(filepath, StreamedNameTable[i]); mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); @@ -1209,39 +1075,149 @@ cSampleManager::Initialise(void) AIL_close_stream(mp3Stream[0]); mp3Stream[0] = NULL; - streamLength[i] = tatalms; + nStreamLength[i] = tatalms; } else { - bFileNotFound = true; + m_bInitialised = false; + Terminate(); + return false; + } + } + + // Find path of MP3s (originally in CD-Rom) + // if NO_CDCHECK is NOT defined but AUDIO_CACHE is defined, we still need to find MP3s' path, but will exit after the first file +#ifndef NO_CDCHECK + int32 drive = 'C'; + do + { + latter[0] = drive; + latter[1] = '\0'; + + strcpy(m_szCDRomRootPath, latter); + strcat(m_szCDRomRootPath, ":"); + strcat(m_MP3FilesPath, m_szCDRomRootPath); +#else + m_MP3FilesPath[0] = '\0'; + { +#endif + + for (int32 i = 0; i < STREAMED_SOUND_MISSION_MOBR1; i++) + { + strcpy(filepath, m_MP3FilesPath); + strcat(filepath, StreamedNameTable[i]); + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + + if (mp3Stream[0]) + { + AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + bFileNotFound = false; +#ifdef AUDIO_CACHE + if (!CreateCache) + break; + else +#endif + nStreamLength[i] = tatalms; + + } + else + { + bFileNotFound = true; + break; + } + } + +#ifndef NO_CDCHECK + if (!bFileNotFound) // otherwise try next drive break; + + } + while (++drive <= 'Z'); +#else + } +#endif + + if ( !bFileNotFound ) { + +#ifdef AUDIO_CACHE + if ( CreateCache ) +#endif + for ( int32 i = STREAMED_SOUND_MISSION_COMPLETED4; i < STREAMED_SOUND_MISSION_PAGER; i++ ) + { + strcpy(filepath, m_MiscomPath); + strcat(filepath, StreamedNameTable[i]); + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + nStreamLength[i] = tatalms; + bFileNotFound = false; + } + else + { + bFileNotFound = true; + break; + } } } - - } - else - bFileNotFound = true; - - if ( !bFileNotFound ) - { - strcpy(m_szCDRomRootPath, rootpath); - for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) - nStreamLength[i] = streamLength[i]; + m_bInitialised = !bFileNotFound; + + if ( !m_bInitialised ) + { +#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) + FrontEndMenuManager.WaitForUserCD(); + if ( FrontEndMenuManager.m_bQuitGameNoCD ) + { + Terminate(); + return false; + } + continue; +#else + m_bInitialised = true; +#endif + } - _bUseHDDAudio = true; + break; } - else - _bUseHDDAudio = false; } -#endif + #ifdef AUDIO_CACHE - cacheFile = fopen("audio\\sound.cache", "wb"); - fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); - fclose(cacheFile); + if (CreateCache) { + cacheFile = fcaseopen("audio\\sound.cache", "wb"); + fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); + fclose(cacheFile); } #endif + if ( !InitialiseSampleBanks() ) + { + Terminate(); + return false; + } + + nSampleBankMemoryStartAddress[SFX_BANK_0] = (int32)AIL_mem_alloc_lock(nSampleBankSize[SFX_BANK_0]); + if ( !nSampleBankMemoryStartAddress[SFX_BANK_0] ) + { + Terminate(); + return false; + } + + nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX); + + LoadSampleBank(SFX_BANK_0); + TRACE("stream"); { for ( int32 i = 0; i < MAX_STREAMS; i++ ) @@ -1270,7 +1246,7 @@ cSampleManager::Initialise(void) while ( n < m_nNumberOfProviders ) { - if ( !strcmp(providers[n].name, "Miles Fast 2D Positional Audio") ) + if ( !strcmp(strupr(providers[n].name), "DIRECTSOUND3D SOFTWARE EMULATION") ) { set_new_provider(n); break; @@ -1285,10 +1261,6 @@ cSampleManager::Initialise(void) } } - TRACE("bank"); - - LoadSampleBank(SFX_BANK_0); - // mp3 TRACE("mp3"); { @@ -1411,26 +1383,25 @@ cSampleManager::CheckForAnAudioFileOnCD(void) #if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) char filepath[MAX_PATH]; -#if defined(GTA3_1_1_PATCH) - if (_bUseHDDAudio) - strcpy(filepath, _aHDDPath); - else - strcpy(filepath, m_szCDRomRootPath); -#else - strcpy(filepath, m_szCDRomRootPath); -#endif // #if defined(GTA3_1_1_PATCH) + strcpy(filepath, m_MiscomPath); + strcat(filepath, StreamedNameTable[STREAMED_SOUND_MISSION_COMPLETED4]); - strcat(filepath, StreamedNameTable[AudioManager.GetRandomNumber(1) % TOTAL_STREAMED_SOUNDS]); - FILE *f = fopen(filepath, "rb"); - + if ( f ) { fclose(f); + DMAudio.SetMusicMasterVolume(FrontEndMenuManager.m_PrefsMusicVolume); + DMAudio.SetEffectsMasterVolume(FrontEndMenuManager.m_PrefsSfxVolume); + DMAudio.Service(); return true; } - + + DMAudio.SetMusicMasterVolume(0); + DMAudio.SetEffectsMasterVolume(0); + DMAudio.Service(); + return false; #else @@ -1441,27 +1412,10 @@ cSampleManager::CheckForAnAudioFileOnCD(void) char cSampleManager::GetCDAudioDriveLetter(void) { -#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) - if (_bUseHDDAudio) - { - if ( strlen(_aHDDPath) != 0 ) - return _aHDDPath[0]; - else - return '\0'; - } - else - { - if ( strlen(m_szCDRomRootPath) != 0 ) - return m_szCDRomRootPath[0]; - else - return '\0'; - } -#else - if ( strlen(m_szCDRomRootPath) != 0 ) - return m_szCDRomRootPath[0]; + if ( strlen(m_MiscomPath) != 0 ) + return m_MiscomPath[0]; else return '\0'; -#endif } void @@ -1629,14 +1583,6 @@ cSampleManager::LoadPedComment(uint32 nComment) break; } - - case MUSICMODE_FRONTEND: - { - if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_CUTSCENE_FINALE ) - return false; - - break; - } } } @@ -1699,69 +1645,45 @@ cSampleManager::UpdateReverb(void) if ( AudioManager.GetFrameCounter() & 15 ) return false; - - float y = AudioManager.GetReflectionsDistance(REFLECTION_TOP) + AudioManager.GetReflectionsDistance(REFLECTION_BOTTOM); - float x = AudioManager.GetReflectionsDistance(REFLECTION_LEFT) + AudioManager.GetReflectionsDistance(REFLECTION_RIGHT); - float z = AudioManager.GetReflectionsDistance(REFLECTION_UP); - - float normy = norm(y, 5.0f, 40.0f); - float normx = norm(x, 5.0f, 40.0f); - float normz = norm(z, 5.0f, 40.0f); - float fRatio; - - if ( normy == 0.0f ) - { - if ( normx == 0.0f ) - { - if ( normz == 0.0f ) - fRatio = 0.3f; - else - fRatio = 0.5f; - } - else - { - fRatio = 0.3f; - } - } - else - { - if ( normx == 0.0f ) - { - if ( normz == 0.0f ) - fRatio = 0.3f; - else - fRatio = 0.5f; - } - else - { - if ( normz == 0.0f ) - fRatio = 0.3f; - else - fRatio = (normy+normx+normz) / 3.0f; - } - } + float fRatio = 0.0f; + +#define MIN_DIST 0.5f +#define CALCULATE_RATIO(value, maxDist, maxRatio) (value > MIN_DIST && value < maxDist ? value / maxDist * maxRatio : 0) + + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_NORTH), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_SOUTH), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_WEST), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_EAST), 10.0f, 1/2.f); + + fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_NORTH) + AudioManager.GetReflectionsDistance(REFLECTION_SOUTH)) / 2.f, 4.0f, 1/3.f); + fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_WEST) + AudioManager.GetReflectionsDistance(REFLECTION_EAST)) / 2.f, 4.0f, 1/3.f); + +#undef CALCULATE_RATIO +#undef MIN_DIST - fRatio = clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f); + fRatio = clamp(fRatio, 0.0f, 0.6f); if ( fRatio == _fPrevEaxRatioDestination ) return false; if ( usingEAX3 ) { + fRatio = Min(fRatio * 1.67f, 1.0f); if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) ) { AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &EAX3Params); - _fEffectsLevel = 1.0f - fRatio * 0.5f; + _fEffectsLevel = fRatio * 0.75f; } } else { if ( _usingMilesFast2D ) - _fEffectsLevel = (1.0f - fRatio) * 0.4f; + _fEffectsLevel = fRatio * 0.8f; else - _fEffectsLevel = (1.0f - fRatio) * 0.7f; + _fEffectsLevel = fRatio * 0.22f; } + _fEffectsLevel = Min(_fEffectsLevel, 1.0f); _fPrevEaxRatioDestination = fRatio; @@ -1870,10 +1792,11 @@ cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) nChannelVolume[nChannel] = vol; // increase the volume for JB.MP3 and S4_BDBD.MP3 - if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE - && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_FINALE ) - { - nChannelVolume[nChannel] >>= 2; + if (MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE ) { + if (MusicManager.GetCurrentTrack() == STREAMED_SOUND_CUTSCENE_FINALE) + nChannelVolume[nChannel] = 0; + else + nChannelVolume[nChannel] >>= 2; } if ( opened_samples[nChannel] ) @@ -2123,7 +2046,7 @@ cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream) char filepath[MAX_PATH]; - strcpy(filepath, m_szCDRomRootPath); + strcpy(filepath, nFile < STREAMED_SOUND_MISSION_COMPLETED4 ? m_MP3FilesPath : (nFile < STREAMED_SOUND_MISSION_MOBR1 ? m_MiscomPath : m_WavFilesPath)); strcat(filepath, StreamedNameTable[nFile]); mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0); @@ -2189,7 +2112,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) if(mp3 == NULL) { _bIsMp3Active = false; nFile = 0; - strcpy(filename, m_szCDRomRootPath); + strcpy(filename, m_MiscomPath); strcat(filename, StreamedNameTable[nFile]); mp3Stream[nStream] = @@ -2239,15 +2162,14 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) if ( e == NULL ) { nFile = 0; - strcpy(filename, m_szCDRomRootPath); + strcpy(filename, m_MiscomPath); strcat(filename, StreamedNameTable[nFile]); mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0); if(mp3Stream[nStream]) { - AIL_set_stream_loop_count( - mp3Stream[nStream], 1); - AIL_set_stream_ms_position( - mp3Stream[nStream], position); + AIL_set_stream_loop_count(mp3Stream[nStream], nStreamLoopedFlag[nStream] ? 0 : 1); + nStreamLoopedFlag[nStream] = true; + AIL_set_stream_ms_position(mp3Stream[nStream], position); AIL_pause_stream(mp3Stream[nStream], 0); return true; } @@ -2285,13 +2207,14 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) nFile = 0; } - strcpy(filename, m_szCDRomRootPath); + strcpy(filename, m_MiscomPath); strcat(filename, StreamedNameTable[nFile]); mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0); if ( mp3Stream[nStream] ) { - AIL_set_stream_loop_count(mp3Stream[nStream], 1); + AIL_set_stream_loop_count(mp3Stream[nStream], nStreamLoopedFlag[nStream] ? 0 : 1); + nStreamLoopedFlag[nStream] = true; AIL_set_stream_ms_position(mp3Stream[nStream], position); AIL_pause_stream(mp3Stream[nStream], 0); return true; @@ -2355,11 +2278,14 @@ void cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream) { uint8 vol = nVolume; + float boostMult = 0.0f; if ( m_bInitialised ) { if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; - if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + if ( MusicManager.GetRadioInCar() == USERTRACK && !MusicManager.CheckForMusicInterruptions() ) + boostMult = m_nMP3BoostVolume / 64.f; nStreamVolume[nStream] = vol; nStreamPan[nStream] = nPan; @@ -2368,13 +2294,13 @@ cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffect { if ( nEffectFlag ) { - if ( nStream == 1 ) // TODO(MIAMI): || nStream == 2 when we have second mission channel? + if ( nStream == 1 || nStream == 2 ) AIL_set_stream_volume(mp3Stream[nStream], 128*vol*m_nEffectsVolume >> 14); else AIL_set_stream_volume(mp3Stream[nStream], m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); } else - AIL_set_stream_volume(mp3Stream[nStream], m_nMusicFadeVolume*vol*m_nMusicVolume >> 14); + AIL_set_stream_volume(mp3Stream[nStream], (m_nMusicFadeVolume*vol*(uint32)(m_nMusicVolume * boostMult + m_nMusicVolume)) >> 14); AIL_set_stream_pan(mp3Stream[nStream], nPan); } @@ -2460,4 +2386,4 @@ cSampleManager::SetStreamedFileLoopFlag(uint8 nLoopFlag, uint8 nChannel) nStreamLoopedFlag[nChannel] = nLoopFlag; } -#endif
\ No newline at end of file +#endif diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp index d0b88245..ce81439b 100644 --- a/src/audio/sampman_oal.cpp +++ b/src/audio/sampman_oal.cpp @@ -1,4 +1,3 @@ -#include "common.h" //#define JUICY_OAL #ifdef AUDIO_OAL @@ -9,6 +8,10 @@ #include "eax.h" #include "eax-util.h" +#define WITHWINDOWS +#include "common.h" +#include "crossplatform.h" + #ifdef _WIN32 #include <io.h> #include <AL/al.h> @@ -27,20 +30,27 @@ #include "MusicManager.h" #include "Frontend.h" #include "Timer.h" -#include "crossplatform.h" #ifdef AUDIO_OPUS #include <opusfile.h> #endif //TODO: fix eax3 reverb -//TODO: max channals +//TODO: max channels //TODO: loop count -//TODO: mp3 player #ifdef _WIN32 #pragma comment( lib, "OpenAL32.lib" ) #endif +// for user MP3s +#ifdef _WIN32 +#include <direct.h> +#include <shobjidl.h> +#include <shlguid.h> +#else +#define _getcwd getcwd +#endif + cSampleManager SampleManager; bool _bSampmanInitialised = false; @@ -128,12 +138,27 @@ struct } }ALBuffers[SAMPLEBANK_MAX]; -uint32 nNumMP3s; +struct tMP3Entry +{ + char aFilename[MAX_PATH]; + + uint32 nTrackLength; + uint32 nTrackStreamPos; + + tMP3Entry* pNext; + char* pLinkPath; +}; + +uint32 nNumMP3s; +tMP3Entry* _pMP3List; +char _mp3DirectoryPath[MAX_PATH]; CStream *aStream[MAX_STREAMS]; uint8 nStreamPan [MAX_STREAMS]; uint8 nStreamVolume[MAX_STREAMS]; uint8 nStreamLoopedFlag[MAX_STREAMS]; - +uint32 _CurMP3Index; +int32 _CurMP3Pos; +bool _bIsMp3Active; /////////////////////////////////////////////////////////////// // Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS EAXLISTENERPROPERTIES StartEAX3 = @@ -452,20 +477,14 @@ int8 cSampleManager::GetCurrent3DProviderIndex(void) int8 cSampleManager::SetCurrent3DProvider(uint8 nProvider) { - if (nProvider >= m_nNumberOfProviders) - nProvider = 0; - ASSERT( nProvider < m_nNumberOfProviders ); int savedprovider = curprovider; - - if ( nProvider < m_nNumberOfProviders ) - { - if ( set_new_provider(nProvider) ) - return curprovider; - else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) ) - return curprovider; - else - return -1; - } + + nProvider = clamp(nProvider, 0, m_nNumberOfProviders - 1); + + if ( set_new_provider(nProvider) ) + return curprovider; + else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) ) + return curprovider; else return curprovider; } @@ -476,7 +495,10 @@ cSampleManager::AutoDetect3DProviders() if (!AudioManager.IsAudioInitialised()) return -1; - int eax = -1, eax2 = -1, eax3 = -1, ds3dh = -1, ds3ds = -1; + if (defaultProvider >= 0 && defaultProvider < m_nNumberOfProviders) { + if (set_new_provider(defaultProvider)) + return defaultProvider; + } for (uint32 i = 0; i < GetNum3DProvidersAvailable(); i++) { @@ -489,19 +511,412 @@ cSampleManager::AutoDetect3DProviders() } } - if (eax3 != -1) - return eax3; - if (eax2 != -1) - return eax2; - if (eax != -1) - return eax; - if (ds3dh != -1) - return ds3dh; - if (ds3ds != -1) - return ds3ds; return -1; } +static bool +_ResolveLink(char const *path, char *out) +{ +#ifdef _WIN32 + size_t len = strlen(path); + if (len < 4 || strcmp(&path[len - 4], ".lnk") != 0) + return false; + + IShellLink* psl; + WIN32_FIND_DATA fd; + char filepath[MAX_PATH]; + + CoInitialize(NULL); + + if (SUCCEEDED( CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl ) )) + { + IPersistFile *ppf; + + if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf))) + { + WCHAR wpath[MAX_PATH]; + + MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH); + + if (SUCCEEDED(ppf->Load(wpath, STGM_READ))) + { + /* Resolve the link */ + if (SUCCEEDED(psl->Resolve(NULL, SLR_ANY_MATCH|SLR_NO_UI|SLR_NOSEARCH))) + { + strcpy(filepath, path); + + if (SUCCEEDED(psl->GetPath(filepath, MAX_PATH, &fd, SLGP_UNCPRIORITY))) + { + OutputDebugString(fd.cFileName); + + strcpy(out, filepath); + // FIX: Release the objects. Taken from SA. +#ifdef FIX_BUGS + ppf->Release(); + psl->Release(); +#endif + return true; + } + } + } + + ppf->Release(); + } + psl->Release(); + } + + return false; +#else + struct stat sb; + + if (lstat(path, &sb) == -1) { + perror("lstat: "); + return false; + } + + if (S_ISLNK(sb.st_mode)) { + char* linkname = (char*)alloca(sb.st_size + 1); + if (linkname == NULL) { + fprintf(stderr, "insufficient memory\n"); + return false; + } + + if (readlink(path, linkname, sb.st_size + 1) < 0) { + perror("readlink: "); + return false; + } + linkname[sb.st_size] = '\0'; + strcpy(out, linkname); + return true; + } else { + return false; + } +#endif +} + +static void +_FindMP3s(void) +{ + tMP3Entry *pList; + bool bShortcut; + bool bInitFirstEntry; + HANDLE hFind; + char path[MAX_PATH]; + char filepath[MAX_PATH*2]; + int total_ms; + WIN32_FIND_DATA fd; + + if (getcwd(_mp3DirectoryPath, MAX_PATH) == NULL) { + perror("getcwd: "); + return; + } + + OutputDebugString("Finding MP3s..."); + strcpy(path, _mp3DirectoryPath); + strcat(path, "\\MP3\\"); + + strcpy(_mp3DirectoryPath, path); + OutputDebugString(_mp3DirectoryPath); + + strcat(path, "*"); + + hFind = FindFirstFile(path, &fd); + + if ( hFind == INVALID_HANDLE_VALUE ) + { + return; + } + + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + size_t filepathlen = strlen(filepath); + + if ( filepathlen <= 0) + { + FindClose(hFind); + return; + } + + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + bShortcut = true; + } else + bShortcut = false; + + aStream[0] = new CStream(filepath, ALStreamSources[0], ALStreamBuffers[0]); + + if (aStream[0] && aStream[0]->IsOpened()) + { + total_ms = aStream[0]->GetLengthMS(); + delete aStream[0]; + aStream[0] = NULL; + + OutputDebugString(fd.cFileName); + + _pMP3List = new tMP3Entry; + + if ( _pMP3List == NULL ) + { + FindClose(hFind); + return; + } + + nNumMP3s = 1; + + strcpy(_pMP3List->aFilename, fd.cFileName); + + _pMP3List->nTrackLength = total_ms; + + _pMP3List->pNext = NULL; + + pList = _pMP3List; + + if ( bShortcut ) + { + _pMP3List->pLinkPath = new char[MAX_PATH*2]; + strcpy(_pMP3List->pLinkPath, filepath); + } + else + { + _pMP3List->pLinkPath = NULL; + } + + bInitFirstEntry = false; + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + + OutputDebugString(filepath); + + bInitFirstEntry = true; + } + + while ( true ) + { + if ( !FindNextFile(hFind, &fd) ) + break; + + if ( bInitFirstEntry ) + { + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + size_t filepathlen = strlen(filepath); + + if ( filepathlen > 0 ) + { + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + bShortcut = true; + } else { + bShortcut = false; + if (filepathlen > MAX_PATH) { + continue; + } + } + aStream[0] = new CStream(filepath, ALStreamSources[0], ALStreamBuffers[0]); + + if (aStream[0] && aStream[0]->IsOpened()) + { + total_ms = aStream[0]->GetLengthMS(); + delete aStream[0]; + aStream[0] = NULL; + + OutputDebugString(fd.cFileName); + + _pMP3List = new tMP3Entry; + + if ( _pMP3List == NULL) + break; + + nNumMP3s = 1; + + strcpy(_pMP3List->aFilename, fd.cFileName); + + _pMP3List->nTrackLength = total_ms; + _pMP3List->pNext = NULL; + + if ( bShortcut ) + { + _pMP3List->pLinkPath = new char [MAX_PATH*2]; + strcpy(_pMP3List->pLinkPath, filepath); + } + else + { + _pMP3List->pLinkPath = NULL; + } + + pList = _pMP3List; + + bInitFirstEntry = false; + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + OutputDebugString(filepath); + } + } + } + else + { + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + size_t filepathlen = strlen(filepath); + + if ( filepathlen > 0 ) + { + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + bShortcut = true; + } else + bShortcut = false; + + aStream[0] = new CStream(filepath, ALStreamSources[0], ALStreamBuffers[0]); + + if (aStream[0] && aStream[0]->IsOpened()) + { + total_ms = aStream[0]->GetLengthMS(); + delete aStream[0]; + aStream[0] = NULL; + + OutputDebugString(fd.cFileName); + + pList->pNext = new tMP3Entry; + + tMP3Entry *e = pList->pNext; + + if ( e == NULL ) + break; + + pList = pList->pNext; + + strcpy(e->aFilename, fd.cFileName); + e->nTrackLength = total_ms; + e->pNext = NULL; + + if ( bShortcut ) + { + e->pLinkPath = new char [MAX_PATH*2]; + strcpy(e->pLinkPath, filepath); + } + else + { + e->pLinkPath = NULL; + } + + nNumMP3s++; + + OutputDebugString(fd.cFileName); + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + OutputDebugString(filepath); + } + } + } + } + + FindClose(hFind); +} + +static void +_DeleteMP3Entries(void) +{ + tMP3Entry *e = _pMP3List; + + while ( e != NULL ) + { + tMP3Entry *next = e->pNext; + + if ( next == NULL ) + next = NULL; + + if ( e->pLinkPath != NULL ) + { +#ifndef FIX_BUGS + delete e->pLinkPath; // BUG: should be delete [] +#else + delete[] e->pLinkPath; +#endif + e->pLinkPath = NULL; + } + + delete e; + + if ( next ) + e = next; + else + e = NULL; + + nNumMP3s--; + } + + + if ( nNumMP3s != 0 ) + { + OutputDebugString("Not all MP3 entries were deleted"); + nNumMP3s = 0; + } + + _pMP3List = NULL; +} + +static tMP3Entry * +_GetMP3EntryByIndex(uint32 idx) +{ + uint32 n = ( idx < nNumMP3s ) ? idx : 0; + + if ( _pMP3List != NULL ) + { + tMP3Entry *e = _pMP3List; + + for ( uint32 i = 0; i < n; i++ ) + e = e->pNext; + + return e; + + } + + return NULL; +} + +static inline bool +_GetMP3PosFromStreamPos(uint32 *pPosition, tMP3Entry **pEntry) +{ + _CurMP3Index = 0; + + for ( *pEntry = _pMP3List; *pEntry != NULL; *pEntry = (*pEntry)->pNext ) + { + if ( *pPosition >= (*pEntry)->nTrackStreamPos + && *pPosition < (*pEntry)->nTrackLength + (*pEntry)->nTrackStreamPos ) + { + *pPosition -= (*pEntry)->nTrackStreamPos; + _CurMP3Pos = *pPosition; + + return true; + } + + _CurMP3Index++; + } + + *pPosition = 0; + *pEntry = _pMP3List; + _CurMP3Pos = 0; + _CurMP3Index = 0; + + return false; +} + bool cSampleManager::IsMP3RadioChannelAvailable(void) { @@ -599,21 +1014,45 @@ cSampleManager::Initialise(void) nChannelVolume[i] = 0; } - { - for ( int32 i = 0; i < MAX_STREAMS; i++ ) - { - aStream[i] = NULL; - nStreamVolume[i] = 100; - nStreamPan[i] = 63; - } - + { for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) nStreamLength[i] = 0; } - { add_providers(); - + +#ifdef AUDIO_CACHE + FILE *cacheFile = fcaseopen("audio\\sound.cache", "rb"); + if (cacheFile) { + fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); + fclose(cacheFile); + } else +#endif + { + + for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) + { + aStream[0] = new CStream(StreamedNameTable[i], ALStreamSources[0], ALStreamBuffers[0]); + + if ( aStream[0] && aStream[0]->IsOpened() ) + { + uint32 tatalms = aStream[0]->GetLengthMS(); + delete aStream[0]; + aStream[0] = NULL; + + nStreamLength[i] = tatalms; + } + else + USERERROR("Can't open '%s'\n", StreamedNameTable[i]); + } +#ifdef AUDIO_CACHE + cacheFile = fcaseopen("audio\\sound.cache", "wb"); + fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); + fclose(cacheFile); +#endif + } + + { if ( !InitialiseSampleBanks() ) { Terminate(); @@ -631,13 +1070,23 @@ cSampleManager::Initialise(void) nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = (uintptr)malloc(PED_BLOCKSIZE*MAX_PEDSFX); ASSERT(nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] != 0); + + LoadSampleBank(SFX_BANK_0); } + { + for ( int32 i = 0; i < MAX_STREAMS; i++ ) + { + aStream[i] = NULL; + nStreamVolume[i] = 100; + nStreamPan[i] = 63; + } + } { _bSampmanInitialised = true; - if ( 0 >= defaultProvider && defaultProvider < m_nNumberOfProviders ) + if ( defaultProvider >= 0 && defaultProvider < m_nNumberOfProviders ) { set_new_provider(defaultProvider); } @@ -647,38 +1096,66 @@ cSampleManager::Initialise(void) return false; } } -#ifdef AUDIO_CACHE - FILE *cacheFile = fopen("audio\\sound.cache", "rb"); - if (cacheFile) { - fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); - fclose(cacheFile); - } else -#endif + { - - for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) - { - aStream[0] = new CStream(StreamedNameTable[i], ALStreamSources[0], ALStreamBuffers[0]); + nNumMP3s = 0; + + _pMP3List = NULL; + + _FindMP3s(); + + if ( nNumMP3s != 0 ) + { + nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] = 0; - if ( aStream[0] && aStream[0]->IsOpened() ) + for ( tMP3Entry *e = _pMP3List; e != NULL; e = e->pNext ) { - uint32 tatalms = aStream[0]->GetLengthMS(); - delete aStream[0]; - aStream[0] = NULL; - - nStreamLength[i] = tatalms; + e->nTrackStreamPos = nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER]; + nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] += e->nTrackLength; } + + time_t t = time(NULL); + tm *localtm; + bool bUseRandomTable; + + if ( t == -1 ) + bUseRandomTable = true; else - USERERROR("Can't open '%s'\n", StreamedNameTable[i]); + { + bUseRandomTable = false; + localtm = localtime(&t); + } + + int32 randval; + if ( bUseRandomTable ) + randval = AudioManager.GetRandomNumber(1); + else + randval = localtm->tm_sec * localtm->tm_min; + + _CurMP3Index = randval % nNumMP3s; + + tMP3Entry *randmp3 = _pMP3List; + for ( int32 i = randval % nNumMP3s; i > 0; --i) + randmp3 = randmp3->pNext; + + if ( bUseRandomTable ) + _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength; + else + { + if ( localtm->tm_sec > 0 ) + { + int32 s = localtm->tm_sec; + _CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength; + } + else + _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength; + } } -#ifdef AUDIO_CACHE - cacheFile = fopen("audio\\sound.cache", "wb"); - fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); - fclose(cacheFile); -#endif - } + else + _CurMP3Pos = 0; - LoadSampleBank(SFX_BANK_0); + _bIsMp3Active = false; + } return true; } @@ -686,8 +1163,6 @@ cSampleManager::Initialise(void) void cSampleManager::Terminate(void) { - release_existing(); - for (int32 i = 0; i < MAX_STREAMS; i++) { CStream *stream = aStream[i]; @@ -698,6 +1173,10 @@ cSampleManager::Terminate(void) } } + release_existing(); + + _DeleteMP3Entries(); + CStream::Terminate(); if ( nSampleBankMemoryStartAddress[SFX_BANK_0] != 0 ) @@ -905,14 +1384,6 @@ cSampleManager::LoadPedComment(uint32 nComment) break; } - - case MUSICMODE_FRONTEND: - { - if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_CUTSCENE_FINALE) - return false; - - break; - } } } @@ -998,24 +1469,24 @@ bool cSampleManager::UpdateReverb(void) if ( AudioManager.GetFrameCounter() & 15 ) return false; - - float y = AudioManager.GetReflectionsDistance(REFLECTION_TOP) + AudioManager.GetReflectionsDistance(REFLECTION_BOTTOM); - float x = AudioManager.GetReflectionsDistance(REFLECTION_LEFT) + AudioManager.GetReflectionsDistance(REFLECTION_RIGHT); - float z = AudioManager.GetReflectionsDistance(REFLECTION_UP); - - float normy = norm(y, 5.0f, 40.0f); - float normx = norm(x, 5.0f, 40.0f); - float normz = norm(z, 5.0f, 40.0f); - - #define ZR(v, a, b) (((v)==0)?(a):(b)) - #define CALCRATIO(x,y,z,min,max,val) (ZR(y, ZR(x, ZR(z, min, max), min), ZR(x, ZR(z, min, max), ZR(z, min, val)))) - - float fRatio = CALCRATIO(normx, normy, normz, 0.3f, 0.5f, (normy+normx+normz)/3.0f); - - #undef CALCRATIO - #undef ZE + + float fRatio = 0.0f; + +#define MIN_DIST 0.5f +#define CALCULATE_RATIO(value, maxDist, maxRatio) (value > MIN_DIST && value < maxDist ? value / maxDist * maxRatio : 0) + + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_NORTH), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_SOUTH), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_WEST), 10.0f, 1/2.f); + fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_EAST), 10.0f, 1/2.f); + + fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_NORTH) + AudioManager.GetReflectionsDistance(REFLECTION_SOUTH)) / 2.f, 4.0f, 1/3.f); + fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_WEST) + AudioManager.GetReflectionsDistance(REFLECTION_EAST)) / 2.f, 4.0f, 1/3.f); + +#undef CALCULATE_RATIO +#undef MIN_DIST - fRatio = clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f); + fRatio = clamp(fRatio, 0.0f, 0.6f); if ( fRatio == _fPrevEaxRatioDestination ) return false; @@ -1026,6 +1497,7 @@ bool cSampleManager::UpdateReverb(void) if ( usingEAX3 ) #endif { + fRatio = Min(fRatio * 1.67f, 1.0f); if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) ) { EAX_SetAll(&EAX3Params); @@ -1040,16 +1512,17 @@ bool cSampleManager::UpdateReverb(void) } */ - _fEffectsLevel = 1.0f - fRatio * 0.5f; + _fEffectsLevel = fRatio * 0.75f; } } else { if ( _usingEFX ) - _fEffectsLevel = (1.0f - fRatio) * 0.4f; + _fEffectsLevel = fRatio * 0.8f; else - _fEffectsLevel = (1.0f - fRatio) * 0.7f; + _fEffectsLevel = fRatio * 0.22f; } + _fEffectsLevel = Min(_fEffectsLevel, 1.0f); _fPrevEaxRatioDestination = fRatio; @@ -1187,12 +1660,14 @@ cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume) nChannelVolume[nChannel] = vol; - if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE - && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_FINALE ) - { - nChannelVolume[nChannel] = vol / 4; + // increase the volume for JB.MP3 and S4_BDBD.MP3 + if (MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE ) { + if (MusicManager.GetCurrentTrack() == STREAMED_SOUND_CUTSCENE_FINALE) + nChannelVolume[nChannel] = 0; + else + nChannelVolume[nChannel] >>= 2; } - + aChannel[nChannel].SetVolume(m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); } } @@ -1260,7 +1735,7 @@ cSampleManager::StopChannel(uint32 nChannel) void cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream) { - char filename[256]; + char filename[MAX_PATH]; ASSERT( nStream < MAX_STREAMS ); @@ -1318,6 +1793,7 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream) bool cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) { + uint32 position = nPos; char filename[256]; ASSERT( nStream < MAX_STREAMS ); @@ -1330,6 +1806,135 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) aStream[nStream] = NULL; } + if ( nFile == STREAMED_SOUND_RADIO_MP3_PLAYER ) + { + uint32 i = 0; + do { + if(i != 0 || _bIsMp3Active) { + if(++_CurMP3Index >= nNumMP3s) _CurMP3Index = 0; + + _CurMP3Pos = 0; + + tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index); + + if(mp3) { + mp3 = _pMP3List; + if(mp3 == NULL) { + _bIsMp3Active = false; + nFile = 0; + strcat(filename, StreamedNameTable[nFile]); + + CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + ASSERT(stream != NULL); + + aStream[nStream] = stream; + + if (stream->IsOpened()) { + if (stream->Setup()) { + if (position != 0) + stream->SetPosMS(position); + + stream->Start(); + } + + return true; + } else { + delete stream; + aStream[nStream] = NULL; + } + + return false; + } + } + + if (mp3->pLinkPath != NULL) + aStream[nStream] = new CStream(mp3->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream]); + else { + strcpy(filename, _mp3DirectoryPath); + strcat(filename, mp3->aFilename); + + aStream[nStream] = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + } + + if (aStream[nStream]->IsOpened()) { + if (aStream[nStream]->Setup()) { + aStream[nStream]->Start(); + } + + return true; + } else { + delete aStream[nStream]; + aStream[nStream] = NULL; + } + + _bIsMp3Active = false; + continue; + } + if ( nPos > nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] ) + position = 0; + + tMP3Entry *e; + if ( !_GetMP3PosFromStreamPos(&position, &e) ) + { + if ( e == NULL ) + { + nFile = 0; + strcat(filename, StreamedNameTable[nFile]); + CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + ASSERT(stream != NULL); + + aStream[nStream] = stream; + + if (stream->IsOpened()) { + if (stream->Setup()) { + if (position != 0) + stream->SetPosMS(position); + + stream->Start(); + } + + return true; + } else { + delete stream; + aStream[nStream] = NULL; + } + + return false; + } + } + + if (e->pLinkPath != NULL) + aStream[nStream] = new CStream(e->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream]); + else { + strcpy(filename, _mp3DirectoryPath); + strcat(filename, e->aFilename); + + aStream[nStream] = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + } + + if (aStream[nStream]->IsOpened()) { + if (aStream[nStream]->Setup()) { + if (position != 0) + aStream[nStream]->SetPosMS(position); + + aStream[nStream]->Start(); + } + + _bIsMp3Active = true; + return true; + } else { + delete aStream[nStream]; + aStream[nStream] = NULL; + } + + _bIsMp3Active = false; + + } while(++i < nNumMP3s); + + position = 0; + nFile = 0; + } + strcpy(filename, StreamedNameTable[nFile]); CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); @@ -1337,21 +1942,16 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) aStream[nStream] = stream; - if ( stream->IsOpened() ) - { - nStreamLength[nFile] = stream->GetLengthMS(); - if ( stream->Setup() ) - { - if ( nPos != 0 ) - stream->SetPosMS(nPos); - + if ( stream->IsOpened() ) { + if ( stream->Setup() ) { + if (position != 0) + stream->SetPosMS(position); + stream->Start(); } return true; - } - else - { + } else { delete stream; aStream[nStream] = NULL; } @@ -1394,11 +1994,16 @@ cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffect { ASSERT( nStream < MAX_STREAMS ); + float boostMult = 0.0f; + if ( nVolume > MAX_VOLUME ) nVolume = MAX_VOLUME; if ( nPan > MAX_VOLUME ) nPan = MAX_VOLUME; + + if ( MusicManager.GetRadioInCar() == USERTRACK && !MusicManager.CheckForMusicInterruptions() ) + boostMult = m_nMP3BoostVolume / 64.f; nStreamVolume[nStream] = nVolume; nStreamPan [nStream] = nPan; @@ -1408,13 +2013,13 @@ cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffect if ( stream ) { if ( nEffectFlag ) { - if ( nStream == 1 ) // TODO(MIAMI): || nStream == 2 when we have second mission channel? + if ( nStream == 1 || nStream == 2 ) stream->SetVolume(128*nVolume*m_nEffectsVolume >> 14); else stream->SetVolume(m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14); } else - stream->SetVolume(m_nMusicFadeVolume*nVolume*m_nMusicVolume >> 14); + stream->SetVolume((m_nMusicFadeVolume*nVolume*(uint32)(m_nMusicVolume * boostMult + m_nMusicVolume)) >> 14); stream->SetPan(nPan); } @@ -1511,8 +2116,7 @@ cSampleManager::InitialiseSampleBanks(void) void cSampleManager::SetStreamedFileLoopFlag(uint8 nLoopFlag, uint8 nChannel) { - if (m_bInitialised) - nStreamLoopedFlag[nChannel] = nLoopFlag; + nStreamLoopedFlag[nChannel] = nLoopFlag; } #endif diff --git a/src/control/AutoPilot.cpp b/src/control/AutoPilot.cpp index da661b8c..1b14e3d7 100644 --- a/src/control/AutoPilot.cpp +++ b/src/control/AutoPilot.cpp @@ -6,7 +6,8 @@ #include "Curves.h" #include "PathFind.h" -//--MIAMI: done +//--MIAMI: file done + void CAutoPilot::ModifySpeed(float speed) { m_fMaxTrafficSpeed = Max(0.01f, speed); @@ -40,7 +41,6 @@ void CAutoPilot::ModifySpeed(float speed) #endif } -//--MIAMI: done void CAutoPilot::RemoveOnePathNode() { --m_nPathFindNodesCount; @@ -49,7 +49,6 @@ void CAutoPilot::RemoveOnePathNode() } #ifdef COMPATIBLE_SAVES -//--MIAMI: TODO void CAutoPilot::Save(uint8*& buf) { WriteSaveBuf<int32>(buf, m_nCurrentRouteNode); @@ -73,6 +72,9 @@ void CAutoPilot::Save(uint8*& buf) WriteSaveBuf<uint32>(buf, m_nTimeTempAction); WriteSaveBuf<float>(buf, m_fMaxTrafficSpeed); WriteSaveBuf<uint8>(buf, m_nCruiseSpeed); + WriteSaveBuf<uint8>(buf, m_nCruiseSpeedMultiplierType); + SkipSaveBuf(buf, 2); + WriteSaveBuf<float>(buf, m_fCruiseSpeedMultiplier); uint8 flags = 0; if (m_bSlowedDownBecauseOfCars) flags |= BIT(0); if (m_bSlowedDownBecauseOfPeds) flags |= BIT(1); @@ -80,6 +82,7 @@ void CAutoPilot::Save(uint8*& buf) if (m_bStayInFastLane) flags |= BIT(3); if (m_bIgnorePathfinding) flags |= BIT(4); WriteSaveBuf<uint8>(buf, flags); + WriteSaveBuf<uint8>(buf, m_nSwitchDistance); SkipSaveBuf(buf, 2); WriteSaveBuf<float>(buf, m_vecDestinationCoors.x); WriteSaveBuf<float>(buf, m_vecDestinationCoors.y); @@ -89,7 +92,6 @@ void CAutoPilot::Save(uint8*& buf) SkipSaveBuf(buf, 6); } -//--MIAMI: TODO void CAutoPilot::Load(uint8*& buf) { m_nCurrentRouteNode = ReadSaveBuf<int32>(buf); @@ -113,12 +115,16 @@ void CAutoPilot::Load(uint8*& buf) m_nTimeTempAction = ReadSaveBuf<uint32>(buf); m_fMaxTrafficSpeed = ReadSaveBuf<float>(buf); m_nCruiseSpeed = ReadSaveBuf<uint8>(buf); + m_nCruiseSpeedMultiplierType = ReadSaveBuf<uint8>(buf); + SkipSaveBuf(buf, 2); + m_fCruiseSpeedMultiplier = ReadSaveBuf<float>(buf); uint8 flags = ReadSaveBuf<uint8>(buf); m_bSlowedDownBecauseOfCars = !!(flags & BIT(0)); m_bSlowedDownBecauseOfPeds = !!(flags & BIT(1)); m_bStayInCurrentLevel = !!(flags & BIT(2)); m_bStayInFastLane = !!(flags & BIT(3)); m_bIgnorePathfinding = !!(flags & BIT(4)); + m_nSwitchDistance = ReadSaveBuf<uint8>(buf); SkipSaveBuf(buf, 2); m_vecDestinationCoors.x = ReadSaveBuf<float>(buf); m_vecDestinationCoors.y = ReadSaveBuf<float>(buf); diff --git a/src/control/Bridge.cpp b/src/control/Bridge.cpp index 1e63cf30..1a1c03bd 100644 --- a/src/control/Bridge.cpp +++ b/src/control/Bridge.cpp @@ -6,6 +6,8 @@ #include "PathFind.h" #include "Stats.h" +//--MIAMI: file done + CEntity *CBridge::pLiftRoad; CEntity *CBridge::pLiftPart; CEntity *CBridge::pWeight; diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp index 93098d6d..db7d7b66 100644 --- a/src/control/CarCtrl.cpp +++ b/src/control/CarCtrl.cpp @@ -292,7 +292,7 @@ CCarCtrl::GenerateOneRandomCar() break; } } - if (!ThePaths.NewGenerateCarCreationCoors(vecTargetPos.x, vecTargetPos.y, frontX, frontY, + if (!ThePaths.GenerateCarCreationCoors(vecTargetPos.x, vecTargetPos.y, frontX, frontY, preferredDistance, angleLimit, invertAngleLimitTest, &spawnPosition, &curNodeId, &nextNodeId, &positionBetweenNodes, carClass == COPS && pWanted->m_nWantedLevel >= 1)) return; @@ -3228,7 +3228,7 @@ bool CCarCtrl::GenerateOneEmergencyServicesCar(uint32 mi, CVector vecPos) int curNode, nextNode; float posBetweenNodes; while (!created && attempts < 5){ - if (ThePaths.NewGenerateCarCreationCoors(pPlayerPos.x, pPlayerPos.y, 0.707f, 0.707f, + if (ThePaths.GenerateCarCreationCoors(pPlayerPos.x, pPlayerPos.y, 0.707f, 0.707f, 120.0f, -1.0f, true, &spawnPos, &curNode, &nextNode, &posBetweenNodes, false)){ int16 colliding[2]; if (!ThePaths.GetNode(curNode)->bWaterPath) { diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp index 1191e8ad..e44cdda9 100644 --- a/src/control/Darkel.cpp +++ b/src/control/Darkel.cpp @@ -7,6 +7,7 @@ #include "Timer.h" #include "DMAudio.h" #include "Population.h" +#include "Replay.h" #include "Weapon.h" #include "World.h" #include "Stats.h" @@ -14,9 +15,8 @@ #include "Text.h" #include "Vehicle.h" #include "GameLogic.h" -#ifdef FIX_BUGS -#include "Replay.h" -#endif + +//--MIAMI: file done except TODO #define FRENZY_ANY_PED -1 #define FRENZY_ANY_CAR -2 @@ -27,7 +27,8 @@ int32 CDarkel::TimeOfFrenzyStart; int32 CDarkel::WeaponType; int32 CDarkel::AmmoInterruptedWeapon; int32 CDarkel::KillsNeeded; -int8 CDarkel::InterruptedWeapon; +int32 CDarkel::InterruptedWeaponType; +int32 CDarkel::InterruptedWeaponSelected; /* * TODO: Collect timer/kill counter RGBA colors on top like in Hud/Frontend. @@ -61,14 +62,12 @@ CDarkel::CalcFade(uint32 time, uint32 start, uint32 end) return 0; } -// Screen positions taken from VC void CDarkel::DrawMessages() { -#ifdef FIX_BUGS if (CReplay::IsPlayingBack()) return; -#endif + switch (Status) { case KILLFRENZY_ONGOING: { @@ -77,8 +76,8 @@ CDarkel::DrawMessages() CFont::SetCentreSize(SCREEN_SCALE_FROM_RIGHT(30.0f)); CFont::SetCentreOn(); CFont::SetPropOn(); - uint32 timePassedSinceStart = CTimer::GetTimeInMilliseconds() - CDarkel::TimeOfFrenzyStart; - if (CDarkel::bStandardSoundAndMessages) { + uint32 timePassedSinceStart = CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart; + if (bStandardSoundAndMessages) { if (timePassedSinceStart >= 3000 && timePassedSinceStart < 11000) { CFont::SetScale(SCREEN_SCALE_X(1.3f), SCREEN_SCALE_Y(1.3f)); CFont::SetJustifyOff(); @@ -103,8 +102,8 @@ CDarkel::DrawMessages() CFont::SetCentreOff(); CFont::SetRightJustifyOn(); CFont::SetFontStyle(FONT_HEADING); - if (CDarkel::TimeLimit >= 0) { - uint32 timeLeft = CDarkel::TimeLimit - (CTimer::GetTimeInMilliseconds() - CDarkel::TimeOfFrenzyStart); + if (TimeLimit >= 0) { + uint32 timeLeft = TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart); sprintf(gString, "%d:%02d", timeLeft / 60000, timeLeft % 60000 / 1000); AsciiToUnicode(gString, gUString); if (timeLeft > 4000 || CTimer::GetFrameCounter() & 1) { @@ -114,7 +113,7 @@ CDarkel::DrawMessages() CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(34.0f), SCREEN_SCALE_Y(108.0f), gUString); } } - sprintf(gString, "%d", (CDarkel::KillsNeeded >= 0 ? CDarkel::KillsNeeded : 0)); + sprintf(gString, "%d", (KillsNeeded >= 0 ? KillsNeeded : 0)); AsciiToUnicode(gString, gUString); CFont::SetColor(CRGBA(0, 0, 0, 255)); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(144.0f), gUString); @@ -124,9 +123,9 @@ CDarkel::DrawMessages() } case KILLFRENZY_PASSED: { - if (CDarkel::bStandardSoundAndMessages) { - uint32 timePassedSinceStart = CTimer::GetTimeInMilliseconds() - CDarkel::TimeOfFrenzyStart; - if (CTimer::GetTimeInMilliseconds() - CDarkel::TimeOfFrenzyStart < 5000) { + if (bStandardSoundAndMessages) { + uint32 timePassedSinceStart = CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart; + if (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart < 5000) { CFont::SetBackgroundOff(); CFont::SetCentreSize(SCREEN_SCALE_FROM_RIGHT(20.0f)); CFont::SetCentreOn(); @@ -186,7 +185,20 @@ CDarkel::RegisterCarBlownUpByPlayer(CVehicle *vehicle) } } RegisteredKills[vehicle->GetModelIndex()]++; - CStats::CarsExploded++; + switch (vehicle->GetVehicleAppearance()) { + case VEHICLE_APPEARANCE_CAR: + case VEHICLE_APPEARANCE_BIKE: + CStats::CarsExploded++;; + break; + case VEHICLE_APPEARANCE_HELI: + case VEHICLE_APPEARANCE_PLANE: + CStats::HelisDestroyed++; + break; + case VEHICLE_APPEARANCE_BOAT: + CStats::BoatsExploded++; + break; + } + } void @@ -245,23 +257,7 @@ CDarkel::ResetOnPlayerDeath() Status = KILLFRENZY_FAILED; TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); - eWeaponType fixedWeapon; - if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) - fixedWeapon = WEAPONTYPE_UZI; - else - fixedWeapon = (eWeaponType)WeaponType; - - CPlayerPed *player = FindPlayerPed(); - if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { - player->m_nSelectedWepSlot = InterruptedWeapon; - player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal = CDarkel::AmmoInterruptedWeapon; - } - - if (FindPlayerVehicle()) { - player->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nModelId); - player->m_currentWeapon = player->m_nSelectedWepSlot; - player->MakeChangesForNewWeapon(player->m_currentWeapon); - } + DealWithWeaponChangeAtEndOfFrenzy(); } void @@ -298,16 +294,19 @@ CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 mode CPlayerPed *player = FindPlayerPed(); if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { - InterruptedWeapon = player->m_currentWeapon; - player->GiveWeapon(fixedWeapon, 0); + InterruptedWeaponSelected = player->GetWeapon()->m_eWeaponType; + player->RemoveWeaponAnims(InterruptedWeaponSelected, -1000.0f); + InterruptedWeaponType = player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_eWeaponType; AmmoInterruptedWeapon = player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal; + if (InterruptedWeaponType) + CModelInfo::GetModelInfo(CWeaponInfo::GetWeaponInfo((eWeaponType)InterruptedWeaponType)->m_nModelId)->AddRef(); player->GiveWeapon(fixedWeapon, 30000); - player->m_nSelectedWepSlot = player->GetWeaponSlot(fixedWeapon); + player->SetCurrentWeapon(fixedWeapon); player->MakeChangesForNewWeapon(player->m_nSelectedWepSlot); if (FindPlayerVehicle()) { - player->m_currentWeapon = player->m_nSelectedWepSlot; - player->GetWeapon()->m_nAmmoInClip = Min(player->GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition); + player->SetCurrentWeapon(FindPlayerPed()->m_nSelectedWepSlot); + player->SetAmmo(fixedWeapon, Min(player->GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition)); player->ClearWeaponTarget(); } } @@ -343,24 +342,7 @@ CDarkel::Update() CPopulation::m_AllRandomPedsThisType = -1; Status = KILLFRENZY_FAILED; TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); - - eWeaponType fixedWeapon; - if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) - fixedWeapon = WEAPONTYPE_UZI; - else - fixedWeapon = (eWeaponType)WeaponType; - - CPlayerPed *player = FindPlayerPed(); - if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { - player->m_nSelectedWepSlot = InterruptedWeapon; - player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal = CDarkel::AmmoInterruptedWeapon; - } - - if (FindPlayerVehicle()) { - player->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nModelId); - player->m_currentWeapon = player->m_nSelectedWepSlot; - player->MakeChangesForNewWeapon(player->m_currentWeapon); - } + DealWithWeaponChangeAtEndOfFrenzy(); if (bStandardSoundAndMessages) DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_FAILED, 0); @@ -377,25 +359,50 @@ CDarkel::Update() FindPlayerPed()->m_pWanted->SetWantedLevel(0); - eWeaponType fixedWeapon; - if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) - fixedWeapon = WEAPONTYPE_UZI; - else - fixedWeapon = (eWeaponType)WeaponType; - - CPlayerPed* player = FindPlayerPed(); - if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { - player->m_nSelectedWepSlot = InterruptedWeapon; - player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal = CDarkel::AmmoInterruptedWeapon; - } - - if (FindPlayerVehicle()) { - player->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nModelId); - player->m_currentWeapon = player->m_nSelectedWepSlot; - player->MakeChangesForNewWeapon(player->m_currentWeapon); - } + DealWithWeaponChangeAtEndOfFrenzy(); if (bStandardSoundAndMessages) DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_PASSED, 0); } } + +void +CDarkel::DealWithWeaponChangeAtEndOfFrenzy() +{ + eWeaponType fixedWeapon; + if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) + fixedWeapon = WEAPONTYPE_UZI; + else + fixedWeapon = (eWeaponType)WeaponType; + + if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS && InterruptedWeaponType) + CModelInfo::GetModelInfo(CWeaponInfo::GetWeaponInfo((eWeaponType)InterruptedWeaponType)->m_nModelId)->RemoveRef(); + + if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { + int slot = CWeaponInfo::GetWeaponInfo(fixedWeapon)->m_nWeaponSlot; + FindPlayerPed()->RemoveWeaponModel(FindPlayerPed()->GetWeapon(slot).GetInfo()->m_nModelId); + FindPlayerPed()->GetWeapon(slot).m_eWeaponType = WEAPONTYPE_UNARMED; + FindPlayerPed()->GetWeapon(slot).m_nAmmoTotal = 0; + FindPlayerPed()->GetWeapon(slot).m_nAmmoInClip = 0; + FindPlayerPed()->GetWeapon(slot).m_eWeaponState = WEAPONSTATE_READY; + FindPlayerPed()->RemoveWeaponAnims(fixedWeapon, -1000.0f); + CModelInfo::GetModelInfo(CWeaponInfo::GetWeaponInfo(fixedWeapon)->m_nModelId)->RemoveRef(); + } + + CPlayerPed* player = FindPlayerPed(); + if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { + player->m_nSelectedWepSlot = CWeaponInfo::GetWeaponInfo((eWeaponType)InterruptedWeaponSelected)->m_nWeaponSlot; + player->GiveWeapon((eWeaponType)InterruptedWeaponType, AmmoInterruptedWeapon, true); + } + + if (FindPlayerVehicle()) { + player->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nModelId); + if (FindPlayerPed()->GetWeapon(WEAPONSLOT_SUBMACHINEGUN).m_eWeaponType) + FindPlayerPed()->m_nSelectedWepSlot = WEAPONSLOT_SUBMACHINEGUN; + else + FindPlayerPed()->m_nSelectedWepSlot = WEAPONSLOT_UNARMED; + player->SetCurrentWeapon(FindPlayerPed()->m_nSelectedWepSlot); + player->MakeChangesForNewWeapon(player->m_currentWeapon); + //player->RemoveDriveByAnims(); // TODO(MIAMI) + } +} diff --git a/src/control/Darkel.h b/src/control/Darkel.h index 0f5c2329..91955479 100644 --- a/src/control/Darkel.h +++ b/src/control/Darkel.h @@ -23,7 +23,8 @@ private: static int32 WeaponType; static int32 AmmoInterruptedWeapon; static int32 KillsNeeded; - static int8 InterruptedWeapon; + static int32 InterruptedWeaponType; + static int32 InterruptedWeaponSelected; static bool bStandardSoundAndMessages; static bool bNeedHeadShot; static bool bProperKillFrenzy; @@ -49,5 +50,6 @@ public: static void ResetOnPlayerDeath(); static void StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot); static void Update(); + static void DealWithWeaponChangeAtEndOfFrenzy(); }; diff --git a/src/control/GameLogic.cpp b/src/control/GameLogic.cpp index 573720be..98209c85 100644 --- a/src/control/GameLogic.cpp +++ b/src/control/GameLogic.cpp @@ -45,9 +45,10 @@ CVector CGameLogic::ShortCutDropOffForMission; float CGameLogic::ShortCutDropOffOrientationForMission; bool CGameLogic::MissionDropOffReadyToBeUsed; -//--MIAMI: file done except TODO +//--MIAMI: file done #define SHORTCUT_TAXI_COST (9) +#define TOTAL_BUSTED_AUDIO (28) void CGameLogic::InitAtStartOfGame() @@ -196,7 +197,7 @@ CGameLogic::Update() sprintf(name, pPlayerInfo.m_nCurrentBustedAudio >= 10 ? "bust_%d" : "bust_0%d", pPlayerInfo.m_nCurrentBustedAudio); DMAudio.ClearMissionAudio(0); DMAudio.PreloadMissionAudio(0, name); - pPlayerInfo.m_nCurrentBustedAudio = pPlayerInfo.m_nCurrentBustedAudio % 28 + 1; // enum? const? TODO + pPlayerInfo.m_nCurrentBustedAudio = pPlayerInfo.m_nCurrentBustedAudio % TOTAL_BUSTED_AUDIO + 1; } } if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 4000 && diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp index dc07d142..44a961c9 100644 --- a/src/control/Garages.cpp +++ b/src/control/Garages.cpp @@ -26,6 +26,8 @@ #include "Wanted.h" #include "World.h" +//--MIAMI: file done + #define CRUSHER_GARAGE_X1 (1135.5f) #define CRUSHER_GARAGE_Y1 (57.0f) #define CRUSHER_GARAGE_Z1 (-1.0f) @@ -236,7 +238,6 @@ int16 CGarages::AddOne(float X1, float Y1, float Z1, float X2, float Y2, float X pGarage->m_nTimeToStartAction = 0; pGarage->field_2 = false; pGarage->m_nTargetModelIndex = targetId; - pGarage->field_96 = nil; pGarage->m_bCollectedCarsState = 0; pGarage->m_bDeactivated = false; pGarage->m_bResprayHappened = false; @@ -2141,11 +2142,11 @@ void CGarages::SetAllDoorsBackToOriginalHeight() } } -// TODO(MIAMI) void CGarages::Save(uint8 * buf, uint32 * size) { -INITSAVEBUF - *size = (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + TOTAL_HIDEOUT_GARAGES * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage)); +//INITSAVEBUF + *size = 7876; // for some reason it's not actual size again + //*size = (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + TOTAL_HIDEOUT_GARAGES * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage)); CloseHideOutGaragesBeforeSave(); WriteSaveBuf(buf, NumGarages); WriteSaveBuf(buf, (uint32)BombsAreFree); @@ -2163,7 +2164,7 @@ INITSAVEBUF } for (int i = 0; i < NUM_GARAGES; i++) WriteSaveBuf(buf, aGarages[i]); -VALIDATESAVEBUF(*size); +//VALIDATESAVEBUF(*size); } const CStoredCar &CStoredCar::operator=(const CStoredCar & other) @@ -2185,11 +2186,11 @@ const CStoredCar &CStoredCar::operator=(const CStoredCar & other) return *this; } -//TODO(MIAMI) void CGarages::Load(uint8* buf, uint32 size) { -INITSAVEBUF - assert(size == (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + TOTAL_HIDEOUT_GARAGES * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage))); +//INITSAVEBUF + assert(size = 7876); + //assert(size == (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + TOTAL_HIDEOUT_GARAGES * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage))); CloseHideOutGaragesBeforeSave(); NumGarages = ReadSaveBuf<uint32>(buf); BombsAreFree = ReadSaveBuf<uint32>(buf); @@ -2210,7 +2211,6 @@ INITSAVEBUF aGarages[i].m_pDoor1 = nil; aGarages[i].m_pDoor2 = nil; aGarages[i].m_pTarget = nil; - aGarages[i].field_96 = nil; aGarages[i].m_bRecreateDoorOnNextRefresh = true; aGarages[i].RefreshDoorPointers(true); if (aGarages[i].m_eGarageType == GARAGE_CRUSHER) @@ -2218,7 +2218,7 @@ INITSAVEBUF else aGarages[i].UpdateDoorsHeight(); } -VALIDATESAVEBUF(size); +//VALIDATESAVEBUF(size); MessageEndTime = 0; bCamShouldBeOutisde = false; diff --git a/src/control/Garages.h b/src/control/Garages.h index 43f40261..04c01719 100644 --- a/src/control/Garages.h +++ b/src/control/Garages.h @@ -132,7 +132,6 @@ class CGarage uint32 m_nTimeToStartAction; uint8 m_bCollectedCarsState; CVehicle *m_pTarget; - void* field_96; // unused CStoredCar m_sStoredCar; // not needed void OpenThisGarage(); diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp index e85893e6..14aead04 100644 --- a/src/control/PathFind.cpp +++ b/src/control/PathFind.cpp @@ -8,6 +8,8 @@ #include "Lines.h" // for debug #include "PathFind.h" +//--MIAMI: file done except mobile unused function + bool gbShowPedPaths; bool gbShowCarPaths; bool gbShowCarPathsLinks; @@ -226,7 +228,6 @@ CPedPath::AddBlockade(CEntity *pEntity, CPedPathNode(*pathNodes)[40], CVector *p } } -//--MIAMI: done // Make sure all externals link TO an internal void CPathInfoForObject::SwapConnectionsToBeRightWayRound(void) @@ -246,7 +247,6 @@ CPathInfoForObject::SwapConnectionsToBeRightWayRound(void) } } -//--MIAMI: done void CPathFind::Init(void) { @@ -263,7 +263,6 @@ CPathFind::Init(void) m_pathNodes[i].distance = MAX_DIST; } -//--MIAMI: done void CPathFind::AllocatePathFindInfoMem(int16 numPathGroups) { @@ -294,14 +293,12 @@ CPathFind::AllocatePathFindInfoMem(int16 numPathGroups) NumDetachedCarNodeGroups = 0; } -//--MIAMI: done void CPathFind::RegisterMapObject(CTreadable *mapObject) { m_mapObjects[m_numMapObjects++] = mapObject; } -//--MIAMI: done void CPathFind::StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, float width, bool crossing, uint8 spawnRate) { @@ -329,7 +326,6 @@ CPathFind::StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, InfoForTilePeds[id*12].SwapConnectionsToBeRightWayRound(); } -//--MIAMI: done void CPathFind::StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, float width, int8 numLeft, int8 numRight, bool disabled, bool betweenLevels, uint8 speedLimit, bool roadBlock, bool waterPath, uint8 spawnRate) @@ -358,7 +354,6 @@ CPathFind::StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, InfoForTileCars[id*12].SwapConnectionsToBeRightWayRound(); } -//--MIAMI: done void CPathFind::StoreDetachedNodeInfoPed(int32 node, int8 type, int32 next, float x, float y, float z, float width, bool crossing, bool disabled, bool betweenLevels, uint8 spawnRate) @@ -392,7 +387,6 @@ CPathFind::StoreDetachedNodeInfoPed(int32 node, int8 type, int32 next, float x, } } -//--MIAMI: done void CPathFind::StoreDetachedNodeInfoCar(int32 node, int8 type, int32 next, float x, float y, float z, float width, int8 numLeft, int8 numRight, bool disabled, bool betweenLevels, uint8 speedLimit, bool roadBlock, bool waterPath, uint8 spawnRate, bool onlySmallBoats) @@ -426,7 +420,6 @@ CPathFind::StoreDetachedNodeInfoCar(int32 node, int8 type, int32 next, float x, } } -//--MIAMI: done void CPathFind::CalcNodeCoors(float x, float y, float z, int id, CVector *out) { @@ -437,7 +430,6 @@ CPathFind::CalcNodeCoors(float x, float y, float z, int id, CVector *out) *out = m_mapObjects[id]->GetMatrix() * pos; } -//--MIAMI: done bool CPathFind::LoadPathFindData(void) { @@ -445,7 +437,6 @@ CPathFind::LoadPathFindData(void) return false; } -//--MIAMI: done void CPathFind::PreparePathData(void) { @@ -536,7 +527,6 @@ CPathFind::PreparePathData(void) printf("Done with PreparePathData\n"); } -//--MIAMI: done /* String together connected nodes in a list by a flood fill algorithm */ void CPathFind::CountFloodFillGroups(uint8 type) @@ -608,7 +598,6 @@ CPathFind::CountFloodFillGroups(uint8 type) int32 TempListLength; -//--MIAMI: done void CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoForObject *objectpathinfo, float maxdist, CPathInfoForObject *detachednodes, int numDetached) @@ -813,7 +802,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor m_carPathLinks[m_numCarPathLinks].dirY = tempnodes[j].dirY; m_carPathLinks[m_numCarPathLinks].x = tempnodes[j].pos.x*8.0f; m_carPathLinks[m_numCarPathLinks].y = tempnodes[j].pos.y*8.0f; - m_carPathLinks[m_numCarPathLinks].flag1 = false; + m_carPathLinks[m_numCarPathLinks].trafficLightDirection = false; m_carPathLinks[m_numCarPathLinks].width = tempnodes[j].width; m_carPathLinks[m_numCarPathLinks].pathNodeIndex = i; m_carPathLinks[m_numCarPathLinks].numLeftLanes = tempnodes[j].numLeftLanes; @@ -892,7 +881,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor m_carPathLinks[m_numCarPathLinks].dirY = dy*100.0f; m_carPathLinks[m_numCarPathLinks].x = posx*8.0f; m_carPathLinks[m_numCarPathLinks].y = posy*8.0f; - m_carPathLinks[m_numCarPathLinks].flag1 = false; + m_carPathLinks[m_numCarPathLinks].trafficLightDirection = false; m_carPathLinks[m_numCarPathLinks].width = width; m_carPathLinks[m_numCarPathLinks].pathNodeIndex = i; m_carPathLinks[m_numCarPathLinks].numLeftLanes = -1; @@ -1028,7 +1017,6 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor delete[] mapObjIndices; } -//--MIAMI: done float CPathFind::CalcRoadDensity(float x, float y) { @@ -1051,7 +1039,6 @@ CPathFind::CalcRoadDensity(float x, float y) return density/2500.0f; } -//--MIAMI: done bool CPathFind::TestForPedTrafficLight(CPathNode *n1, CPathNode *n2) { @@ -1062,7 +1049,6 @@ CPathFind::TestForPedTrafficLight(CPathNode *n1, CPathNode *n2) return false; } -//--MIAMI: done bool CPathFind::TestCrossesRoad(CPathNode *n1, CPathNode *n2) { @@ -1073,7 +1059,6 @@ CPathFind::TestCrossesRoad(CPathNode *n1, CPathNode *n2) return false; } -//--MIAMI: done void CPathFind::AddNodeToList(CPathNode *node, int32 listId) { @@ -1086,7 +1071,6 @@ CPathFind::AddNodeToList(CPathNode *node, int32 listId) node->distance = listId; } -//--MIAMI: done void CPathFind::RemoveNodeFromList(CPathNode *node) { @@ -1095,7 +1079,6 @@ CPathFind::RemoveNodeFromList(CPathNode *node) node->GetNext()->SetPrev(node->GetPrev()); } -//--MIAMI: done void CPathFind::RemoveBadStartNode(CVector pos, CPathNode **nodes, int16 *n) { @@ -1123,7 +1106,6 @@ CPathFind::SetLinksBridgeLights(float x1, float x2, float y1, float y2, bool ena } #endif -//--MIAMI: done void CPathFind::SwitchOffNodeAndNeighbours(int32 nodeId, bool disable) { @@ -1139,7 +1121,6 @@ CPathFind::SwitchOffNodeAndNeighbours(int32 nodeId, bool disable) } } -//--MIAMI: done void CPathFind::SwitchRoadsOffInArea(float x1, float x2, float y1, float y2, float z1, float z2, bool disable) { @@ -1155,7 +1136,6 @@ CPathFind::SwitchRoadsOffInArea(float x1, float x2, float y1, float y2, float z1 } } -//--MIAMI: done void CPathFind::SwitchPedRoadsOffInArea(float x1, float x2, float y1, float y2, float z1, float z2, bool disable) { @@ -1171,7 +1151,6 @@ CPathFind::SwitchPedRoadsOffInArea(float x1, float x2, float y1, float y2, float } } -//--MIAMI: unused (still needed for script here) void CPathFind::SwitchRoadsInAngledArea(float x1, float y1, float z1, float x2, float y2, float z2, float length, uint8 type, uint8 mode) { @@ -1223,7 +1202,6 @@ CPathFind::SwitchRoadsInAngledArea(float x1, float y1, float z1, float x2, float } } -//--MIAMI: unused (still needed for script here) void CPathFind::MarkRoadsBetweenLevelsNodeAndNeighbours(int32 nodeId) { @@ -1239,7 +1217,6 @@ CPathFind::MarkRoadsBetweenLevelsNodeAndNeighbours(int32 nodeId) } } -//--MIAMI: unused (still needed for script here) void CPathFind::MarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2) { @@ -1254,7 +1231,6 @@ CPathFind::MarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, } } -//--MIAMI: unused (still needed for script here) void CPathFind::PedMarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2) { @@ -1269,9 +1245,8 @@ CPathFind::PedMarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y } } -//--MIAMI: done int32 -CPathFind::FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled, bool ignoreBetweenLevels, bool ignoreFlagB4, bool bWaterPath) +CPathFind::FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled, bool ignoreBetweenLevels, bool ignoreSelected, bool bWaterPath) { int i; int firstNode, lastNode; @@ -1293,7 +1268,7 @@ CPathFind::FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bo for(i = firstNode; i < lastNode; i++){ if(ignoreDisabled && m_pathNodes[i].bDisabled) continue; if(ignoreBetweenLevels && m_pathNodes[i].bBetweenLevels) continue; - if(ignoreFlagB4 && m_pathNodes[i].flagB4) continue; + if(ignoreSelected && m_pathNodes[i].bSelected) continue; if(bWaterPath != m_pathNodes[i].bWaterPath) continue; dist = Abs(m_pathNodes[i].GetX() - coors.x) + Abs(m_pathNodes[i].GetY() - coors.y) + @@ -1306,7 +1281,6 @@ CPathFind::FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bo return closestDist < distLimit ? closestNode : -1; } -//--MIAMI: done int32 CPathFind::FindNodeClosestToCoorsFavourDirection(CVector coors, uint8 type, float dirX, float dirY) { @@ -1345,7 +1319,102 @@ CPathFind::FindNodeClosestToCoorsFavourDirection(CVector coors, uint8 type, floa return closestNode; } -//--MIAMI: done +void +CPathFind::FindNodePairClosestToCoors(CVector coors, uint8 type, int* node1, int* node2, float* angle, float minDist, float maxDist, bool ignoreDisabled, bool ignoreBetweenLevels, bool bWaterPath) +{ + int i, j; + int firstNode, lastNode, connectedNode; + float dist; + float closestDist = 10000.0f; + int closestNode = 0, closestConnectedNode = 0; + + switch (type) { + case PATH_CAR: + firstNode = 0; + lastNode = m_numCarPathNodes; + break; + case PATH_PED: + firstNode = m_numCarPathNodes; + lastNode = m_numPathNodes; + break; + } + + for (i = firstNode; i < lastNode; i++) { + if (ignoreDisabled && m_pathNodes[i].bDisabled) continue; + if (ignoreBetweenLevels && m_pathNodes[i].bBetweenLevels) continue; + if (bWaterPath != m_pathNodes[i].bWaterPath) continue; + dist = Abs(m_pathNodes[i].GetX() - coors.x) + + Abs(m_pathNodes[i].GetY() - coors.y) + + 3.0f * Abs(m_pathNodes[i].GetZ() - coors.z); + if (dist < closestDist) { + for (j = 0; j < m_pathNodes[i].numLinks; j++) { + connectedNode = ConnectedNode(m_pathNodes[i].firstLink + j); + if (ignoreDisabled && m_pathNodes[connectedNode].bDisabled) continue; + if (ignoreBetweenLevels && m_pathNodes[connectedNode].bBetweenLevels) continue; + if (bWaterPath != m_pathNodes[connectedNode].bWaterPath) continue; + if ((m_pathNodes[connectedNode].GetPosition() - m_pathNodes[i].GetPosition()).Magnitude() > minDist) { + closestDist = dist; + closestNode = i; + closestConnectedNode = connectedNode; + } + } + } + } + if (closestDist < maxDist) { + *node1 = closestNode; + *node2 = closestConnectedNode; + CVector dir(m_pathNodes[*node2].GetX() - m_pathNodes[*node1].GetX(), m_pathNodes[*node2].GetY() - m_pathNodes[*node1].GetY(), 0.0f); + dir.Normalise(); + *angle = RADTODEG(Atan2(-dir.x, dir.y)); + } + else { + *node1 = -1; + *node2 = -1; + *angle = 0.0f; + } +} + +int32 +CPathFind::FindNthNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled, bool ignoreBetweenLevels, int N, bool bWaterPath) +{ + int i; + int firstNode, lastNode; + switch (type) { + case PATH_CAR: + firstNode = 0; + lastNode = m_numCarPathNodes; + break; + case PATH_PED: + firstNode = m_numCarPathNodes; + lastNode = m_numPathNodes; + break; + } + for (i = firstNode; i < lastNode; i++) + m_pathNodes[i].bSelected = false; + + for (; N > 0; N--) { + i = FindNodeClosestToCoors(coors, type, distLimit, ignoreDisabled, ignoreBetweenLevels, true, bWaterPath); + if (i < 0) + return -1; + m_pathNodes[i].bSelected = true; + } + return FindNodeClosestToCoors(coors, type, distLimit, ignoreDisabled, ignoreBetweenLevels, true, bWaterPath); +} + +CVector +CPathFind::FindNodeCoorsForScript(int32 id) +{ + // the point is to return valid position in case there is a divider in the middle of the road + if (!m_pathNodes[id].HasDivider() || m_pathNodes[id].numLinks == 0) + return m_pathNodes[id].GetPosition(); + CVector2D dir(m_pathNodes[ConnectedNode(m_pathNodes[id].firstLink)].GetX() - m_pathNodes[id].GetX(), + m_pathNodes[ConnectedNode(m_pathNodes[id].firstLink)].GetY() - m_pathNodes[id].GetY()); + dir.Normalise(); + if (dir.x < 0) + dir = -dir; + return m_pathNodes[id].GetPosition() + CVector(-dir.x, dir.y, 0.0f) * (LANE_WIDTH / 2 + m_pathNodes[id].GetDividerWidth()); +} + float CPathFind::FindNodeOrientationForCarPlacement(int32 nodeId) { @@ -1357,7 +1426,6 @@ CPathFind::FindNodeOrientationForCarPlacement(int32 nodeId) return RADTODEG(dir.Heading()); } -//--MIAMI: unused (still needed for script here) float CPathFind::FindNodeOrientationForCarPlacementFacingDestination(int32 nodeId, float x, float y, bool towards) { @@ -1401,10 +1469,8 @@ CPathFind::FindNodeOrientationForCarPlacementFacingDestination(int32 nodeId, flo return RADTODEG(dir.Heading()); } -// no "New" in MIAMI -//--MIAMI: TODO bool -CPathFind::NewGenerateCarCreationCoors(float x, float y, float dirX, float dirY, float spawnDist, float angleLimit, bool forward, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, bool ignoreDisabled) +CPathFind::GenerateCarCreationCoors(float x, float y, float dirX, float dirY, float spawnDist, float angleLimit, bool forward, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, bool ignoreDisabled) { int i, j; int node1, node2; @@ -1457,67 +1523,83 @@ CPathFind::NewGenerateCarCreationCoors(float x, float y, float dirX, float dirY, return false; } -//--MIAMI: TODO bool CPathFind::GeneratePedCreationCoors(float x, float y, float minDist, float maxDist, float minDistOffScreen, float maxDistOffScreen, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, CMatrix *camMatrix) { int i; int node1, node2; + float node1_dist, node2_dist; + static int32 node_cnt; if(m_numPedPathNodes == 0) return false; - for(i = 0; i < 400; i++){ - node1 = m_numCarPathNodes + CGeneral::GetRandomNumber() % m_numPedPathNodes; - if(DistanceSqr2D(m_pathNodes[node1].GetPosition(), x, y) < sq(maxDist+30.0f)){ - if(m_pathNodes[node1].numLinks == 0) - continue; - int link = m_pathNodes[node1].firstLink + CGeneral::GetRandomNumber() % m_pathNodes[node1].numLinks; - if(ConnectionCrossesRoad(link)) - continue; - node2 = ConnectedNode(link); - if(m_pathNodes[node1].bDisabled || m_pathNodes[node2].bDisabled) - continue; + for(i = 0; i < 230; i++){ + if (node_cnt++ >= m_numPedPathNodes) + node_cnt = 0; + node1 = node_cnt + m_numCarPathNodes; + node1_dist = Distance2D(m_pathNodes[node1].GetPosition(), x, y); + if(node1_dist < maxDist+30.0f){ + if(m_pathNodes[node1].numLinks != 0) + break; + } + } + if (i >= 230) + return false; - float f2 = (CGeneral::GetRandomNumber()&0xFF)/256.0f; - float f1 = 1.0f - f2; - *pPositionBetweenNodes = f2; - CVector pos = m_pathNodes[node1].GetPosition()*f1 + m_pathNodes[node2].GetPosition()*f2; - if(Distance2D(pos, x, y) < maxDist+20.0f){ - pos.x += ((CGeneral::GetRandomNumber()&0xFF)-128)*0.01f; - pos.y += ((CGeneral::GetRandomNumber()&0xFF)-128)*0.01f; - float dist = Distance2D(pos, x, y); - - bool visible; - if(camMatrix) - visible = TheCamera.IsSphereVisible(pos, 2.0f, camMatrix); - else - visible = TheCamera.IsSphereVisible(pos, 2.0f); - if(!visible){ - minDist = minDistOffScreen; - maxDist = maxDistOffScreen; - } - if(minDist < dist && dist < maxDist){ - *pNode1 = node1; - *pNode2 = node2; - *pPosition = pos; - - bool found; - float groundZ = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z+2.0f, &found); - if(!found) - return false; - if(Abs(groundZ - pos.z) > 3.0f) - return false; - pPosition->z = groundZ; - return true; - } + for(i = 0; i < m_pathNodes[node1].numLinks; i++){ + int link = m_pathNodes[node1].firstLink + i; + if(ConnectionCrossesRoad(link)) + continue; + node2 = ConnectedNode(link); + if(m_pathNodes[node1].bDisabled || m_pathNodes[node2].bDisabled) + continue; + node2_dist = Distance2D(m_pathNodes[node2].GetPosition(), x, y); + if ((node1_dist < maxDist || node2_dist < maxDist) && (node1_dist > minDistOffScreen || node2_dist > minDistOffScreen)) + break; + } + if(i >= m_pathNodes[node1].numLinks) + return false; + + for(i = 0; i < 5; i++){ + float f2 = (CGeneral::GetRandomNumber()&0xFF)/256.0f; + float f1 = 1.0f - f2; + *pPositionBetweenNodes = f2; + CVector pos = m_pathNodes[node1].GetPosition()*f1 + m_pathNodes[node2].GetPosition()*f2; + if(Distance2D(pos, x, y) < maxDist+20.0f){ + pos.x += ((CGeneral::GetRandomNumber()&0xFF)-128)*0.01f; + pos.y += ((CGeneral::GetRandomNumber()&0xFF)-128)*0.01f; + float dist = Distance2D(pos, x, y); + + bool visible; + if(camMatrix) + visible = TheCamera.IsSphereVisible(pos, 2.0f, camMatrix); + else + visible = TheCamera.IsSphereVisible(pos, 2.0f); + if(!visible){ + minDist = minDistOffScreen; + maxDist = maxDistOffScreen; + } + if(visible && (minDist < dist && dist < maxDist) || + !visible && (minDistOffScreen < dist && dist < maxDistOffScreen)){ + *pNode1 = node1; + *pNode2 = node2; + *pPosition = pos; + + bool found; + float groundZ = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z+2.0f, &found); + if(!found) + return false; + if(Abs(groundZ - pos.z) > 3.0f) + return false; + pPosition->z = groundZ; + return true; } } } return false; } -//--MIAMI: done void CPathFind::FindNextNodeWandering(uint8 type, CVector coors, CPathNode **lastNode, CPathNode **nextNode, uint8 curDir, uint8 *nextDir) { @@ -1584,7 +1666,6 @@ CPathFind::FindNextNodeWandering(uint8 type, CVector coors, CPathNode **lastNode static CPathNode *apNodesToBeCleared[6525]; -//--MIAMI: done void CPathFind::DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector target, CPathNode **nodes, int16 *pNumNodes, int16 maxNumNodes, CVehicle *vehicle, float *pDist, float distLimit, int32 targetNodeId) { @@ -1676,7 +1757,6 @@ static CPathNode *pNodeList[32]; static int16 DummyResult; static int16 DummyResult2; -//--MIAMI: done bool CPathFind::TestCoorsCloseness(CVector target, uint8 type, CVector start) { @@ -1692,7 +1772,6 @@ CPathFind::TestCoorsCloseness(CVector target, uint8 type, CVector start) return dist < 100.0f; } -//--MIAMI: done void CPathFind::Save(uint8 *buf, uint32 *size) { @@ -1714,7 +1793,6 @@ CPathFind::Save(uint8 *buf, uint32 *size) buf[i/8 + n] &= ~(1 << i%8); } -//--MIAMI: done void CPathFind::Load(uint8 *buf, uint32 size) { diff --git a/src/control/PathFind.h b/src/control/PathFind.h index 820d0b86..acf9929a 100644 --- a/src/control/PathFind.h +++ b/src/control/PathFind.h @@ -52,6 +52,8 @@ public: static void AddNodeToList(CPedPathNode *pNode, int16 index, CPedPathNode *pList); static void AddBlockade(CEntity *pEntity, CPedPathNode(*pathNodes)[40], CVector *pPosition); static void AddBlockadeSectorList(CPtrList& list, CPedPathNode(*pathNodes)[40], CVector *pPosition); + static void AddBuildingBlockade(CEntity*, CPedPathNode(*)[40], CVector*); + static void AddBuildingBlockadeSectorList(CPtrList&, CPedPathNode(*)[40], CVector*); }; struct CPathNode @@ -74,7 +76,7 @@ struct CPathNode uint8 bWaterPath : 1; uint8 bOnlySmallBoats : 1; - uint8 flagB4 : 1; // where is this set? + uint8 bSelected : 1; uint8 speedLimit : 2; //uint8 flagB20 : 1; //uint8 flagB40 : 1; @@ -115,7 +117,7 @@ struct CCarPathLink int8 dirY; int8 numLeftLanes : 3; int8 numRightLanes : 3; - uint8 flag1 : 1; + uint8 trafficLightDirection : 1; uint8 trafficLightType : 2; uint8 bBridgeLights : 1; // at least in LCS... int8 width; @@ -160,6 +162,7 @@ struct CPathInfoForObject uint8 spawnRate : 4; + void CheckIntegrity(void); void SwapConnectionsToBeRightWayRound(void); }; extern CPathInfoForObject *InfoForTileCars; @@ -189,6 +192,14 @@ struct CTempNodeExternal // made up name bool isCross; }; +// from mobile +template<typename T> +class CRoute +{ + T m_node[8]; +}; + + class CPathFind { public: @@ -242,12 +253,14 @@ public: void MarkRoadsBetweenLevelsNodeAndNeighbours(int32 nodeId); void MarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2); void PedMarkRoadsBetweenLevelsInArea(float x1, float x2, float y1, float y2, float z1, float z2); -// TODO(MIAMI): check callers for new arguments - int32 FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled = false, bool ignoreBetweenLevels = false, bool ignoreFlagB4 = false, bool bWaterPath = false); + int32 FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled = false, bool ignoreBetweenLevels = false, bool ignoreSelected = false, bool bWaterPath = false); int32 FindNodeClosestToCoorsFavourDirection(CVector coors, uint8 type, float dirX, float dirY); + void FindNodePairClosestToCoors(CVector coors, uint8 type, int* node1, int* node2, float* angle, float minDist, float maxDist, bool ignoreDisabled = false, bool ignoreBetweenLevels = false, bool bWaterPath = false); + int32 FindNthNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool ignoreDisabled, bool ignoreBetweenLevels, int N, bool bWaterPath = false); + CVector FindNodeCoorsForScript(int32 id); float FindNodeOrientationForCarPlacement(int32 nodeId); float FindNodeOrientationForCarPlacementFacingDestination(int32 nodeId, float x, float y, bool towards); - bool NewGenerateCarCreationCoors(float x, float y, float dirX, float dirY, float spawnDist, float angleLimit, bool forward, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, bool ignoreDisabled = false); + bool GenerateCarCreationCoors(float x, float y, float dirX, float dirY, float spawnDist, float angleLimit, bool forward, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, bool ignoreDisabled = false); bool GeneratePedCreationCoors(float x, float y, float minDist, float maxDist, float minDistOffScreen, float maxDistOffScreen, CVector *pPosition, int32 *pNode1, int32 *pNode2, float *pPositionBetweenNodes, CMatrix *camMatrix); void FindNextNodeWandering(uint8, CVector, CPathNode**, CPathNode**, uint8, uint8*); void DoPathSearch(uint8 type, CVector start, int32 startNodeId, CVector target, CPathNode **nodes, int16 *numNodes, int16 maxNumNodes, CVehicle *vehicle, float *dist, float distLimit, int32 forcedTargetNode); @@ -267,6 +280,16 @@ public: void ConnectionSetTrafficLight(int id) { m_connections[id] |= 0x4000; } void DisplayPathData(void); + + // Following methods are present on mobile but are unused. TODO: implement them + void SavePathFindData(void); + void ComputeRoute(uint8, const CVector&, const CVector&, CRoute<CPathNode*>&); + void RecordNodesClosestToCoors(CVector, uint8, int, CPathNode**, float, bool, bool, bool); + void RecordNodesInCircle(const CVector&, float, uint8, int, CPathNode**, bool, bool, bool, bool); + void ArrangeOneNodeList(CPathInfoForObject*, int16); + void ArrangeNodes(int16); + void RegisterMarker(CVector*); + void Shutdown(void); }; extern CPathFind ThePaths; diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp index 7a9808f6..490be370 100644 --- a/src/control/Pickups.cpp +++ b/src/control/Pickups.cpp @@ -122,11 +122,11 @@ CPickup::GiveUsAPickUpObject(int32 handle) { CObject *object; - if (handle <= 0) object = new CObject(m_eModelIndex, false); - else { + if (handle >= 0) { CPools::MakeSureSlotInObjectPoolIsEmpty(handle); - object = new(handle) CObject(m_eModelIndex, false); - } + object = new (handle) CObject(m_eModelIndex, false); + } else + object = new CObject(m_eModelIndex, false); if (object == nil) return nil; object->ObjectCreatedBy = MISSION_OBJECT; @@ -729,7 +729,7 @@ CPickups::Update() #ifdef CAMERA_PICKUP if ( bPickUpcamActivated ) // taken from PS2 { - float dist = (FindPlayerCoors() - StaticCamCoors).Magnitude2D(); + float dist = Distance2D(StaticCamCoors, FindPlayerCoors()); float mult; if ( dist < 10.0f ) mult = 1.0f - (dist / 10.0f ); @@ -745,8 +745,7 @@ CPickups::Update() TheCamera.TakeControl(FindPlayerVehicle(), CCam::MODE_FIXED, JUMP_CUT, CAMCONTROL_SCRIPT); } - if ( FindPlayerVehicle() != pPlayerVehicle - || (FindPlayerCoors() - StaticCamCoors).Magnitude() > 40.0f + if ( FindPlayerVehicle() != pPlayerVehicle || Distance(StaticCamCoors, FindPlayerCoors()) > 40.0f || ((CTimer::GetTimeInMilliseconds() - StaticCamStartTime) > 60000) ) { TheCamera.RestoreWithJumpCut(); @@ -836,7 +835,7 @@ CPickups::DoPickUpEffects(CEntity *entity) CObject *object = (CObject*)entity; if (object->bPickupObjWithMessage || object->bOutOfStock || object->m_nBonusValue) { - float dist = (TheCamera.GetPosition() - pos).Magnitude(); + float dist = Distance2D(pos, TheCamera.GetPosition()); const float MAXDIST = 12.0f; if (dist < MAXDIST && NumMessages < NUMPICKUPMESSAGES) { @@ -879,7 +878,7 @@ void CPickups::DoMineEffects(CEntity *entity) { const CVector &pos = entity->GetPosition(); - float dist = (TheCamera.GetPosition() - pos).Magnitude(); + float dist = Distance(pos, TheCamera.GetPosition()); const float MAXDIST = 20.0f; if (dist < MAXDIST) { @@ -898,7 +897,7 @@ void CPickups::DoMoneyEffects(CEntity *entity) { const CVector &pos = entity->GetPosition(); - float dist = (TheCamera.GetPosition() - pos).Magnitude(); + float dist = Distance(pos, TheCamera.GetPosition()); const float MAXDIST = 20.0f; if (dist < MAXDIST) { @@ -917,7 +916,7 @@ void CPickups::DoCollectableEffects(CEntity *entity) { const CVector &pos = entity->GetPosition(); - float dist = (TheCamera.GetPosition() - pos).Magnitude(); + float dist = Distance(pos, TheCamera.GetPosition()); const float MAXDIST = 14.0f; if (dist < MAXDIST) { diff --git a/src/control/Record.cpp b/src/control/Record.cpp index 5e6c7cdb..9b4a21fc 100644 --- a/src/control/Record.cpp +++ b/src/control/Record.cpp @@ -10,6 +10,8 @@ #include "VehicleModelInfo.h" #include "World.h" +//--MIAMI: file done + uint16 CRecordDataForGame::RecordingState; void CRecordDataForGame::Init(void) diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index 0aec58bb..4fdd3439 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -53,6 +53,8 @@ #include "Fluff.h" #include "WaterCreatures.h" +//--MIAMI: file done except TODO + uint8 CReplay::Mode; CAddressInReplayBuffer CReplay::Record; CAddressInReplayBuffer CReplay::Playback; @@ -160,7 +162,6 @@ static void(*CBArray[])(CAnimBlendAssociation*, void*) = &CPed::PedAnimShuffleCB, &CPed::DeleteSunbatheIdleAnimCB, &StartTalkingOnMobileCB, &FinishTalkingOnMobileCB }; -// --MIAMI: Done static uint8 FindCBFunctionID(void(*f)(CAnimBlendAssociation*, void*)) { for (int i = 0; i < sizeof(CBArray) / sizeof(*CBArray); i++){ @@ -171,13 +172,11 @@ static uint8 FindCBFunctionID(void(*f)(CAnimBlendAssociation*, void*)) return 0; } -// --MIAMI: Done static void(*FindCBFunction(uint8 id))(CAnimBlendAssociation*, void*) { return CBArray[id]; } -// --MIAMI: Done static void ApplyPanelDamageToCar(uint32 panels, CAutomobile* vehicle, bool flying) { if(vehicle->Damage.GetPanelStatus(VEHPANEL_FRONT_LEFT) != CDamageManager::GetPanelStatus(panels, VEHPANEL_FRONT_LEFT)){ @@ -210,7 +209,6 @@ static void ApplyPanelDamageToCar(uint32 panels, CAutomobile* vehicle, bool flyi } } -// --MIAMI: Done void PrintElementsInPtrList(void) { for (CPtrNode* node = CWorld::GetBigBuildingList(LEVEL_GENERIC).first; node; node = node->next) { @@ -218,7 +216,6 @@ void PrintElementsInPtrList(void) } } -// --MIAMI: Done void CReplay::Init(void) { pBuf0 = nil; @@ -261,20 +258,17 @@ void CReplay::Init(void) MarkEverythingAsNew(); } -// --MIAMI: Done void CReplay::DisableReplays(void) { bReplayEnabled = false; } -// --MIAMI: Done void CReplay::EnableReplays(void) { bReplayEnabled = true; } void PlayReplayFromHD(void); -// --MIAMI: Done void CReplay::Update(void) { if (CCutsceneMgr::IsCutsceneProcessing() || CPad::GetPad(0)->ArePlayerControlsDisabled() || CScriptPaths::IsOneActive() || FrontEndMenuManager.GetIsMenuActive()) { @@ -309,7 +303,6 @@ void CReplay::Update(void) } } -// --MIAMI: Done except TODO void CReplay::RecordThisFrame(void) { uint32 memory_required = sizeof(tGeneralPacket) + sizeof(tClockPacket) + sizeof(tWeatherPacket) + sizeof(tTimerPacket) + sizeof(tMiscPacket); @@ -394,10 +387,8 @@ void CReplay::RecordThisFrame(void) tBulletTracePacket* bt = (tBulletTracePacket*)&Record.m_pBase[Record.m_nOffset]; bt->type = REPLAYPACKET_BULLET_TRACES; bt->index = i; - bt->frames = CBulletTraces::aTraces[i].m_framesInUse; - bt->lifetime = CBulletTraces::aTraces[i].m_lifeTime; - bt->inf = CBulletTraces::aTraces[i].m_vecCurrentPos; - bt->sup = CBulletTraces::aTraces[i].m_vecTargetPos; + bt->inf = CBulletTraces::aTraces[i].m_vecStartPos; + bt->sup = CBulletTraces::aTraces[i].m_vecEndPos; Record.m_nOffset += sizeof(*bt); } tMiscPacket* misc = (tMiscPacket*)&Record.m_pBase[Record.m_nOffset]; @@ -413,7 +404,6 @@ void CReplay::RecordThisFrame(void) Record.m_pBase[Record.m_nOffset] = REPLAYPACKET_END; } -// --MIAMI: Done void CReplay::GoToNextBlock(void) { Record.m_pBase[Record.m_nOffset] = REPLAYPACKET_END; @@ -426,7 +416,6 @@ void CReplay::GoToNextBlock(void) MarkEverythingAsNew(); } -// --MIAMI: Done void CReplay::RecordParticle(tParticleType type, const CVector& vecPos, const CVector& vecDir, float fSize, const RwRGBA& color) { if (Record.m_nOffset > REPLAYBUFFERSIZE - 16 - sizeof(tParticlePacket)) @@ -449,7 +438,6 @@ void CReplay::RecordParticle(tParticleType type, const CVector& vecPos, const CV Record.m_pBase[Record.m_nOffset] = REPLAYPACKET_END; } -// --MIAMI: Done void CReplay::StorePedUpdate(CPed *ped, int id) { tPedUpdatePacket* pp = (tPedUpdatePacket*)&Record.m_pBase[Record.m_nOffset]; @@ -469,7 +457,6 @@ void CReplay::StorePedUpdate(CPed *ped, int id) Record.m_nOffset += sizeof(tPedUpdatePacket); } -// --MIAMI: Done void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state) { CAnimBlendAssociation* second; @@ -515,7 +502,6 @@ void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state) } } -// --MIAMI: Done void CReplay::StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState *state) { for (int i = 0; i < NUM_MAIN_ANIMS_IN_REPLAY; i++){ @@ -573,7 +559,6 @@ void CReplay::StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState } } -// --MIAMI: Done void CReplay::ProcessPedUpdate(CPed *ped, float interpolation, CAddressInReplayBuffer *buffer) { tPedUpdatePacket *pp = (tPedUpdatePacket*)&buffer->m_pBase[buffer->m_nOffset]; @@ -618,14 +603,12 @@ void CReplay::ProcessPedUpdate(CPed *ped, float interpolation, CAddressInReplayB buffer->m_nOffset += sizeof(tPedUpdatePacket); } -// --MIAMI: Done bool HasAnimGroupLoaded(uint8 group) { CAnimBlendAssocGroup* pGroup = &CAnimManager::GetAnimAssocGroups()[group]; return pGroup->animBlock && pGroup->animBlock->isLoaded; } -// --MIAMI: Done void CReplay::RetrievePedAnimation(CPed *ped, CStoredAnimationState *state) { CAnimBlendAssociation* anim1; @@ -669,7 +652,6 @@ void CReplay::RetrievePedAnimation(CPed *ped, CStoredAnimationState *state) } } -// --MIAMI: Done void CReplay::RetrieveDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState *state) { CAnimBlendAssociation* assoc; @@ -715,7 +697,6 @@ void CReplay::RetrieveDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationSt } } -// --MIAMI: Done void CReplay::PlaybackThisFrame(void) { static int FrameSloMo = 0; @@ -743,7 +724,6 @@ void CReplay::PlaybackThisFrame(void) // next two functions are only found in mobile version // most likely they were optimized out for being unused -// --MIAMI: Done void CReplay::TriggerPlaybackLastCoupleOfSeconds(uint32 start, uint8 cam_mode, float cam_x, float cam_y, float cam_z, uint32 slomo) { if (Mode != MODE_RECORD) @@ -755,7 +735,6 @@ void CReplay::TriggerPlaybackLastCoupleOfSeconds(uint32 start, uint8 cam_mode, f Mode = MODE_RECORD; } -// --MIAMI: Done bool CReplay::FastForwardToTime(uint32 start) { uint32 timer = 0; @@ -765,7 +744,6 @@ bool CReplay::FastForwardToTime(uint32 start) return true; } -// --MIAMI: Done void CReplay::StoreCarUpdate(CVehicle *vehicle, int id) { tVehicleUpdatePacket* vp = (tVehicleUpdatePacket*)&Record.m_pBase[Record.m_nOffset]; @@ -806,7 +784,6 @@ void CReplay::StoreCarUpdate(CVehicle *vehicle, int id) Record.m_nOffset += sizeof(tVehicleUpdatePacket); } -// --MIAMI: Done void CReplay::StoreBikeUpdate(CVehicle* vehicle, int id) { CBike* bike = (CBike*)vehicle; @@ -832,7 +809,6 @@ void CReplay::StoreBikeUpdate(CVehicle* vehicle, int id) Record.m_nOffset += sizeof(tBikeUpdatePacket); } -// --MIAMI: Done void CReplay::ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressInReplayBuffer *buffer) { tVehicleUpdatePacket* vp = (tVehicleUpdatePacket*)&buffer->m_pBase[buffer->m_nOffset]; @@ -906,7 +882,6 @@ void CReplay::ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressI ((CBoat*)vehicle)->m_fMovingSpeed = vp->skimmer_speed / 50.0f; } -// --MIAMI: Done void CReplay::ProcessBikeUpdate(CVehicle* vehicle, float interpolation, CAddressInReplayBuffer* buffer) { CBike* bike = (CBike*)vehicle; @@ -940,7 +915,6 @@ void CReplay::ProcessBikeUpdate(CVehicle* vehicle, float interpolation, CAddress CWorld::Add(vehicle); } -// --MIAMI: Done bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, float interpolation, uint32 *pTimer) { CBulletTraces::Init(); @@ -1141,10 +1115,8 @@ bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, flo { tBulletTracePacket* pb = (tBulletTracePacket*)&ptr[offset]; CBulletTraces::aTraces[pb->index].m_bInUse = true; - CBulletTraces::aTraces[pb->index].m_framesInUse = pb->frames; - CBulletTraces::aTraces[pb->index].m_lifeTime = pb->lifetime; - CBulletTraces::aTraces[pb->index].m_vecCurrentPos = pb->inf; - CBulletTraces::aTraces[pb->index].m_vecTargetPos = pb->sup; + CBulletTraces::aTraces[pb->index].m_vecStartPos = pb->inf; + CBulletTraces::aTraces[pb->index].m_vecEndPos = pb->sup; buffer->m_nOffset += sizeof(tBulletTracePacket); break; } @@ -1197,7 +1169,6 @@ bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, flo return false; } -// --MIAMI: Done void CReplay::FinishPlayback(void) { if (Mode != MODE_PLAYBACK) @@ -1220,7 +1191,6 @@ void CReplay::FinishPlayback(void) DMAudio.SetMusicFadeVol(127); } -// --MIAMI: Done void CReplay::EmptyReplayBuffer(void) { if (Mode == MODE_PLAYBACK) @@ -1236,7 +1206,6 @@ void CReplay::EmptyReplayBuffer(void) MarkEverythingAsNew(); } -// --MIAMI: Done void CReplay::ProcessReplayCamera(void) { switch (CameraMode) { @@ -1283,7 +1252,6 @@ void CReplay::ProcessReplayCamera(void) extern CWeaponEffects gCrossHair; -// --MIAMI: Done except TODO void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float cam_z, bool load_scene) { if (Mode != MODE_RECORD) @@ -1343,7 +1311,6 @@ void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float ca CDraw::SetFOV(70.0f); } -// --MIAMI: Done void CReplay::StoreStuffInMem(void) { #ifdef FIX_BUGS @@ -1430,7 +1397,6 @@ void CReplay::StoreStuffInMem(void) CScriptPaths::Save_ForReplay(); } -// --MIAMI: Done void CReplay::RestoreStuffFromMem(void) { CPools::GetVehiclePool()->CopyBack(pBuf0, pBuf1); @@ -1655,7 +1621,6 @@ void CReplay::RestoreStuffFromMem(void) DMAudio.ChangeMusicMode(MUSICMODE_GAME); } -// --MIAMI: Done void CReplay::EmptyPedsAndVehiclePools(void) { int i = CPools::GetVehiclePool()->GetSize(); @@ -1676,7 +1641,6 @@ void CReplay::EmptyPedsAndVehiclePools(void) } } -// --MIAMI: Done void CReplay::EmptyAllPools(void) { EmptyPedsAndVehiclePools(); @@ -1698,7 +1662,6 @@ void CReplay::EmptyAllPools(void) } } -// --MIAMI: Done void CReplay::MarkEverythingAsNew(void) { int i = CPools::GetVehiclePool()->GetSize(); @@ -1748,7 +1711,6 @@ void CReplay::SaveReplayToHD(void) CFileMgr::SetDir(""); } -// --MIAMI: Done void PlayReplayFromHD(void) { CFileMgr::SetDirMyDocuments(); @@ -1781,7 +1743,6 @@ void PlayReplayFromHD(void) CReplay::StreamAllNecessaryCarsAndPeds(); } -// --MIAMI: Done void CReplay::StreamAllNecessaryCarsAndPeds(void) { for (int slot = 0; slot < NUM_REPLAYBUFFERS; slot++) { @@ -1806,7 +1767,6 @@ void CReplay::StreamAllNecessaryCarsAndPeds(void) CStreaming::LoadAllRequestedModels(false); } -// --MIAMI: Done void CReplay::FindFirstFocusCoordinate(CVector *coord) { *coord = CVector(0.0f, 0.0f, 0.0f); @@ -1822,7 +1782,6 @@ void CReplay::FindFirstFocusCoordinate(CVector *coord) } } -// --MIAMI: Done bool CReplay::ShouldStandardCameraBeProcessed(void) { if (Mode != MODE_PLAYBACK) @@ -1832,7 +1791,6 @@ bool CReplay::ShouldStandardCameraBeProcessed(void) return FindPlayerVehicle() != nil; } -// --MIAMI: Done void CReplay::ProcessLookAroundCam(void) { if (!bAllowLookAroundCam) @@ -1889,7 +1847,6 @@ void CReplay::ProcessLookAroundCam(void) RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera)); } -// --MIAMI: Done size_t CReplay::FindSizeOfPacket(uint8 type) { switch (type) { @@ -1911,7 +1868,6 @@ size_t CReplay::FindSizeOfPacket(uint8 type) return 0; } -// --MIAMI: Done (function didn't change since III and we already had it modified) void CReplay::Display() { static int TimeCount = 0; diff --git a/src/control/Restart.cpp b/src/control/Restart.cpp index 8fa018d6..052e6b61 100644 --- a/src/control/Restart.cpp +++ b/src/control/Restart.cpp @@ -4,6 +4,8 @@ #include "Zones.h" #include "PathFind.h" +//--MIAMI: file done + uint8 CRestart::OverrideHospitalLevel; uint8 CRestart::OverridePoliceStationLevel; bool CRestart::bFadeInAfterNextArrest; diff --git a/src/control/RoadBlocks.cpp b/src/control/RoadBlocks.cpp index e7831b82..dee2cbe3 100644 --- a/src/control/RoadBlocks.cpp +++ b/src/control/RoadBlocks.cpp @@ -236,7 +236,7 @@ CRoadBlocks::CreateRoadBlockBetween2Points(CVector point1, CVector point2) tmp.GetPosition().z += fModelRadius - 0.6f; pVehicle->m_matrix = tmp; pVehicle->PlaceOnRoadProperly(); - pVehicle->bIsStatic = false; + pVehicle->SetIsStatic(false); pVehicle->m_matrix.UpdateRW(); pVehicle->m_nDoorLock = CARLOCK_UNLOCKED; CCarCtrl::JoinCarWithRoadSystem(pVehicle); diff --git a/src/control/SceneEdit.cpp b/src/control/SceneEdit.cpp index a7727fde..21512290 100644 --- a/src/control/SceneEdit.cpp +++ b/src/control/SceneEdit.cpp @@ -20,6 +20,8 @@ #include "WeaponInfo.h" #include "World.h" +//--MIAMI: file done + bool CSceneEdit::m_bEditOn; int32 CSceneEdit::m_bCameraFollowActor; bool CSceneEdit::m_bRecording; @@ -1070,7 +1072,7 @@ bool CSceneEdit::SelectWeapon(void) } if (CPad::GetPad(1)->GetLeftShoulder1JustDown()) { if (++m_nWeaponType >= WEAPONTYPE_DETONATOR) - m_nWeaponType = WEAPONTYPE_BASEBALLBAT; + m_nWeaponType = WEAPONTYPE_BRASSKNUCKLE; pActors[m_nActor]->ClearWeapons(); pActors[m_nActor]->GiveWeapon((eWeaponType)m_nWeaponType, 1000); pActors[m_nActor]->AddWeaponModel(CWeaponInfo::GetWeaponInfo(pActors[m_nActor]->GetWeapon()->m_eWeaponType)->m_nModelId); @@ -1078,7 +1080,7 @@ bool CSceneEdit::SelectWeapon(void) } else if (CPad::GetPad(1)->GetRightShoulder1JustDown()){ if (--m_nWeaponType <= WEAPONTYPE_UNARMED) - m_nWeaponType = WEAPONTYPE_GRENADE; + m_nWeaponType = WEAPONTYPE_MINIGUN; pActors[m_nActor]->ClearWeapons(); pActors[m_nActor]->GiveWeapon((eWeaponType)m_nWeaponType, 1000); pActors[m_nActor]->AddWeaponModel(CWeaponInfo::GetWeaponInfo(pActors[m_nActor]->GetWeapon()->m_eWeaponType)->m_nModelId); diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 55139f2e..0df6d5a2 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -1705,7 +1705,7 @@ static void PossiblyWakeThisEntity(CPhysical* pEntity, bool ifColLoaded = false) return; if (!ifColLoaded || CColStore::HasCollisionLoaded(pEntity->GetPosition())) { pEntity->bIsStaticWaitingForCollision = false; - if (!pEntity->IsStatic()) + if (!pEntity->GetIsStatic()) pEntity->AddToMovingList(); } } @@ -1805,9 +1805,8 @@ void CMissionCleanup::Process() if (!CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) TheCamera.Restore(); TheCamera.SetWideScreenOff(); - // TODO(MIAMI) - //CSpecialFX::bLiftCam = false; - //CSpecialFX::bVideoCam = false; + CSpecialFX::bLiftCam = false; + CSpecialFX::bVideoCam = false; CTimeCycle::StopExtraColour(0); for (int i = 0; i < MISSION_AUDIO_SLOTS; i++) DMAudio.ClearMissionAudio(i); @@ -1828,7 +1827,7 @@ void CMissionCleanup::Process() CWorld::Players[0].m_pPed->m_nDrunkCountdown = 0; CPad::GetPad(0)->SetDrunkInputDelay(0); CWorld::Players[0].m_bDriveByAllowed = true; - // DMAudio::ShutUpPlayerTalking(0); // TODO(Miami) + DMAudio.ShutUpPlayerTalking(0); CVehicle::bDisableRemoteDetonation = false; CVehicle::bDisableRemoteDetonationOnContact = false; CGameLogic::ClearShortCut(); @@ -2382,9 +2381,11 @@ void CTheScripts::Process() case 4: AllowMissionReplay = 5; RetryMission(0, 0); + break; case 6: AllowMissionReplay = 7; TimeToWaitTill = CTimer::GetTimeInMilliseconds() + 500; + break; case 7: if (TimeToWaitTill < CTimer::GetTimeInMilliseconds()) { AllowMissionReplay = 0; @@ -3972,7 +3973,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); pos.z += car->GetDistanceFromCentreOfMassToBaseOfModel(); - car->bIsStatic = false; + car->SetIsStatic(false); /* Again weird usage of virtual functions. */ if (car->IsBoat()) { car->Teleport(pos); @@ -6373,7 +6374,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) } case COMMAND_ADD_EXPLOSION: CollectParameters(&m_nIp, 4); - CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0); + CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0, true); return 0; case COMMAND_IS_CAR_UPRIGHT: @@ -7043,7 +7044,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); CCoronas::RegisterCorona((uintptr)this + m_nIp, ScriptParams[6], ScriptParams[7], ScriptParams[8], - 255, pos, *(float*)&ScriptParams[3], 150.0f, ScriptParams[4], ScriptParams[5], 1, 0, 0, 0.0f); // TODO(MIAMI): more params + 255, pos, *(float*)&ScriptParams[3], 150.0f, ScriptParams[4], ScriptParams[5], 1, 0, 0, 0.0f); return 0; } case COMMAND_DRAW_LIGHT: @@ -7498,7 +7499,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CVector pos = *(CVector*)&ScriptParams[0]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); - CPathNode* pNode = &ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, 1, 999999.9f)]; + CPathNode* pNode = &ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, 1, 999999.9f, true)]; *(CVector*)&ScriptParams[0] = pNode->GetPosition(); StoreParameters(&m_nIp, 3); return 0; @@ -7509,8 +7510,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) CVector pos = *(CVector*)&ScriptParams[0]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); - CPathNode* pNode = &ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f)]; - *(CVector*)&ScriptParams[0] = pNode->GetPosition(); + *(CVector*)&ScriptParams[0] = ThePaths.FindNodeCoorsForScript(ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f, true, true)); StoreParameters(&m_nIp, 3); return 0; } @@ -8979,7 +8979,6 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) CollectParameters(&m_nIp, 1); char zone[KEY_LENGTH_IN_SCRIPT]; CTheScripts::ReadTextLabelFromScript(&m_nIp, zone); -// TODO(MIAMI): just getting this to compile with new argument int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone, ZONE_DEFAULT); if (zone_id != -1) m_nIp += KEY_LENGTH_IN_SCRIPT; @@ -9650,13 +9649,13 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) script_assert(pObject); if (ScriptParams[1]) { if (pObject->bIsStatic) { - pObject->bIsStatic = false; + pObject->SetIsStatic(false); pObject->AddToMovingList(); } } else { if (!pObject->bIsStatic) { - pObject->bIsStatic = true; + pObject->SetIsStatic(true); pObject->RemoveFromMovingList(); } } @@ -10345,8 +10344,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); int node = ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f, true, true); - // TODO(MIAMI): replace GetPosition with FindNodeCoorsForScript - *(CVector*)&ScriptParams[0] = ThePaths.m_pathNodes[node].GetPosition(); + *(CVector*)&ScriptParams[0] = ThePaths.FindNodeCoorsForScript(node); *(float*)&ScriptParams[3] = ThePaths.FindNodeOrientationForCarPlacement(node); StoreParameters(&m_nIp, 4); return 0; @@ -11205,7 +11203,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) return 0; */ case COMMAND_ARE_ANY_CAR_CHEATS_ACTIVATED: - UpdateCompareFlag(CVehicle::bAllDodosCheat || CVehicle::bCheat3 || CVehicle::bHoverCheat || CVehicle::bCheat8); // TODO(MIAMI): more cheats! + UpdateCompareFlag(CVehicle::bAllDodosCheat || CVehicle::bCheat3 || CVehicle::bHoverCheat || CVehicle::bCheat8 || CVehicle::bCheat9); return 0; case COMMAND_SET_CHAR_SUFFERS_CRITICAL_HITS: { @@ -12285,10 +12283,20 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) case COMMAND_GET_CLOSEST_STRAIGHT_ROAD: { CollectParameters(&m_nIp, 5); - debug("GET_CLOSEST_STRAIGHT_ROAD not implemented!\n"); - for (int i = 0; i < 7; i++) - ScriptParams[i] = 0; - StoreParameters(&m_nIp, 7); // TODO(MIAMI) + int node1, node2; + float angle; + ThePaths.FindNodePairClosestToCoors(*(CVector*)&ScriptParams[0], PATH_CAR, &node1, &node2, &angle, + *(float*)&ScriptParams[3], *(float*)&ScriptParams[4], true, true); + if (node1 == -1) { + for (int i = 0; i < 7; i++) + ScriptParams[i] = 0; + } + else { + *(CVector*)&ScriptParams[0] = ThePaths.FindNodeCoorsForScript(node1); + *(CVector*)&ScriptParams[3] = ThePaths.FindNodeCoorsForScript(node2); + *(float*)&ScriptParams[6] = angle; + } + StoreParameters(&m_nIp, 7); return 0; } case COMMAND_SET_CAR_FORWARD_SPEED: @@ -12396,7 +12404,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) case COMMAND_SWITCH_SECURITY_CAMERA: { CollectParameters(&m_nIp, 1); - debug("SWITCH_SECURITY_CAMERA is not implemented\n"); // TODO(MIAMI) + CSpecialFX::bVideoCam = ScriptParams[0] != 0; return 0; } //case COMMAND_IS_CHAR_IN_FLYING_VEHICLE: @@ -12462,9 +12470,11 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) case COMMAND_GET_NTH_CLOSEST_CAR_NODE: { CollectParameters(&m_nIp, 4); - debug("GET_NTH_CLOSEST_CAR_NODE is not implemented\n"); // TODO(MIAMI) - ScriptParams[0] = 0; - StoreParameters(&m_nIp, 1); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= MAP_Z_LOW_LIMIT) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + *(CVector*)&ScriptParams[0] = ThePaths.FindNodeCoorsForScript(ThePaths.FindNthNodeClosestToCoors(pos, 0, 999999.9f, true, true, ScriptParams[3] - 1)); + StoreParameters(&m_nIp, 3); return 0; } //case COMMAND_GET_NTH_CLOSEST_CHAR_NODE: @@ -12834,7 +12844,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) case COMMAND_SWITCH_LIFT_CAMERA: { CollectParameters(&m_nIp, 1); - debug("SWITCH_LIFT_CAMERA is not implemented\n"); // TODO(MIAMI) + CSpecialFX::bLiftCam = ScriptParams[0] != 0; return 0; } case COMMAND_CLOSE_ALL_CAR_DOORS: @@ -13253,7 +13263,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) case COMMAND_SET_TONIGHTS_EVENT: { CollectParameters(&m_nIp, 1); - debug("skipping SET_TONIGHTS_EVENT\n"); // TODO(MIAMI) + CScrollBar::TonightsEvent = ScriptParams[0]; return 0; } case COMMAND_CLEAR_CHAR_LAST_DAMAGE_ENTITY: @@ -13417,9 +13427,9 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed; script_assert(pPed); if (pPed->bInVehicle) { - if (pPed->GetWeapon(5).m_eWeaponType) { // TODO(MIAMI): enum - if (pPed->GetWeapon(5).m_nAmmoTotal < ScriptParams[1]) - pPed->SetAmmo(pPed->GetWeapon(5).m_eWeaponType, ScriptParams[1]); + if (pPed->GetWeapon(WEAPONSLOT_SUBMACHINEGUN).m_eWeaponType) { + if (pPed->GetWeapon(WEAPONSLOT_SUBMACHINEGUN).m_nAmmoTotal < ScriptParams[1]) + pPed->SetAmmo(pPed->GetWeapon(WEAPONSLOT_SUBMACHINEGUN).m_eWeaponType, ScriptParams[1]); } else { pPed->GiveWeapon(WEAPONTYPE_UZI, ScriptParams[1], true); @@ -13441,7 +13451,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) case COMMAND_ADD_EXPLOSION_NO_SOUND: { CollectParameters(&m_nIp, 4); - CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0); // TODO(MIAMI): last arg is 0 + CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0, false); return 0; } case COMMAND_SET_OBJECT_AREA_VISIBLE: @@ -13717,7 +13727,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) pVehicle->bDontLoadCollision = true; if (pVehicle->bIsStaticWaitingForCollision) { pVehicle->bIsStaticWaitingForCollision = false; - if (!pVehicle->IsStatic()) + if (!pVehicle->GetIsStatic()) pVehicle->AddToMovingList(); } } @@ -13740,7 +13750,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) pPed->bDontLoadCollision = true; if (pPed->bIsStaticWaitingForCollision) { pPed->bIsStaticWaitingForCollision = false; - if (!pPed->IsStatic()) + if (!pPed->GetIsStatic()) pPed->AddToMovingList(); } } diff --git a/src/control/Script.h b/src/control/Script.h index c7218847..c63025b2 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -288,8 +288,8 @@ class CTheScripts static uint16 ScriptsUpdated; static uint32 LastMissionPassedTime; static uint16 NumberOfExclusiveMissionScripts; - static bool bPlayerIsInTheStatium; public: + static bool bPlayerIsInTheStatium; static uint8 RiotIntensity; static bool bPlayerHasMetDebbieHarry; public: @@ -562,4 +562,4 @@ void RetryMission(int, int); #ifdef USE_DEBUG_SCRIPT_LOADER extern int scriptToLoad; -#endif
\ No newline at end of file +#endif diff --git a/src/control/TrafficLights.cpp b/src/control/TrafficLights.cpp index 5559b1c4..ecfc7207 100644 --- a/src/control/TrafficLights.cpp +++ b/src/control/TrafficLights.cpp @@ -15,8 +15,7 @@ #include "Weather.h" #include "World.h" -// TODO: figure out the meaning of this -enum { SOME_FLAG = 0x80 }; +//--MIAMI: file done bool CTrafficLights::bGreenLightsCheat; @@ -28,113 +27,286 @@ CTrafficLights::DisplayActualLight(CEntity *ent) int phase; if(FindTrafficLightType(ent) == 1) - phase = LightForCars1(); + phase = LightForCars1_Visual(); else - phase = LightForCars2(); - - int i; - CBaseModelInfo *mi = CModelInfo::GetModelInfo(ent->GetModelIndex()); - float x = mi->Get2dEffect(0)->pos.x; - float yMin = mi->Get2dEffect(0)->pos.y; - float yMax = mi->Get2dEffect(0)->pos.y; - float zMin = mi->Get2dEffect(0)->pos.z; - float zMax = mi->Get2dEffect(0)->pos.z; - for(i = 1; i < 6; i++){ - assert(mi->Get2dEffect(i)); - yMin = Min(yMin, mi->Get2dEffect(i)->pos.y); - yMax = Max(yMax, mi->Get2dEffect(i)->pos.y); - zMin = Min(zMin, mi->Get2dEffect(i)->pos.z); - zMax = Max(zMax, mi->Get2dEffect(i)->pos.z); + phase = LightForCars2_Visual(); + + int i, m = ent->GetModelIndex(); + if (MI_TRAFFICLIGHTS == m) { + CBaseModelInfo* mi = CModelInfo::GetModelInfo(ent->GetModelIndex()); + float x = mi->Get2dEffect(0)->pos.x; + float yMin = mi->Get2dEffect(0)->pos.y; + float yMax = mi->Get2dEffect(0)->pos.y; + float zMin = mi->Get2dEffect(0)->pos.z; + float zMax = mi->Get2dEffect(0)->pos.z; + for (i = 1; i < 6; i++) { + assert(mi->Get2dEffect(i)); + yMin = Min(yMin, mi->Get2dEffect(i)->pos.y); + yMax = Max(yMax, mi->Get2dEffect(i)->pos.y); + zMin = Min(zMin, mi->Get2dEffect(i)->pos.z); + zMax = Max(zMax, mi->Get2dEffect(i)->pos.z); + } + + CVector pos1, pos2; + uint8 r, g; + int id; + switch (phase) { + case CAR_LIGHTS_GREEN: + r = 0; + g = 255; + pos1 = ent->GetMatrix() * CVector(x, yMax, zMin); + pos2 = ent->GetMatrix() * CVector(x, yMin, zMin); + id = 0; + break; + case CAR_LIGHTS_YELLOW: + r = 255; + g = 128; + pos1 = ent->GetMatrix() * CVector(x, yMax, (zMin + zMax) / 2.0f); + pos2 = ent->GetMatrix() * CVector(x, yMin, (zMin + zMax) / 2.0f); + id = 1; + break; + case CAR_LIGHTS_RED: + r = 255; + g = 0; + pos1 = ent->GetMatrix() * CVector(x, yMax, zMax); + pos2 = ent->GetMatrix() * CVector(x, yMin, zMax); + id = 2; + break; + default: + r = 0; + g = 0; + pos1 = ent->GetMatrix() * CVector(x, yMax, (zMin + zMax) / 2.0f); + pos2 = ent->GetMatrix() * CVector(x, yMin, (zMin + zMax) / 2.0f); + id = -1; + break; + } + + if (CWeather::TrafficLightBrightness > 0.5f) + CPointLights::AddLight(CPointLights::LIGHT_POINT, + pos1, CVector(0.0f, 0.0f, 0.0f), 8.0f, + r / 255.0f, g / 255.0f, 0 / 255.0f, CPointLights::FOG_NORMAL, true); + + if (CWeather::TrafficLightBrightness > 0.05f) + CShadows::StoreStaticShadow((uintptr)ent, + SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos1, + 8.0f, 0.0f, 0.0f, -8.0f, 128, + r * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + g * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + 0 * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + 12.0f, 1.0f, 40.0f, false, 0.0f); + + if (DotProduct(TheCamera.GetForward(), ent->GetForward()) < 0.0f) + CCoronas::RegisterCorona((uintptr)ent + id, + r * CTimeCycle::GetSpriteBrightness() * 0.7f, + g * CTimeCycle::GetSpriteBrightness() * 0.7f, + 0 * CTimeCycle::GetSpriteBrightness() * 0.7f, + 255, + pos1, 1.75f * CTimeCycle::GetSpriteSize(), 50.0f, + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, + CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + else + CCoronas::RegisterCorona((uintptr)ent + id + 3, + r * CTimeCycle::GetSpriteBrightness() * 0.7f, + g * CTimeCycle::GetSpriteBrightness() * 0.7f, + 0 * CTimeCycle::GetSpriteBrightness() * 0.7f, + 255, + pos2, 1.75f * CTimeCycle::GetSpriteSize(), 50.0f, + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, + CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + + CBrightLights::RegisterOne(pos1, ent->GetUp(), ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN); + CBrightLights::RegisterOne(pos2, ent->GetUp(), -ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN); } + else if (MI_TRAFFICLIGHTS_VERTICAL == m) { + CBaseModelInfo* mi = CModelInfo::GetModelInfo(ent->GetModelIndex()); + float x = mi->Get2dEffect(0)->pos.x; + float yMin = mi->Get2dEffect(0)->pos.y; + float yMax = mi->Get2dEffect(0)->pos.y; + float zMin = mi->Get2dEffect(0)->pos.z; + float zMax = mi->Get2dEffect(0)->pos.z; + for (i = 1; i < 6; i++) { + assert(mi->Get2dEffect(i)); + yMin = Min(yMin, mi->Get2dEffect(i)->pos.y); + yMax = Max(yMax, mi->Get2dEffect(i)->pos.y); + zMin = Min(zMin, mi->Get2dEffect(i)->pos.z); + zMax = Max(zMax, mi->Get2dEffect(i)->pos.z); + } + + CVector pos1; + uint8 r, g; + int id; + switch (phase) { + case CAR_LIGHTS_GREEN: + r = 0; + g = 255; + pos1 = ent->GetMatrix() * mi->Get2dEffect(2)->pos; + id = 0; + break; + case CAR_LIGHTS_YELLOW: + r = 255; + g = 128; + pos1 = ent->GetMatrix() * mi->Get2dEffect(1)->pos; + id = 1; + break; + case CAR_LIGHTS_RED: + r = 255; + g = 0; + pos1 = ent->GetMatrix() * mi->Get2dEffect(0)->pos; + id = 2; + break; + default: + r = 0; + g = 0; + pos1 = ent->GetMatrix() * mi->Get2dEffect(1)->pos; + id = -1; + break; + } - CVector pos1, pos2; - uint8 r, g; - int id; - switch(phase){ - case CAR_LIGHTS_GREEN: - r = 0; - g = 255; - pos1 = ent->GetMatrix() * CVector(x, yMax, zMin); - pos2 = ent->GetMatrix() * CVector(x, yMin, zMin); - id = 0; - break; - case CAR_LIGHTS_YELLOW: - r = 255; - g = 128; - pos1 = ent->GetMatrix() * CVector(x, yMax, (zMin+zMax)/2.0f); - pos2 = ent->GetMatrix() * CVector(x, yMin, (zMin+zMax)/2.0f); - id = 1; - break; - case CAR_LIGHTS_RED: - default: - r = 255; - g = 0; - pos1 = ent->GetMatrix() * CVector(x, yMax, zMax); - pos2 = ent->GetMatrix() * CVector(x, yMin, zMax); - id = 2; - break; + CBrightLights::RegisterOne(pos1, ent->GetUp(), ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN); + + if (CWeather::TrafficLightBrightness > 0.5f) + CPointLights::AddLight(CPointLights::LIGHT_POINT, + pos1, CVector(0.0f, 0.0f, 0.0f), 8.0f, + r / 255.0f, g / 255.0f, 0 / 255.0f, CPointLights::FOG_NORMAL, true); + + if (CWeather::TrafficLightBrightness > 0.05f) + CShadows::StoreStaticShadow((uintptr)ent, + SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos1, + 8.0f, 0.0f, 0.0f, -8.0f, 128, + r * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + g * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + 0 * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + 12.0f, 1.0f, 40.0f, false, 0.0f); + + if (DotProduct(TheCamera.GetForward(), ent->GetForward()) < 0.0f) + CCoronas::RegisterCorona((uintptr)ent + id, + r * CTimeCycle::GetSpriteBrightness() * 0.7f, + g * CTimeCycle::GetSpriteBrightness() * 0.7f, + 0 * CTimeCycle::GetSpriteBrightness() * 0.7f, + 255, + pos1, 1.75f * CTimeCycle::GetSpriteSize(), 50.0f, + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, + CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); } + else if (MI_TRAFFICLIGHTS_MIAMI == m || MI_TRAFFICLIGHTS_TWOVERTICAL == m) { + CBaseModelInfo* mi = CModelInfo::GetModelInfo(ent->GetModelIndex()); + CVector pos1, pos2; + uint8 r, g; + int id; + if (MI_TRAFFICLIGHTS_MIAMI == m) { + switch (phase) { + case CAR_LIGHTS_GREEN: + r = 0; + g = 255; + pos1 = ent->GetMatrix() * mi->Get2dEffect(4)->pos; + pos2 = ent->GetMatrix() * mi->Get2dEffect(5)->pos; + id = 0; + break; + case CAR_LIGHTS_YELLOW: + r = 255; + g = 128; + pos1 = ent->GetMatrix() * mi->Get2dEffect(2)->pos; + pos2 = ent->GetMatrix() * mi->Get2dEffect(3)->pos; + id = 1; + break; + case CAR_LIGHTS_RED: + r = 255; + g = 0; + pos1 = ent->GetMatrix() * mi->Get2dEffect(0)->pos; + pos2 = ent->GetMatrix() * mi->Get2dEffect(1)->pos; + id = 2; + break; + default: + r = 0; + g = 0; + pos1 = ent->GetMatrix() * mi->Get2dEffect(2)->pos; + pos2 = ent->GetMatrix() * mi->Get2dEffect(3)->pos; + id = -1; + break; + } + } + else { + switch (phase) { + case CAR_LIGHTS_GREEN: + r = 0; + g = 255; + pos1 = ent->GetMatrix() * mi->Get2dEffect(2)->pos; + pos2 = ent->GetMatrix() * mi->Get2dEffect(5)->pos; + id = 0; + break; + case CAR_LIGHTS_YELLOW: + r = 255; + g = 128; + pos1 = ent->GetMatrix() * mi->Get2dEffect(1)->pos; + pos2 = ent->GetMatrix() * mi->Get2dEffect(4)->pos; + id = 1; + break; + case CAR_LIGHTS_RED: + r = 255; + g = 0; + pos1 = ent->GetMatrix() * mi->Get2dEffect(0)->pos; + pos2 = ent->GetMatrix() * mi->Get2dEffect(3)->pos; + id = 2; + break; + default: + r = 0; + g = 0; + pos1 = ent->GetMatrix() * mi->Get2dEffect(1)->pos; + pos2 = ent->GetMatrix() * mi->Get2dEffect(4)->pos; + id = -1; + break; + } + } - if(CClock::GetHours() > 19 || CClock::GetHours() < 6 || CWeather::Foggyness > 0.05f) - CPointLights::AddLight(CPointLights::LIGHT_POINT, - pos1, CVector(0.0f, 0.0f, 0.0f), 8.0f, - r/255.0f, g/255.0f, 0/255.0f, CPointLights::FOG_NORMAL, true); - - CShadows::StoreStaticShadow((uintptr)ent, - SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos1, - 8.0f, 0.0f, 0.0f, -8.0f, 128, - r*CTimeCycle::GetLightOnGroundBrightness()/8.0f, - g*CTimeCycle::GetLightOnGroundBrightness()/8.0f, - 0*CTimeCycle::GetLightOnGroundBrightness()/8.0f, - 12.0f, 1.0f, 40.0f, false, 0.0f); - - if(DotProduct(TheCamera.GetForward(), ent->GetForward()) < 0.0f) - CCoronas::RegisterCorona((uintptr)ent + id, - r*CTimeCycle::GetSpriteBrightness()*0.7f, - g*CTimeCycle::GetSpriteBrightness()*0.7f, - 0*CTimeCycle::GetSpriteBrightness()*0.7f, - 255, - pos1, 1.75f*CTimeCycle::GetSpriteSize(), 50.0f, - CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, - CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); - else - CCoronas::RegisterCorona((uintptr)ent + id + 3, - r*CTimeCycle::GetSpriteBrightness()*0.7f, - g*CTimeCycle::GetSpriteBrightness()*0.7f, - 0*CTimeCycle::GetSpriteBrightness()*0.7f, - 255, - pos2, 1.75f*CTimeCycle::GetSpriteSize(), 50.0f, - CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, - CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); - - CBrightLights::RegisterOne(pos1, ent->GetUp(), ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN); - CBrightLights::RegisterOne(pos2, ent->GetUp(), -ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN); - -/* - static const float top = -0.127f; - static const float bot = -0.539f; - static const float mid = bot + (top-bot)/3.0f; - static const float left = 1.256f; - static const float right = 0.706f; - phase = CTrafficLights::LightForPeds(); - if(phase == PED_LIGHTS_DONT_WALK){ - CVector p0(2.7f, right, top); - CVector p1(2.7f, left, top); - CVector p2(2.7f, right, mid); - CVector p3(2.7f, left, mid); - CShinyTexts::RegisterOne(ent->GetMatrix()*p0, ent->GetMatrix()*p1, ent->GetMatrix()*p2, ent->GetMatrix()*p3, - 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, - SHINYTEXT_WALK, 255, 0, 0, 60.0f); - }else if(phase == PED_LIGHTS_WALK || CTimer::GetTimeInMilliseconds() & 0x100){ - CVector p0(2.7f, right, mid); - CVector p1(2.7f, left, mid); - CVector p2(2.7f, right, bot); - CVector p3(2.7f, left, bot); - CShinyTexts::RegisterOne(ent->GetMatrix()*p0, ent->GetMatrix()*p1, ent->GetMatrix()*p2, ent->GetMatrix()*p3, - 1.0f, 0.5f, 0.0f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f, - SHINYTEXT_WALK, 255, 255, 255, 60.0f); + CVector pos = (pos1 + pos2) / 2; + if (id >= 0) { + CBrightLights::RegisterOne(pos1, ent->GetUp(), ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN); + CBrightLights::RegisterOne(pos2, ent->GetUp(), ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN); + } + + if (CWeather::TrafficLightBrightness > 0.5f) + CPointLights::AddLight(CPointLights::LIGHT_POINT, + pos, CVector(0.0f, 0.0f, 0.0f), 8.0f, + r / 255.0f, g / 255.0f, 0 / 255.0f, CPointLights::FOG_NORMAL, true); + + if (CWeather::TrafficLightBrightness > 0.05f) + CShadows::StoreStaticShadow((uintptr)ent, + SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos, + 8.0f, 0.0f, 0.0f, -8.0f, 128, + r * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + g * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + 0 * CTimeCycle::GetLightOnGroundBrightness() * CWeather::TrafficLightBrightness / 8.0f, + 12.0f, 1.0f, 40.0f, false, 0.0f); + + if (id >= 0) { + if (DotProduct(TheCamera.GetForward(), ent->GetForward()) < 0.0f) + CCoronas::RegisterCorona((uintptr)ent + id, + r * CTimeCycle::GetSpriteBrightness() * 0.7f, + g * CTimeCycle::GetSpriteBrightness() * 0.7f, + 0 * CTimeCycle::GetSpriteBrightness() * 0.7f, + 255, + pos1, 1.75f * CTimeCycle::GetSpriteSize(), 50.0f, + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, + CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + else + CCoronas::RegisterCorona((uintptr)ent + id, + r * CTimeCycle::GetSpriteBrightness() * 0.7f, + g * CTimeCycle::GetSpriteBrightness() * 0.7f, + 0 * CTimeCycle::GetSpriteBrightness() * 0.7f, + 255, + pos2, 1.75f * CTimeCycle::GetSpriteSize(), 50.0f, + CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, + CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + } } -*/ +} + +bool DoesLineSegmentIntersect(float l1x1, float l1y1, float l1x2, float l1y2, float l2x1, float l2y1, float l2x2, float l2y2) +{ + return ((l2y2 - l1y1) * (l1x2 - l1x1) + (l1x1 - l2x2) * (l1y2 - l1y1)) * + ((l2y1 - l1y1) * (l1x2 - l1x1) + (l1x1 - l2x1) * (l1y2 - l1y1)) <= 0.0f && + ((l1y2 - l2y1) * (l2x2 - l2x1) + (l2y2 - l2y1) * (l2x1 - l1x2)) * + ((l1y1 - l2y1) * (l2x2 - l2x1) + (l2y2 - l2y1) * (l2x1 - l1x1)) <= 0.0f; } void @@ -152,33 +324,28 @@ CTrafficLights::ScanForLightsOnMap(void) if (!IsTrafficLight(light->GetModelIndex())) continue; + CVector pos1 = light->GetMatrix() * CVector(17.0f, 0.0f, 0.0f); + CVector pos2 = light->GetMatrix() * CVector(-15.0f, 0.0f, 0.0f); + // Check cars - for(i = 0; i < ThePaths.m_numCarPathLinks; i++){ - CVector2D dist = ThePaths.m_carPathLinks[i].GetPosition() - light->GetPosition(); - float dotY = Abs(DotProduct2D(dist, light->GetForward())); // forward is direction of car light - float dotX = DotProduct2D(dist, light->GetRight()); // towards base of light - // it has to be on the correct side of the node and also not very far away - if(dotX < 0.0f && dotX > -15.0f && dotY < 3.0f){ - float dz = ThePaths.m_pathNodes[ThePaths.m_carPathLinks[i].pathNodeIndex].GetZ() - - light->GetPosition().z; - if(dz < 15.0f){ - ThePaths.m_carPathLinks[i].trafficLightType = FindTrafficLightType(light); - // Find two neighbour nodes of this one - int n1 = -1; - int n2 = -1; - for(j = 0; j < ThePaths.m_numPathNodes; j++) - for(l = 0; l < ThePaths.m_pathNodes[j].numLinks; l++) - if(ThePaths.m_carPathConnections[ThePaths.m_pathNodes[j].firstLink + l] == i){ - if(n1 == -1) - n1 = j; - else - n2 = j; - } - // What's going on here? - if(ThePaths.m_pathNodes[n1].numLinks <= ThePaths.m_pathNodes[n2].numLinks) - n1 = n2; - if(ThePaths.m_carPathLinks[i].pathNodeIndex != n1) - ThePaths.m_carPathLinks[i].trafficLightType |= SOME_FLAG; + for(i = 0; i < ThePaths.m_numCarPathNodes; i++){ + if ((ThePaths.m_pathNodes[i].GetPosition() - pos1).MagnitudeSqr() >= SQR(100.0f)) + continue; + for (j = 0; j < ThePaths.m_pathNodes[i].numLinks; j++){ + int con = ThePaths.ConnectedNode(ThePaths.m_pathNodes[i].firstLink + j); + if (i < con) { + CVector i_pos = ThePaths.m_pathNodes[i].GetPosition(); + CVector con_pos = ThePaths.m_pathNodes[con].GetPosition(); + if (Abs(pos1.z - (i_pos.z + con_pos.z) / 2) < 10.0f && + DoesLineSegmentIntersect(pos1.x, pos1.y, pos2.x, pos2.y, i_pos.x, i_pos.y, con_pos.x, con_pos.y)) { + //debug("Setting up light: nodes %f %f %f - %f %f %f, light %f %f %f - %f %f %f\n", i_pos.x, i_pos.y, i_pos.z, con_pos.x, con_pos.y, con_pos.z, pos1.x, pos1.y, pos1.z, pos2.x, pos2.y, pos2.z); + int link = ThePaths.m_carPathConnections[ThePaths.m_pathNodes[i].firstLink + j]; + ThePaths.m_carPathLinks[link].trafficLightType = FindTrafficLightType(light); + if (ThePaths.m_pathNodes[i].numLinks > ThePaths.m_pathNodes[con].numLinks) + con = i; + if (ThePaths.m_carPathLinks[link].pathNodeIndex != con) + ThePaths.m_carPathLinks[link].trafficLightDirection = true; + } } } } @@ -209,15 +376,18 @@ bool CTrafficLights::ShouldCarStopForLight(CVehicle *vehicle, bool alwaysStop) { int node, type; + bool direction; node = vehicle->AutoPilot.m_nNextPathNodeInfo; type = ThePaths.m_carPathLinks[node].trafficLightType; + direction = ThePaths.m_carPathLinks[node].trafficLightDirection; + if(type){ - if((type & SOME_FLAG || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nNextRouteNode) && - (!(type & SOME_FLAG) || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nNextRouteNode)) + if((direction || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nNextRouteNode) && + (!direction || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nNextRouteNode)) if(alwaysStop || - (type&~SOME_FLAG) == 1 && LightForCars1() != CAR_LIGHTS_GREEN || - (type&~SOME_FLAG) == 2 && LightForCars2() != CAR_LIGHTS_GREEN){ + type == 1 && LightForCars1() != CAR_LIGHTS_GREEN || + type == 2 && LightForCars2() != CAR_LIGHTS_GREEN){ float dist = DotProduct2D(CVector2D(vehicle->GetPosition()) - ThePaths.m_carPathLinks[node].GetPosition(), ThePaths.m_carPathLinks[node].GetDirection()); if(vehicle->AutoPilot.m_nNextDirection == -1){ @@ -232,12 +402,13 @@ CTrafficLights::ShouldCarStopForLight(CVehicle *vehicle, bool alwaysStop) node = vehicle->AutoPilot.m_nCurrentPathNodeInfo; type = ThePaths.m_carPathLinks[node].trafficLightType; + direction = ThePaths.m_carPathLinks[node].trafficLightDirection; if(type){ - if((type & SOME_FLAG || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nCurrentRouteNode) && - (!(type & SOME_FLAG) || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nCurrentRouteNode)) + if((direction || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nCurrentRouteNode) && + (!direction || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nCurrentRouteNode)) if(alwaysStop || - (type&~SOME_FLAG) == 1 && LightForCars1() != CAR_LIGHTS_GREEN || - (type&~SOME_FLAG) == 2 && LightForCars2() != CAR_LIGHTS_GREEN){ + type == 1 && LightForCars1() != CAR_LIGHTS_GREEN || + type == 2 && LightForCars2() != CAR_LIGHTS_GREEN){ float dist = DotProduct2D(CVector2D(vehicle->GetPosition()) - ThePaths.m_carPathLinks[node].GetPosition(), ThePaths.m_carPathLinks[node].GetDirection()); if(vehicle->AutoPilot.m_nCurrentDirection == -1){ @@ -253,12 +424,13 @@ CTrafficLights::ShouldCarStopForLight(CVehicle *vehicle, bool alwaysStop) if(vehicle->GetStatus() == STATUS_PHYSICS){ node = vehicle->AutoPilot.m_nPreviousPathNodeInfo; type = ThePaths.m_carPathLinks[node].trafficLightType; + direction = ThePaths.m_carPathLinks[node].trafficLightDirection; if(type){ - if((type & SOME_FLAG || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nPrevRouteNode) && - (!(type & SOME_FLAG) || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nPrevRouteNode)) + if((direction || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nPrevRouteNode) && + (!direction || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nPrevRouteNode)) if(alwaysStop || - (type&~SOME_FLAG) == 1 && LightForCars1() != CAR_LIGHTS_GREEN || - (type&~SOME_FLAG) == 2 && LightForCars2() != CAR_LIGHTS_GREEN){ + type == 1 && LightForCars1() != CAR_LIGHTS_GREEN || + type == 2 && LightForCars2() != CAR_LIGHTS_GREEN){ float dist = DotProduct2D(CVector2D(vehicle->GetPosition()) - ThePaths.m_carPathLinks[node].GetPosition(), ThePaths.m_carPathLinks[node].GetDirection()); if(vehicle->AutoPilot.m_nPreviousDirection == -1){ @@ -348,3 +520,19 @@ CTrafficLights::LightForCars2(void) else return CAR_LIGHTS_RED; } + +uint8 +CTrafficLights::LightForCars1_Visual(void) +{ + if (CWeather::Wind <= 1.1f) + return LightForCars1(); + return (CTimer::GetTimeInMilliseconds() & 0x400 ? CAR_LIGHTS_NONE : CAR_LIGHTS_YELLOW); +} + +uint8 +CTrafficLights::LightForCars2_Visual(void) +{ + if (CWeather::Wind <= 1.1f) + return LightForCars2(); + return (CTimer::GetTimeInMilliseconds() & 0x400 ? CAR_LIGHTS_NONE : CAR_LIGHTS_YELLOW); +} diff --git a/src/control/TrafficLights.h b/src/control/TrafficLights.h index 6cd5e04a..8dba45e1 100644 --- a/src/control/TrafficLights.h +++ b/src/control/TrafficLights.h @@ -10,7 +10,8 @@ enum { CAR_LIGHTS_GREEN = 0, CAR_LIGHTS_YELLOW, - CAR_LIGHTS_RED + CAR_LIGHTS_RED, + CAR_LIGHTS_NONE }; class CTrafficLights @@ -24,6 +25,8 @@ public: static uint8 LightForPeds(void); static uint8 LightForCars1(void); static uint8 LightForCars2(void); + static uint8 LightForCars1_Visual(void); + static uint8 LightForCars2_Visual(void); static bool ShouldCarStopForLight(CVehicle*, bool); static bool ShouldCarStopForBridge(CVehicle*); }; diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index b996e77f..7af652ad 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -4247,7 +4247,7 @@ CCam::GetLookFromLampPostPos(CEntity *Target, CPed *Cop, CVector &TargetCoors, C CWorld::FindObjectsInRange(TargetCoors, 30.0f, true, &NumObjects, 15, Objects, false, false, false, true, true); float NearestDist = 10000.0f; for(i = 0; i < NumObjects; i++){ - if(Objects[i]->IsStatic() && Objects[i]->GetUp().z > 0.9f && IsLampPost(Objects[i]->GetModelIndex())){ + if(Objects[i]->GetIsStatic() && Objects[i]->GetUp().z > 0.9f && IsLampPost(Objects[i]->GetModelIndex())){ float Dist = (Objects[i]->GetPosition() - TargetCoors).Magnitude2D(); if(Abs(ARRESTCAM_LAMP_BEST_DIST - Dist) < NearestDist){ CVector TestStart = Objects[i]->GetColModel()->boundingBox.max; diff --git a/src/core/CdStreamPosix.cpp b/src/core/CdStreamPosix.cpp index a6ab62bc..fdc63a05 100644 --- a/src/core/CdStreamPosix.cpp +++ b/src/core/CdStreamPosix.cpp @@ -240,9 +240,8 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size) CdReadInfo *pChannel = &gpReadInfo[channel]; ASSERT( pChannel != nil ); - if ( pChannel->nSectorsToRead != 0 || pChannel->bReading ) { - if (pChannel->nSectorOffset == _GET_OFFSET(offset) && pChannel->nSectorsToRead >= size) + if (pChannel->hFile == hImage - 1 && pChannel->nSectorOffset == _GET_OFFSET(offset) && pChannel->nSectorsToRead >= size) return STREAM_SUCCESS; flushStream[channel] = 1; @@ -293,7 +292,6 @@ CdStreamGetStatus(int32 channel) if ( pChannel->nStatus != STREAM_NONE ) { int32 status = pChannel->nStatus; - pChannel->nStatus = STREAM_NONE; return status; @@ -322,15 +320,16 @@ CdStreamSync(int32 channel) pthread_kill(pChannel->pChannelThread, SIGUSR1); if (pChannel->bReading) { pChannel->bLocked = true; - sem_wait(pChannel->pDoneSemaphore); + while (pChannel->bLocked) + sem_wait(pChannel->pDoneSemaphore); } #else pChannel->nSectorsToRead = 0; if (pChannel->bReading) { pChannel->bLocked = true; pthread_kill(_gCdStreamThread, SIGUSR1); - sem_wait(pChannel->pDoneSemaphore); - + while (pChannel->bLocked) + sem_wait(pChannel->pDoneSemaphore); } #endif pChannel->bReading = false; @@ -341,8 +340,8 @@ CdStreamSync(int32 channel) if ( pChannel->nSectorsToRead != 0 ) { pChannel->bLocked = true; - - sem_wait(pChannel->pDoneSemaphore); + while (pChannel->bLocked) + sem_wait(pChannel->pDoneSemaphore); } pChannel->bReading = false; @@ -443,9 +442,9 @@ void *CdStreamThread(void *param) #endif pChannel->nSectorsToRead = 0; - if ( pChannel->bLocked ) { + pChannel->bLocked = 0; sem_post(pChannel->pDoneSemaphore); } pChannel->bReading = false; diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp index 5b57cb73..a47ca3cf 100644 --- a/src/core/Fire.cpp +++ b/src/core/Fire.cpp @@ -406,8 +406,8 @@ CFireManager::ExtinguishPointWithWater(CVector point, float range) CFire *fireToExtinguish = &m_aFires[fireI]; fireToExtinguish->m_fWaterExtinguishCountdown -= 0.012f * CTimer::GetTimeStep(); CVector steamPos = fireToExtinguish->m_vecPos + - CVector((CGeneral::GetRandomNumber() - 128) * 31.f / 200.f, - (CGeneral::GetRandomNumber() - 128) * 31.f / 200.f, + CVector((CGeneral::GetRandomNumber() - 128) * 3.1f / 200.f, + (CGeneral::GetRandomNumber() - 128) * 3.1f / 200.f, CGeneral::GetRandomNumber() / 200.f); CParticle::AddParticle(PARTICLE_STEAM_NY_SLOWMOTION, steamPos, CVector(0.f, 0.f, 0.2f), nil, 0.5f); diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 59649e93..4eda2301 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -37,6 +37,7 @@ #include "Messages.h" #include "FileLoader.h" #include "User.h" +#include "sampman.h" // TODO(Miami): Remove that!! That was my map implementation for III, instead use MAP_ENHACEMENTS on some places #define CUSTOM_MAP @@ -376,8 +377,7 @@ CMenuManager::CMenuManager() m_bShowMouse = true; m_nHoverOption = HOVEROPTION_NOT_HOVERING; - // TODO(Miami) - // DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); + DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); m_bMenuActive = false; m_bActivateSaveMenu = false; m_bWantToLoad = false; @@ -426,9 +426,7 @@ CMenuManager::Initialise(void) DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); m_PrefsRadioStation = DMAudio.GetRadioInCar(); - - // TODO(Miami) - // DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); + DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); if (DMAudio.IsMP3RadioChannelAvailable()) { if (m_PrefsRadioStation < WILDSTYLE || m_PrefsRadioStation > USERTRACK) m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10; @@ -570,6 +568,7 @@ CMenuManager::CheckHover(int x1, int x2, int y1, int y2) m_nMousePosY > y1 && m_nMousePosY < y2; } +// --MIAMI: Done void CMenuManager::CheckSliderMovement(int value) { @@ -587,14 +586,27 @@ CMenuManager::CheckSliderMovement(int value) CRenderer::ms_lodDistScale = m_PrefsLOD; break; case MENUACTION_MUSICVOLUME: - m_PrefsMusicVolume += value * (128/32); - m_PrefsMusicVolume = clamp(m_PrefsMusicVolume, 0, 65); - DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); + if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { + m_PrefsMusicVolume += value * (128 / 32); + m_PrefsMusicVolume = clamp(m_PrefsMusicVolume, 0, 65); + DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); + } break; case MENUACTION_SFXVOLUME: - m_PrefsSfxVolume += value * (128/32); - m_PrefsSfxVolume = clamp(m_PrefsSfxVolume, 0, 65); - DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); + if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { + m_PrefsSfxVolume += value * (128 / 32); + m_PrefsSfxVolume = clamp(m_PrefsSfxVolume, 0, 65); + DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); + } + break; + case MENUACTION_MP3VOLUMEBOOST: + if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { + if (DMAudio.IsMP3RadioChannelAvailable()) { + m_PrefsMP3BoostVolume += value * (128 / 32); + m_PrefsMP3BoostVolume = clamp(m_PrefsMP3BoostVolume, 0, 65); + DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); + } + } break; case MENUACTION_MOUSESENS: TheCamera.m_fMouseAccelHorzntl += value * 1.0f/200.0f/15.0f; // ??? @@ -1065,20 +1077,17 @@ CMenuManager::DrawStandardMenus(bool activeScreen) else if (m_nPrefsAudio3DProviderIndex == -1) rightText = TheText.Get("FEA_ADP"); else { - char* provider = DMAudio.Get3DProviderName(m_nPrefsAudio3DProviderIndex); - if (provider != NULL) { - if (!strcmp(strupr(provider), "DIRECTSOUND3D HARDWARE SUPPORT")) { - strcpy(provider, "DSOUND3D HARDWARE SUPPORT"); - } - else if (!strcmp(strupr(provider), "DIRECTSOUND3D SOFTWARE EMULATION")) { - strcpy(provider, "DSOUND3D SOFTWARE EMULATION"); - } - AsciiToUnicode(provider, unicodeTemp); - rightText = unicodeTemp; - } - else { - rightText = TheText.Get("not defined"); + char *rawProvider = DMAudio.Get3DProviderName(m_nPrefsAudio3DProviderIndex); + AsciiToUnicode(rawProvider, unicodeTemp); + char *provider = UnicodeToAscii(unicodeTemp); // genius + strupr(provider); + if (!strcmp(provider, "DIRECTSOUND3D HARDWARE SUPPORT")) { + strcpy(provider, "DSOUND3D HARDWARE SUPPORT"); + } else if (!strcmp(provider, "DIRECTSOUND3D SOFTWARE EMULATION")) { + strcpy(provider, "DSOUND3D SOFTWARE EMULATION"); } + AsciiToUnicode(provider, unicodeTemp); + rightText = unicodeTemp; } break; case MENUACTION_SPEAKERCONF: { @@ -4007,6 +4016,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u if (selectedProvider != NO_AUDIO_PROVIDER) { if (selectedProvider == -1) selectedProvider = m_nPrefsAudio3DProviderIndex = DMAudio.AutoDetect3DProviders(); + m_nPrefsAudio3DProviderIndex = DMAudio.SetCurrent3DProvider(m_nPrefsAudio3DProviderIndex); if (selectedProvider != m_nPrefsAudio3DProviderIndex) { SetHelperText(5); @@ -4039,7 +4049,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u m_PrefsMP3BoostVolume = 0; m_PrefsStereoMono = 1; m_PrefsSpeakers = 0; - // DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); // TODO(Miami) + DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); DMAudio.SetRadioInCar(m_PrefsRadioStation); @@ -4180,11 +4190,36 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u break; #endif case MENUACTION_AUDIOHW: - // TODO(Miami): What are the extra things in here?? - if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { m_nPrefsAudio3DProviderIndex += changeAmount; - m_nPrefsAudio3DProviderIndex = clamp(m_nPrefsAudio3DProviderIndex, 0, DMAudio.GetNum3DProvidersAvailable() - 1); + + bool checkIfForbidden = true; + while (checkIfForbidden) { + checkIfForbidden = false; + + if (m_nPrefsAudio3DProviderIndex < -1) + m_nPrefsAudio3DProviderIndex = DMAudio.GetNum3DProvidersAvailable() - 1; + else if (m_nPrefsAudio3DProviderIndex > DMAudio.GetNum3DProvidersAvailable() - 1) + m_nPrefsAudio3DProviderIndex = -1; + + // what a retarded move... + if (m_nPrefsAudio3DProviderIndex != -1) { + char* provider = DMAudio.Get3DProviderName(m_nPrefsAudio3DProviderIndex); + strupr(provider); + if (!strcmp(provider, "MILES FAST 2D POSITIONAL AUDIO")) { + m_nPrefsAudio3DProviderIndex += changeAmount; + checkIfForbidden = true; + + } else if (!strcmp(provider, "AUREAL A3D 2.0 (TM)")) { + m_nPrefsAudio3DProviderIndex += changeAmount; + checkIfForbidden = true; + + } else if (!strcmp(provider, "AUREAL A3D INTERACTIVE (TM)")) { + m_nPrefsAudio3DProviderIndex += changeAmount; + checkIfForbidden = true; + } + } + } } break; case MENUACTION_SPEAKERCONF: @@ -4543,19 +4578,13 @@ CMenuManager::UnloadTextures() CUserDisplay::PlaceName.ProcessAfterFrontEndShutDown(); } +// --MIAMI: Done void CMenuManager::WaitForUserCD() { CSprite2d *splash; char *splashscreen = nil; -#if (!(defined RANDOMSPLASH) && !(defined GTA3_1_1_PATCH)) - if (CGame::frenchGame || CGame::germanGame || !CGame::nastyGame) - splashscreen = "mainsc2"; - else - splashscreen = "mainsc1"; -#endif - splash = LoadSplash(splashscreen); if (RsGlobal.quit) @@ -4707,6 +4736,53 @@ CMenuManager::PrintMap(void) } CRadar::DrawBlips(); + if (m_PrefsShowLegends) { + CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(40.0f)); + CFont::SetRightJustifyWrap(SCREEN_SCALE_X(84.0f)); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetColor(CRGBA(255, 150, 225, FadeIn(255))); + CFont::SetDropShadowPosition(2); + CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); + CFont::SetCentreOn(); + CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); + CFont::SetScale(SCREEN_SCALE_X(0.65f), SCREEN_SCALE_Y(0.95f)); + + int secondColumnStart = (CRadar::MapLegendCounter - 1) / 2; + int boxBottom = MENU_Y(100.0f); + + // + 3, because we want 19*3 px padding + for (int i = 0; i < secondColumnStart + 3; i++) { + boxBottom += MENU_Y(19.f); + } + + CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(95.0f), MENU_Y(100.0f), MENU_X_LEFT_ALIGNED(555.f), boxBottom), + CRGBA(0, 0, 0, FadeIn(190))); + + CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), MENU_Y(102.0f), TheText.Get("FE_MLG")); + CFont::SetRightJustifyOff(); + CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + if (m_PrefsLanguage == LANGUAGE_AMERICAN) + CFont::SetScale(SCREEN_SCALE_X(0.55f), SCREEN_SCALE_Y(0.55f)); + else + CFont::SetScale(SCREEN_SCALE_X(0.45f), SCREEN_SCALE_Y(0.55f)); + + CFont::SetColor(CRGBA(225, 225, 225, FadeIn(255))); + CFont::SetDropShadowPosition(0); + + int y = MENU_Y(127.0f); + int x = MENU_X_LEFT_ALIGNED(160.0f); + + for (int16 i = 0; i < CRadar::MapLegendCounter; i++) { + CRadar::DrawLegend(x, y, CRadar::MapLegendList[i]); + + if (i == secondColumnStart) { + x = MENU_X_LEFT_ALIGNED(350.0f); + y = MENU_Y(127.0f); + } else { + y += MENU_Y(19.0f); + } + } + } #ifdef CUSTOM_MAP CVector2D mapPoint; @@ -4785,7 +4861,7 @@ CMenuManager::PrintMap(void) #endif m_bMenuMapActive = false; - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(5.0f)); + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(10.0f)); CFont::SetRightJustifyWrap(SCREEN_SCALE_X(10.0f)); DisplayHelperText("FEH_MPH"); } diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp index fe2cf7ad..b25fa4e1 100644 --- a/src/core/Pools.cpp +++ b/src/core/Pools.cpp @@ -2,6 +2,7 @@ #include "Pools.h" +#include "Bike.h" #include "Boat.h" #include "CarCtrl.h" #ifdef MISSION_REPLAY @@ -13,6 +14,8 @@ #include "Wanted.h" #include "World.h" +//--MIAMI: file done + CCPtrNodePool *CPools::ms_pPtrNodePool; CEntryInfoNodePool *CPools::ms_pEntryInfoNodePool; CPedPool *CPools::ms_pPedPool; @@ -24,7 +27,6 @@ CDummyPool *CPools::ms_pDummyPool; CAudioScriptObjectPool *CPools::ms_pAudioScriptObjectPool; CColModelPool *CPools::ms_pColModelPool; -//--MIAMI: done void CPools::Initialise(void) { @@ -40,7 +42,6 @@ CPools::Initialise(void) ms_pColModelPool = new CColModelPool(NUMCOLMODELS, "ColModel"); } -//--MIAMI: done void CPools::ShutDown(void) { @@ -119,7 +120,8 @@ void CPools::LoadVehiclePool(uint8* buf, uint32 size) INITSAVEBUF int nNumCars = ReadSaveBuf<int>(buf); int nNumBoats = ReadSaveBuf<int>(buf); - for (int i = 0; i < nNumCars + nNumBoats; i++) { + int nNumBikes = ReadSaveBuf<int>(buf); + for (int i = 0; i < nNumCars + nNumBoats + nNumBikes; i++) { uint32 type = ReadSaveBuf<uint32>(buf); int16 model = ReadSaveBuf<int16>(buf); CStreaming::RequestModel(model, STREAMFLAGS_DEPENDENCY); @@ -131,13 +133,15 @@ INITSAVEBUF pVehicle = new(slot) CBoat(model, RANDOM_VEHICLE); else if (type == VEHICLE_TYPE_CAR) pVehicle = new(slot) CAutomobile(model, RANDOM_VEHICLE); + else if (type == VEHICLE_TYPE_BIKE) + pVehicle = new(slot) CBike(model, RANDOM_VEHICLE); else assert(0); --CCarCtrl::NumRandomCars; pVehicle->Load(buf); CWorld::Add(pVehicle); #else - char* vbuf = new char[Max(CAutomobile::nSaveStructSize, CBoat::nSaveStructSize)]; + char* vbuf = new char[Max(CBike::nSaveStructSize, Max(CAutomobile::nSaveStructSize, CBoat::nSaveStructSize))]; if (type == VEHICLE_TYPE_BOAT) { memcpy(vbuf, buf, sizeof(CBoat)); SkipSaveBuf(buf, sizeof(CBoat)); @@ -156,6 +160,17 @@ INITSAVEBUF pAutomobile->Damage = ((CAutomobile*)vbuf)->Damage; pAutomobile->SetupDamageAfterLoad(); } + else if (type == VEHICLE_TYPE_BIKE) { +#ifdef FIX_BUGS + memcpy(vbuf, buf, sizeof(CBike)); +#else + memcpy(vbuf, buf, sizeof(CAutomobile)); +#endif + SkipSaveBuf(buf, sizeof(CBike)); + CBike* pBike = new(slot) CBike(model, RANDOM_VEHICLE); + pVehicle = pBike; + --CCarCtrl::NumRandomCars; + } else assert(0); CVehicle* pBufferVehicle = (CVehicle*)vbuf; @@ -193,6 +208,7 @@ INITSAVEBUF (pVehicle->GetAddressOfEntityProperties())[0] = (pBufferVehicle->GetAddressOfEntityProperties())[0]; (pVehicle->GetAddressOfEntityProperties())[1] = (pBufferVehicle->GetAddressOfEntityProperties())[1]; pVehicle->AutoPilot = pBufferVehicle->AutoPilot; + CCarCtrl::UpdateCarCount(pVehicle, false); CWorld::Add(pVehicle); delete[] vbuf; #endif @@ -205,6 +221,7 @@ void CPools::SaveVehiclePool(uint8* buf, uint32* size) INITSAVEBUF int nNumCars = 0; int nNumBoats = 0; + int nNumBikes = 0; int nPoolSize = GetVehiclePool()->GetSize(); for (int i = 0; i < nPoolSize; i++) { CVehicle* pVehicle = GetVehiclePool()->GetSlot(i); @@ -226,19 +243,25 @@ INITSAVEBUF ++nNumCars; if (pVehicle->IsBoat() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) ++nNumBoats; + if (pVehicle->IsBike() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) + ++nNumBoats; #else if (!pVehicle->pDriver && !bHasPassenger) { if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) ++nNumCars; if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) ++nNumBoats; + if (pVehicle->IsBike() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) + ++nNumBoats; #endif } } *size = nNumCars * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CAutomobile::nSaveStructSize) + sizeof(int) + - nNumBoats * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CBoat::nSaveStructSize) + sizeof(int); + nNumBoats * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CBoat::nSaveStructSize) + sizeof(int) + + nNumBikes * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CBike::nSaveStructSize) + sizeof(int); WriteSaveBuf(buf, nNumCars); WriteSaveBuf(buf, nNumBoats); + WriteSaveBuf(buf, nNumBikes); for (int i = 0; i < nPoolSize; i++) { CVehicle* pVehicle = GetVehiclePool()->GetSlot(i); if (!pVehicle) @@ -258,9 +281,9 @@ INITSAVEBUF #endif #ifdef COMPATIBLE_SAVES #ifdef MISSION_REPLAY - if ((pVehicle->IsCar() || pVehicle->IsBoat()) && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) { + if ((pVehicle->IsCar() || pVehicle->IsBoat() || pVehicle->IsBike()) && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) { #else - if ((pVehicle->IsCar() || pVehicle->IsBoat()) && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { + if ((pVehicle->IsCar() || pVehicle->IsBoat() || pVehicle->IsBike()) && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { #endif WriteSaveBuf<uint32>(buf, pVehicle->m_vehType); WriteSaveBuf<int16>(buf, pVehicle->GetModelIndex()); @@ -290,6 +313,17 @@ INITSAVEBUF memcpy(buf, pVehicle, sizeof(CBoat)); SkipSaveBuf(buf, sizeof(CBoat)); } +#ifdef MISSION_REPLAY + if (pVehicle->IsBike() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) { +#else + if (pVehicle->IsBike() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { +#endif + WriteSaveBuf(buf, (uint32)pVehicle->m_vehType); + WriteSaveBuf(buf, pVehicle->GetModelIndex()); + WriteSaveBuf(buf, GetVehicleRef(pVehicle)); + memcpy(buf, pVehicle, sizeof(CBike)); + SkipSaveBuf(buf, sizeof(CBike)); + } #endif } } @@ -311,8 +345,9 @@ INITSAVEBUF ++nObjects; } *size = nObjects * (sizeof(int16) + sizeof(int) + sizeof(CCompressedMatrix) + - sizeof(float) + sizeof(CCompressedMatrix) + sizeof(int8) + 7 * sizeof(bool) + sizeof(float) + - sizeof(int8) + sizeof(int8) + sizeof(uint32) + 2 * sizeof(uint32)) + sizeof(int); + sizeof(float) + sizeof(CCompressedMatrix) + sizeof(int8) + 7 * sizeof(bool) + sizeof(int16) + + + sizeof(int8) * 2 + sizeof(float) + sizeof(int8) + sizeof(int8) + + sizeof(uint32) + 2 * sizeof(uint32)) + sizeof(int); CopyToBuf(buf, nObjects); for (int i = 0; i < nPoolSize; i++) { CObject* pObject = GetObjectPool()->GetSlot(i); @@ -343,6 +378,9 @@ INITSAVEBUF CopyToBuf(buf, bGlassBroken); CopyToBuf(buf, bHasBeenDamaged); CopyToBuf(buf, bUseVehicleColours); + CopyToBuf(buf, pObject->m_nCostValue); + CopyToBuf(buf, pObject->m_nBonusValue); + SkipSaveBuf(buf, 1); CopyToBuf(buf, pObject->m_fCollisionDamageMultiplier); CopyToBuf(buf, pObject->m_nCollisionDamageEffect); CopyToBuf(buf, pObject->m_nSpecialCollisionResponseCases); @@ -392,6 +430,9 @@ INITSAVEBUF pBufferObject->bHasBeenDamaged = bitFlag; CopyFromBuf(buf, bitFlag); pBufferObject->bUseVehicleColours = bitFlag; + CopyFromBuf(buf, pBufferObject->m_nCostValue); + CopyFromBuf(buf, pBufferObject->m_nBonusValue); + SkipSaveBuf(buf, 1); CopyFromBuf(buf, pBufferObject->m_fCollisionDamageMultiplier); CopyFromBuf(buf, pBufferObject->m_nCollisionDamageEffect); CopyFromBuf(buf, pBufferObject->m_nSpecialCollisionResponseCases); @@ -426,6 +467,8 @@ INITSAVEBUF (pObject->GetAddressOfEntityProperties())[1] = (pBufferObject->GetAddressOfEntityProperties())[1]; #endif pObject->bHasCollided = false; + pObject->m_nCostValue = pBufferObject->m_nCostValue; + pObject->m_nBonusValue = pBufferObject->m_nBonusValue; CWorld::Add(pObject); delete[] obuf; } diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp index 5317040f..8fe900ae 100644 --- a/src/core/Radar.cpp +++ b/src/core/Radar.cpp @@ -15,6 +15,9 @@ #include "World.h" #include "Streaming.h" #include "SpecialFX.h" +#include "Font.h" + +// --MIAMI: file done float CRadar::m_radarRange; sRadarTrace CRadar::ms_RadarTrace[NUMRADARBLIPS]; @@ -123,7 +126,7 @@ static_assert(RADAR_TILE_SIZE == (RADAR_SIZE_Y / RADAR_NUM_TILES), "CRadar: not CRGBA CRadar::ArrowBlipColour1; CRGBA CRadar::ArrowBlipColour2; -uint16 CRadar::MapLegendCounter; +int16 CRadar::MapLegendCounter; int16 CRadar::MapLegendList[NUM_MAP_LEGENDS]; #ifdef MAP_ENHANCEMENTS int CRadar::TargetMarkerId = -1; @@ -153,7 +156,7 @@ void RequestMapSection(int32 x, int32 y) void RemoveMapSection(int32 x, int32 y) { - if (x >= 0 && x <= 7 && y >= 0 && y <= 7) + if (x >= 0 && x <= RADAR_NUM_TILES - 1 && y >= 0 && y <= RADAR_NUM_TILES - 1) CStreaming::RemoveTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y]); } @@ -260,7 +263,6 @@ int LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D & return edge; } - uint8 CRadar::CalculateBlipAlpha(float dist) { if (FrontEndMenuManager.m_bMenuMapActive) @@ -269,8 +271,8 @@ uint8 CRadar::CalculateBlipAlpha(float dist) if (dist <= 1.0f) return 255; - if (dist <= 5.0f) - return (128.0f * ((dist - 1.0f) / 4.0f)) + ((1.0f - (dist - 1.0f) / 4.0f) * 255.0f); + if (dist <= 10.0f) + return (128.0f * ((dist - 1.0f) / 9.0f)) + ((1.0f - (dist - 1.0f) / 9.0f) * 255.0f); return 128; } @@ -507,7 +509,6 @@ void CRadar::DrawBlips() DrawRadarSprite(RADAR_SPRITE_NORTH, out.x, out.y, 255); } - CEntity *blipEntity = nil; for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) { if (!ms_RadarTrace[blipId].m_bInUse) continue; @@ -516,173 +517,65 @@ void CRadar::DrawBlips() case BLIP_CAR: case BLIP_CHAR: case BLIP_OBJECT: - if (ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE - || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_GUN) { + if (ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_PROPERTY + && (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive)) + DrawEntityBlip(blipId); - switch (ms_RadarTrace[blipId].m_eBlipType) { - case BLIP_CAR: - blipEntity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); - break; - case BLIP_CHAR: - blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); - if (blipEntity != nil) { - if (((CPed*)blipEntity)->InVehicle()) - blipEntity = ((CPed*)blipEntity)->m_pMyVehicle; - } - break; - case BLIP_OBJECT: - blipEntity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); - break; - default: - break; - } - if (blipEntity) { - uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); - if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { - if (CTheScripts::IsDebugOn()) { - ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius); - ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f; - if (ms_RadarTrace[blipId].m_Radius < 1.0f) - ms_RadarTrace[blipId].m_Radius = 5.0f; - } - } - if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) { - TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition()); - float dist = LimitRadarPoint(in); - TransformRadarPointToScreenSpace(out, in); - if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { - DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); - } - else { -#ifdef TRIANGULAR_BLIPS - const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); - const CVector& blipPos = blipEntity->GetPosition(); - uint8 mode = BLIP_MODE_TRIANGULAR_UP; - if (blipPos.z - pos.z <= 2.0f) { - if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; - else mode = BLIP_MODE_SQUARE; - } - ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); -#else - ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); -#endif - } - } - } - } - } break; case BLIP_COORD: case BLIP_CONTACT_POINT: - if ((ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE - || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_GUN) - && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) { - - uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); - if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { - if (CTheScripts::IsDebugOn()) { - ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius); - ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f; - if (ms_RadarTrace[blipId].m_Radius < 1.0f) - ms_RadarTrace[blipId].m_Radius = 5.0f; - } - } - if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) { - TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos); - float dist = LimitRadarPoint(in); - TransformRadarPointToScreenSpace(out, in); - if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { - DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); - } - else { -#ifdef TRIANGULAR_BLIPS - const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); - const CVector& blipPos = ms_RadarTrace[blipId].m_vecPos; - uint8 mode = BLIP_MODE_TRIANGULAR_UP; - if (blipPos.z - pos.z <= 2.0f) { - if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; - else mode = BLIP_MODE_SQUARE; - } - ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); -#else - ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); -#endif - } - } - } - } + if (ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_PHONE + && (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive)) + DrawCoordBlip(blipId); + break; default: break; } } + + // New in VC: Always draw Hardware/gun/pay'n spray/save blips for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) { if (!ms_RadarTrace[blipId].m_bInUse) continue; + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_HARDWARE + && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN) + continue; + switch (ms_RadarTrace[blipId].m_eBlipType) { case BLIP_CAR: case BLIP_CHAR: case BLIP_OBJECT: - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE - && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN) { + if (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive) + DrawEntityBlip(blipId); - switch (ms_RadarTrace[blipId].m_eBlipType) { - case BLIP_CAR: - blipEntity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); - break; - case BLIP_CHAR: - blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); - if (blipEntity != nil) { - if (((CPed*)blipEntity)->InVehicle()) - blipEntity = ((CPed*)blipEntity)->m_pMyVehicle; - } - break; - case BLIP_OBJECT: - blipEntity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); - break; - default: - break; - } + break; + case BLIP_COORD: + case BLIP_CONTACT_POINT: + if (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive) + DrawCoordBlip(blipId); + + break; + default: + break; + } + } - if (blipEntity) { - uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); - if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { - if (CTheScripts::IsDebugOn()) { - ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius); - ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f; - if (ms_RadarTrace[blipId].m_Radius < 1.0f) - ms_RadarTrace[blipId].m_Radius = 5.0f; - } - } - if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) { - TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition()); - float dist = LimitRadarPoint(in); - TransformRadarPointToScreenSpace(out, in); - if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) - DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); - else -#ifdef TRIANGULAR_BLIPS - { - const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); - const CVector& blipPos = blipEntity->GetPosition(); - uint8 mode = BLIP_MODE_TRIANGULAR_UP; - if (blipPos.z - pos.z <= 2.0f) { - if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; - else mode = BLIP_MODE_SQUARE; - } - ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); - } -#else - ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); -#endif - } - } - } - } + for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) { + if (!ms_RadarTrace[blipId].m_bInUse) + continue; + + switch (ms_RadarTrace[blipId].m_eBlipType) { + case BLIP_CAR: + case BLIP_CHAR: + case BLIP_OBJECT: + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_HARDWARE + && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_PROPERTY + && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN + && (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive)) + + DrawEntityBlip(blipId); break; default: break; @@ -695,44 +588,12 @@ void CRadar::DrawBlips() switch (ms_RadarTrace[blipId].m_eBlipType) { case BLIP_COORD: case BLIP_CONTACT_POINT: - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE - && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN - && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) { - - uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); - if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { - if (CTheScripts::IsDebugOn()) { - ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius); - ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f; - if (ms_RadarTrace[blipId].m_Radius < 1.0f) - ms_RadarTrace[blipId].m_Radius = 5.0f; - } - } - if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) { - TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos); - float dist = LimitRadarPoint(in); - TransformRadarPointToScreenSpace(out, in); - if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) - DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); - else -#ifdef TRIANGULAR_BLIPS - { - const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); - const CVector& blipPos = ms_RadarTrace[blipId].m_vecPos; - uint8 mode = BLIP_MODE_TRIANGULAR_UP; - if (blipPos.z - pos.z <= 2.0f) { - if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; - else mode = BLIP_MODE_SQUARE; - } - ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); - } -#else - ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); -#endif - } - } - } + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_HARDWARE + && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_PROPERTY + && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_PHONE + && (!CTheScripts::bPlayerIsInTheStatium || !FrontEndMenuManager.m_bMenuMapActive)) + + DrawCoordBlip(blipId); break; default: break; @@ -740,7 +601,12 @@ void CRadar::DrawBlips() } if (FrontEndMenuManager.m_bMenuMapActive) { CVector2D in, out; - TransformRealWorldPointToRadarSpace(in, FindPlayerCentreOfWorld_NoSniperShift()); + if (!CTheScripts::bPlayerIsInTheStatium) + TransformRealWorldPointToRadarSpace(in, FindPlayerCentreOfWorld_NoSniperShift()); + else + TransformRealWorldPointToRadarSpace(in, CVector2D(-1302.5f, 1332.8f)); + + LimitRadarPoint(in); TransformRadarPointToScreenSpace(out, in); DrawYouAreHereSprite(out.x, out.y); } @@ -771,8 +637,6 @@ void CRadar::DrawMap() void CRadar::DrawRadarMap() { - // Game calculates an unused CRect here - DrawRadarMask(); // top left ist (0, 0) @@ -812,14 +676,20 @@ void CRadar::DrawRadarMask() }; RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE); - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDZERO); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT); RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); +#if !defined(GTA_PS2_STUFF) && defined(RWLIBS) + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS); +#else + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDZERO); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); +#endif CVector2D out[8]; CVector2D in; @@ -840,7 +710,11 @@ void CRadar::DrawRadarMask() CSprite2d::SetMaskVertices(8, (float *)out); RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), 8); - }; + } +#if !defined(GTA_PS2_STUFF) && defined(RWLIBS) + RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); +#endif + } void CRadar::DrawRadarSection(int32 x, int32 y) @@ -858,11 +732,8 @@ void CRadar::DrawRadarSection(int32 x, int32 y) GetTextureCorners(x, y, worldPoly); ClipRadarTileCoords(x, y); - assert(CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y])); - txd = CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y])->texDict; - if (txd) - texture = GetFirstTexture(txd); - if (texture == nil) + if (!CTheScripts::bPlayerIsInTheStatium && + (!(txd = CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y])->texDict) || !(texture = GetFirstTexture(txd)))) return; for (i = 0; i < 4; i++) @@ -880,8 +751,15 @@ void CRadar::DrawRadarSection(int32 x, int32 y) TransformRealWorldToTexCoordSpace(texCoords[i], worldPoly[i], x, y); TransformRadarPointToScreenSpace(screenPoly[i], radarPoly[i]); } - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(texture)); - CSprite2d::SetVertices(numVertices, (float*)screenPoly, (float*)texCoords, CRGBA(255, 255, 255, 255)); + + if (CTheScripts::bPlayerIsInTheStatium) { + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil); + CSprite2d::SetVertices(numVertices, (float*)screenPoly, (float*)texCoords, CRGBA(204, 204, 204, 255)); + } else { + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(texture)); + CSprite2d::SetVertices(numVertices, (float*)screenPoly, (float*)texCoords, CRGBA(255, 255, 255, 255)); + } + // check done above now // if(numVertices > 2) RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), numVertices); @@ -907,28 +785,17 @@ void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha) void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int32 alpha) { CVector curPosn[4]; - CVector oldPosn[4]; - - curPosn[0].x = x - SCREEN_SCALE_X(5.6f); - curPosn[0].y = y + SCREEN_SCALE_Y(5.6f); - - curPosn[1].x = x + SCREEN_SCALE_X(5.6f); - curPosn[1].y = y + SCREEN_SCALE_Y(5.6f); - - curPosn[2].x = x - SCREEN_SCALE_X(5.6f); - curPosn[2].y = y - SCREEN_SCALE_Y(5.6f); - - curPosn[3].x = x + SCREEN_SCALE_X(5.6f); - curPosn[3].y = y - SCREEN_SCALE_Y(5.6f); + const float sizeX = SCREEN_SCALE_X(8.0f); + const float correctedAngle = angle - PI / 4.f; + const float sizeY = SCREEN_SCALE_Y(8.0f); for (uint32 i = 0; i < 4; i++) { - oldPosn[i] = curPosn[i]; - - curPosn[i].x = x + (oldPosn[i].x - x) * Cos(angle) + (oldPosn[i].y - y) * Sin(angle); - curPosn[i].y = y - (oldPosn[i].x - x) * Sin(angle) + (oldPosn[i].y - y) * Cos(angle); + const float cornerAngle = i * HALFPI + correctedAngle; + curPosn[i].x = x + (0.0f * Cos(cornerAngle) + 1.0f * Sin(cornerAngle)) * sizeX; + curPosn[i].y = y - (0.0f * Sin(cornerAngle) - 1.0f * Cos(cornerAngle)) * sizeY; } - sprite->Draw(curPosn[2].x, curPosn[2].y, curPosn[3].x, curPosn[3].y, curPosn[0].x, curPosn[0].y, curPosn[1].x, curPosn[1].y, CRGBA(255, 255, 255, alpha)); + sprite->Draw(curPosn[3].x, curPosn[3].y, curPosn[2].x, curPosn[2].y, curPosn[0].x, curPosn[0].y, curPosn[1].x, curPosn[1].y, CRGBA(255, 255, 255, alpha)); } int32 CRadar::GetActualBlipArrayIndex(int32 i) @@ -954,43 +821,43 @@ uint32 CRadar::GetRadarTraceColour(uint32 color, bool bright) { int32 c; switch (color) { - case 0: + case RADAR_TRACE_RED: if (bright) c = 0x712B49FF; else c = 0x7F0000FF; break; - case 1: + case RADAR_TRACE_GREEN: if (bright) c = 0x5FA06AFF; else c = 0x007F00FF; break; - case 2: + case RADAR_TRACE_LIGHT_BLUE: if (bright) c = 0x80A7F3FF; else c = 0x00007FFF; break; - case 3: + case RADAR_TRACE_GRAY: if (bright) c = 0xE1E1E1FF; else c = 0x7F7F7FFF; break; - case 4: + case RADAR_TRACE_YELLOW: if (bright) c = 0xFFFF00FF; else c = 0x7F7F00FF; break; - case 5: + case RADAR_TRACE_MAGENTA: if (bright) c = 0xFF00FFFF; else c = 0x7F007FFF; break; - case 6: + case RADAR_TRACE_CYAN: if (bright) c = 0x00FFFFFF; else @@ -1055,12 +922,65 @@ void CRadar::LoadAllRadarBlips(uint8 *buf, uint32 size) INITSAVEBUF CheckSaveHeader(buf, 'R', 'D', 'R', '\0', size - SAVE_HEADER_SIZE); - for (int i = 0; i < NUMRADARBLIPS; i++) - ms_RadarTrace[i] = ReadSaveBuf<sRadarTrace>(buf); + for (int i = 0; i < NUMRADARBLIPS; i++) { + ms_RadarTrace[i].m_nColor = ReadSaveBuf<uint32>(buf); + ms_RadarTrace[i].m_Radius = ReadSaveBuf<float>(buf); + ms_RadarTrace[i].m_eBlipType = ReadSaveBuf<uint32>(buf); + ms_RadarTrace[i].m_nEntityHandle = ReadSaveBuf<int32>(buf); + ms_RadarTrace[i].m_vec2DPos.x = ReadSaveBuf<float>(buf); // CVector2D + ms_RadarTrace[i].m_vec2DPos.y = ReadSaveBuf<float>(buf); + ms_RadarTrace[i].m_vecPos = ReadSaveBuf<CVector>(buf); + ms_RadarTrace[i].m_BlipIndex = ReadSaveBuf<uint16>(buf); + ms_RadarTrace[i].m_bDim = ReadSaveBuf<bool>(buf); + ms_RadarTrace[i].m_bInUse = ReadSaveBuf<bool>(buf); + ms_RadarTrace[i].m_bShortRange = ReadSaveBuf<bool>(buf); + ms_RadarTrace[i].m_unused = ReadSaveBuf<bool>(buf); + ms_RadarTrace[i].m_wScale = ReadSaveBuf<int16>(buf); + ms_RadarTrace[i].m_eBlipDisplay = ReadSaveBuf<uint16>(buf); + ms_RadarTrace[i].m_eRadarSprite = ReadSaveBuf<uint16>(buf); + } VALIDATESAVEBUF(size); } +void CRadar::SaveAllRadarBlips(uint8 *buf, uint32 *size) +{ + *size = SAVE_HEADER_SIZE + NUMRADARBLIPS * sizeof(sRadarTraceSave); + +INITSAVEBUF + WriteSaveHeader(buf, 'R', 'D', 'R', '\0', *size - SAVE_HEADER_SIZE); + +#ifdef MAP_ENHANCEMENTS + if (TargetMarkerId != -1) { + ClearBlip(TargetMarkerId); + TargetMarkerId = -1; + } +#endif + + for (int i = 0; i < NUMRADARBLIPS; i++) { + sRadarTraceSave *saveStruct = (sRadarTraceSave*) buf; + + saveStruct->m_nColor = ms_RadarTrace[i].m_nColor; + saveStruct->m_Radius = ms_RadarTrace[i].m_Radius; + saveStruct->m_eBlipType = ms_RadarTrace[i].m_eBlipType; + saveStruct->m_nEntityHandle = ms_RadarTrace[i].m_nEntityHandle; + saveStruct->m_vec2DPos = ms_RadarTrace[i].m_vec2DPos; + saveStruct->m_vecPos = ms_RadarTrace[i].m_vecPos; + saveStruct->m_BlipIndex = ms_RadarTrace[i].m_BlipIndex; + saveStruct->m_bDim = ms_RadarTrace[i].m_bDim; + saveStruct->m_bInUse = ms_RadarTrace[i].m_bInUse; + saveStruct->m_bShortRange = ms_RadarTrace[i].m_bShortRange; + saveStruct->m_unused = ms_RadarTrace[i].m_unused; + saveStruct->m_wScale = ms_RadarTrace[i].m_wScale; + saveStruct->m_eBlipDisplay = ms_RadarTrace[i].m_eBlipDisplay; + saveStruct->m_eRadarSprite = ms_RadarTrace[i].m_eRadarSprite; + + SkipSaveBuf(buf, sizeof(sRadarTraceSave)); + } + +VALIDATESAVEBUF(*size); +} + void CRadar::LoadTextures() { @@ -1115,25 +1035,6 @@ void CRadar::RemoveRadarSections() RemoveMapSection(i, j); } -void CRadar::SaveAllRadarBlips(uint8 *buf, uint32 *size) -{ - *size = SAVE_HEADER_SIZE + sizeof(ms_RadarTrace); -INITSAVEBUF - WriteSaveHeader(buf, 'R', 'D', 'R', '\0', *size - SAVE_HEADER_SIZE); - -#ifdef MAP_ENHANCEMENTS - if (TargetMarkerId != -1) { - ClearBlip(TargetMarkerId); - TargetMarkerId = -1; - } -#endif - - for (int i = 0; i < NUMRADARBLIPS; i++) - WriteSaveBuf(buf, ms_RadarTrace[i]); - -VALIDATESAVEBUF(*size); -} - void CRadar::SetBlipSprite(int32 i, int32 icon) { int index = CRadar::GetActualBlipArrayIndex(i); @@ -1142,7 +1043,7 @@ void CRadar::SetBlipSprite(int32 i, int32 icon) } } -int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay display) +int CRadar::SetCoordBlip(eBlipType type, CVector pos, uint32 color, eBlipDisplay display) { int nextBlip; for (nextBlip = 0; nextBlip < NUMRADARBLIPS; nextBlip++) { @@ -1154,7 +1055,7 @@ int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay return -1; #endif ms_RadarTrace[nextBlip].m_eBlipType = type; - ms_RadarTrace[nextBlip].m_nColor = color; + ms_RadarTrace[nextBlip].m_nColor = RADAR_TRACE_MAGENTA; ms_RadarTrace[nextBlip].m_bDim = true; ms_RadarTrace[nextBlip].m_bInUse = true; ms_RadarTrace[nextBlip].m_bShortRange = false; @@ -1168,7 +1069,7 @@ int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay return CRadar::GetNewUniqueBlipIndex(nextBlip); } -int CRadar::SetShortRangeCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay display) +int CRadar::SetShortRangeCoordBlip(eBlipType type, CVector pos, uint32 color, eBlipDisplay display) { int index = SetCoordBlip(type, pos, color, display); if (index == -1) @@ -1177,7 +1078,7 @@ int CRadar::SetShortRangeCoordBlip(eBlipType type, CVector pos, int32 color, eBl return index; } -int CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDisplay display) +int CRadar::SetEntityBlip(eBlipType type, int32 handle, uint32 color, eBlipDisplay display) { int nextBlip; for (nextBlip = 0; nextBlip < NUMRADARBLIPS; nextBlip++) { @@ -1189,7 +1090,7 @@ int CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDispla return -1; #endif ms_RadarTrace[nextBlip].m_eBlipType = type; - ms_RadarTrace[nextBlip].m_nColor = color; + ms_RadarTrace[nextBlip].m_nColor = RADAR_TRACE_YELLOW; ms_RadarTrace[nextBlip].m_bDim = true; ms_RadarTrace[nextBlip].m_bInUse = true; ms_RadarTrace[nextBlip].m_bShortRange = false; @@ -1261,12 +1162,12 @@ void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red, switch (mode) { case BLIP_MODE_TRIANGULAR_UP: - // size++; // VC does size + 1 for triangles + size++; CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(size + 3.0f), y + SCREEN_SCALE_Y(size + 2.0f), x - (SCREEN_SCALE_X(size + 3.0f)), y + SCREEN_SCALE_Y(size + 2.0f), x, y - (SCREEN_SCALE_Y(size + 3.0f)), x, y - (SCREEN_SCALE_Y(size + 3.0f)), CRGBA(0, 0, 0, alpha)); CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(size + 1.0f), y + SCREEN_SCALE_Y(size + 1.0f), x - (SCREEN_SCALE_X(size + 1.0f)), y + SCREEN_SCALE_Y(size + 1.0f), x, y - (SCREEN_SCALE_Y(size + 1.0f)), x, y - (SCREEN_SCALE_Y(size + 1.0f)), CRGBA(red, green, blue, alpha)); break; case BLIP_MODE_TRIANGULAR_DOWN: - // size++; // VC does size + 1 for triangles + size++; CSprite2d::Draw2DPolygon(x, y + SCREEN_SCALE_Y(size + 2.0f), x, y + SCREEN_SCALE_Y(size + 3.0f), x + SCREEN_SCALE_X(size + 3.0f), y - (SCREEN_SCALE_Y(size + 2.0f)), x - (SCREEN_SCALE_X(size + 3.0f)), y - (SCREEN_SCALE_Y(size + 2.0f)), CRGBA(0, 0, 0, alpha)); CSprite2d::Draw2DPolygon(x, y + SCREEN_SCALE_Y(size + 1.0f), x, y + SCREEN_SCALE_Y(size + 1.0f), x + SCREEN_SCALE_X(size + 1.0f), y - (SCREEN_SCALE_Y(size + 1.0f)), x - (SCREEN_SCALE_X(size + 1.0f)), y - (SCREEN_SCALE_Y(size + 1.0f)), CRGBA(red, green, blue, alpha)); break; @@ -1275,21 +1176,6 @@ void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red, CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size), y - SCREEN_SCALE_Y(size), SCREEN_SCALE_X(size) + x, SCREEN_SCALE_Y(size) + y), CRGBA(red, green, blue, alpha)); break; } - - // TODO(Miami): Map - // VC uses -1 for coords and -2 for entities but meh, I don't want to edit DrawBlips - if (FrontEndMenuManager.m_bMenuMapActive) { - bool alreadyThere = false; - for (int i = 0; i < NUM_MAP_LEGENDS; i++) { - if (MapLegendList[i] == -1) - alreadyThere = true; - } - if (!alreadyThere) { - MapLegendList[MapLegendCounter] = -1; - MapLegendCounter++; - ArrowBlipColour1 = CRGBA(red, green, blue, alpha); - } - } } void CRadar::Shutdown() @@ -1338,7 +1224,8 @@ void CRadar::Shutdown() void CRadar::StreamRadarSections(const CVector &posn) { - StreamRadarSections(Floor((2000.0f + posn.x) / 500.0f), Ceil(7.0f - (2000.0f + posn.y) / 500.0f)); + if (!CStreaming::ms_disableStreaming) + StreamRadarSections(Floor((RADAR_MAX_X + posn.x) / RADAR_TILE_SIZE), Ceil((RADAR_NUM_TILES - 1) - (RADAR_MAX_Y + posn.y) / RADAR_TILE_SIZE)); } void CRadar::StreamRadarSections(int32 x, int32 y) @@ -1405,8 +1292,8 @@ void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D void CRadar::CalculateCachedSinCos() { - if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED - || FrontEndMenuManager.m_bMenuMapActive ) { + if (/*TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED || */ + FrontEndMenuManager.m_bMenuMapActive ) { cachedSin = 0.0f; cachedCos = 1.0f; } else if (TheCamera.GetLookDirection() == LOOKING_FORWARD) { @@ -1445,7 +1332,7 @@ CRadar::InitFrontEndMap() void CRadar::DrawYouAreHereSprite(float x, float y) { - static uint32 lastChange = 0; + static PauseModeTime lastChange = 0; static bool show = true; if (show) { @@ -1461,13 +1348,30 @@ CRadar::DrawYouAreHereSprite(float x, float y) } if (show) { - float left = x - SCREEN_SCALE_X(12.0f); - float top = y; - float right = SCREEN_SCALE_X(12.0) + x; - float bottom = y - SCREEN_SCALE_Y(24.0f); - CentreSprite.Draw(CRect(left, top, right, bottom), CRGBA(255, 255, 255, 255)); + const float left = x - SCREEN_SCALE_X(8.0f); + const float top = y - SCREEN_SCALE_Y(40.0f); + const float right = x + SCREEN_SCALE_X(40.0); + const float bottom = y + SCREEN_SCALE_Y(8.0f); + MapHereSprite.Draw(CRect(left + SCREEN_SCALE_X(2.f), top + SCREEN_SCALE_Y(2.f), right + SCREEN_SCALE_X(2.f), bottom + SCREEN_SCALE_Y(2.f)), + CRGBA(0, 0, 0, 255)); + + MapHereSprite.Draw(CRect(left, top, right, bottom), CRGBA(255, 255, 255, 255)); + + CFont::SetWrapx(right + SCREEN_SCALE_X(28.0f)); + CFont::SetRightJustifyWrap(right); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetColor(CRGBA(255, 150, 225, 255)); + CFont::SetDropShadowPosition(2); + CFont::SetDropColor(CRGBA(0, 0, 0, 255)); + CFont::SetCentreOff(); + CFont::SetRightJustifyOff(); + CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); + CFont::SetScale(SCREEN_SCALE_X(0.65f), SCREEN_SCALE_Y(0.95f)); + CFont::PrintString(right, top, TheText.Get("MAP_YAH")); + CFont::SetDropShadowPosition(0); + CFont::DrawFonts(); } - MapLegendList[MapLegendCounter++] = RADAR_SPRITE_CENTRE; + MapLegendList[MapLegendCounter++] = RADAR_SPRITE_MAP_HERE; } #ifdef MAP_ENHANCEMENTS @@ -1485,8 +1389,8 @@ CRadar::ToggleTargetMarker(float x, float y) return; ms_RadarTrace[nextBlip].m_eBlipType = BLIP_COORD; - ms_RadarTrace[nextBlip].m_nColor = 0x333333FF; - ms_RadarTrace[nextBlip].m_bDim = 1; + ms_RadarTrace[nextBlip].m_nColor = RADAR_TRACE_GRAY; + ms_RadarTrace[nextBlip].m_bDim = 0; ms_RadarTrace[nextBlip].m_bInUse = 1; ms_RadarTrace[nextBlip].m_Radius = 1.0f; CVector pos(x, y, CWorld::FindGroundZForCoord(x,y)); @@ -1505,3 +1409,287 @@ CRadar::ToggleTargetMarker(float x, float y) } #endif +void +CRadar::DrawEntityBlip(int32 blipId) +{ + CVector2D out; + CVector2D in; + CEntity *blipEntity; + switch (ms_RadarTrace[blipId].m_eBlipType) { + case BLIP_CAR: + blipEntity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); + break; + case BLIP_CHAR: + blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); + if (blipEntity != nil) { + if (((CPed*)blipEntity)->InVehicle()) + blipEntity = ((CPed*)blipEntity)->m_pMyVehicle; + } + break; + case BLIP_OBJECT: + blipEntity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); + break; + default: + break; + } + if (blipEntity) { + uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); + if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { + if (CTheScripts::IsDebugOn()) { + ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius); + ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f; + if (ms_RadarTrace[blipId].m_Radius < 1.0f) + ms_RadarTrace[blipId].m_Radius = 5.0f; + } + } + if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) { + TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition()); + float dist = LimitRadarPoint(in); + TransformRadarPointToScreenSpace(out, in); + if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { + DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); + } else { + const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); + const CVector& blipPos = blipEntity->GetPosition(); + uint8 mode = BLIP_MODE_TRIANGULAR_UP; + if (blipPos.z - pos.z <= 2.0f) { + if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; + else mode = BLIP_MODE_SQUARE; + } + ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); + + if (FrontEndMenuManager.m_bMenuMapActive) { + bool alreadyThere = false; + for (int i = 0; i < NUM_MAP_LEGENDS; i++) { + if (MapLegendList[i] == -2) + alreadyThere = true; + } + if (!alreadyThere) { + MapLegendList[MapLegendCounter] = -2; + MapLegendCounter++; + ArrowBlipColour2 = CRGBA((uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); + } + } + } + } + } + } +} + +void +CRadar::DrawCoordBlip(int32 blipId) +{ + CVector2D out; + CVector2D in; + if (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission()) { + + uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); + if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { + if (CTheScripts::IsDebugOn()) { + ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius); + ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f; + if (ms_RadarTrace[blipId].m_Radius < 1.0f) + ms_RadarTrace[blipId].m_Radius = 5.0f; + } + } + if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) { + TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos); + float dist = LimitRadarPoint(in); + TransformRadarPointToScreenSpace(out, in); + if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { + DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); + } else { + const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); + const CVector& blipPos = ms_RadarTrace[blipId].m_vecPos; + uint8 mode = BLIP_MODE_TRIANGULAR_UP; + if (blipPos.z - pos.z <= 2.0f) { + if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; + else mode = BLIP_MODE_SQUARE; + } + ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); + + if (FrontEndMenuManager.m_bMenuMapActive) { + bool alreadyThere = false; + for (int i = 0; i < NUM_MAP_LEGENDS; i++) { + if (MapLegendList[i] == -1) + alreadyThere = true; + } + if (!alreadyThere) { + MapLegendList[MapLegendCounter] = -1; + MapLegendCounter++; + ArrowBlipColour1 = CRGBA((uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); + } + } + } + } + } + } +} + +void +CRadar::DrawLegend(int32 x, int32 y, int32 sprite) +{ + if (sprite < 0) { + static PauseModeTime lastChange = 0; + static int8 blipMode = 0; + + CRGBA color; + if (sprite == -1) { + color = ArrowBlipColour1; + } else { + color = ArrowBlipColour2; + } + + if (CTimer::GetTimeInMillisecondsPauseMode() - lastChange > 600) { + lastChange = CTimer::GetTimeInMillisecondsPauseMode(); + if ( blipMode == 2 ) + blipMode = 0; + else + ++blipMode; + } + + switch (blipMode) { + case BLIP_MODE_TRIANGULAR_UP: + CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(14.0f), y + SCREEN_SCALE_Y(13.0f), x + SCREEN_SCALE_X(2.0f), y + SCREEN_SCALE_Y(13.0f), x + SCREEN_SCALE_X(8.f), y + SCREEN_SCALE_Y(2.0f), x + SCREEN_SCALE_X(8.f), y + SCREEN_SCALE_Y(2.0f), CRGBA(0, 0, 0, 255)); + CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(12.0f), y + SCREEN_SCALE_Y(12.0f), x + SCREEN_SCALE_X(4.0f), y + SCREEN_SCALE_Y(12.0f), x + SCREEN_SCALE_X(8.f), y + SCREEN_SCALE_Y(4.0f), x + SCREEN_SCALE_X(8.f), y + SCREEN_SCALE_Y(4.0f), color); + break; + case BLIP_MODE_TRIANGULAR_DOWN: + CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(14.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(14.0f), x + SCREEN_SCALE_X(2.f), y + SCREEN_SCALE_Y(3.0f), x + SCREEN_SCALE_X(2.f), y + SCREEN_SCALE_Y(3.0f), CRGBA(0, 0, 0, 255)); + CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(12.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(12.0f), x + SCREEN_SCALE_X(12.f), y + SCREEN_SCALE_Y(4.0f), x + SCREEN_SCALE_X(4.f), y + SCREEN_SCALE_Y(4.0f), color); + break; + case BLIP_MODE_SQUARE: + CSprite2d::DrawRect(CRect(x + SCREEN_SCALE_X(4.0f), y + SCREEN_SCALE_Y(3.0f), SCREEN_SCALE_X(12.0f) + x, SCREEN_SCALE_Y(12.0f) + y), CRGBA(0, 0, 0, 255)); + CSprite2d::DrawRect(CRect(x + SCREEN_SCALE_X(5.0f), y + SCREEN_SCALE_Y(4.0f), SCREEN_SCALE_X(11.0f) + x, SCREEN_SCALE_Y(11.0f) + y), color); + break; + } + + } else { + RadarSprites[sprite]->Draw(CRect(x, y, x + SCREEN_SCALE_X(16.f), y + SCREEN_SCALE_X(16.f)), CRGBA(255, 255, 255, 255)); + } + + wchar *text; + switch ( sprite ) { + case RADAR_SPRITE_ENTITY_BLIP: + text = TheText.Get("LG_38"); + break; + case RADAR_SPRITE_COORD_BLIP: + text = TheText.Get("LG_35"); + break; + case RADAR_SPRITE_MAP_HERE: + text = TheText.Get("LG_01"); + break; + case RADAR_SPRITE_AVERY: + text = TheText.Get("LG_02"); + break; + case RADAR_SPRITE_BIKER: + text = TheText.Get("LG_03"); + break; + case RADAR_SPRITE_CORTEZ: + text = TheText.Get("LG_04"); + break; + case RADAR_SPRITE_DIAZ: + text = TheText.Get("LG_05"); + break; + case RADAR_SPRITE_KENT: + text = TheText.Get("LG_06"); + break; + case RADAR_SPRITE_LAWYER: + text = TheText.Get("LG_07"); + break; + case RADAR_SPRITE_PHIL: + text = TheText.Get("LG_08"); + break; + case RADAR_SPRITE_BIKERS: + text = TheText.Get("LG_03"); + break; + case RADAR_SPRITE_BOATYARD: + text = TheText.Get("LG_09"); + break; + case RADAR_SPRITE_MALIBU_CLUB: + text = TheText.Get("LG_10"); + break; + case RADAR_SPRITE_CUBANS: + text = TheText.Get("LG_11"); + break; + case RADAR_SPRITE_FILM: + text = TheText.Get("LG_12"); + break; + case RADAR_SPRITE_GUN: + text = TheText.Get("LG_13"); + break; + case RADAR_SPRITE_HAITIANS: + text = TheText.Get("LG_14"); + break; + case RADAR_SPRITE_HARDWARE: + text = TheText.Get("LG_15"); + break; + case RADAR_SPRITE_SAVE: + text = TheText.Get("LG_16"); + break; + case RADAR_SPRITE_STRIP: + text = TheText.Get("LG_37"); + break; + case RADAR_SPRITE_ICE: + text = TheText.Get("LG_17"); + break; + case RADAR_SPRITE_KCABS: + text = TheText.Get("LG_18"); + break; + case RADAR_SPRITE_LOVEFIST: + text = TheText.Get("LG_19"); + break; + case RADAR_SPRITE_PRINTWORKS: + text = TheText.Get("LG_20"); + break; + case RADAR_SPRITE_PROPERTY: + text = TheText.Get("LG_21"); + break; + case RADAR_SPRITE_SUNYARD: + text = TheText.Get("LG_36"); + break; + case RADAR_SPRITE_SPRAY: + text = TheText.Get("LG_22"); + break; + case RADAR_SPRITE_TSHIRT: + text = TheText.Get("LG_23"); + break; + case RADAR_SPRITE_TOMMY: + text = TheText.Get("LG_24"); + break; + case RADAR_SPRITE_PHONE: + text = TheText.Get("LG_25"); + break; + case RADAR_SPRITE_RADIO_WILDSTYLE: + text = TheText.Get("LG_26"); + break; + case RADAR_SPRITE_RADIO_FLASH: + text = TheText.Get("LG_27"); + break; + case RADAR_SPRITE_RADIO_KCHAT: + text = TheText.Get("LG_28"); + break; + case RADAR_SPRITE_RADIO_FEVER: + text = TheText.Get("LG_29"); + break; + case RADAR_SPRITE_RADIO_VROCK: + text = TheText.Get("LG_30"); + break; + case RADAR_SPRITE_RADIO_VCPR: + text = TheText.Get("LG_31"); + break; + case RADAR_SPRITE_RADIO_ESPANTOSO: + text = TheText.Get("LG_32"); + break; + case RADAR_SPRITE_RADIO_EMOTION: + text = TheText.Get("LG_33"); + break; + case RADAR_SPRITE_RADIO_WAVE: + text = TheText.Get("LG_34"); + break; + default: + break; + } + CFont::PrintString(SCREEN_SCALE_X(20.f) + x, SCREEN_SCALE_Y(3.0f) + y, text); +} diff --git a/src/core/Radar.h b/src/core/Radar.h index 100da8f3..8f2e7069 100644 --- a/src/core/Radar.h +++ b/src/core/Radar.h @@ -98,6 +98,17 @@ enum eRadarSprite enum { + RADAR_TRACE_RED, + RADAR_TRACE_GREEN, + RADAR_TRACE_LIGHT_BLUE, + RADAR_TRACE_GRAY, + RADAR_TRACE_YELLOW, + RADAR_TRACE_MAGENTA, + RADAR_TRACE_CYAN +}; + +enum +{ BLIP_MODE_TRIANGULAR_UP = 0, BLIP_MODE_TRIANGULAR_DOWN, BLIP_MODE_SQUARE, @@ -108,17 +119,39 @@ struct sRadarTrace uint32 m_nColor; uint32 m_eBlipType; // eBlipType int32 m_nEntityHandle; - CVector2D m_vec2DPos; + CVector m_vec2DPos; CVector m_vecPos; uint16 m_BlipIndex; bool m_bDim; bool m_bInUse; bool m_bShortRange; + bool m_unused; + float m_Radius; + int16 m_wScale; + uint16 m_eBlipDisplay; // eBlipDisplay + uint16 m_eRadarSprite; // eRadarSprite +}; + +// Either that was a thing while saving/loading blips, or they added sizes of each field one by one. I want to do the former. +#pragma pack(push,1) +struct sRadarTraceSave +{ + uint32 m_nColor; float m_Radius; + uint32 m_eBlipType; // eBlipType + int32 m_nEntityHandle; + CVector2D m_vec2DPos; + CVector m_vecPos; + uint16 m_BlipIndex; + bool m_bDim; + bool m_bInUse; + bool m_bShortRange; + bool m_unused; int16 m_wScale; uint16 m_eBlipDisplay; // eBlipDisplay uint16 m_eRadarSprite; // eRadarSprite }; +#pragma pack(pop) // Values for screen space #define RADAR_LEFT (40.0f) @@ -176,7 +209,7 @@ public: static CRGBA ArrowBlipColour1; static CRGBA ArrowBlipColour2; static int16 MapLegendList[NUM_MAP_LEGENDS]; - static uint16 MapLegendCounter; + static int16 MapLegendCounter; #ifdef MAP_ENHANCEMENTS static int TargetMarkerId; @@ -215,9 +248,9 @@ public: static void RemoveRadarSections(); static void SaveAllRadarBlips(uint8*, uint32*); static void SetBlipSprite(int32 i, int32 icon); - static int32 SetCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay); - static int32 SetEntityBlip(eBlipType type, int32, int32, eBlipDisplay); - static int32 SetShortRangeCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay); + static int32 SetCoordBlip(eBlipType type, CVector pos, uint32, eBlipDisplay); + static int32 SetEntityBlip(eBlipType type, int32, uint32, eBlipDisplay); + static int32 SetShortRangeCoordBlip(eBlipType type, CVector pos, uint32, eBlipDisplay); static void SetRadarMarkerState(int32 i, bool flag); static void ShowRadarMarker(CVector pos, uint32 color, float radius); static void ShowRadarTrace(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha); @@ -229,7 +262,8 @@ public: static void TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D &in); static void TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in); static void TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in); - - // no in CRadar in the game: static void CalculateCachedSinCos(); + static void DrawEntityBlip(int32 blipId); + static void DrawCoordBlip(int32 blipId); + static void DrawLegend(int32, int32, int32); }; diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index ddde4664..40d4acee 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -903,7 +903,7 @@ CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flag int i, n; mi = CModelInfo::GetModelInfo(modelId); - if(!CGeneral::faststrcmp("CSPlay", modelName)){ + if(strncasecmp("CSPlay", modelName, 6) == 0){ char *curname = CModelInfo::GetModelInfo(MI_PLAYER)->GetName(); for(int i = 0; CSnames[i][0]; i++){ if(strcasecmp(curname, IGnames[i]) == 0){ diff --git a/src/core/Timer.cpp b/src/core/Timer.cpp index f60adf07..5adc36b5 100644 --- a/src/core/Timer.cpp +++ b/src/core/Timer.cpp @@ -5,6 +5,7 @@ #include "DMAudio.h" #include "Record.h" #include "Timer.h" +#include "SpecialFX.h" uint32 CTimer::m_snTimeInMilliseconds; PauseModeTime CTimer::m_snTimeInMillisecondsPauseMode = 1; @@ -141,7 +142,7 @@ void CTimer::Update(void) } } - if ( ms_fTimeStep < 0.01f && !GetIsPaused() ) + if ( ms_fTimeStep < 0.01f && !GetIsPaused() && !CSpecialFX::bSnapShotActive) ms_fTimeStep = 0.01f; ms_fTimeStepNonClipped = ms_fTimeStep; diff --git a/src/core/World.cpp b/src/core/World.cpp index 6d5e8a81..14c06a81 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -79,7 +79,7 @@ CWorld::Add(CEntity *ent) if(ent->IsBuilding() || ent->IsDummy()) return; - if(!ent->IsStatic()) ((CPhysical *)ent)->AddToMovingList(); + if(!ent->GetIsStatic()) ((CPhysical *)ent)->AddToMovingList(); } void @@ -94,7 +94,7 @@ CWorld::Remove(CEntity *ent) if(ent->IsBuilding() || ent->IsDummy()) return; - if(!ent->IsStatic()) ((CPhysical *)ent)->RemoveFromMovingList(); + if(!ent->GetIsStatic()) ((CPhysical *)ent)->RemoveFromMovingList(); } void @@ -1962,7 +1962,7 @@ CWorld::Process(void) RemoveEntityInsteadOfProcessingIt(movingEnt); } else { movingEnt->ProcessControl(); - if(movingEnt->IsStatic()) { movingEnt->RemoveFromMovingList(); } + if(movingEnt->GetIsStatic()) { movingEnt->RemoveFromMovingList(); } } } bForceProcessControl = true; @@ -1973,7 +1973,7 @@ CWorld::Process(void) RemoveEntityInsteadOfProcessingIt(movingEnt); } else { movingEnt->ProcessControl(); - if(movingEnt->IsStatic()) { movingEnt->RemoveFromMovingList(); } + if(movingEnt->GetIsStatic()) { movingEnt->RemoveFromMovingList(); } } } } @@ -2133,13 +2133,13 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa CObject *pObject = (CObject *)pEntity; CVehicle *pVehicle = (CVehicle *)pEntity; if(!pEntity->bExplosionProof && (!pEntity->IsPed() || !pPed->bInVehicle)) { - if(pEntity->IsStatic()) { + if(pEntity->GetIsStatic()) { if(pEntity->IsObject()) { if (fPower > pObject->m_fUprootLimit || IsFence(pObject->GetModelIndex())) { if (IsGlass(pObject->GetModelIndex())) { CGlass::WindowRespondsToExplosion(pObject, position); } else { - pObject->bIsStatic = false; + pObject->SetIsStatic(false); pObject->AddToMovingList(); int16 modelId = pEntity->GetModelIndex(); if(modelId != MI_FIRE_HYDRANT || @@ -2157,18 +2157,18 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa } } } - if(pEntity->IsStatic()) { + if(pEntity->GetIsStatic()) { float fDamageMultiplier = (fRadius - fMagnitude) * 2.0f / fRadius; float fDamage = 300.0f * Min(fDamageMultiplier, 1.0f); pObject->ObjectDamage(fDamage); } } else { - pEntity->bIsStatic = false; + pEntity->SetIsStatic(false); pEntity->AddToMovingList(); } } - if(!pEntity->IsStatic()) { + if(!pEntity->GetIsStatic()) { float fDamageMultiplier = Min((fRadius - fMagnitude) * 2.0f / fRadius, 1.0f); CVector vecForceDir = vecDistance * (fPower * pEntity->m_fMass * 0.00071429f * fDamageMultiplier / diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp index 288b975e..45fe6fff 100644 --- a/src/core/Zones.cpp +++ b/src/core/Zones.cpp @@ -633,14 +633,17 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size) INITSAVEBUF int i; +#define CZONE_SAVE_SIZE (sizeof(char)*8+sizeof(float)+sizeof(float)+sizeof(float)+sizeof(float)+sizeof(float)+sizeof(float)+sizeof(eZoneType)+sizeof(eLevelName)+sizeof(int16)+sizeof(int16)+sizeof(int32)+sizeof(int32)+sizeof(int32)) + *size = SAVE_HEADER_SIZE + sizeof(m_CurrLevel) + sizeof(FindIndex) + sizeof(int16) // padding - + sizeof(NavigationZoneArray) + sizeof(InfoZoneArray) + sizeof(ZoneInfoArray) + + CZONE_SAVE_SIZE * ARRAY_SIZE(NavigationZoneArray) + CZONE_SAVE_SIZE * ARRAY_SIZE(InfoZoneArray) + sizeof(ZoneInfoArray) + sizeof(TotalNumberOfNavigationZones) + sizeof(TotalNumberOfInfoZones) + sizeof(TotalNumberOfZoneInfos) + sizeof(int16) // padding - + sizeof(MapZoneArray) + sizeof(AudioZoneArray) + + CZONE_SAVE_SIZE * ARRAY_SIZE(MapZoneArray) + sizeof(AudioZoneArray) + sizeof(TotalNumberOfMapZones) + sizeof(NumberOfAudioZones); +#undef CZONE_SAVE_SIZE uint32 length = 0; WriteSaveHeaderWithLength(buffer, length, 'Z', 'N', 'S', '\0', *size - SAVE_HEADER_SIZE); diff --git a/src/core/config.h b/src/core/config.h index 3f077f4c..770a7c2e 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -172,7 +172,6 @@ enum Config { # define RANDOMSPLASH # define VU_COLLISION #elif defined GTA_PC -# define GTA3_1_1_PATCH //# define GTA3_STEAM_PATCH //# define GTAVC_JP_PATCH # ifdef GTA_PS2_STUFF @@ -263,7 +262,6 @@ enum Config { // Hud, frontend and radar //#define BETA_SLIDING_TEXT -#define TRIANGULAR_BLIPS // height indicating triangular radar blips, as in VC #define PC_MENU #ifndef PC_MENU @@ -315,9 +313,7 @@ enum Config { #define FREE_CAM // Rotating cam // Audio -#ifndef AUDIO_OAL // is not working yet for openal #define AUDIO_CACHE // cache sound lengths to speed up the cold boot -#endif //#define PS2_AUDIO // changes audio paths for cutscenes and radio to PS2 paths, needs vbdec to support VB with MSS diff --git a/src/core/main.cpp b/src/core/main.cpp index b39a9c8b..fa5a5000 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -969,7 +969,7 @@ Render2dStuff(void) else CHud::Draw(); // TODO(Miami) - // CSpecialFX::Render2DFXs(); + CSpecialFX::Render2DFXs(); CUserDisplay::OnscnTimer.ProcessForDisplay(); CMessages::Display(); CDarkel::DrawMessages(); diff --git a/src/entities/Entity.h b/src/entities/Entity.h index fbf5cb3b..08d1900a 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -104,7 +104,8 @@ public: eEntityStatus GetStatus() const { return (eEntityStatus)m_status; } void SetStatus(eEntityStatus status) { m_status = status; } CColModel *GetColModel(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); } - bool IsStatic(void) { return bIsStatic || bIsStaticWaitingForCollision; } + bool GetIsStatic(void) const { return bIsStatic || bIsStaticWaitingForCollision; } + void SetIsStatic(bool state) { bIsStatic = state; } #ifdef COMPATIBLE_SAVES void SaveEntityFlags(uint8*& buf); void LoadEntityFlags(uint8*& buf); diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp index b190d03a..5483641f 100644 --- a/src/entities/Physical.cpp +++ b/src/entities/Physical.cpp @@ -344,7 +344,7 @@ CPhysical::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints) AddCollisionRecord(ent); if(!ent->IsBuilding()) // Can't this catch dummies too? ((CPhysical*)ent)->AddCollisionRecord(this); - if(ent->IsBuilding() || ent->IsStatic()) + if(ent->IsBuilding() || ent->GetIsStatic()) this->bHasHitWall = true; } return numSpheres; @@ -380,7 +380,7 @@ CPhysical::ProcessControl(void) m_nStaticFrames++; if(m_nStaticFrames > 10){ m_nStaticFrames = 10; - bIsStatic = true; + SetIsStatic(true); m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f); m_vecMoveFriction = m_vecMoveSpeed; @@ -614,7 +614,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl } float speedA, speedB; - if(B->IsStatic() && !foo){ + if(B->GetIsStatic() && !foo){ if(A->bPedPhysics){ speedA = DotProduct(A->m_vecMoveSpeed, colpoint.normal); if(speedA < 0.0f){ @@ -625,7 +625,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl if(IsGlass(B->GetModelIndex())) CGlass::WindowRespondsToCollision(B, impulseA, A->m_vecMoveSpeed, colpoint.point, false); else if(!B->bInfiniteMass){ - B->bIsStatic = false; + B->SetIsStatic(false); CWorld::Players[CWorld::PlayerInFocus].m_nHavocLevel += 2; CStats::PropertyDestroyed += CGeneral::GetRandomNumberInRange(30, 60); } @@ -637,7 +637,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl return true; } }else if(!B->bInfiniteMass) - B->bIsStatic = false; + B->SetIsStatic(false); if(B->bInfiniteMass){ impulseA = -speedA * A->m_fMass; @@ -675,7 +675,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl if(IsGlass(B->GetModelIndex())) CGlass::WindowRespondsToCollision(B, impulseA, A->m_vecMoveSpeed, colpoint.point, false); else - B->bIsStatic = false; + B->SetIsStatic(false); int16 model = B->GetModelIndex(); if(model == MI_FIRE_HYDRANT && !Bobj->bHasBeenDamaged){ CParticleObject::AddObject(POBJECT_FIRE_HYDRANT, B->GetPosition() - CVector(0.0f, 0.0f, 0.5f), true); @@ -699,11 +699,11 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl return true; } }else if(!B->bInfiniteMass) - B->bIsStatic = false; + B->SetIsStatic(false); } } - if(B->IsStatic()) + if(B->GetIsStatic()) return false; if(!B->bInfiniteMass && !B->m_phy_flagA08) B->AddToMovingList(); @@ -1231,7 +1231,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists) canshift = true; else canshift = A->IsPed() && - B->IsObject() && B->IsStatic() && !Bobj->bHasBeenDamaged; + B->IsObject() && B->GetIsStatic() && !Bobj->bHasBeenDamaged; if(B == A || B->m_scanCode == CWorld::GetCurrentScanCode() || !B->bUsesCollision || @@ -1255,7 +1255,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists) CObject *Aobj = (CObject*)A; if(Aobj->ObjectCreatedBy != TEMP_OBJECT && !Aobj->bHasBeenDamaged && - Aobj->IsStatic()){ + Aobj->GetIsStatic()){ if(Aobj->m_pCollidingEntity == B) Aobj->m_pCollidingEntity = nil; }else if(Aobj->m_pCollidingEntity != B){ @@ -1272,7 +1272,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists) CObject *Bobj = (CObject*)B; if(Bobj->ObjectCreatedBy != TEMP_OBJECT && !Bobj->bHasBeenDamaged && - Bobj->IsStatic()){ + Bobj->GetIsStatic()){ if(Bobj->m_pCollidingEntity == A) Bobj->m_pCollidingEntity = nil; }else if(Bobj->m_pCollidingEntity != A){ @@ -1595,7 +1595,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) skipCollision = true; else if(Aobj->ObjectCreatedBy == TEMP_OBJECT || Aobj->bHasBeenDamaged || - !Aobj->IsStatic()){ + !Aobj->GetIsStatic()){ if(Aobj->m_pCollidingEntity == B) skipCollision = true; else if(Aobj->m_nCollisionDamageEffect < DAMAGE_EFFECT_SMASH_COMPLETELY){ @@ -1614,7 +1614,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) skipCollision = true; else if(Bobj->ObjectCreatedBy == TEMP_OBJECT || Bobj->bHasBeenDamaged || - !Bobj->IsStatic()){ + !Bobj->GetIsStatic()){ if(Bobj->m_pCollidingEntity == A) skipCollision = true; else if(Bobj->m_nCollisionDamageEffect < DAMAGE_EFFECT_SMASH_COMPLETELY){ diff --git a/src/math/Vector.h b/src/math/Vector.h index 7ee01149..082b296f 100644 --- a/src/math/Vector.h +++ b/src/math/Vector.h @@ -115,6 +115,14 @@ Distance(const CVector &v1, const CVector &v2) return (v2 - v1).Magnitude(); } +inline float +Distance2D(const CVector &v1, const CVector &v2) +{ + float x = v2.x - v1.x; + float y = v2.y - v1.y; + return Sqrt(x*x + y*y); +} + class CMatrix; CVector Multiply3x3(const CMatrix &mat, const CVector &vec); diff --git a/src/math/Vector2D.h b/src/math/Vector2D.h index 2c4e57b5..deabd0b1 100644 --- a/src/math/Vector2D.h +++ b/src/math/Vector2D.h @@ -53,6 +53,9 @@ public: CVector2D operator/(float t) const { return CVector2D(x/t, y/t); } + CVector2D operator-() const { + return CVector2D(-x, -y); + } }; inline float diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp index 9a9eaa73..8b78bdbd 100644 --- a/src/objects/Object.cpp +++ b/src/objects/Object.cpp @@ -98,7 +98,7 @@ CObject::ProcessControl(void) CPhysical::ProcessControl(); if (mod_Buoyancy.ProcessBuoyancy(this, m_fBuoyancy, &point, &impulse)) { bIsInWater = true; - bIsStatic = false; + SetIsStatic(false); ApplyMoveForce(impulse); ApplyTurnForce(impulse, point); float fTimeStep = Pow(0.97f, CTimer::GetTimeStep()); @@ -197,7 +197,7 @@ CObject::ObjectDamage(float amount) case DAMAGE_EFFECT_SMASH_COMPLETELY: bIsVisible = false; bUsesCollision = false; - bIsStatic = true; + SetIsStatic(true); bExplosionProof = true; SetMoveSpeed(0.0f, 0.0f, 0.0f); SetTurnSpeed(0.0f, 0.0f, 0.0f); @@ -209,7 +209,7 @@ CObject::ObjectDamage(float amount) else { bIsVisible = false; bUsesCollision = false; - bIsStatic = true; + SetIsStatic(true); bExplosionProof = true; SetMoveSpeed(0.0f, 0.0f, 0.0f); SetTurnSpeed(0.0f, 0.0f, 0.0f); @@ -218,7 +218,7 @@ CObject::ObjectDamage(float amount) case DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY: { bIsVisible = false; bUsesCollision = false; - bIsStatic = true; + SetIsStatic(true); bExplosionProof = true; SetMoveSpeed(0.0f, 0.0f, 0.0f); SetTurnSpeed(0.0f, 0.0f, 0.0f); @@ -241,7 +241,7 @@ CObject::ObjectDamage(float amount) case DAMAGE_EFFECT_SMASH_WOODENBOX_COMPLETELY: { bIsVisible = false; bUsesCollision = false; - bIsStatic = true; + SetIsStatic(true); bExplosionProof = true; SetMoveSpeed(0.0f, 0.0f, 0.0f); SetTurnSpeed(0.0f, 0.0f, 0.0f); @@ -264,7 +264,7 @@ CObject::ObjectDamage(float amount) case DAMAGE_EFFECT_SMASH_TRAFFICCONE_COMPLETELY: { bIsVisible = false; bUsesCollision = false; - bIsStatic = true; + SetIsStatic(true); bExplosionProof = true; SetMoveSpeed(0.0f, 0.0f, 0.0f); SetTurnSpeed(0.0f, 0.0f, 0.0f); @@ -289,7 +289,7 @@ CObject::ObjectDamage(float amount) case DAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY: { bIsVisible = false; bUsesCollision = false; - bIsStatic = true; + SetIsStatic(true); bExplosionProof = true; SetMoveSpeed(0.0f, 0.0f, 0.0f); SetTurnSpeed(0.0f, 0.0f, 0.0f); @@ -329,7 +329,7 @@ CObject::Init(void) CObjectData::SetObjectData(GetModelIndex(), *this); m_nEndOfLifeTime = 0; ObjectCreatedBy = GAME_OBJECT; - bIsStatic = true; + SetIsStatic(true); bIsPickup = false; bPickupObjWithMessage = false; bOutOfStock = false; diff --git a/src/objects/Object.h b/src/objects/Object.h index b81e84b6..ce45509f 100644 --- a/src/objects/Object.h +++ b/src/objects/Object.h @@ -70,7 +70,8 @@ public: uint8 bUseVehicleColours : 1; uint8 bIsWeapon : 1; uint8 bIsStreetLight : 1; - int8 m_nBonusValue; + int8 m_nBonusValue; + uint16 m_nCostValue; float m_fCollisionDamageMultiplier; uint8 m_nCollisionDamageEffect; uint8 m_nSpecialCollisionResponseCases; diff --git a/src/peds/CivilianPed.cpp b/src/peds/CivilianPed.cpp index 1950c4b3..74a7c9ba 100644 --- a/src/peds/CivilianPed.cpp +++ b/src/peds/CivilianPed.cpp @@ -425,7 +425,7 @@ void CCivilianPed::FindNearbyAttractorsSectorList(CPtrList& list, float& minDist { for (CPtrNode* pNode = list.first; pNode != nil; pNode = pNode->next) { CEntity* pEntity = (CEntity*)pNode->item; - if (pEntity->IsObject() && (!pEntity->IsStatic() || ((CObject*)pEntity)->bHasBeenDamaged)) + if (pEntity->IsObject() && (!pEntity->GetIsStatic() || ((CObject*)pEntity)->bHasBeenDamaged)) continue; CBaseModelInfo* pModelInfo = CModelInfo::GetModelInfo(pEntity->GetModelIndex()); for (int i = 0; i < pModelInfo->GetNum2dEffects(); i++) { diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 492d19b5..82298e74 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -15404,17 +15404,17 @@ CPed::ProcessObjective(void) CVector distance = m_nextRoutePointPos - GetPosition(); distance.z = 0.0f; if (m_objective == OBJECTIVE_GOTO_SHELTER_ON_FOOT) { - if (m_nMoveState == PEDMOVE_SPRINT && distance.Magnitude() < SQR(2.0f)) { + if (m_nMoveState == PEDMOVE_RUN && distance.MagnitudeSqr() < SQR(2.0f)) { SetMoveState(PEDMOVE_WALK); bIsRunning = false; } - else if (CWeather::Rain < 0.2f && m_attractor) { + if (CWeather::Rain < 0.2f && m_attractor) { GetPedAttractorManager()->DeRegisterPed(this, m_attractor); return; } } else if (m_objective == OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT) { - if (m_nMoveState == PEDMOVE_SPRINT && distance.Magnitude() < SQR(4.0f)) { + if (m_nMoveState == PEDMOVE_RUN && distance.MagnitudeSqr() < SQR(4.0f)) { SetMoveState(PEDMOVE_WALK); bIsRunning = false; } @@ -15440,8 +15440,10 @@ CPed::ProcessObjective(void) } } if (sq(m_distanceToCountSeekDone) < distance.MagnitudeSqr()) { - if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer || GetPedState() != PED_SEEK_POS) + if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer || GetPedState() != PED_SEEK_POS) { + m_vecSeekPos = m_nextRoutePointPos; SetSeek(m_vecSeekPos, m_distanceToCountSeekDone); + } } else { if (!bReachedAttractorHeadingTarget) { @@ -15511,6 +15513,10 @@ CPed::ProcessObjective(void) SetObjective(OBJECTIVE_WAIT_ON_FOOT_AT_ICE_CREAM_VAN); break; } + } else { + m_prevObjective = OBJECTIVE_NONE; + SetObjective(OBJECTIVE_WAIT_ON_FOOT); + m_objectiveTimer = 0; } } } @@ -15694,11 +15700,11 @@ CPed::ProcessObjective(void) } if (!pVan->m_bSirenOrAlarm) { GetPedAttractorManager()->DeRegisterPed(this, m_attractor); - return; // ??? + return; // Why? } if (pVan->GetStatus() == STATUS_WRECKED) { GetPedAttractorManager()->DeRegisterPed(this, m_attractor); - return; // ??? + return; // Why? } break; } @@ -16423,11 +16429,11 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints) if (!collidingEnt->IsBuilding()) ((CPhysical*)collidingEnt)->AddCollisionRecord(this); - if (ourCollidedSpheres > 0 && (collidingEnt->IsBuilding() || collidingEnt->IsStatic())) { + if (ourCollidedSpheres > 0 && (collidingEnt->IsBuilding() || collidingEnt->GetIsStatic())) { bHasHitWall = true; } } - if (collidingEnt->IsBuilding() || collidingEnt->IsStatic()) { + if (collidingEnt->IsBuilding() || collidingEnt->GetIsStatic()) { if (bWasStanding) { CVector sphereNormal; float normalLength; @@ -17004,72 +17010,69 @@ CPed::ProcessBuoyancy(void) } } } - float speedMult = 0.0f; - if (buoyancyImpulse.z / m_fMass > GRAVITY * CTimer::GetTimeStep() - || mod_Buoyancy.m_waterlevel > GetPosition().z) { + } + float speedMult = 0.0f; + if (buoyancyImpulse.z / m_fMass > GRAVITY * CTimer::GetTimeStep() + || mod_Buoyancy.m_waterlevel > GetPosition().z + 0.6f) { + speedMult = pow(0.9f, CTimer::GetTimeStep()); + m_vecMoveSpeed.x *= speedMult; + m_vecMoveSpeed.y *= speedMult; + m_vecMoveSpeed.z *= speedMult; + bIsStanding = false; + bIsDrowning = true; + InflictDamage(nil, WEAPONTYPE_DROWNING, 3.0f * CTimer::GetTimeStep(), PEDPIECE_TORSO, 0); + } + if (buoyancyImpulse.z / m_fMass > GRAVITY * 0.25f * CTimer::GetTimeStep()) { + if (speedMult == 0.0f) { speedMult = pow(0.9f, CTimer::GetTimeStep()); - m_vecMoveSpeed.x *= speedMult; - m_vecMoveSpeed.y *= speedMult; - m_vecMoveSpeed.z *= speedMult; - bIsStanding = false; - bIsDrowning = true; - InflictDamage(nil, WEAPONTYPE_DROWNING, 3.0f * CTimer::GetTimeStep(), PEDPIECE_TORSO, 0); - } - if (buoyancyImpulse.z / m_fMass > GRAVITY * 0.25f * CTimer::GetTimeStep()) { - if (speedMult == 0.0f) { - speedMult = pow(0.9f, CTimer::GetTimeStep()); - } - m_vecMoveSpeed.x *= speedMult; - m_vecMoveSpeed.y *= speedMult; - if (m_vecMoveSpeed.z >= -0.1f) { - if (m_vecMoveSpeed.z < -0.04f) - m_vecMoveSpeed.z = -0.02f; - } else { - m_vecMoveSpeed.z = -0.01f; - DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLASH, 0.0f); - CVector aBitForward = 2.2f * m_vecMoveSpeed + GetPosition(); - float level = 0.0f; - if (CWaterLevel::GetWaterLevel(aBitForward, &level, false)) - aBitForward.z = level; - - CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, CVector(0.0f, 0.0f, 0.1f), 0.0f, 200, color, true); - nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 80; - nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 100; - } } - } else - return; - } else - bTouchingWater = false; - - if (nGenerateWaterCircles && CTimer::GetTimeInMilliseconds() >= nGenerateWaterCircles) { - CVector pos = GetPosition(); - float level = 0.0f; - if (CWaterLevel::GetWaterLevel(pos, &level, false)) - pos.z = level; + m_vecMoveSpeed.x *= speedMult; + m_vecMoveSpeed.y *= speedMult; + if (m_vecMoveSpeed.z >= -0.1f) { + if (m_vecMoveSpeed.z < -0.04f) + m_vecMoveSpeed.z = -0.02f; + } else { + m_vecMoveSpeed.z = -0.01f; + DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLASH, 0.0f); + CVector aBitForward = 2.2f * m_vecMoveSpeed + GetPosition(); + float level = 0.0f; + if (CWaterLevel::GetWaterLevel(aBitForward, &level, false)) + aBitForward.z = level; - if (pos.z != 0.0f) { - nGenerateWaterCircles = 0; - for(int i = 0; i < 4; i++) { - pos.x += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f); - pos.y += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f); - CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, 0, 0, 0, 0); + CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, CVector(0.0f, 0.0f, 0.1f), 0.0f, 200, color, true); + nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 80; + nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 100; } } - } + if (nGenerateWaterCircles && CTimer::GetTimeInMilliseconds() >= nGenerateWaterCircles) { + CVector pos = GetPosition(); + float level = 0.0f; + if (CWaterLevel::GetWaterLevel(pos, &level, false)) + pos.z = level; - if (nGenerateRaindrops && CTimer::GetTimeInMilliseconds() >= nGenerateRaindrops) { - CVector pos = GetPosition(); - float level = 0.0f; - if (CWaterLevel::GetWaterLevel(pos, &level, false)) - pos.z = level; + if (pos.z != 0.0f) { + nGenerateWaterCircles = 0; + for(int i = 0; i < 4; i++) { + pos.x += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f); + pos.y += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f); + CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, 0, 0, 0, 0); + } + } + } + if (nGenerateRaindrops && CTimer::GetTimeInMilliseconds() >= nGenerateRaindrops) { + CVector pos = GetPosition(); + float level = 0.0f; + if (CWaterLevel::GetWaterLevel(pos, &level, false)) + pos.z = level; - if (pos.z >= 0.0f) { - pos.z += 0.25f; - nGenerateRaindrops = 0; - CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 1500, CRGBA(0,0,0,0), true); + if (pos.z >= 0.0f) { + pos.z += 0.25f; + nGenerateRaindrops = 0; + CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 1500, CRGBA(0,0,0,0), true); + } } - } + } else + bTouchingWater = false; } // --MIAMI: Done @@ -18412,7 +18415,7 @@ CPed::SeekCar(void) { m_fRotationCur = m_fRotationDest; if (!bVehEnterDoorIsBlocked) { - vehToSeek->bIsStatic = false; + vehToSeek->SetIsStatic(false); if (m_objective == OBJECTIVE_SOLICIT_VEHICLE) { SetSolicit(1000); } else if (m_objective == OBJECTIVE_BUY_ICE_CREAM) { @@ -20038,15 +20041,13 @@ CPed::Save(uint8*& buf) CopyToBuf(buf, GetPosition().z); SkipSaveBuf(buf, 288); CopyToBuf(buf, CharCreatedBy); - SkipSaveBuf(buf, 351); + SkipSaveBuf(buf, 499); CopyToBuf(buf, m_fHealth); CopyToBuf(buf, m_fArmour); - SkipSaveBuf(buf, 148); - for (int i = 0; i < 13; i++) // has to be hardcoded + SkipSaveBuf(buf, 172); + for (int i = 0; i < 10; i++) // has to be hardcoded m_weapons[i].Save(buf); - SkipSaveBuf(buf, 5); - CopyToBuf(buf, m_maxWeaponTypeAllowed); - SkipSaveBuf(buf, 162); + SkipSaveBuf(buf, 252); } void @@ -20058,16 +20059,15 @@ CPed::Load(uint8*& buf) CopyFromBuf(buf, GetMatrix().GetPosition().z); SkipSaveBuf(buf, 288); CopyFromBuf(buf, CharCreatedBy); - SkipSaveBuf(buf, 351); + SkipSaveBuf(buf, 499); CopyFromBuf(buf, m_fHealth); CopyFromBuf(buf, m_fArmour); - SkipSaveBuf(buf, 148); + SkipSaveBuf(buf, 172); + m_currentWeapon = WEAPONTYPE_UNARMED; CWeapon bufWeapon; - for (int i = 0; i < 13; i++) { // has to be hardcoded + for (int i = 0; i < 10; i++) { // has to be hardcoded bufWeapon.Load(buf); - if (i >= 10) - continue; // tmp hack before we fix save/load if (bufWeapon.m_eWeaponType != WEAPONTYPE_UNARMED) { int modelId = CWeaponInfo::GetWeaponInfo(bufWeapon.m_eWeaponType)->m_nModelId; @@ -20082,9 +20082,7 @@ CPed::Load(uint8*& buf) GiveWeapon(bufWeapon.m_eWeaponType, bufWeapon.m_nAmmoTotal); } } - SkipSaveBuf(buf, 5); - CopyFromBuf(buf, m_maxWeaponTypeAllowed); - SkipSaveBuf(buf, 162); + SkipSaveBuf(buf, 252); } #undef CopyFromBuf #undef CopyToBuf diff --git a/src/peds/PedAttractor.cpp b/src/peds/PedAttractor.cpp index 9f77f2a4..cebe31b0 100644 --- a/src/peds/PedAttractor.cpp +++ b/src/peds/PedAttractor.cpp @@ -135,8 +135,10 @@ void CPedAttractorManager::RemoveIceCreamVanEffects(C2dEffect* pEffect) if (vVehicleToEffect.empty()) return; for (std::vector<CVehicleToEffect>::const_iterator assoc = vVehicleToEffect.cbegin(); assoc != vVehicleToEffect.cend();) { - if (assoc->GetVehicle() != pVehicle) - return; + if (assoc->GetVehicle() != pVehicle) { + assoc++; + continue; + } uint32 total = 0; for (uint32 j = 0; j < NUM_ATTRACTORS_FOR_ICECREAM_VAN; j++) { if (FindAssociatedAttractor(assoc->GetEffect(j), vIceCreamAttractors)) diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index 041fb5e8..1f53853f 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -23,7 +23,7 @@ const uint32 CPlayerPed::nSaveStructSize = #ifdef COMPATIBLE_SAVES - 1520; + 1752; #else sizeof(CPlayerPed); #endif @@ -1935,7 +1935,7 @@ CPlayerPed::Save(uint8*& buf) CopyToBuf(buf, m_nTargettableObjects[1]); CopyToBuf(buf, m_nTargettableObjects[2]); CopyToBuf(buf, m_nTargettableObjects[3]); - SkipSaveBuf(buf, 116); + SkipSaveBuf(buf, 164); } void @@ -1949,7 +1949,7 @@ CPlayerPed::Load(uint8*& buf) CopyFromBuf(buf, m_nTargettableObjects[1]); CopyFromBuf(buf, m_nTargettableObjects[2]); CopyFromBuf(buf, m_nTargettableObjects[3]); - SkipSaveBuf(buf, 116); + SkipSaveBuf(buf, 164); } #undef CopyFromBuf #undef CopyToBuf diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp index 94533f4a..d52c8c7c 100644 --- a/src/peds/Population.cpp +++ b/src/peds/Population.cpp @@ -945,7 +945,7 @@ CPopulation::ConvertToRealObject(CDummyObject *dummy) if (IsGlass(obj->GetModelIndex()) && !mi->m_isArtistGlass) { obj->bIsVisible = false; } else if (obj->GetModelIndex() == MI_BUOY) { - obj->bIsStatic = false; + obj->SetIsStatic(false); obj->m_vecMoveSpeed = CVector(0.0f, 0.0f, -0.001f); obj->bTouchingWater = true; obj->AddToMovingList(); diff --git a/src/render/2dEffect.h b/src/render/2dEffect.h index baf07342..8ad2b946 100644 --- a/src/render/2dEffect.h +++ b/src/render/2dEffect.h @@ -88,14 +88,10 @@ public: if(type == EFFECT_LIGHT){ if(light.corona) RwTextureDestroy(light.corona); -#ifdef GTA3_1_1_PATCH light.corona = nil; -#endif if(light.shadow) RwTextureDestroy(light.shadow); -#ifdef GTA3_1_1_PATCH light.shadow = nil; -#endif } } }; diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp index 773561f3..19a172fb 100644 --- a/src/render/Fluff.cpp +++ b/src/render/Fluff.cpp @@ -386,6 +386,8 @@ CMovingThing CMovingThings::StartCloseList; CMovingThing CMovingThings::EndCloseList; int16 CMovingThings::Num; CMovingThing CMovingThings::aMovingThings[NUMMOVINGTHINGS]; + +int32 CScrollBar::TonightsEvent; void CMovingThings::Init() { @@ -1603,7 +1605,7 @@ void CScriptPath::Update(void) { void CScriptPath::Clear(void) { if (m_pNode) - delete m_pNode; + delete[] m_pNode; m_pNode = nil; m_numNodes = 0; for (int i = 0; i < 6; i++) diff --git a/src/render/Fluff.h b/src/render/Fluff.h index a6a28cb7..f61da350 100644 --- a/src/render/Fluff.h +++ b/src/render/Fluff.h @@ -170,6 +170,9 @@ private: float m_fScale; public: + static int TonightsEvent; + +public: void SetVisibility(bool visible) { m_bVisible = visible; } bool IsVisible() { return m_bVisible; } diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index 3ea756fa..753bb42b 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -583,7 +583,7 @@ void CHud::Draw() CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f), SCREEN_SCALE_Y(65.0f), sPrint); - if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss + 2000 || CTimer::GetFrameCounter() & 1) { + if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss + 2000 || CTimer::GetFrameCounter() & 4) { // CFont::SetColor(ARMOUR_COLOR); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f + 52.0f), SCREEN_SCALE_Y(65.0f), sPrintIcon); } diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp index fa8379f0..7864b0f0 100644 --- a/src/render/SpecialFX.cpp +++ b/src/render/SpecialFX.cpp @@ -24,21 +24,44 @@ #include "ColStore.h" #include "Coronas.h" #include "Script.h" +#include "DMAudio.h" RwIm3DVertex StreakVertices[4]; RwImVertexIndex StreakIndexList[12]; -RwIm3DVertex TraceVertices[6]; -RwImVertexIndex TraceIndexList[12]; +RwIm3DVertex TraceVertices[10]; +static RwImVertexIndex TraceIndexList[48] = {0, 5, 7, 0, 7, 2, 0, 7, 5, 0, 2, 7, 0, 4, 9, 0, + 9, 5, 0, 9, 4, 0, 5, 9, 0, 1, 6, 0, 6, 5, 0, 6, + 1, 0, 5, 6, 0, 3, 8, 0, 8, 5, 0, 8, 3, 0, 5, 8 }; +bool CSpecialFX::bVideoCam; +bool CSpecialFX::bLiftCam; bool CSpecialFX::bSnapShotActive; int32 CSpecialFX::SnapShotFrames; +static RwTexture* gpSmokeTrailTexture; + void CSpecialFX::Init(void) { CBulletTraces::Init(); + RwIm3DVertexSetU(&TraceVertices[0], 0.0); + RwIm3DVertexSetV(&TraceVertices[0], 0.0); + RwIm3DVertexSetU(&TraceVertices[1], 1.0); + RwIm3DVertexSetV(&TraceVertices[1], 0.0); + RwIm3DVertexSetU(&TraceVertices[2], 1.0); + RwIm3DVertexSetV(&TraceVertices[2], 0.0); + RwIm3DVertexSetU(&TraceVertices[3], 1.0); + RwIm3DVertexSetV(&TraceVertices[3], 0.0); + RwIm3DVertexSetU(&TraceVertices[4], 1.0); + RwIm3DVertexSetV(&TraceVertices[4], 0.0); + RwIm3DVertexSetU(&TraceVertices[5], 0.0); + RwIm3DVertexSetU(&TraceVertices[6], 1.0); + RwIm3DVertexSetU(&TraceVertices[7], 1.0); + RwIm3DVertexSetU(&TraceVertices[8], 1.0); + RwIm3DVertexSetU(&TraceVertices[9], 1.0); + RwIm3DVertexSetU(&StreakVertices[0], 0.0f); RwIm3DVertexSetV(&StreakVertices[0], 0.0f); RwIm3DVertexSetU(&StreakVertices[1], 1.0f); @@ -47,7 +70,6 @@ CSpecialFX::Init(void) RwIm3DVertexSetV(&StreakVertices[2], 0.0f); RwIm3DVertexSetU(&StreakVertices[3], 1.0f); RwIm3DVertexSetV(&StreakVertices[3], 0.0f); - StreakIndexList[0] = 0; StreakIndexList[1] = 1; StreakIndexList[2] = 2; @@ -61,43 +83,51 @@ CSpecialFX::Init(void) StreakIndexList[10] = 2; StreakIndexList[11] = 3; - RwIm3DVertexSetRGBA(&TraceVertices[0], 20, 20, 20, 255); - RwIm3DVertexSetRGBA(&TraceVertices[1], 20, 20, 20, 255); - RwIm3DVertexSetRGBA(&TraceVertices[2], 70, 70, 70, 255); - RwIm3DVertexSetRGBA(&TraceVertices[3], 70, 70, 70, 255); - RwIm3DVertexSetRGBA(&TraceVertices[4], 10, 10, 10, 255); - RwIm3DVertexSetRGBA(&TraceVertices[5], 10, 10, 10, 255); - RwIm3DVertexSetU(&TraceVertices[0], 0.0); - RwIm3DVertexSetV(&TraceVertices[0], 0.0); - RwIm3DVertexSetU(&TraceVertices[1], 1.0); - RwIm3DVertexSetV(&TraceVertices[1], 0.0); - RwIm3DVertexSetU(&TraceVertices[2], 0.0); - RwIm3DVertexSetV(&TraceVertices[2], 0.5); - RwIm3DVertexSetU(&TraceVertices[3], 1.0); - RwIm3DVertexSetV(&TraceVertices[3], 0.5); - RwIm3DVertexSetU(&TraceVertices[4], 0.0); - RwIm3DVertexSetV(&TraceVertices[4], 1.0); - RwIm3DVertexSetU(&TraceVertices[5], 1.0); - RwIm3DVertexSetV(&TraceVertices[5], 1.0); - - TraceIndexList[0] = 0; - TraceIndexList[1] = 2; - TraceIndexList[2] = 1; - TraceIndexList[3] = 1; - TraceIndexList[4] = 2; - TraceIndexList[5] = 3; - TraceIndexList[6] = 2; - TraceIndexList[7] = 4; - TraceIndexList[8] = 3; - TraceIndexList[9] = 3; - TraceIndexList[10] = 4; - TraceIndexList[11] = 5; - CMotionBlurStreaks::Init(); CBrightLights::Init(); CShinyTexts::Init(); CMoneyMessages::Init(); C3dMarkers::Init(); + CSpecialFX::bSnapShotActive = false; + CSpecialFX::bVideoCam = false; + CSpecialFX::SnapShotFrames = 0; + CSpecialFX::bLiftCam = false; + CTxdStore::PushCurrentTxd(); + CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("particle")); + if(gpSmokeTrailTexture == nil) + gpSmokeTrailTexture = RwTextureRead("smoketrail", 0); + CTxdStore::PopCurrentTxd(); +} + +void +CSpecialFX::AddWeaponStreak(int type) +{ + static CMatrix matrix; + CVector start; + CVector end; + + if (FindPlayerPed() != nil && FindPlayerPed()->m_pWeaponModel != nil) { + switch (type) { + case WEAPONTYPE_BASEBALLBAT: + matrix = RwFrameGetLTM(RpAtomicGetFrame(FindPlayerPed()->m_pWeaponModel)); + start = matrix * CVector(0.02f, 0.05f, 0.07f); + end = matrix * CVector(0.246f, 0.0325f, 0.796f); + break; + case WEAPONTYPE_GOLFCLUB: + matrix = RwFrameGetLTM(RpAtomicGetFrame(FindPlayerPed()->m_pWeaponModel)); + start = matrix * CVector(0.02f, 0.05f, 0.07f); + end = matrix * CVector(-0.054f, 0.0325f, 0.796f); + break; + case WEAPONTYPE_KATANA: + matrix = RwFrameGetLTM(RpAtomicGetFrame(FindPlayerPed()->m_pWeaponModel)); + start = matrix * CVector(0.02f, 0.05f, 0.07f); + end = matrix * CVector(0.096f, -0.0175f, 1.096f); + break; + default: + return; + } + CMotionBlurStreaks::RegisterStreak((uintptr)FindPlayerPed()->m_pWeaponModel, 100, 100, 100, start, end); + } } RwObject* @@ -119,23 +149,16 @@ CSpecialFX::Update(void) { CMotionBlurStreaks::Update(); CBulletTraces::Update(); - - if(FindPlayerPed() && - FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT && - FindPlayerPed()->GetWeapon()->m_eWeaponState == WEAPONSTATE_FIRING){ -#ifdef PED_SKIN - if(IsClumpSkinned(FindPlayerPed()->GetClump())){ - LookForBatCB((RwObject*)FindPlayerPed()->m_pWeaponModel, CModelInfo::GetModelInfo(MI_BASEBALL_BAT)); - }else -#endif - RwFrameForAllObjects(FindPlayerPed()->m_pFrames[PED_HANDR]->frame, LookForBatCB, CModelInfo::GetModelInfo(MI_BASEBALL_BAT)); - } } void CSpecialFX::Shutdown(void) { C3dMarkers::Shutdown(); + if (gpSmokeTrailTexture) { + RwTextureDestroy(gpSmokeTrailTexture); + gpSmokeTrailTexture = nil; + } } void @@ -149,6 +172,80 @@ CSpecialFX::Render(void) C3dMarkers::Render(); } +void +CSpecialFX::Render2DFXs(void) +{ + if (CSpecialFX::bVideoCam) { + CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f)); + CFont::SetJustifyOff(); + CFont::SetBackgroundOff(); + CFont::SetCentreSize(SCREEN_SCALE_FROM_RIGHT(20.0f)); + CFont::SetCentreOff(); + CFont::SetPropOn(); + CFont::SetColor(CRGBA(0, 255, 0, 200)); + FONT_LOCALE(FONT_STANDARD); + sprintf(gString, "%d", CTimer::GetFrameCounter() & 0x3F); // mb % 63 + AsciiToUnicode(gString, gUString); + CFont::PrintString(SCREEN_WIDTH * 8 / 10, SCREEN_HEIGHT * 8 / 10, gUString); + for (int32 i = 0; i < SCREEN_HEIGHT; i += 4) { + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDONE); + CSprite2d::Draw2DPolygon(0.0f, i, SCREEN_WIDTH, i, 0.0f, i+1, SCREEN_WIDTH, i+1, CRGBA(0, 100, 0, 100)); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + CSprite2d::Draw2DPolygon(0.0f, i+2, SCREEN_WIDTH, i+2, 0.0f, i+3, SCREEN_WIDTH, i+3, CRGBA(0, 0, 0, 150)); + } + int32 tmp = (CTimer::GetTimeInMilliseconds() & 0x7ff) * (SCREEN_HEIGHT + 70.0f) / 2048 - 70.0f; //mb % 2048 + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + CSprite2d::Draw2DPolygon(0.0, tmp, SCREEN_WIDTH, tmp, 0.0, tmp + 70.0f, SCREEN_WIDTH, tmp + 70.0f , CRGBA(0, 100, 0, 60)); + } + if (CSpecialFX::bLiftCam) { + CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f)); + CFont::SetJustifyOff(); + CFont::SetBackgroundOff(); + CFont::SetCentreSize(SCREEN_SCALE_FROM_RIGHT(20.0f)); + CFont::SetCentreOff(); + CFont::SetPropOn(); + CFont::SetColor(CRGBA(100, 100, 100, 200)); + FONT_LOCALE(FONT_STANDARD); + CFont::PrintString(SCREEN_WIDTH * 8 / 10, SCREEN_HEIGHT * 8 / 10, gUString); + for (int32 i = 0; i < SCREEN_HEIGHT; i += 4) { + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + CSprite2d::Draw2DPolygon(0.0f, i, SCREEN_WIDTH, i, 0.0f, i + 1, SCREEN_WIDTH, i + 1, CRGBA(100, 100, 100, 100)); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + CSprite2d::Draw2DPolygon(0.0f, i + 2, SCREEN_WIDTH, i + 2, 0.0f, i + 3, SCREEN_WIDTH, i + 3, CRGBA(0, 0, 0, 150)); + } + int32 tmp = (CTimer::GetTimeInMilliseconds() & 0x7ff) * (SCREEN_HEIGHT + 70.0f) / 2048 - 70.0f; //mb % 2048 + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + CSprite2d::Draw2DPolygon(0.0, tmp, SCREEN_WIDTH, tmp, 0.0, tmp + 70.0f, SCREEN_WIDTH, tmp + 70.0f, CRGBA(100, 100, 100, 60)); + for (int32 i = 0; i < 200; i++) { + int32 posX = CGeneral::GetRandomNumber() % (int32)SCREEN_WIDTH; + int32 posY = CGeneral::GetRandomNumber() % (int32)SCREEN_HEIGHT; + CSprite2d::DrawRect(CRect(posX, posY + 2, posX+20, posY), CRGBA(255, 255, 255, 64)); + } + } + if (CSpecialFX::bSnapShotActive) { + if (++CSpecialFX::SnapShotFrames > 20) { + CSpecialFX::bSnapShotActive = false; + CTimer::SetTimeScale(1.0f); + } else { + CTimer::SetTimeScale(0.0f); //in andro it's 0.00001 + if (CSpecialFX::SnapShotFrames < 10) { + int32 tmp = (255 - 255 * CSpecialFX::SnapShotFrames / 10) * 0.65f; + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + CSprite2d::Draw2DPolygon(0.0f, 0.0f, SCREEN_WIDTH, 0.0f, 0.0f, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, CRGBA(tmp, tmp, tmp, tmp)); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + } + } + } +} + CRegisteredMotionBlurStreak CMotionBlurStreaks::aStreaks[NUMMBLURSTREAKS]; void @@ -209,7 +306,7 @@ CMotionBlurStreaks::Update(void) { int i; for(i = 0; i < NUMMBLURSTREAKS; i++) - if(aStreaks[i].m_id) + if(aStreaks[i].m_id != 0) aStreaks[i].Update(); } @@ -217,6 +314,7 @@ void CMotionBlurStreaks::RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2) { int i; + for(i = 0; i < NUMMBLURSTREAKS; i++){ if(aStreaks[i].m_id == id){ // Found a streak from last frame, update @@ -229,10 +327,12 @@ CMotionBlurStreaks::RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVecto return; } } + // Find free slot - for(i = 0; aStreaks[i].m_id; i++) + for(i = 0; aStreaks[i].m_id != 0 ; i++) if(i == NUMMBLURSTREAKS-1) return; + // Create a new streak aStreaks[i].m_id = id; aStreaks[i].m_red = r; @@ -251,7 +351,7 @@ CMotionBlurStreaks::Render(void) bool setRenderStates = false; int i; for(i = 0; i < NUMMBLURSTREAKS; i++) - if(aStreaks[i].m_id){ + if(aStreaks[i].m_id != 0){ if(!setRenderStates){ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); @@ -281,20 +381,103 @@ void CBulletTraces::Init(void) aTraces[i].m_bInUse = false; } -void CBulletTraces::AddTrace(CVector* vecStart, CVector* vecTarget) +void CBulletTraces::AddTrace(CVector* start, CVector* end, float thickness, uint32 lifeTime, uint8 visibility) { - int index; - for (index = 0; index < NUMBULLETTRACES; index++) { - if (!aTraces[index].m_bInUse) - break; + int32 enabledCount; + uint32 modifiedLifeTime; + int32 nextSlot; + + enabledCount = 0; + for (int i = 0; i < NUMBULLETTRACES; i++) + if (aTraces[i].m_bInUse) + enabledCount++; + if (enabledCount >= 10) + modifiedLifeTime = lifeTime / 4; + else if (enabledCount >= 5) + modifiedLifeTime = lifeTime / 2; + else + modifiedLifeTime = lifeTime; + + nextSlot = 0; + for (int i = 0; nextSlot < NUMBULLETTRACES && aTraces[i].m_bInUse; i++) + nextSlot++; + if (nextSlot < 16) { + aTraces[nextSlot].m_vecStartPos = *start; + aTraces[nextSlot].m_vecEndPos = *end; + aTraces[nextSlot].m_bInUse = true; + aTraces[nextSlot].m_nCreationTime = CTimer::GetTimeInMilliseconds(); + aTraces[nextSlot].m_fVisibility = visibility; + aTraces[nextSlot].m_fThickness = thickness; + aTraces[nextSlot].m_nLifeTime = modifiedLifeTime; + } + + float startProjFwd = DotProduct(TheCamera.GetForward(), *start - TheCamera.GetPosition()); + float endProjFwd = DotProduct(TheCamera.GetForward(), *end - TheCamera.GetPosition()); + if (startProjFwd * endProjFwd < 0.0f) { //if one of point behind us and second before us + float fStartDistFwd = Abs(startProjFwd) / (Abs(startProjFwd) + Abs(endProjFwd)); + + float startProjUp = DotProduct(TheCamera.GetUp(), *start - TheCamera.GetPosition()); + float endProjUp = DotProduct(TheCamera.GetUp(), *end - TheCamera.GetPosition()); + float distUp = (endProjUp - startProjUp) * fStartDistFwd + startProjUp; + + float startProjRight = DotProduct(TheCamera.GetRight(), *start - TheCamera.GetPosition()); + float endProjRight = DotProduct(TheCamera.GetRight(), *end - TheCamera.GetPosition()); + float distRight = (endProjRight - startProjRight) * fStartDistFwd + startProjRight; + + float dist = Sqrt(SQR(distUp) + SQR(distRight)); + if (dist < 2.0f) { + if(distRight < 0.0f) + DMAudio.PlayFrontEndSound(SOUND_BULLETTRACE_2, 127 * (1.0f - dist * 0.5f)); + else + DMAudio.PlayFrontEndSound(SOUND_BULLETTRACE_1, 127 * (1.0f - dist * 0.5f)); + } + } +} + +void CBulletTraces::AddTrace(CVector* start, CVector* end, int32 weaponType, class CEntity* shooter) +{ + CPhysical* player; + float speed; + int16 camMode; + + if (shooter == (CEntity*)FindPlayerPed() || (FindPlayerVehicle() != nil && FindPlayerVehicle() == (CVehicle*)shooter)) { + camMode = TheCamera.Cams[TheCamera.ActiveCam].Mode; + if (camMode == CCam::MODE_M16_1STPERSON + || camMode == CCam::MODE_CAMERA + || camMode == CCam::MODE_SNIPER + || camMode == CCam::MODE_M16_1STPERSON_RUNABOUT + || camMode == CCam::MODE_ROCKETLAUNCHER + || camMode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT + || camMode == CCam::MODE_SNIPER_RUNABOUT + || camMode == CCam::MODE_HELICANNON_1STPERSON) { + + player = FindPlayerVehicle() ? (CPhysical*)FindPlayerVehicle() : (CPhysical*)FindPlayerPed(); + speed = player->m_vecMoveSpeed.Magnitude(); + if (speed < 0.05f) + return; + } + } + + switch (weaponType) { + case WEAPONTYPE_PYTHON: + case WEAPONTYPE_SHOTGUN: + case WEAPONTYPE_SPAS12_SHOTGUN: + case WEAPONTYPE_STUBBY_SHOTGUN: + CBulletTraces::AddTrace(start, end, 0.7f, 1000, 200); + break; + case WEAPONTYPE_M4: + case WEAPONTYPE_RUGER: + case WEAPONTYPE_SNIPERRIFLE: + case WEAPONTYPE_LASERSCOPE: + case WEAPONTYPE_M60: + case WEAPONTYPE_MINIGUN: + case WEAPONTYPE_HELICANNON: + CBulletTraces::AddTrace(start, end, 1.0f, 2000, 220); + break; + default: + CBulletTraces::AddTrace(start, end, 0.4f, 750, 150); + break; } - if (index == NUMBULLETTRACES) - return; - aTraces[index].m_vecCurrentPos = *vecStart; - aTraces[index].m_vecTargetPos = *vecTarget; - aTraces[index].m_bInUse = true; - aTraces[index].m_framesInUse = 0; - aTraces[index].m_lifeTime = 25 + CGeneral::GetRandomNumber() % 32; } void CBulletTraces::Render(void) @@ -303,35 +486,135 @@ void CBulletTraces::Render(void) if (!aTraces[i].m_bInUse) continue; RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); -#ifdef FIX_BUGS - // Raster has no transparent pixels so it relies on the raster format having alpha - // to turn on blending. librw image conversion might get rid of it right now so let's - // just force it on. - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSmokeTrailTexture)); + + float timeAlive = CTimer::GetTimeInMilliseconds() - aTraces[i].m_nCreationTime; + + float traceThickness = aTraces[i].m_fThickness * timeAlive / aTraces[i].m_nLifeTime; + CVector horizontalOffset = aTraces[i].m_vecEndPos - aTraces[i].m_vecStartPos; + horizontalOffset.Normalise(); + horizontalOffset *= traceThickness; + + //then closer trace to die then it more transparent + uint8 nAlphaValue = aTraces[i].m_fVisibility * (aTraces[i].m_nLifeTime - timeAlive) / aTraces[i].m_nLifeTime; + + CVector start = aTraces[i].m_vecStartPos; + CVector end = aTraces[i].m_vecEndPos; + float startProj = DotProduct(start - TheCamera.GetPosition(), TheCamera.GetForward()) - 0.7f; + float endProj = DotProduct(end - TheCamera.GetPosition(), TheCamera.GetForward()) - 0.7f; + if (startProj < 0.0f && endProj < 0.0f) //we dont need render trace behind us + continue; + + if (startProj < 0.0f) { //if strat behind us move it closer + float absStartProj = Abs(startProj); + float absEndProj = Abs(endProj); + start = (absEndProj * start + absStartProj * end) / (absStartProj + absEndProj); + } else if (endProj < 0.0f) { + float absStartProj = Abs(startProj); + float absEndProj = Abs(endProj); + end = (absEndProj * start + absStartProj * end) / (absStartProj + absEndProj); + } + + //we divide trace at three parts + CVector start2 = (7.0f * start + end) / 8; + CVector end2 = (7.0f * end + start) / 8; + + RwIm3DVertexSetV(&TraceVertices[5], 10.0f); + RwIm3DVertexSetV(&TraceVertices[6], 10.0f); + RwIm3DVertexSetV(&TraceVertices[7], 10.0f); + RwIm3DVertexSetV(&TraceVertices[8], 10.0f); + RwIm3DVertexSetV(&TraceVertices[9], 10.0f); + + RwIm3DVertexSetRGBA(&TraceVertices[0], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[1], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[2], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[3], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[4], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[5], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[6], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[7], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[8], 255, 255, 255, nAlphaValue); + RwIm3DVertexSetRGBA(&TraceVertices[9], 255, 255, 255, nAlphaValue); + //two points in center + RwIm3DVertexSetPos(&TraceVertices[0], start2.x, start2.y, start2.z); + RwIm3DVertexSetPos(&TraceVertices[5], end2.x, end2.y, end2.z); + //vertical planes + RwIm3DVertexSetPos(&TraceVertices[1], start2.x, start2.y, start2.z + traceThickness); + RwIm3DVertexSetPos(&TraceVertices[3], start2.x, start2.y, start2.z - traceThickness); + RwIm3DVertexSetPos(&TraceVertices[6], end2.x, end2.y, end2.z + traceThickness); + RwIm3DVertexSetPos(&TraceVertices[8], end2.x, end2.y, end2.z - traceThickness); + //horizontal planes + RwIm3DVertexSetPos(&TraceVertices[2], start2.x + horizontalOffset.y, start2.y - horizontalOffset.x, start2.z); + RwIm3DVertexSetPos(&TraceVertices[7], end2.x + horizontalOffset.y, end2.y - horizontalOffset.x, end2.z); +#ifdef FIX_BUGS //this point calculated wrong for some reason + RwIm3DVertexSetPos(&TraceVertices[4], start2.x - horizontalOffset.y, start2.y + horizontalOffset.x, start2.z); + RwIm3DVertexSetPos(&TraceVertices[9], end2.x - horizontalOffset.y, end2.y + horizontalOffset.x, end2.z); +#else + RwIm3DVertexSetPos(&TraceVertices[4], start2.x - horizontalOffset.y, start2.y - horizontalOffset.y, start2.z); + RwIm3DVertexSetPos(&TraceVertices[9], end2.x - horizontalOffset.y, end2.y - horizontalOffset.y, end2.z); #endif - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpShadowExplosionTex)); - CVector inf = aTraces[i].m_vecCurrentPos; - CVector sup = aTraces[i].m_vecTargetPos; - CVector center = (inf + sup) / 2; - CVector width = CrossProduct(TheCamera.GetForward(), (sup - inf)); - width.Normalise(); - width /= 20; - uint8 intensity = aTraces[i].m_lifeTime; - for (int i = 0; i < ARRAY_SIZE(TraceVertices); i++) - RwIm3DVertexSetRGBA(&TraceVertices[i], intensity, intensity, intensity, 0xFF); - RwIm3DVertexSetPos(&TraceVertices[0], inf.x + width.x, inf.y + width.y, inf.z + width.z); - RwIm3DVertexSetPos(&TraceVertices[1], inf.x - width.x, inf.y - width.y, inf.z - width.z); - RwIm3DVertexSetPos(&TraceVertices[2], center.x + width.x, center.y + width.y, center.z + width.z); - RwIm3DVertexSetPos(&TraceVertices[3], center.x - width.x, center.y - width.y, center.z - width.z); - RwIm3DVertexSetPos(&TraceVertices[4], sup.x + width.x, sup.y + width.y, sup.z + width.z); - RwIm3DVertexSetPos(&TraceVertices[5], sup.x - width.x, sup.y - width.y, sup.z - width.z); - LittleTest(); + if (RwIm3DTransform(TraceVertices, ARRAY_SIZE(TraceVertices), nil, 1)) { RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TraceIndexList, ARRAY_SIZE(TraceIndexList)); RwIm3DEnd(); } + + RwIm3DVertexSetV(&TraceVertices[5], 2.0f); + RwIm3DVertexSetV(&TraceVertices[6], 2.0f); + RwIm3DVertexSetV(&TraceVertices[7], 2.0f); + RwIm3DVertexSetV(&TraceVertices[8], 2.0f); + RwIm3DVertexSetV(&TraceVertices[9], 2.0f); + RwIm3DVertexSetRGBA(&TraceVertices[0], 255, 255, 255, 0); + RwIm3DVertexSetRGBA(&TraceVertices[1], 255, 255, 255, 0); + RwIm3DVertexSetRGBA(&TraceVertices[2], 255, 255, 255, 0); + RwIm3DVertexSetRGBA(&TraceVertices[3], 255, 255, 255, 0); + RwIm3DVertexSetRGBA(&TraceVertices[4], 255, 255, 255, 0); + + RwIm3DVertexSetPos(&TraceVertices[0], start.x, start.y, start.z); + RwIm3DVertexSetPos(&TraceVertices[1], start.x, start.y, start.z + traceThickness); + RwIm3DVertexSetPos(&TraceVertices[3], start.x, start.y, start.z - traceThickness); + RwIm3DVertexSetPos(&TraceVertices[2], start.x + horizontalOffset.y, start.y - horizontalOffset.x, start.z); + + RwIm3DVertexSetPos(&TraceVertices[5], start2.x, start2.y, start2.z); + RwIm3DVertexSetPos(&TraceVertices[6], start2.x, start2.y, start2.z + traceThickness); + RwIm3DVertexSetPos(&TraceVertices[8], start2.x, start2.y, start2.z - traceThickness); + RwIm3DVertexSetPos(&TraceVertices[7], start2.x + horizontalOffset.y, start2.y - horizontalOffset.x, start2.z); +#ifdef FIX_BUGS + RwIm3DVertexSetPos(&TraceVertices[4], start.x - horizontalOffset.y, start.y + horizontalOffset.x, start.z); + RwIm3DVertexSetPos(&TraceVertices[9], start2.x - horizontalOffset.y, start2.y + horizontalOffset.x, start2.z); +#else + RwIm3DVertexSetPos(&TraceVertices[4], start.x - horizontalOffset.y, start.y - horizontalOffset.y, start.z); + RwIm3DVertexSetPos(&TraceVertices[9], start2.x - horizontalOffset.y, start2.y - horizontalOffset.y, start2.z); +#endif + + if (RwIm3DTransform(TraceVertices, ARRAY_SIZE(TraceVertices), nil, rwIM3D_VERTEXUV)) { + RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TraceIndexList, ARRAY_SIZE(TraceIndexList)); + RwIm3DEnd(); + } + + RwIm3DVertexSetPos(&TraceVertices[1], end.x, end.y, end.z); + RwIm3DVertexSetPos(&TraceVertices[2], end.x, end.y, end.z + traceThickness); + RwIm3DVertexSetPos(&TraceVertices[4], end.x, end.y, end.z - traceThickness); + RwIm3DVertexSetPos(&TraceVertices[3], end.x + horizontalOffset.y, end.y - horizontalOffset.x, end.z); + + RwIm3DVertexSetPos(&TraceVertices[5], end2.x, end2.y, end2.z); + RwIm3DVertexSetPos(&TraceVertices[6], end2.x, end2.y, end2.z + traceThickness); + RwIm3DVertexSetPos(&TraceVertices[8], end2.x, end2.y, end2.z - traceThickness); + RwIm3DVertexSetPos(&TraceVertices[7], end2.x + horizontalOffset.y, end2.y - horizontalOffset.x, end2.z); +#ifdef FIX_BUGS + RwIm3DVertexSetPos(&TraceVertices[5], end.x - horizontalOffset.y, end.y + horizontalOffset.x, end.z); + RwIm3DVertexSetPos(&TraceVertices[9], end2.x - horizontalOffset.y, end2.y + horizontalOffset.x, end2.z); +#else + RwIm3DVertexSetPos(&TraceVertices[5], end.x - horizontalOffset.y, end.y - horizontalOffset.y, end.z); + RwIm3DVertexSetPos(&TraceVertices[9], end2.x - horizontalOffset.y, end2.y - horizontalOffset.y, end2.z); +#endif + + if (RwIm3DTransform(TraceVertices, ARRAY_SIZE(TraceVertices), nil, rwIM3D_VERTEXUV)) { + RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TraceIndexList, ARRAY_SIZE(TraceIndexList)); + RwIm3DEnd(); + } } RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); @@ -348,23 +631,8 @@ void CBulletTraces::Update(void) void CBulletTrace::Update(void) { - if (m_framesInUse == 0) { - m_framesInUse++; - return; - } - if (m_framesInUse > 60) { - m_bInUse = false; - return; - } - CVector diff = m_vecCurrentPos - m_vecTargetPos; - float remaining = diff.Magnitude(); - if (remaining > 0.8f) - m_vecCurrentPos = m_vecTargetPos + (remaining - 0.8f) / remaining * diff; - else + if (CTimer::GetTimeInMilliseconds() - m_nCreationTime >= m_nLifeTime) m_bInUse = false; - if (--m_lifeTime == 0) - m_bInUse = false; - m_framesInUse++; } RpAtomic * @@ -578,7 +846,7 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size } else { pMarker->m_fStdSize = size; } - } else if (type == MARKERTYPE_CYLINDER) { + } else { if (dist < size + 12.0f) { if (dist > size + 1.0f) pMarker->m_Color.alpha = (1.0f - (size + 12.0f - dist) * 0.7f / 11.0f) * (float)a; @@ -591,15 +859,9 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size float someSin = Sin(TWOPI * (float)((pMarker->m_nPulsePeriod - 1) & (CTimer::GetTimeInMilliseconds() - pMarker->m_nStartTime)) / (float)pMarker->m_nPulsePeriod); pMarker->m_fSize = pMarker->m_fStdSize - pulseFraction * pMarker->m_fStdSize * someSin; - if (type == MARKERTYPE_ARROW) { + if (type == MARKERTYPE_ARROW) pos.z += 0.25f * pMarker->m_fStdSize * someSin; - } else if (type == MARKERTYPE_0) { - if (someSin > 0.0f) - pMarker->m_Color.alpha = (float)a * 0.7f * someSin + a; - else - pMarker->m_Color.alpha = (float)a * 0.4f * someSin + a; - } - if (pMarker->m_nRotateRate) { + if (pMarker->m_nRotateRate != 0) { RwV3d pos = pMarker->m_Matrix.m_matrix.pos; pMarker->m_Matrix.RotateZ(DEGTORAD(pMarker->m_nRotateRate * CTimer::GetTimeStep())); pMarker->m_Matrix.GetPosition() = pos; @@ -623,7 +885,7 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size pMarker->DeleteMarkerObject(); pMarker->AddMarker(identifier, type, size, r, g, b, a, pulsePeriod, pulseFraction, rotateRate); - if (type == MARKERTYPE_CYLINDER || type == MARKERTYPE_0 || type == MARKERTYPE_2) { + if (type == MARKERTYPE_CYLINDER) { if ((playerPos - pos).MagnitudeSqr() < sq(100.f) && CColStore::HasCollisionLoaded(CVector2D(pos))) { float z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 1.0f, nil); if (z != 0.0f) @@ -634,10 +896,6 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size } } pMarker->m_Matrix.SetTranslate(pos.x, pos.y, pos.z); - if (type == MARKERTYPE_2) { - pMarker->m_Matrix.RotateX(PI); - pMarker->m_Matrix.GetPosition() = pos; - } pMarker->m_Matrix.UpdateRW(); if (type == MARKERTYPE_ARROW) { if (dist < 25.0f) { @@ -648,7 +906,7 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size } else { pMarker->m_fStdSize = size; } - } else if (type == MARKERTYPE_CYLINDER) { + } else { if (dist < size + 12.0f) { if (dist > size + 1.0f) pMarker->m_Color.alpha = (1.0f - (size + 12.0f - dist) * 0.7f / 11.0f) * (float)a; @@ -752,6 +1010,9 @@ CBrightLights::Render(void) RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil); + TempBufferVerticesStored = 0; + TempBufferIndicesStored = 0; + for(i = 0; i < NumBrightLights; i++){ if(TempBufferIndicesStored > TEMPBUFFERINDEXSIZE-40 || TempBufferVerticesStored > TEMPBUFFERVERTSIZE-40) RenderOutGeometryBuffer(); @@ -788,6 +1049,10 @@ CBrightLights::Render(void) g = aBrightLights[i].m_green; b = aBrightLights[i].m_blue; break; +#ifdef FIX_BUGS //just to make sure that color never will be undefined + default: + return; +#endif } if(aBrightLights[i].m_camDist < BRIGHTLIGHTS_FADE_DIST) @@ -851,6 +1116,22 @@ CBrightLights::Render(void) TempBufferIndicesStored += 12*3; break; + case BRIGHTLIGHT_FRONT_BIG: + case BRIGHTLIGHT_REAR_BIG: + for (j = 0; j < 8; j++) { + pos = BigCarHeadLightsSide[j] * aBrightLights[i].m_side + + BigCarHeadLightsUp[j] * aBrightLights[i].m_up + + BigCarHeadLightsFront[j] * aBrightLights[i].m_front + + aBrightLights[i].m_pos; + RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + j], r, g, b, a); + RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + j], pos.x, pos.y, pos.z); + } + for (j = 0; j < 12 * 3; j++) + TempBufferRenderIndexList[TempBufferIndicesStored + j] = CubeIndices[j] + TempBufferVerticesStored; + TempBufferVerticesStored += 8; + TempBufferIndicesStored += 12 * 3; + break; + case BRIGHTLIGHT_FRONT_TALL: case BRIGHTLIGHT_REAR_TALL: for(j = 0; j < 8; j++){ @@ -869,8 +1150,8 @@ CBrightLights::Render(void) case BRIGHTLIGHT_SIREN: for(j = 0; j < 6; j++){ - pos = SirenLightsSide[j]*aBrightLights[i].m_side + - SirenLightsUp[j]*aBrightLights[i].m_up + + pos = SirenLightsSide[j] * TheCamera.GetRight() + + SirenLightsUp[j] * TheCamera.GetUp() + aBrightLights[i].m_pos; RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+j], r, g, b, a); RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+j], pos.x, pos.y, pos.z); @@ -1056,8 +1337,9 @@ CMoneyMessage::Render() { const float MAX_SCALE = 4.0f; uint32 nLifeTime = CTimer::GetTimeInMilliseconds() - m_nTimeRegistered; - if (nLifeTime >= MONEY_MESSAGE_LIFETIME_MS) m_nTimeRegistered = 0; - else { + if (nLifeTime >= MONEY_MESSAGE_LIFETIME_MS) { + m_nTimeRegistered = 0; + } else { float fLifeTime = (float)nLifeTime / MONEY_MESSAGE_LIFETIME_MS; RwV3d vecOut; float fDistX, fDistY; @@ -1066,20 +1348,15 @@ CMoneyMessage::Render() fDistY *= (0.7 * fLifeTime + 2.0) * m_fSize; CFont::SetPropOn(); CFont::SetBackgroundOff(); - - float fScaleY = fDistY / 100.0f; - if (fScaleY > MAX_SCALE) fScaleY = MAX_SCALE; - - float fScaleX = fDistX / 100.0f; - if (fScaleX > MAX_SCALE) fScaleX = MAX_SCALE; - + float fScaleY = Min(fDistY / 100.0f, MAX_SCALE); + float fScaleX = Min(fDistX / 100.0f, MAX_SCALE); CFont::SetScale(fScaleX, fScaleY); // maybe use SCREEN_SCALE_X and SCREEN_SCALE_Y here? CFont::SetCentreOn(); CFont::SetCentreSize(SCREEN_WIDTH); CFont::SetJustifyOff(); CFont::SetColor(CRGBA(m_Colour.r, m_Colour.g, m_Colour.b, (255.0f - 255.0f * fLifeTime) * m_fOpacity)); CFont::SetBackGroundOnlyTextOff(); - CFont::SetFontStyle(FONT_STANDARD); + FONT_LOCALE(FONT_STANDARD); CFont::PrintString(vecOut.x, vecOut.y, m_aText); } } diff --git a/src/render/SpecialFX.h b/src/render/SpecialFX.h index 8bd0d5e1..f163d8ca 100644 --- a/src/render/SpecialFX.h +++ b/src/render/SpecialFX.h @@ -1,8 +1,12 @@ #pragma once +//file done + class CSpecialFX { public: + static bool bVideoCam; + static bool bLiftCam; static bool bSnapShotActive; static int32 SnapShotFrames; @@ -10,8 +14,11 @@ public: static void Update(void); static void Init(void); static void Shutdown(void); + static void AddWeaponStreak(int type); + static void Render2DFXs(); }; + class CRegisteredMotionBlurStreak { public: @@ -27,6 +34,7 @@ public: void Render(void); }; + class CMotionBlurStreaks { static CRegisteredMotionBlurStreak aStreaks[NUMMBLURSTREAKS]; @@ -37,33 +45,31 @@ public: static void Render(void); }; + struct CBulletTrace { - CVector m_vecCurrentPos; - CVector m_vecTargetPos; + CVector m_vecStartPos; + CVector m_vecEndPos; bool m_bInUse; - uint8 m_framesInUse; - uint8 m_lifeTime; + uint32 m_nCreationTime; + uint32 m_nLifeTime; + float m_fThickness; + uint8 m_fVisibility; void Update(void); }; + class CBulletTraces { public: static CBulletTrace aTraces[NUMBULLETTRACES]; static void Init(void); - static void AddTrace(CVector*, CVector*); static void Render(void); static void Update(void); - -//TODO(MIAMI) - static void AddTrace(CVector *, CVector *, float, unsigned int, unsigned char) {} - static void AddTrace(CVector *a, CVector *b, int32 weapontype, class CEntity *shooter) - { - AddTrace(a, b); //TODO: temp - } + static void AddTrace(CVector* start, CVector* end, float thickness, uint32 lifeTime, uint8 visibility); + static void AddTrace(CVector* start, CVector* end, int32 weaponType, class CEntity* shooter); }; enum @@ -104,6 +110,7 @@ public: void Render(); }; + class C3dMarkers { public: @@ -144,6 +151,7 @@ enum BRIGHTLIGHT_REAR = BRIGHTLIGHT_REAR_LONG, }; + class CBrightLight { public: @@ -158,6 +166,7 @@ public: uint8 m_blue; }; + class CBrightLights { static int NumBrightLights; @@ -177,6 +186,7 @@ enum SHINYTEXT_FLAT }; + class CShinyText { public: @@ -189,7 +199,8 @@ public: uint8 m_blue; }; -class CShinyTexts + +class CShinyTexts { static int NumShinyTexts; static CShinyText aShinyTexts[NUMSHINYTEXTS]; @@ -197,11 +208,12 @@ public: static void Init(void); static void RegisterOne(CVector p0, CVector p1, CVector p2, CVector p3, float u0, float v0, float u1, float v1, float u2, float v2, float u3, float v3, - uint8 type, uint8 red, uint8 green, uint8 blue, float maxDist); + uint8 type, uint8 red, uint8 green, uint8 blue, float maxDist); //not used static void Render(void); static void RenderOutGeometryBuffer(void); }; + class CMoneyMessage { friend class CMoneyMessages; @@ -216,6 +228,7 @@ public: void Render(); }; + class CMoneyMessages { static CMoneyMessage aMoneyMessages[NUMMONEYMESSAGES]; @@ -225,11 +238,12 @@ public: static void RegisterOne(CVector vecPos, const char *pText, uint8 bRed, uint8 bGreen, uint8 bBlue, float fSize, float fOpacity); }; + class CSpecialParticleStuff { static uint32 BoatFromStart; public: - static void CreateFoamAroundObject(CMatrix*, float, float, float, int32); - static void StartBoatFoamAnimation(); - static void UpdateBoatFoamAnimation(CMatrix*); + static void CreateFoamAroundObject(CMatrix*, float, float, float, int32); //not used + static void StartBoatFoamAnimation(); //not used + static void UpdateBoatFoamAnimation(CMatrix*); //not used }; diff --git a/src/render/WaterCannon.cpp b/src/render/WaterCannon.cpp index bd2b9a68..91304be3 100644 --- a/src/render/WaterCannon.cpp +++ b/src/render/WaterCannon.cpp @@ -11,6 +11,9 @@ #include "Fire.h" #include "WaterLevel.h" #include "Camera.h" +#include "Particle.h" + +// --MIAMI: file done #define WATERCANNONVERTS 4 #define WATERCANNONINDEXES 12 @@ -64,7 +67,7 @@ void CWaterCannon::Update_OncePerFrame(int16 index) if (CTimer::GetTimeInMilliseconds() > m_nTimeCreated + WATERCANNON_LIFETIME ) { - m_nCur = (m_nCur + 1) % -NUM_SEGMENTPOINTS; + m_nCur = (m_nCur + 1) % NUM_SEGMENTPOINTS; m_abUsed[m_nCur] = false; } @@ -128,7 +131,7 @@ void CWaterCannon::Render(void) RwIm3DVertexSetV(&WaterCannonVertices[2], v); RwIm3DVertexSetV(&WaterCannonVertices[3], v); - int16 pointA = m_nCur % -NUM_SEGMENTPOINTS; + int16 pointA = m_nCur % NUM_SEGMENTPOINTS; int16 pointB = pointA - 1; if ( (pointA - 1) < 0 ) @@ -235,11 +238,16 @@ void CWaterCannon::PushPeds(void) ped->m_vecMoveSpeed.x = (0.6f * m_avecVelocity[j].x + ped->m_vecMoveSpeed.x) * 0.5f; ped->m_vecMoveSpeed.y = (0.6f * m_avecVelocity[j].y + ped->m_vecMoveSpeed.y) * 0.5f; - ped->SetFall(2000, AnimationId(ANIM_KO_SKID_FRONT + localDir), 0); - - CFire *fire = ped->m_pFire; - if ( fire ) - fire->Extinguish(); + float pedSpeed2D = ped->m_vecMoveSpeed.Magnitude2D(); + + if ( pedSpeed2D > 0.2f ) { + ped->m_vecMoveSpeed.x *= (0.2f / pedSpeed2D); + ped->m_vecMoveSpeed.y *= (0.2f / pedSpeed2D); + } + ped->SetFall(2000, (AnimationId)(localDir + ANIM_KO_SKID_FRONT), 0); + CParticle::AddParticle(PARTICLE_STEAM_NY_SLOWMOTION, ped->GetPosition(), ped->m_vecMoveSpeed * 0.3f, 0, 0.5f); + CParticle::AddParticle(PARTICLE_CAR_SPLASH, ped->GetPosition(), ped->m_vecMoveSpeed * -0.3f + CVector(0.f, 0.f, 0.5f), 0, 0.5f, + CGeneral::GetRandomNumberInRange(0.f, 10.f), CGeneral::GetRandomNumberInRange(0.f, 90.f), 1); j = NUM_SEGMENTPOINTS; } diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp index 07304b77..85418edd 100644 --- a/src/rw/RwHelper.cpp +++ b/src/rw/RwHelper.cpp @@ -534,12 +534,13 @@ CameraSize(RwCamera * camera, RwRect * rect, } } - // BUG: game just changes camera raster's sizes, but this is a hack - if (( origSize.w != rect->w ) && ( origSize.h != rect->h )) + if (( origSize.w != rect->w ) || ( origSize.h != rect->h )) { RwRaster *raster; RwRaster *zRaster; + // BUG: game just changes camera raster's sizes, but this is a hack +#ifdef FIX_BUGS /* * Destroy rasters... */ @@ -597,6 +598,13 @@ CameraSize(RwCamera * camera, RwRect * rect, RwCameraSetRaster(camera, raster); RwCameraSetZRaster(camera, zRaster); } +#else + raster = RwCameraGetRaster(camera); + zRaster = RwCameraGetZRaster(camera); + + raster->width = zRaster->width = rect->w; + raster->height = zRaster->height = rect->h; +#endif } /* Figure out the view window */ diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp index 18eecd95..966f353a 100644 --- a/src/save/GenericGameStorage.cpp +++ b/src/save/GenericGameStorage.cpp @@ -41,8 +41,10 @@ #include "Timecycle.h" #include "Fluff.h" -#define BLOCK_COUNT 20 -#define SIZE_OF_SIMPLEVARS 0xFC +// --MIAMI: file done + +#define BLOCK_COUNT 22 +#define SIZE_OF_SIMPLEVARS 0xE4 const uint32 SIZE_OF_ONE_GAME_IN_BYTES = 201729; @@ -60,7 +62,6 @@ int CheckSum; eLevelName m_LevelToLoad; char SaveFileNameJustSaved[260]; int Slots[SLOT_COUNT]; -CDate CompileDateAndTime; bool b_FoundRecentSavedGameWantToLoad; bool JustLoadedDontFadeInYet; @@ -112,13 +113,14 @@ do {\ buf += size;\ } while (0) -#define WriteSaveDataBlock(save_func)\ +#define WriteSaveDataBlock(save_func, msg)\ do {\ size = 0;\ buf = work_buff;\ reserved = 0;\ MakeSpaceForSizeInBufferPointer(presize, buf, postsize);\ save_func(buf, &size);\ + debug(msg"== %i \n", size);\ CopySizeAndPreparePointer(presize, buf, postsize, reserved, size);\ if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, buf - work_buff))\ return false;\ @@ -145,9 +147,10 @@ GenericSave(int file) reserved = 0; // Save simple vars - lastMissionPassed = TheText.Get(CStats::LastMissionPassedName); + lastMissionPassed = TheText.Get(CStats::LastMissionPassedName[0] ? CStats::LastMissionPassedName : "ITBEG"); if (lastMissionPassed[0] != '\0') { AsciiToUnicode("...'", suffix); + suffix[3] = L'\0'; #ifdef FIX_BUGS // fix buffer overflow int len = UnicodeStrlen(lastMissionPassed); @@ -194,12 +197,6 @@ GenericSave(int file) WriteDataToBufferPointer(buf, CWeather::NewWeatherType); WriteDataToBufferPointer(buf, CWeather::ForcedWeatherType); WriteDataToBufferPointer(buf, CWeather::InterpolationValue); - WriteDataToBufferPointer(buf, CompileDateAndTime.m_nSecond); - WriteDataToBufferPointer(buf, CompileDateAndTime.m_nMinute); - WriteDataToBufferPointer(buf, CompileDateAndTime.m_nHour); - WriteDataToBufferPointer(buf, CompileDateAndTime.m_nDay); - WriteDataToBufferPointer(buf, CompileDateAndTime.m_nMonth); - WriteDataToBufferPointer(buf, CompileDateAndTime.m_nYear); WriteDataToBufferPointer(buf, CWeather::WeatherTypeInList); #ifdef COMPATIBLE_SAVES // converted to float for compatibility with original format @@ -227,6 +224,7 @@ GenericSave(int file) buf += 4; postsize = buf; CTheScripts::SaveAllScripts(buf, &size); + debug("ScriptSize== %i \n", size); CopySizeAndPreparePointer(presize, buf, postsize, reserved, size); if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, buf - work_buff)) return false; @@ -234,28 +232,28 @@ GenericSave(int file) totalSize = buf - work_buff; // Save the rest - WriteSaveDataBlock(CPools::SavePedPool); - WriteSaveDataBlock(CGarages::Save); - WriteSaveDataBlock(CGameLogic::Save); - WriteSaveDataBlock(CPools::SaveVehiclePool); - WriteSaveDataBlock(CPools::SaveObjectPool); - WriteSaveDataBlock(ThePaths.Save); - WriteSaveDataBlock(CCranes::Save); - WriteSaveDataBlock(CPickups::Save); - WriteSaveDataBlock(gPhoneInfo.Save); - WriteSaveDataBlock(CRestart::SaveAllRestartPoints); - WriteSaveDataBlock(CRadar::SaveAllRadarBlips); - WriteSaveDataBlock(CTheZones::SaveAllZones); - WriteSaveDataBlock(CGangs::SaveAllGangData); - WriteSaveDataBlock(CTheCarGenerators::SaveAllCarGenerators); - WriteSaveDataBlock(CParticleObject::SaveParticle); - WriteSaveDataBlock(cAudioScriptObject::SaveAllAudioScriptObjects); - WriteSaveDataBlock(CScriptPaths::Save); - WriteSaveDataBlock(CWorld::Players[CWorld::PlayerInFocus].SavePlayerInfo); - WriteSaveDataBlock(CStats::SaveStats); - WriteSaveDataBlock(CSetPieces::Save); - WriteSaveDataBlock(CStreaming::MemoryCardSave); - WriteSaveDataBlock(CPedType::Save); + WriteSaveDataBlock(CPools::SavePedPool, "PedPoolSize"); + WriteSaveDataBlock(CGarages::Save, "GaragesSize"); + WriteSaveDataBlock(CGameLogic::Save, "GameLogicSize"); + WriteSaveDataBlock(CPools::SaveVehiclePool, "VehPoolSize"); + WriteSaveDataBlock(CPools::SaveObjectPool, "ObjectPoolSize"); + WriteSaveDataBlock(ThePaths.Save, "ThePathsSize"); + WriteSaveDataBlock(CCranes::Save, "CranesSize"); + WriteSaveDataBlock(CPickups::Save, "PickUpsSize"); + WriteSaveDataBlock(gPhoneInfo.Save, "PhoneInfoSize"); + WriteSaveDataBlock(CRestart::SaveAllRestartPoints, "RestartPointsBufferSize"); + WriteSaveDataBlock(CRadar::SaveAllRadarBlips, "RadarBlipsBufferSize"); + WriteSaveDataBlock(CTheZones::SaveAllZones, "AllZonesBufferSize"); + WriteSaveDataBlock(CGangs::SaveAllGangData, "AllGangDataSize"); + WriteSaveDataBlock(CTheCarGenerators::SaveAllCarGenerators, "AllCarGeneratorsSize"); + WriteSaveDataBlock(CParticleObject::SaveParticle, "ParticlesSize"); + WriteSaveDataBlock(cAudioScriptObject::SaveAllAudioScriptObjects, "AllAudioScriptObjectsSize"); + WriteSaveDataBlock(CScriptPaths::Save, "ScriptPathsSize"); + WriteSaveDataBlock(CWorld::Players[CWorld::PlayerInFocus].SavePlayerInfo, "PlayerInfoSize"); + WriteSaveDataBlock(CStats::SaveStats, "StatsSize"); + WriteSaveDataBlock(CSetPieces::Save, "SetPiecesSize"); + WriteSaveDataBlock(CStreaming::MemoryCardSave, "StreamingSize"); + WriteSaveDataBlock(CPedType::Save, "PedTypeSize"); // Write padding for (int i = 0; i < 4; i++) { @@ -331,12 +329,6 @@ GenericLoad() ReadDataFromBufferPointer(buf, CWeather::NewWeatherType); ReadDataFromBufferPointer(buf, CWeather::ForcedWeatherType); ReadDataFromBufferPointer(buf, CWeather::InterpolationValue); - ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nSecond); - ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nMinute); - ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nHour); - ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nDay); - ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nMonth); - ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nYear); ReadDataFromBufferPointer(buf, CWeather::WeatherTypeInList); #ifdef COMPATIBLE_SAVES // converted to float for compatibility with original format @@ -470,8 +462,13 @@ CloseFile(int32 file) void DoGameSpecificStuffAfterSucessLoad() { + CCollision::SortOutCollisionAfterLoad(); + CStreaming::LoadSceneCollision(TheCamera.GetPosition()); + CStreaming::LoadScene(TheCamera.GetPosition()); + CGame::TidyUpMemory(true, false); StillToFadeOut = true; JustLoadedDontFadeInYet = true; + TheCamera.Fade(0.0f, 0); CTheScripts::Process(); } diff --git a/src/save/GenericGameStorage.h b/src/save/GenericGameStorage.h index 236e34f5..07aa23ca 100644 --- a/src/save/GenericGameStorage.h +++ b/src/save/GenericGameStorage.h @@ -25,8 +25,6 @@ bool CheckDataNotCorrupt(int32 slot, char *name); bool RestoreForStartLoad(); int align4bytes(int32 size); -extern class CDate CompileDateAndTime; - extern char DefaultPCSaveFileName[260]; extern char ValidSaveName[260]; extern char LoadFileName[256]; diff --git a/src/skel/crossplatform.cpp b/src/skel/crossplatform.cpp index 452ad9fa..ac4bbe85 100644 --- a/src/skel/crossplatform.cpp +++ b/src/skel/crossplatform.cpp @@ -27,13 +27,28 @@ void GetLocalTime_CP(SYSTEMTIME *out) { #ifndef _WIN32 HANDLE FindFirstFile(const char* pathname, WIN32_FIND_DATA* firstfile) { char newpathname[32]; + strncpy(newpathname, pathname, 32); - char* path = strtok(newpathname, "\\*"); + char* path = strtok(newpathname, "*"); + + // Case-sensitivity and backslashes... + char *real = casepath(path); + if (real) { + real[strlen(real)] = '*'; + char *extension = strtok(NULL, "*"); + if (extension) + strcat(real, extension); + + strncpy(newpathname, real, 32); + free(real); + path = strtok(newpathname, "*"); + } + strncpy(firstfile->folder, path, sizeof(firstfile->folder)); // Both w/ extension and w/o extension is ok - if (strlen(path) + 2 != strlen(pathname)) - strncpy(firstfile->extension, strtok(NULL, "\\*"), sizeof(firstfile->extension)); + if (strlen(path) + 1 != strlen(pathname)) + strncpy(firstfile->extension, strtok(NULL, "*"), sizeof(firstfile->extension)); else strncpy(firstfile->extension, "", sizeof(firstfile->extension)); @@ -52,8 +67,8 @@ bool FindNextFile(HANDLE d, WIN32_FIND_DATA* finddata) { while ((file = readdir((DIR*)d)) != NULL) { // We only want "DT_REG"ular Files, but reportedly some FS and OSes gives DT_UNKNOWN as type. - if ((file->d_type == DT_UNKNOWN || file->d_type == DT_REG) && - (extensionLen == 0 || strncmp(&file->d_name[strlen(file->d_name) - extensionLen], finddata->extension, extensionLen) == 0)) { + if ((file->d_type == DT_UNKNOWN || file->d_type == DT_REG || file->d_type == DT_LNK) && + (extensionLen == 0 || strncasecmp(&file->d_name[strlen(file->d_name) - extensionLen], finddata->extension, extensionLen) == 0)) { sprintf(relativepath, "%s/%s", finddata->folder, file->d_name); realpath(relativepath, path); diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp index 08e5c021..26a3a509 100644 --- a/src/skel/glfw/glfw.cpp +++ b/src/skel/glfw/glfw.cpp @@ -43,6 +43,7 @@ #define MAX_SUBSYSTEMS (16) +// --MIAMI: file done rw::EngineOpenParams openParams; @@ -152,7 +153,7 @@ const char *_psGetUserFilesFolder() &KeycbData) == ERROR_SUCCESS ) { RegCloseKey(hKey); - strcat(szUserFiles, "\\GTA3 User Files"); + strcat(szUserFiles, "\\GTA Vice City User Files"); _psCreateFolder(szUserFiles); return szUserFiles; } @@ -386,10 +387,6 @@ psInitialize(void) InitialiseLanguage(); -#ifndef GTA3_1_1_PATCH - FrontEndMenuManager.LoadSettings(); -#endif - #endif gGameState = GS_START_UP; @@ -422,7 +419,7 @@ psInitialize(void) } else if ( verInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) { - if ( verInfo.dwMajorVersion > 4 || verInfo.dwMajorVersion == 4 && verInfo.dwMinorVersion == 1 ) + if ( verInfo.dwMajorVersion > 4 || verInfo.dwMajorVersion == 4 && verInfo.dwMinorVersion != 0 ) { debug("Operating System is Win98\n"); _dwOperatingSystemVersion = OS_WIN98; @@ -439,13 +436,9 @@ psInitialize(void) #ifndef PS2_MENU - -#ifdef GTA3_1_1_PATCH FrontEndMenuManager.LoadSettings(); #endif -#endif - #ifdef _WIN32 MEMORYSTATUS memstats; @@ -867,7 +860,8 @@ bool IsThisJoystickBlacklisted(int i) const char* joyname = glfwGetJoystickName(i); - if (strncmp(joyname, gSelectedJoystickName, strlen(gSelectedJoystickName)) == 0) + if (gSelectedJoystickName[0] != '\0' && + strncmp(joyname, gSelectedJoystickName, strlen(gSelectedJoystickName)) == 0) return false; return true; @@ -1250,14 +1244,17 @@ void resizeCB(GLFWwindow* window, int width, int height) { * memory things don't work. */ /* redraw window */ - if (RwInitialised && (gGameState == GS_PLAYING_GAME #ifndef MASTER - || gGameState == GS_ANIMVIEWER -#endif - )) + if (RwInitialised && (gGameState == GS_PLAYING_GAME || gGameState == GS_ANIMVIEWER)) { - RsEventHandler((gGameState == GS_PLAYING_GAME ? rsIDLE : rsANIMVIEWER), (void*)TRUE); + RsEventHandler((gGameState == GS_PLAYING_GAME ? rsIDLE : rsANIMVIEWER), (void *)TRUE); } +#else + if (RwInitialised && gGameState == GS_PLAYING_GAME) + { + RsEventHandler(rsIDLE, (void *)TRUE); + } +#endif if (RwInitialised && height > 0 && width > 0) { RwRect r; @@ -1765,6 +1762,7 @@ main(int argc, char *argv[]) printf("Into TheGame!!!\n"); #else LoadingScreen(nil, nil, "loadsc0"); + // LoadingScreen(nil, nil, "loadsc0"); // duplicate #endif if ( !CGame::InitialiseOnceAfterRW() ) RsGlobal.quit = TRUE; @@ -1781,6 +1779,7 @@ main(int argc, char *argv[]) case GS_INIT_FRONTEND: { LoadingScreen(nil, nil, "loadsc0"); + // LoadingScreen(nil, nil, "loadsc0"); // duplicate FrontEndMenuManager.m_bGameNotLoaded = true; diff --git a/src/skel/skeleton.cpp b/src/skel/skeleton.cpp index 99f44fed..e21abb17 100644 --- a/src/skel/skeleton.cpp +++ b/src/skel/skeleton.cpp @@ -11,7 +11,7 @@ #include "skeleton.h" #include "platform.h" - +// --MIAMI: file done static RwBool DefaultVideoMode = TRUE; @@ -371,8 +371,8 @@ RsRwInitialize(void *displayID) psNativeTextureSupport(); + RwTextureSetAutoMipmapping(TRUE); RwTextureSetMipmapping(FALSE); - RwTextureSetAutoMipmapping(FALSE); return TRUE; } diff --git a/src/skel/win/resource.h b/src/skel/win/resource.h index 84dffb95..93f14216 100644 --- a/src/skel/win/resource.h +++ b/src/skel/win/resource.h @@ -8,7 +8,7 @@ #define IDEXIT 1002 #define IDC_SELECTDEVICE 1005 -#define IDI_MAIN_ICON 1042 +#define IDI_MAIN_ICON 100 // Next default values for new objects // #ifdef APSTUDIO_INVOKED diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp index 1d1037af..a10a1a92 100644 --- a/src/skel/win/win.cpp +++ b/src/skel/win/win.cpp @@ -53,6 +53,7 @@ #define MAX_SUBSYSTEMS (16) +// --MIAMI: file done static RwBool ForegroundApp = TRUE; @@ -189,7 +190,7 @@ const char *_psGetUserFilesFolder() &KeycbData) == ERROR_SUCCESS ) { RegCloseKey(hKey); - strcat(szUserFiles, "\\GTA3 User Files"); + strcat(szUserFiles, "\\GTA Vice City User Files"); _psCreateFolder(szUserFiles); return szUserFiles; } @@ -650,10 +651,6 @@ psInitialize(void) C_PcSave::SetSaveDirectory(_psGetUserFilesFolder()); InitialiseLanguage(); -#ifndef GTA3_1_1_PATCH - FrontEndMenuManager.LoadSettings(); -#endif - #endif gGameState = GS_START_UP; @@ -688,7 +685,7 @@ psInitialize(void) } else if ( verInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) { - if ( verInfo.dwMajorVersion > 4 || verInfo.dwMajorVersion == 4 && verInfo.dwMinorVersion == 1 ) + if ( verInfo.dwMajorVersion > 4 || verInfo.dwMajorVersion == 4 && verInfo.dwMinorVersion != 0 ) { debug("Operating System is Win98\n"); _dwOperatingSystemVersion = OS_WIN98; @@ -701,13 +698,9 @@ psInitialize(void) } #ifndef PS2_MENU - -#ifdef GTA3_1_1_PATCH FrontEndMenuManager.LoadSettings(); #endif -#endif - dwDXVersion = GetDXVersion(); debug("DirectX version 0x%x\n", dwDXVersion); @@ -945,8 +938,7 @@ void HandleGraphEvent(void) /* ***************************************************************************** - */ - + */ LRESULT CALLBACK MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) { @@ -1016,10 +1008,17 @@ MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) RECT rect; /* redraw window */ +#ifndef MASTER if (RwInitialised && (gGameState == GS_PLAYING_GAME || gGameState == GS_ANIMVIEWER)) { RsEventHandler((gGameState == GS_PLAYING_GAME ? rsIDLE : rsANIMVIEWER), (void *)TRUE); } +#else + if (RwInitialised && gGameState == GS_PLAYING_GAME) + { + RsEventHandler(rsIDLE, (void *)TRUE); + } +#endif /* Manually resize window */ rect.left = rect.top = 0; @@ -1327,7 +1326,7 @@ InitApplication(HANDLE instance) windowClass.cbClsExtra = 0; windowClass.cbWndExtra = 0; windowClass.hInstance = (HINSTANCE)instance; - windowClass.hIcon = nil; + windowClass.hIcon = LoadIcon((HINSTANCE)instance, (LPCSTR)IDI_MAIN_ICON); windowClass.hCursor = LoadCursor(nil, IDC_ARROW); windowClass.hbrBackground = nil; windowClass.lpszMenuName = NULL; @@ -1382,17 +1381,17 @@ UINT GetBestRefreshRate(UINT width, UINT height, UINT depth) #endif if ( mode.Width == width && mode.Height == height && mode.Format == format ) { - if ( mode.RefreshRate == 0 ) + if ( mode.RefreshRate == 0 ) { + d3d->Release(); return 0; + } if ( mode.RefreshRate < refreshRate && mode.RefreshRate >= 60 ) refreshRate = mode.RefreshRate; } } -#ifdef FIX_BUGS d3d->Release(); -#endif if ( refreshRate == -1 ) return -1; @@ -2255,6 +2254,8 @@ WinMain(HINSTANCE instance, if ( startupDeactivate || ControlsManager.GetJoyButtonJustDown() != 0 ) ++gGameState; + else if ( CPad::GetPad(0)->NewState.CheckForInput() ) + ++gGameState; else if ( CPad::GetPad(0)->GetLeftMouseJustDown() ) ++gGameState; else if ( CPad::GetPad(0)->GetEnterJustDown() ) @@ -2292,6 +2293,8 @@ WinMain(HINSTANCE instance, if ( startupDeactivate || ControlsManager.GetJoyButtonJustDown() != 0 ) ++gGameState; + else if ( CPad::GetPad(0)->NewState.CheckForInput() ) + ++gGameState; else if ( CPad::GetPad(0)->GetLeftMouseJustDown() ) ++gGameState; else if ( CPad::GetPad(0)->GetEnterJustDown() ) @@ -2328,6 +2331,7 @@ WinMain(HINSTANCE instance, printf("Into TheGame!!!\n"); #else LoadingScreen(nil, nil, "loadsc0"); + // LoadingScreen(nil, nil, "loadsc0"); // duplicate #endif if ( !CGame::InitialiseOnceAfterRW() ) RsGlobal.quit = TRUE; @@ -2345,6 +2349,7 @@ WinMain(HINSTANCE instance, case GS_INIT_FRONTEND: { LoadingScreen(nil, nil, "loadsc0"); + // LoadingScreen(nil, nil, "loadsc0"); // duplicate FrontEndMenuManager.m_bGameNotLoaded = true; diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 1316985d..d1a7505e 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -1,4 +1,4 @@ -#include "common.h" +#include "common.h" #include "main.h" #include "General.h" @@ -59,7 +59,7 @@ bool CAutomobile::m_sAllTaxiLights; const uint32 CAutomobile::nSaveStructSize = #ifdef COMPATIBLE_SAVES - 1448; + 1500; #else sizeof(CAutomobile); #endif @@ -4635,7 +4635,6 @@ CAutomobile::ProcessOpenDoor(uint32 component, uint32 anim, float time) case ANIM_CAR_ROLLDOOR_LOW: ProcessDoorOpenCloseAnimation(this, component, door, time, 0.1f, 0.6f, 0.95f); break; - break; case ANIM_CAR_GETOUT_LHS: case ANIM_CAR_GETOUT_LOW_LHS: case ANIM_CAR_GETOUT_RHS: @@ -4649,6 +4648,7 @@ CAutomobile::ProcessOpenDoor(uint32 component, uint32 anim, float time) case ANIM_CAR_PULLOUT_RHS: case ANIM_CAR_PULLOUT_LOW_RHS: OpenDoor(component, door, 1.0f); + break; case ANIM_COACH_OPEN_L: case ANIM_COACH_OPEN_R: ProcessDoorOpenAnimation(this, component, door, time, 0.66f, 0.8f); @@ -5349,7 +5349,7 @@ CAutomobile::SpawnFlyingComponent(int32 component, uint32 type) obj->m_fElasticity = 0.1f; obj->m_fBuoyancy = obj->m_fMass*GRAVITY/0.75f; obj->ObjectCreatedBy = TEMP_OBJECT; - obj->bIsStatic = false; + obj->SetIsStatic(false); obj->bIsPickup = false; obj->bUseVehicleColours = true; obj->m_colour1 = m_currentColour1; @@ -5713,7 +5713,7 @@ CAutomobile::Save(uint8*& buf) { CVehicle::Save(buf); WriteSaveBuf<CDamageManager>(buf, Damage); - SkipSaveBuf(buf, 800 - sizeof(CDamageManager)); + SkipSaveBuf(buf, 1500 - 672 - sizeof(CDamageManager)); } void @@ -5721,7 +5721,7 @@ CAutomobile::Load(uint8*& buf) { CVehicle::Load(buf); Damage = ReadSaveBuf<CDamageManager>(buf); - SkipSaveBuf(buf, 800 - sizeof(CDamageManager)); + SkipSaveBuf(buf, 1500 - 672 - sizeof(CDamageManager)); SetupDamageAfterLoad(); } #endif diff --git a/src/vehicles/Bike.cpp b/src/vehicles/Bike.cpp index b5bc9480..4a4b0516 100644 --- a/src/vehicles/Bike.cpp +++ b/src/vehicles/Bike.cpp @@ -39,6 +39,14 @@ //--MIAMI: file done +const uint32 CBike::nSaveStructSize = +#ifdef COMPATIBLE_SAVES + 1260; +#else + sizeof(CBoat); +#endif + + // TODO: maybe put this somewhere else inline void GetRelativeMatrix(RwMatrix *mat, RwFrame *frm, RwFrame *end) @@ -2922,3 +2930,19 @@ CBike::ReduceHornCounter(void) if(m_nCarHornTimer != 0) m_nCarHornTimer--; } + +#ifdef COMPATIBLE_SAVES +void +CBike::Save(uint8*& buf) +{ + CVehicle::Save(buf); + SkipSaveBuf(buf, 1260 - 672); +} + +void +CBike::Load(uint8*& buf) +{ + CVehicle::Load(buf); + SkipSaveBuf(buf, 1260 - 672); +} +#endif diff --git a/src/vehicles/Bike.h b/src/vehicles/Bike.h index 885fe1b0..3fcf66a2 100644 --- a/src/vehicles/Bike.h +++ b/src/vehicles/Bike.h @@ -132,6 +132,12 @@ public: void Fix(void); void SetupModelNodes(void); void ReduceHornCounter(void); + +#ifdef COMPATIBLE_SAVES + virtual void Save(uint8*& buf); + virtual void Load(uint8*& buf); +#endif + static const uint32 nSaveStructSize; }; // These functions and function names are made up diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp index 8c9dd241..8b5de929 100644 --- a/src/vehicles/Boat.cpp +++ b/src/vehicles/Boat.cpp @@ -43,7 +43,7 @@ CBoat *CBoat::apFrameWakeGeneratingBoats[4]; const uint32 CBoat::nSaveStructSize = #ifdef COMPATIBLE_SAVES - 1156; + 1216; #else sizeof(CBoat); #endif @@ -893,7 +893,7 @@ CBoat::BlowUpCar(CEntity *culprit) obj->m_fElasticity = 0.1f; obj->m_fBuoyancy = obj->m_fMass*GRAVITY/0.75f; obj->ObjectCreatedBy = TEMP_OBJECT; - obj->bIsStatic = false; + obj->SetIsStatic(false); obj->bIsPickup = false; // life time @@ -1449,13 +1449,13 @@ void CBoat::Save(uint8*& buf) { CVehicle::Save(buf); - SkipSaveBuf(buf, 1156 - 648); + SkipSaveBuf(buf, 1216 - 672); } void CBoat::Load(uint8*& buf) { CVehicle::Load(buf); - SkipSaveBuf(buf, 1156 - 648); + SkipSaveBuf(buf, 1216 - 672); } #endif diff --git a/src/vehicles/CarGen.cpp b/src/vehicles/CarGen.cpp index 598b8342..77d66cbf 100644 --- a/src/vehicles/CarGen.cpp +++ b/src/vehicles/CarGen.cpp @@ -91,7 +91,7 @@ void CCarGenerator::DoInternalProcessing() pVehicle = pBoat; if (pos.z <= -100.0f) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); - pBoat->bExtendedRange = false; + pBoat->bExtendedRange = true; }else{ bool groundFound; pos = m_vecPos; diff --git a/src/vehicles/Cranes.cpp b/src/vehicles/Cranes.cpp index 1ab31574..2a571a67 100644 --- a/src/vehicles/Cranes.cpp +++ b/src/vehicles/Cranes.cpp @@ -12,6 +12,8 @@ #include "Object.h" #include "World.h" +// --MIAMI: file done + #define MAX_DISTANCE_TO_FIND_CRANE (10.0f) #define CRANE_UPDATE_RADIUS (300.0f) #define CRANE_MOVEMENT_PROCESSING_RADIUS (150.0f) @@ -259,7 +261,6 @@ void CCrane::Update(void) m_pVehiclePickedUp->bUsesCollision = false; if (m_bIsCrusher) m_pVehiclePickedUp->bCollisionProof = true; - DMAudio.PlayOneShot(m_nAudioEntity, SOUND_CRANE_PICKUP, 0.0f); } } } @@ -439,8 +440,6 @@ bool CCrane::DoesCranePickUpThisCarType(uint32 mi) mi != MI_TRASH && #ifdef FIX_BUGS mi != MI_COACH && -#else - mi != MI_BLISTA && #endif mi != MI_SECURICA && mi != MI_BUS && @@ -657,11 +656,6 @@ void CCranes::Load(uint8* buf, uint32 size) if (pCrane->m_pVehiclePickedUp != nil) pCrane->m_pVehiclePickedUp = CPools::GetVehiclePool()->GetSlot((uintptr)pCrane->m_pVehiclePickedUp - 1); } - /*for (int i = 0; i < NUM_CRANES; i++) { - aCranes[i].m_nAudioEntity = DMAudio.CreateEntity(AUDIOTYPE_CRANE, &aCranes[i]); - if (aCranes[i].m_nAudioEntity != 0) - DMAudio.SetEntityStatus(aCranes[i].m_nAudioEntity, 1); - }*/ VALIDATESAVEBUF(size); } diff --git a/src/vehicles/Cranes.h b/src/vehicles/Cranes.h index 6d877d82..45ea7a8d 100644 --- a/src/vehicles/Cranes.h +++ b/src/vehicles/Cranes.h @@ -26,7 +26,6 @@ public: }; CBuilding *m_pCraneEntity; CObject *m_pHook; - int32 m_nAudioEntity; float m_fPickupX1; float m_fPickupX2; float m_fPickupY1; diff --git a/src/vehicles/Heli.cpp b/src/vehicles/Heli.cpp index 2c2fb33c..d6a237e5 100644 --- a/src/vehicles/Heli.cpp +++ b/src/vehicles/Heli.cpp @@ -671,7 +671,7 @@ CHeli::SpawnFlyingComponent(int32 component) obj->m_fElasticity = 0.1f; obj->m_fBuoyancy = obj->m_fMass*GRAVITY/0.75f; obj->ObjectCreatedBy = TEMP_OBJECT; - obj->bIsStatic = false; + obj->SetIsStatic(false); obj->bIsPickup = false; // life time diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index 994f3c99..cba465b7 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -2367,15 +2367,15 @@ CVehicle::Save(uint8*& buf) WriteSaveBuf<float>(buf, GetPosition().z); SkipSaveBuf(buf, 16); SaveEntityFlags(buf); - SkipSaveBuf(buf, 212); + SkipSaveBuf(buf, 208); AutoPilot.Save(buf); WriteSaveBuf<int8>(buf, m_currentColour1); WriteSaveBuf<int8>(buf, m_currentColour2); SkipSaveBuf(buf, 2); WriteSaveBuf<int16>(buf, m_nAlarmState); - SkipSaveBuf(buf, 43); + SkipSaveBuf(buf, 42); WriteSaveBuf<uint8>(buf, m_nNumMaxPassengers); - SkipSaveBuf(buf, 2); + SkipSaveBuf(buf, 3); WriteSaveBuf<float>(buf, field_1D0[0]); WriteSaveBuf<float>(buf, field_1D0[1]); WriteSaveBuf<float>(buf, field_1D0[2]); @@ -2398,13 +2398,13 @@ CVehicle::Save(uint8*& buf) WriteSaveBuf<uint8>(buf, m_nCurrentGear); SkipSaveBuf(buf, 3); WriteSaveBuf<float>(buf, m_fChangeGearTime); - SkipSaveBuf(buf, 4); + SkipSaveBuf(buf, 12); WriteSaveBuf<uint32>(buf, m_nTimeOfDeath); SkipSaveBuf(buf, 2); WriteSaveBuf<int16>(buf, m_nBombTimer); SkipSaveBuf(buf, 12); WriteSaveBuf<int8>(buf, m_nDoorLock); - SkipSaveBuf(buf, 99); + SkipSaveBuf(buf, 111); } void @@ -2430,15 +2430,15 @@ CVehicle::Load(uint8*& buf) m_matrix = tmp; SkipSaveBuf(buf, 16); LoadEntityFlags(buf); - SkipSaveBuf(buf, 212); + SkipSaveBuf(buf, 208); AutoPilot.Load(buf); m_currentColour1 = ReadSaveBuf<int8>(buf); m_currentColour2 = ReadSaveBuf<int8>(buf); SkipSaveBuf(buf, 2); m_nAlarmState = ReadSaveBuf<int16>(buf); - SkipSaveBuf(buf, 43); + SkipSaveBuf(buf, 42); m_nNumMaxPassengers = ReadSaveBuf<int8>(buf); - SkipSaveBuf(buf, 2); + SkipSaveBuf(buf, 3); field_1D0[0] = ReadSaveBuf<float>(buf); field_1D0[1] = ReadSaveBuf<float>(buf); field_1D0[2] = ReadSaveBuf<float>(buf); @@ -2460,13 +2460,13 @@ CVehicle::Load(uint8*& buf) m_nCurrentGear = ReadSaveBuf<uint8>(buf); SkipSaveBuf(buf, 3); m_fChangeGearTime = ReadSaveBuf<float>(buf); - SkipSaveBuf(buf, 4); + SkipSaveBuf(buf, 12); m_nTimeOfDeath = ReadSaveBuf<uint32>(buf); SkipSaveBuf(buf, 2); m_nBombTimer = ReadSaveBuf<int16>(buf); SkipSaveBuf(buf, 12); m_nDoorLock = (eCarLock)ReadSaveBuf<int8>(buf); - SkipSaveBuf(buf, 99); + SkipSaveBuf(buf, 111); } #endif diff --git a/src/weapons/BulletInfo.cpp b/src/weapons/BulletInfo.cpp index 375a2ca9..13032300 100644 --- a/src/weapons/BulletInfo.cpp +++ b/src/weapons/BulletInfo.cpp @@ -205,13 +205,13 @@ void CBulletInfo::Update(void) if (pHitEntity->IsObject()) { CObject *pHitObject = (CObject*)pHitEntity; if ( !pHitObject->bInfiniteMass && pHitObject->m_fCollisionDamageMultiplier < 99.9f) { - bool notStatic = !pHitObject->IsStatic(); + bool notStatic = !pHitObject->GetIsStatic(); if (notStatic && pHitObject->m_fUprootLimit <= 0.0f) { pHitObject->bIsStatic = false; pHitObject->AddToMovingList(); } - notStatic = !pHitObject->IsStatic(); + notStatic = !pHitObject->GetIsStatic(); if (!notStatic) { CVector moveForce = point.normal * -BULLET_HIT_FORCE; pHitObject->ApplyMoveForce(moveForce.x, moveForce.y, moveForce.z); diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp index 48f90897..5d9686b5 100644 --- a/src/weapons/Weapon.cpp +++ b/src/weapons/Weapon.cpp @@ -1526,14 +1526,14 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim, if ( !victimObject->bInfiniteMass && victimObject->m_fCollisionDamageMultiplier < 99.9f) { - bool notStatic = !victimObject->IsStatic(); + bool notStatic = !victimObject->GetIsStatic(); if (notStatic && victimObject->m_fUprootLimit <= 0.0f) { - victimObject->bIsStatic = false; + victimObject->SetIsStatic(false); victimObject->AddToMovingList(); } - notStatic = !victimObject->IsStatic(); + notStatic = !victimObject->GetIsStatic(); if (!notStatic) { CVector moveForce = point->normal * -4.0f; @@ -1922,14 +1922,14 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) if ( !victimObject->bInfiniteMass ) { - bool notStatic = !victimObject->IsStatic(); + bool notStatic = !victimObject->GetIsStatic(); if ( notStatic && victimObject->m_fUprootLimit <= 0.0f ) { - victimObject->bIsStatic = false; + victimObject->SetIsStatic(false); victimObject->AddToMovingList(); } - notStatic = !victimObject->IsStatic(); + notStatic = !victimObject->GetIsStatic(); if ( !notStatic ) { CVector moveForce = point.normal*-5.0f; @@ -3149,9 +3149,9 @@ CWeapon::BlowUpExplosiveThings(CEntity *thing) object->m_vecMoveSpeed.x += float((CGeneral::GetRandomNumber()&255) - 128) * 0.0002f; object->m_vecMoveSpeed.y += float((CGeneral::GetRandomNumber()&255) - 128) * 0.0002f; - if ( object->IsStatic()) + if ( object->GetIsStatic()) { - object->bIsStatic = false; + object->SetIsStatic(false); object->AddToMovingList(); } } diff --git a/src/weapons/WeaponType.h b/src/weapons/WeaponType.h index 65d715ec..1220196f 100644 --- a/src/weapons/WeaponType.h +++ b/src/weapons/WeaponType.h @@ -54,7 +54,17 @@ enum eWeaponType }; enum { - TOTAL_WEAPON_SLOTS = 10, + WEAPONSLOT_UNARMED = 0, + WEAPONSLOT_MELEE, + WEAPONSLOT_PROJECTILE, + WEAPONSLOT_HANDGUN, + WEAPONSLOT_SHOTGUN, + WEAPONSLOT_SUBMACHINEGUN, + WEAPONSLOT_RIFLE, + WEAPONSLOT_HEAVY, + WEAPONSLOT_SNIPER, + WEAPONSLOT_OTHER, + TOTAL_WEAPON_SLOTS }; enum eWeaponFire { diff --git a/vendor/librw b/vendor/librw -Subproject 30b77b0b32b4113b5dce2b67813ce9b85d1e1e5 +Subproject edc77742c512b85ad35544b2cfbe3f359dc7580 |