diff options
Diffstat (limited to 'src/audio')
-rw-r--r-- | src/audio/AudioManager.cpp | 109 | ||||
-rw-r--r-- | src/audio/AudioManager.h | 21 | ||||
-rw-r--r-- | src/audio/oal/stream.cpp | 18 | ||||
-rw-r--r-- | src/audio/sampman.h | 4 | ||||
-rw-r--r-- | src/audio/sampman_miles.cpp | 518 | ||||
-rw-r--r-- | src/audio/sampman_oal.cpp | 838 |
6 files changed, 1050 insertions, 458 deletions
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..713ac4f3 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, except MP3 player + 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 |