#include "common.h" #ifdef AUDIO_MSS #include #include #include #include "eax.h" #include "eax-util.h" #include "mss.h" #include "sampman.h" #include "AudioManager.h" #include "MusicManager.h" #include "Frontend.h" #include "Timer.h" #pragma comment( lib, "mss32.lib" ) cSampleManager SampleManager; uint32 BankStartOffset[MAX_SFX_BANKS]; /////////////////////////////////////////////////////////////// char SampleBankDescFilename[] = "AUDIO\\SFX.SDT"; char SampleBankDataFilename[] = "AUDIO\\SFX.RAW"; FILE *fpSampleDescHandle; FILE *fpSampleDataHandle; bool bSampleBankLoaded [MAX_SFX_BANKS]; int32 nSampleBankDiscStartOffset [MAX_SFX_BANKS]; int32 nSampleBankSize [MAX_SFX_BANKS]; int32 nSampleBankMemoryStartAddress[MAX_SFX_BANKS]; int32 _nSampleDataEndOffset; int32 nPedSlotSfx [MAX_PEDSFX]; int32 nPedSlotSfxAddr[MAX_PEDSFX]; uint8 nCurrentPedSlot; uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS]; uint32 nStreamLength[TOTAL_STREAMED_SOUNDS]; /////////////////////////////////////////////////////////////// struct tMP3Entry { char aFilename[MAX_PATH]; uint32 nTrackLength; uint32 nTrackStreamPos; tMP3Entry *pNext; char *pLinkPath; }; uint32 nNumMP3s; tMP3Entry *_pMP3List; char _mp3DirectoryPath[MAX_PATH]; HSTREAM mp3Stream [MAX_STREAMS]; int8 nStreamPan [MAX_STREAMS]; int8 nStreamVolume[MAX_STREAMS]; uint32 _CurMP3Index; int32 _CurMP3Pos; bool _bIsMp3Active; #if GTA_VERSION >= GTA3_PC_11 || defined(NO_CDCHECK) bool _bUseHDDAudio; char _aHDDPath[MAX_PATH]; #endif /////////////////////////////////////////////////////////////// bool _bSampmanInitialised = false; // // Miscellaneous globals / defines // 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 = {26, 1.7f, 0.8f, -1000, -1000, -100, 4.42f, 0.14f, 1.00f, 429, 0.014f, 0.00f,0.00f,0.00f, 1023, 0.021f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2727.1f, 250.0f, 0.00f, 0x3f }; EAXLISTENERPROPERTIES FinishEAX3 = {26, 100.0f, 1.0f, 0, -1000, -2200, 20.0f, 1.39f, 1.00f, 1000, 0.069f, 0.00f,0.00f,0.00f, 400, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 3.982f, 0.000f, -18.0f, 3530.8f, 417.9f, 6.70f, 0x3f }; EAXLISTENERPROPERTIES EAX3Params; S32 prevprovider=-1; S32 curprovider=-1; S32 usingEAX=0; S32 usingEAX3=0; HPROVIDER opened_provider=0; H3DSAMPLE opened_samples[MAXCHANNELS] = {0}; HSAMPLE opened_2dsamples[MAX2DCHANNELS] = {0}; HDIGDRIVER DIG; S32 speaker_type=0; U32 _maxSamples; float _fPrevEaxRatioDestination; bool _usingMilesFast2D; float _fEffectsLevel; struct { HPROVIDER id; char name[80]; }providers[MAXPROVIDERS]; typedef struct provider_stuff { char* name; HPROVIDER id; } provider_stuff; static int __cdecl comp(const provider_stuff*s1,const provider_stuff*s2) { return( _stricmp(s1->name,s2->name) ); } static void add_providers() { provider_stuff pi[MAXPROVIDERS]; U32 n,i,j; SampleManager.SetNum3DProvidersAvailable(0); HPROENUM next = HPROENUM_FIRST; n=0; while (AIL_enumerate_3D_providers(&next, &pi[n].id, &pi[n].name) && (n MAXCHANNELS ) _maxSamples = MAXCHANNELS; SampleManager.SetSpeakerConfig(speaker_type); //obtain a 3D sample handles for ( U32 i = 0; i < _maxSamples; ++i ) { opened_samples[i] = AIL_allocate_3D_sample_handle(opened_provider); if ( opened_samples[i] != NULL ) AIL_set_3D_sample_effects_level(opened_samples[i], 0.0f); } return true; } } return false; } cSampleManager::cSampleManager(void) : m_nNumberOfProviders(0) { ; } cSampleManager::~cSampleManager(void) { } void cSampleManager::SetSpeakerConfig(int32 which) { switch ( which ) { case 1: speaker_type=AIL_3D_2_SPEAKER; break; case 2: speaker_type=AIL_3D_HEADPHONE; break; case 3: speaker_type=AIL_3D_4_SPEAKER; break; default: return; break; } if (opened_provider) AIL_set_3D_speaker_type(opened_provider, speaker_type); } uint32 cSampleManager::GetMaximumSupportedChannels(void) { if ( _maxSamples > MAXCHANNELS ) return MAXCHANNELS; return _maxSamples; } uint32 cSampleManager::GetNum3DProvidersAvailable() { return m_nNumberOfProviders; } void cSampleManager::SetNum3DProvidersAvailable(uint32 num) { m_nNumberOfProviders = num; } char *cSampleManager::Get3DProviderName(uint8 id) { return m_aAudioProviders[id]; } void cSampleManager::Set3DProviderName(uint8 id, char *name) { m_aAudioProviders[id] = name; } int8 cSampleManager::GetCurrent3DProviderIndex(void) { return curprovider; } int8 cSampleManager::SetCurrent3DProvider(uint8 nProvider) { S32 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; } else return curprovider; } static bool _ResolveLink(char const *path, char *out) { 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; } static void _FindMP3s(void) { tMP3Entry *pList; bool bShortcut; bool bInitFirstEntry; HANDLE hFind; char path[MAX_PATH]; char filepath[MAX_PATH*2]; S32 total_ms; WIN32_FIND_DATA fd; if ( GetCurrentDirectory(MAX_PATH, _mp3DirectoryPath) == 0 ) { GetLastError(); 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 ) { GetLastError(); return; } strcpy(filepath, _mp3DirectoryPath); strcat(filepath, fd.cFileName); int32 filepathlen = strlen(filepath); if ( filepathlen <= 0) { 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 ) { if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) { if ( _ResolveLink(filepath, filepath) ) { OutputDebugString("Resolving Link"); OutputDebugString(filepath); if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); } else { if ( f ) fprintf(f, " - couldn't resolve shortcut"); } bShortcut = true; } else bShortcut = false; } mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); if ( mp3Stream[0] ) { AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); AIL_close_stream(mp3Stream[0]); mp3Stream[0] = NULL; OutputDebugString(fd.cFileName); _pMP3List = new tMP3Entry; if ( _pMP3List == NULL ) { FindClose(hFind); if ( f ) fclose(f); 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; } 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"); bInitFirstEntry = true; } while ( true ) { if ( !FindNextFile(hFind, &fd) ) break; if ( bInitFirstEntry ) { strcpy(filepath, _mp3DirectoryPath); strcat(filepath, fd.cFileName); int32 filepathlen = strlen(filepath); if ( f ) fprintf(f, "\"%s\"", fd.cFileName); if ( filepathlen > 0 ) { if ( filepathlen > 4 ) { if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) { if ( _ResolveLink(filepath, filepath) ) { OutputDebugString("Resolving Link"); OutputDebugString(filepath); if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); } else { if ( f ) fprintf(f, " - couldn't resolve shortcut"); } bShortcut = true; } else { bShortcut = false; if ( filepathlen > MAX_PATH ) { if ( f ) fprintf(f, " - Filename and path too long - %s - IGNORED)\n", filepath); continue; } } } mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); if ( mp3Stream[0] ) { AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); AIL_close_stream(mp3Stream[0]); mp3Stream[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; 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"); } } } else { strcpy(filepath, _mp3DirectoryPath); strcat(filepath, fd.cFileName); int32 filepathlen = strlen(filepath); if ( filepathlen > 0 ) { if ( f ) fprintf(f, "\"%s\"", fd.cFileName); if ( filepathlen > 4 ) { if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) { if ( _ResolveLink(filepath, filepath) ) { OutputDebugString("Resolving Link"); OutputDebugString(filepath); if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); } else { if ( f ) fprintf(f, " - couldn't resolve shortcut"); } bShortcut = true; } else { bShortcut = false; } } mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); if ( mp3Stream[0] ) { AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); AIL_close_stream(mp3Stream[0]); mp3Stream[0] = NULL; 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); 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); } 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) { return nNumMP3s != 0; } void cSampleManager::ReleaseDigitalHandle(void) { if ( DIG ) { prevprovider = curprovider; release_existing(); curprovider = -1; AIL_digital_handle_release(DIG); } } void cSampleManager::ReacquireDigitalHandle(void) { if ( DIG ) { AIL_digital_handle_reacquire(DIG); if ( prevprovider != -1 ) set_new_provider(prevprovider); } } bool cSampleManager::Initialise(void) { TRACE("start"); if ( _bSampmanInitialised ) return true; { for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) { m_aSamples[i].nOffset = 0; m_aSamples[i].nSize = 0; m_aSamples[i].nFrequency = 22050; m_aSamples[i].nLoopStart = 0; m_aSamples[i].nLoopEnd = -1; } m_nEffectsVolume = MAX_VOLUME; m_nMusicVolume = MAX_VOLUME; m_nEffectsFadeVolume = MAX_VOLUME; m_nMusicFadeVolume = MAX_VOLUME; m_nMonoMode = 0; } // miles TRACE("MILES"); { curprovider = -1; prevprovider = -1; _usingMilesFast2D = false; usingEAX=0; usingEAX3=0; _fEffectsLevel = 0.0f; _maxSamples = 0; opened_provider = NULL; DIG = NULL; for ( int32 i = 0; i < MAXCHANNELS; i++ ) opened_samples[i] = NULL; } // banks TRACE("banks"); { fpSampleDescHandle = NULL; fpSampleDataHandle = NULL; _nSampleDataEndOffset = 0; for ( int32 i = 0; i < MAX_SFX_BANKS; i++ ) { bSampleBankLoaded[i] = false; nSampleBankDiscStartOffset[i] = 0; nSampleBankSize[i] = 0; nSampleBankMemoryStartAddress[i] = 0; } } // pedsfx TRACE("pedsfx"); { for ( int32 i = 0; i < MAX_PEDSFX; i++ ) { nPedSlotSfx[i] = NO_SAMPLE; nPedSlotSfxAddr[i] = 0; } nCurrentPedSlot = 0; } // channel volume TRACE("vol"); { for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ ) nChannelVolume[i] = 0; } TRACE("mss"); { AIL_set_redist_directory( "mss" ); AIL_startup(); 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); } #ifdef AUDIO_CACHE TRACE("cache"); FILE *cacheFile = fopen("audio\\sound.cache", "rb"); if (cacheFile) { fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); fclose(cacheFile); m_bInitialised = true; }else { #endif TRACE("cdrom"); S32 tatalms; char filepath[MAX_PATH]; { m_bInitialised = false; while (true) { int32 drive = 'C'; do { char latter[2]; latter[0] = drive; latter[1] = '\0'; strcpy(m_szCDRomRootPath, latter); strcat(m_szCDRomRootPath, ":\\"); if ( GetDriveType(m_szCDRomRootPath) == DRIVE_CDROM ) { strcpy(filepath, m_szCDRomRootPath); strcat(filepath, StreamedNameTable[0]); FILE *f = fopen(filepath, "rb"); 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; } } } } while ( ++drive <= 'Z' ); if ( !m_bInitialised ) { #if GTA_VERSION < GTA3_PC_STEAM && !defined(NO_CDCHECK) FrontEndMenuManager.WaitForUserCD(); if ( FrontEndMenuManager.m_bQuitGameNoCD ) { Terminate(); return false; } continue; #else m_bInitialised = true; #endif } break; } } #if GTA_VERSION >= GTA3_PC_11 || 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++ ) { strcpy(filepath, rootpath); 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; streamLength[i] = tatalms; } 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]; _bUseHDDAudio = true; } else _bUseHDDAudio = false; } #endif #ifdef AUDIO_CACHE cacheFile = fopen("audio\\sound.cache", "wb"); fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile); fclose(cacheFile); } #endif TRACE("stream"); { for ( int32 i = 0; i < MAX_STREAMS; i++ ) { mp3Stream [i] = NULL; nStreamPan [i] = 63; nStreamVolume[i] = 100; } } for ( int32 i = 0; i < MAX2DCHANNELS; i++ ) { opened_2dsamples[i] = AIL_allocate_sample_handle(DIG); if ( opened_2dsamples[i] ) { AIL_init_sample(opened_2dsamples[i]); AIL_set_sample_type(opened_2dsamples[i], DIG_F_MONO_16, DIG_PCM_SIGN); } } TRACE("providerset"); { _bSampmanInitialised = true; U32 n = 0; while ( n < m_nNumberOfProviders ) { if ( !strcmp(providers[n].name, "Miles Fast 2D Positional Audio") ) { set_new_provider(n); break; } n++; } if ( n == m_nNumberOfProviders ) { Terminate(); return false; } } TRACE("bank"); LoadSampleBank(SFX_BANK_0); // mp3 TRACE("mp3"); { nNumMP3s = 0; _pMP3List = NULL; _FindMP3s(); if ( nNumMP3s != 0 ) { nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] = 0; for ( tMP3Entry *e = _pMP3List; e != NULL; e = e->pNext ) { 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 { 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; } } else _CurMP3Pos = 0; _bIsMp3Active = false; } TRACE("end"); return true; } void cSampleManager::Terminate(void) { for ( int32 i = 0; i < MAX_STREAMS; i++ ) { if ( mp3Stream[i] ) { AIL_pause_stream(mp3Stream[i], 1); AIL_close_stream(mp3Stream[i]); mp3Stream[i] = NULL; } } for ( int32 i = 0; i < MAX2DCHANNELS; i++ ) { if ( opened_2dsamples[i] ) { AIL_release_sample_handle(opened_2dsamples[i]); opened_2dsamples[i] = NULL; } } release_existing(); _DeleteMP3Entries(); if ( nSampleBankMemoryStartAddress[SFX_BANK_0] != 0 ) { AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SFX_BANK_0]); nSampleBankMemoryStartAddress[SFX_BANK_0] = 0; } if ( nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] != 0 ) { AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS]); nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = 0; } if ( DIG ) { AIL_close_digital_driver(DIG); DIG = NULL; } AIL_shutdown(); _bSampmanInitialised = false; } bool cSampleManager::CheckForAnAudioFileOnCD(void) { #if GTA_VERSION < GTA3_PC_STEAM && !defined(NO_CDCHECK) char filepath[MAX_PATH]; #if GTA_VERSION >= GTA3_PC_11 if (_bUseHDDAudio) strcpy(filepath, _aHDDPath); else strcpy(filepath, m_szCDRomRootPath); #else strcpy(filepath, m_szCDRomRootPath); #endif // #if GTA_VERSION >= GTA3_PC_11 strcat(filepath, StreamedNameTable[AudioManager.GetRandomNumber(1) % TOTAL_STREAMED_SOUNDS]); FILE *f = fopen(filepath, "rb"); if ( f ) { fclose(f); return true; } return false; #else return true; #endif // #if GTA_VERSION < GTA3_PC_STEAM && !defined(NO_CDCHECK) } char cSampleManager::GetCDAudioDriveLetter(void) { #if GTA_VERSION >= GTA3_PC_11 || 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]; else return '\0'; #endif } void cSampleManager::UpdateEffectsVolume(void) //[Y], cSampleManager::UpdateSoundBuffers ? { if ( _bSampmanInitialised ) { for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ ) { if ( i < MAXCHANNELS ) { if ( opened_samples[i] && GetChannelUsedFlag(i) ) { if ( nChannelVolume[i] ) { AIL_set_3D_sample_volume(opened_samples[i], m_nEffectsFadeVolume * nChannelVolume[i] * m_nEffectsVolume >> 14); } } } else { if ( opened_2dsamples[i - MAXCHANNELS] ) { if ( GetChannelUsedFlag(i - MAXCHANNELS) ) { if ( nChannelVolume[i - MAXCHANNELS] ) { AIL_set_sample_volume(opened_2dsamples[i - MAXCHANNELS], m_nEffectsFadeVolume * nChannelVolume[i - MAXCHANNELS] * m_nEffectsVolume >> 14); } } } } } } } void cSampleManager::SetEffectsMasterVolume(uint8 nVolume) { m_nEffectsVolume = nVolume; UpdateEffectsVolume(); } void cSampleManager::SetMusicMasterVolume(uint8 nVolume) { m_nMusicVolume = nVolume; } void cSampleManager::SetEffectsFadeVolume(uint8 nVolume) { m_nEffectsFadeVolume = nVolume; UpdateEffectsVolume(); } void cSampleManager::SetMusicFadeVolume(uint8 nVolume) { m_nMusicFadeVolume = nVolume; } void cSampleManager::SetMonoMode(uint8 nMode) { m_nMonoMode = nMode; } bool cSampleManager::LoadSampleBank(uint8 nBank) { if ( CTimer::GetIsCodePaused() ) return false; if ( MusicManager.IsInitialised() && MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE && nBank != SFX_BANK_0 ) { return false; } if ( fseek(fpSampleDataHandle, nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 ) return false; if ( fread((void *)nSampleBankMemoryStartAddress[nBank], 1, nSampleBankSize[nBank],fpSampleDataHandle) != nSampleBankSize[nBank] ) return false; bSampleBankLoaded[nBank] = true; return true; } void cSampleManager::UnloadSampleBank(uint8 nBank) { bSampleBankLoaded[nBank] = false; } bool cSampleManager::IsSampleBankLoaded(uint8 nBank) { return bSampleBankLoaded[nBank]; } bool cSampleManager::IsPedCommentLoaded(uint32 nComment) { int8 slot; for ( int32 i = 0; i < _TODOCONST(3); i++ ) { slot = nCurrentPedSlot - i - 1; #ifdef FIX_BUGS if (slot < 0) slot += ARRAY_SIZE(nPedSlotSfx); #endif if ( nComment == nPedSlotSfx[slot] ) return true; } return false; } int32 cSampleManager::_GetPedCommentSlot(uint32 nComment) { int8 slot; for ( int32 i = 0; i < _TODOCONST(3); i++ ) { slot = nCurrentPedSlot - i - 1; #ifdef FIX_BUGS if (slot < 0) slot += ARRAY_SIZE(nPedSlotSfx); #endif if ( nComment == nPedSlotSfx[slot] ) return slot; } return -1; } bool cSampleManager::LoadPedComment(uint32 nComment) { if ( CTimer::GetIsCodePaused() ) return false; // no talking peds during cutsenes or the game end if ( MusicManager.IsInitialised() ) { switch ( MusicManager.GetMusicMode() ) { case MUSICMODE_CUTSCENE: { return false; break; } case MUSICMODE_FRONTEND: { if ( MusicManager.GetNextTrack() == STREAMED_SOUND_GAME_COMPLETED ) return false; break; } } } if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 ) return false; if ( fread((void *)(nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize ) return false; nPedSlotSfxAddr[nCurrentPedSlot] = nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] + PED_BLOCKSIZE*nCurrentPedSlot; nPedSlotSfx [nCurrentPedSlot] = nComment; if ( ++nCurrentPedSlot >= MAX_PEDSFX ) nCurrentPedSlot = 0; return true; } int32 cSampleManager::GetBankContainingSound(uint32 offset) { if ( offset >= BankStartOffset[SFX_BANK_PED_COMMENTS] ) return SFX_BANK_PED_COMMENTS; if ( offset >= BankStartOffset[SFX_BANK_0] ) return SFX_BANK_0; return INVALID_SFX_BANK; } int32 cSampleManager::GetSampleBaseFrequency(uint32 nSample) { return m_aSamples[nSample].nFrequency; } int32 cSampleManager::GetSampleLoopStartOffset(uint32 nSample) { return m_aSamples[nSample].nLoopStart; } int32 cSampleManager::GetSampleLoopEndOffset(uint32 nSample) { return m_aSamples[nSample].nLoopEnd; } uint32 cSampleManager::GetSampleLength(uint32 nSample) { return m_aSamples[nSample].nSize >> 1; } bool cSampleManager::UpdateReverb(void) { if ( !usingEAX ) return false; 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; } } fRatio = clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f); if ( fRatio == _fPrevEaxRatioDestination ) return false; if ( usingEAX3 ) { if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) ) { AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &EAX3Params); _fEffectsLevel = 1.0f - fRatio * 0.5f; } } else { if ( _usingMilesFast2D ) _fEffectsLevel = (1.0f - fRatio) * 0.4f; else _fEffectsLevel = (1.0f - fRatio) * 0.7f; } _fPrevEaxRatioDestination = fRatio; return true; } void cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag) { bool b2d = false; switch ( nChannel ) { case CHANNEL2D: { b2d = true; break; } } if ( usingEAX ) { if ( nReverbFlag != 0 ) { if ( !b2d ) AIL_set_3D_sample_effects_level(opened_samples[nChannel], _fEffectsLevel); } else { if ( !b2d ) AIL_set_3D_sample_effects_level(opened_samples[nChannel], 0.0f); } } } bool cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) { bool b2d = false; switch ( nChannel ) { case CHANNEL2D: { b2d = true; break; } } int32 addr; if ( nSfx < SAMPLEBANK_MAX ) { if ( !IsSampleBankLoaded(nBank) ) return false; addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset; } else { if ( !IsPedCommentLoaded(nSfx) ) return false; int32 slot = _GetPedCommentSlot(nSfx); addr = nPedSlotSfxAddr[slot]; } if ( b2d ) { if ( opened_2dsamples[nChannel - MAXCHANNELS] ) { AIL_set_sample_address(opened_2dsamples[nChannel - MAXCHANNELS], (void *)addr, m_aSamples[nSfx].nSize); return true; } else return false; } else { AILSOUNDINFO info; info.format = WAVE_FORMAT_PCM; info.data_ptr = (void *)addr; info.channels = 1; info.data_len = m_aSamples[nSfx].nSize; info.rate = m_aSamples[nSfx].nFrequency; info.bits = 16; if ( AIL_set_3D_sample_info(opened_samples[nChannel], &info) == 0 ) { OutputDebugString(AIL_last_error()); return false; } return true; } } void cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) { uint32 vol = nVolume; if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; nChannelVolume[nChannel] = vol; // increase the volume for JB.MP3 and S4_BDBD.MP3 if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE && MusicManager.GetNextTrack() != STREAMED_SOUND_NEWS_INTRO && MusicManager.GetNextTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD ) { nChannelVolume[nChannel] >>= 2; } if ( opened_samples[nChannel] ) AIL_set_3D_sample_volume(opened_samples[nChannel], m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14); } void cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ) { if ( opened_samples[nChannel] ) AIL_set_3D_position(opened_samples[nChannel], -fX, fY, fZ); } void cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin) { if ( opened_samples[nChannel] ) AIL_set_3D_sample_distances(opened_samples[nChannel], fMax, fMin); } void cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume) { uint32 vol = nVolume; if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; switch ( nChannel ) { case CHANNEL2D: { nChannelVolume[nChannel] = vol; // increase the volume for JB.MP3 and S4_BDBD.MP3 if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE && MusicManager.GetNextTrack() != STREAMED_SOUND_NEWS_INTRO && MusicManager.GetNextTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD ) { nChannelVolume[nChannel] >>= 2; } if ( opened_2dsamples[nChannel - MAXCHANNELS] ) { AIL_set_sample_volume(opened_2dsamples[nChannel - MAXCHANNELS], m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); } break; } } } void cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan) { switch ( nChannel ) { case CHANNEL2D: { #ifndef FIX_BUGS if ( opened_samples[nChannel - MAXCHANNELS] ) // BUG #else if ( opened_2dsamples[nChannel - MAXCHANNELS] ) #endif AIL_set_sample_pan(opened_2dsamples[nChannel - MAXCHANNELS], nPan); break; } } } void cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq) { bool b2d = false; switch ( nChannel ) { case CHANNEL2D: { b2d = true; break; } } if ( b2d ) { if ( opened_2dsamples[nChannel - MAXCHANNELS] ) AIL_set_sample_playback_rate(opened_2dsamples[nChannel - MAXCHANNELS], nFreq); } else { if ( opened_samples[nChannel] ) AIL_set_3D_sample_playback_rate(opened_samples[nChannel], nFreq); } } void cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd) { bool b2d = false; switch ( nChannel ) { case CHANNEL2D: { b2d = true; break; } } if ( b2d ) { if ( opened_2dsamples[nChannel - MAXCHANNELS] ) AIL_set_sample_loop_block(opened_2dsamples[nChannel - MAXCHANNELS], nLoopStart, nLoopEnd); } else { if ( opened_samples[nChannel] ) AIL_set_3D_sample_loop_block(opened_samples[nChannel], nLoopStart, nLoopEnd); } } void cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount) { bool b2d = false; switch ( nChannel ) { case CHANNEL2D: { b2d = true; break; } } if ( b2d ) { if ( opened_2dsamples[nChannel - MAXCHANNELS] ) AIL_set_sample_loop_count(opened_2dsamples[nChannel - MAXCHANNELS], nLoopCount); } else { if ( opened_samples[nChannel] ) AIL_set_3D_sample_loop_count(opened_samples[nChannel], nLoopCount); } } bool cSampleManager::GetChannelUsedFlag(uint32 nChannel) { bool b2d = false; switch ( nChannel ) { case CHANNEL2D: { b2d = true; break; } } if ( b2d ) { if ( opened_2dsamples[nChannel - MAXCHANNELS] ) return AIL_sample_status(opened_2dsamples[nChannel - MAXCHANNELS]) == SMP_PLAYING; else return false; } else { if ( opened_samples[nChannel] ) return AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING; else return false; } } void cSampleManager::StartChannel(uint32 nChannel) { bool b2d = false; switch ( nChannel ) { case CHANNEL2D: { b2d = true; break; } } if ( b2d ) { if ( opened_2dsamples[nChannel - MAXCHANNELS] ) AIL_start_sample(opened_2dsamples[nChannel - MAXCHANNELS]); } else { if ( opened_samples[nChannel] ) AIL_start_3D_sample(opened_samples[nChannel]); } } void cSampleManager::StopChannel(uint32 nChannel) { bool b2d = false; switch ( nChannel ) { case CHANNEL2D: { b2d = true; break; } } if ( b2d ) { if ( opened_2dsamples[nChannel - MAXCHANNELS] ) AIL_end_sample(opened_2dsamples[nChannel - MAXCHANNELS]); } else { if ( opened_samples[nChannel] ) { if ( AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING ) AIL_end_3D_sample(opened_samples[nChannel]); } } } void cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream) { if ( m_bInitialised ) { if ( nFile < TOTAL_STREAMED_SOUNDS ) { if ( mp3Stream[nStream] ) { AIL_pause_stream(mp3Stream[nStream], 1); AIL_close_stream(mp3Stream[nStream]); } char filepath[MAX_PATH]; strcpy(filepath, m_szCDRomRootPath); strcat(filepath, StreamedNameTable[nFile]); mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0); if ( mp3Stream[nStream] ) { AIL_set_stream_loop_count(mp3Stream[nStream], 1); AIL_service_stream(mp3Stream[nStream], 1); } else OutputDebugString(AIL_last_error()); } } } void cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream) { if ( m_bInitialised ) { if ( mp3Stream[nStream] ) AIL_pause_stream(mp3Stream[nStream], nPauseFlag != 0); } } void cSampleManager::StartPreloadedStreamedFile(uint8 nStream) { if ( m_bInitialised ) { if ( mp3Stream[nStream] ) AIL_start_stream(mp3Stream[nStream]); } } bool cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream) { uint32 position = nPos; char filename[MAX_PATH]; if ( m_bInitialised && nFile < TOTAL_STREAMED_SOUNDS ) { if ( mp3Stream[nStream] ) { AIL_pause_stream(mp3Stream[nStream], 1); AIL_close_stream(mp3Stream[nStream]); } 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; strcpy(filename, m_szCDRomRootPath); 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_pause_stream(mp3Stream[nStream], 0); return true; } return false; } } if(mp3->pLinkPath != NULL) mp3Stream[nStream] = AIL_open_stream(DIG, mp3->pLinkPath, 0); else { strcpy(filename, _mp3DirectoryPath); strcat(filename, mp3->aFilename); 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], 0); AIL_pause_stream(mp3Stream[nStream], 0); return true; } _bIsMp3Active = false; continue; } if ( nPos > nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] ) position = 0; tMP3Entry *e; if ( !_GetMP3PosFromStreamPos(&position, &e) ) { if ( e == NULL ) { nFile = 0; strcpy(filename, m_szCDRomRootPath); 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_pause_stream(mp3Stream[nStream], 0); return true; } return false; } } if ( e->pLinkPath != NULL ) mp3Stream[nStream] = AIL_open_stream(DIG, e->pLinkPath, 0); else { strcpy(filename, _mp3DirectoryPath); strcat(filename, e->aFilename); 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_pause_stream(mp3Stream[nStream], 0); _bIsMp3Active = true; return true; } _bIsMp3Active = false; } while(++i < nNumMP3s); position = 0; nFile = 0; } strcpy(filename, m_szCDRomRootPath); 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_pause_stream(mp3Stream[nStream], 0); return true; } } return false; } void cSampleManager::StopStreamedFile(uint8 nStream) { if ( m_bInitialised ) { if ( mp3Stream[nStream] ) { AIL_pause_stream(mp3Stream[nStream], 1); AIL_close_stream(mp3Stream[nStream]); mp3Stream[nStream] = NULL; if ( nStream == 0 ) _bIsMp3Active = false; } } } int32 cSampleManager::GetStreamedFilePosition(uint8 nStream) { S32 currentms; if ( m_bInitialised ) { if ( mp3Stream[nStream] ) { if ( _bIsMp3Active ) { tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index); if ( mp3 != NULL ) { AIL_stream_ms_position(mp3Stream[nStream], NULL, ¤tms); return currentms + mp3->nTrackStreamPos; } else return 0; } else { AIL_stream_ms_position(mp3Stream[nStream], NULL, ¤tms); return currentms; } } } return 0; } void cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream) { uint8 vol = nVolume; if ( m_bInitialised ) { if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; nStreamVolume[nStream] = vol; nStreamPan[nStream] = nPan; if ( mp3Stream[nStream] ) { if ( nEffectFlag ) 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_pan(mp3Stream[nStream], nPan); } } } int32 cSampleManager::GetStreamedFileLength(uint8 nStream) { if ( m_bInitialised ) return nStreamLength[nStream]; return 0; } bool cSampleManager::IsStreamPlaying(uint8 nStream) { if ( m_bInitialised ) { if ( mp3Stream[nStream] ) { if ( AIL_stream_status(mp3Stream[nStream]) == SMP_PLAYING ) return true; else return false; } } return false; } bool cSampleManager::InitialiseSampleBanks(void) { int32 nBank = SFX_BANK_0; fpSampleDescHandle = fopen(SampleBankDescFilename, "rb"); if ( fpSampleDescHandle == NULL ) return false; fpSampleDataHandle = fopen(SampleBankDataFilename, "rb"); if ( fpSampleDataHandle == NULL ) { fclose(fpSampleDescHandle); fpSampleDescHandle = NULL; return false; } fseek(fpSampleDataHandle, 0, SEEK_END); _nSampleDataEndOffset = ftell(fpSampleDataHandle); rewind(fpSampleDataHandle); fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle); fclose(fpSampleDescHandle); fpSampleDescHandle = NULL; for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) { #ifdef FIX_BUGS if (nBank >= MAX_SFX_BANKS) break; #endif if ( BankStartOffset[nBank] == BankStartOffset[SFX_BANK_0] + i ) { nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset; nBank++; } } nSampleBankSize[SFX_BANK_0] = nSampleBankDiscStartOffset[SFX_BANK_PED_COMMENTS] - nSampleBankDiscStartOffset[SFX_BANK_0]; nSampleBankSize[SFX_BANK_PED_COMMENTS] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SFX_BANK_PED_COMMENTS]; return true; } #endif