2019-08-02 22:20:12 +02:00
|
|
|
#include <windows.h>
|
|
|
|
#include <shobjidl.h>
|
|
|
|
#include <shlguid.h>
|
|
|
|
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#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"
|
|
|
|
#include "patcher.h"
|
|
|
|
|
|
|
|
#pragma comment( lib, "mss32.lib" )
|
|
|
|
|
|
|
|
cSampleManager &SampleManager = *(cSampleManager *)0x7341E0;
|
2019-10-27 18:39:17 +01:00
|
|
|
extern int32 (&BankStartOffset)[MAX_SAMPLEBANKS] = *(int32 (*)[MAX_SAMPLEBANKS])*(int *)0x6FAB70;
|
2019-08-02 22:20:12 +02:00
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
char SampleBankDescFilename[] = "AUDIO\\SFX.SDT";
|
|
|
|
char SampleBankDataFilename[] = "AUDIO\\SFX.RAW";
|
|
|
|
|
|
|
|
FILE *fpSampleDescHandle;
|
|
|
|
FILE *fpSampleDataHandle;
|
|
|
|
bool bSampleBankLoaded [MAX_SAMPLEBANKS];
|
|
|
|
int32 nSampleBankDiscStartOffset [MAX_SAMPLEBANKS];
|
|
|
|
int32 nSampleBankSize [MAX_SAMPLEBANKS];
|
|
|
|
int32 nSampleBankMemoryStartAddress[MAX_SAMPLEBANKS];
|
|
|
|
int32 _nSampleDataEndOffset;
|
|
|
|
|
|
|
|
int32 nPedSlotSfx [MAX_PEDSFX];
|
|
|
|
int32 nPedSlotSfxAddr[MAX_PEDSFX];
|
2019-11-09 16:17:54 +01:00
|
|
|
uint8 nCurrentPedSlot;
|
2019-08-02 22:20:12 +02:00
|
|
|
|
|
|
|
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_MP3STREAMS];
|
|
|
|
int8 nStreamPan [MAX_MP3STREAMS];
|
|
|
|
int8 nStreamVolume[MAX_MP3STREAMS];
|
|
|
|
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
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2019-10-30 00:12:58 +01:00
|
|
|
return(strcasecmp(s1->name, s2->name));
|
2019-08-02 22:20:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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<MAXPROVIDERS))
|
|
|
|
{
|
|
|
|
++n;
|
|
|
|
}
|
|
|
|
|
|
|
|
qsort(pi,n,sizeof(pi[0]), (int(__cdecl*)(void const*, void const*))comp);
|
|
|
|
|
|
|
|
for(i=0;i<n;i++)
|
|
|
|
{
|
|
|
|
providers[i].id=pi[i].id;
|
|
|
|
strcpy(providers[i].name, pi[i].name);
|
|
|
|
SampleManager.Set3DProviderName(i, providers[i].name);
|
|
|
|
}
|
|
|
|
|
|
|
|
SampleManager.SetNum3DProvidersAvailable(n);
|
|
|
|
|
|
|
|
for(j=n;j<MAXPROVIDERS;j++)
|
|
|
|
SampleManager.Set3DProviderName(j, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
release_existing()
|
|
|
|
{
|
|
|
|
for ( U32 i = 0; i < _maxSamples; i++ )
|
|
|
|
{
|
|
|
|
if ( opened_samples[i] )
|
|
|
|
{
|
|
|
|
AIL_release_3D_sample_handle(opened_samples[i]);
|
|
|
|
opened_samples[i] = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( opened_provider )
|
|
|
|
{
|
|
|
|
AIL_close_3D_provider(opened_provider);
|
|
|
|
opened_provider = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
_fPrevEaxRatioDestination = 0.0f;
|
|
|
|
_usingMilesFast2D = false;
|
|
|
|
_fEffectsLevel = 0.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
set_new_provider(S32 index)
|
|
|
|
{
|
|
|
|
DWORD result;
|
|
|
|
|
|
|
|
if ( curprovider == index )
|
|
|
|
return true;
|
|
|
|
|
|
|
|
//close the already opened provider
|
|
|
|
curprovider = index;
|
|
|
|
|
|
|
|
release_existing();
|
|
|
|
|
|
|
|
if ( curprovider != -1 )
|
|
|
|
{
|
|
|
|
if ( !strcmp(providers[index].name, "Dolby Surround") )
|
|
|
|
_maxSamples = MAXCHANNELS_SURROUND;
|
|
|
|
else
|
|
|
|
_maxSamples = MAXCHANNELS;
|
|
|
|
|
|
|
|
AIL_set_3D_provider_preference(providers[index].id, "Maximum supported samples", &_maxSamples);
|
|
|
|
|
|
|
|
//load the new provider
|
|
|
|
result = AIL_open_3D_provider(providers[index].id);
|
|
|
|
|
|
|
|
if (result != M3D_NOERR)
|
|
|
|
{
|
|
|
|
curprovider=-1;
|
|
|
|
|
|
|
|
OutputDebugStringA(AIL_last_error());
|
|
|
|
|
|
|
|
release_existing();
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
opened_provider=providers[index].id;
|
|
|
|
|
|
|
|
//see if we're running under an EAX compatible provider
|
|
|
|
|
|
|
|
if ( !strcmp(providers[index].name, "Creative Labs EAX 3 (TM)") )
|
|
|
|
{
|
|
|
|
usingEAX = 1;
|
|
|
|
usingEAX3 = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
usingEAX3 = 0;
|
|
|
|
|
|
|
|
result=AIL_3D_room_type(opened_provider);
|
|
|
|
usingEAX=(((S32)result)!=-1)?1:0; // will be something other than -1 on EAX
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( usingEAX3 )
|
|
|
|
{
|
|
|
|
OutputDebugString("DOING SPECIAL EAX 3 STUFF!");
|
|
|
|
AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &FinishEAX3);
|
|
|
|
}
|
|
|
|
else if ( usingEAX )
|
|
|
|
{
|
|
|
|
AIL_set_3D_room_type(opened_provider, ENVIRONMENT_CAVE);
|
|
|
|
|
|
|
|
if ( !strcmp(providers[index].name, "Miles Fast 2D Positional Audio") )
|
|
|
|
_usingMilesFast2D = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
AIL_3D_provider_attribute(opened_provider, "Maximum supported samples", &_maxSamples);
|
|
|
|
|
|
|
|
if ( _maxSamples > 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2019-08-03 17:15:31 +02:00
|
|
|
cSampleManager::GetMaximumSupportedChannels(void)
|
2019-08-02 22:20:12 +02:00
|
|
|
{
|
|
|
|
if ( _maxSamples > MAXCHANNELS )
|
|
|
|
return MAXCHANNELS;
|
|
|
|
|
|
|
|
return _maxSamples;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
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) )
|
|
|
|
{
|
|
|
|
if ( f )
|
|
|
|
{
|
|
|
|
fprintf(f, "\nTOTAL SUPPORTED MP3s: %d\n", nNumMP3s);
|
|
|
|
fclose(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
FindClose(hFind);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
if ( f )
|
|
|
|
{
|
|
|
|
fprintf(f, "\nTOTAL SUPPORTED MP3s: %d\n", nNumMP3s);
|
|
|
|
fclose(f);
|
|
|
|
}
|
|
|
|
FindClose(hFind);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
if ( f )
|
|
|
|
{
|
|
|
|
fprintf(f, "\nTOTAL SUPPORTED MP3s: %d\n", nNumMP3s);
|
|
|
|
fclose(f);
|
|
|
|
}
|
|
|
|
FindClose(hFind);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-08-03 17:15:31 +02:00
|
|
|
m_nEffectsVolume = MAX_VOLUME;
|
|
|
|
m_nMusicVolume = MAX_VOLUME;
|
|
|
|
m_nEffectsFadeVolume = MAX_VOLUME;
|
|
|
|
m_nMusicFadeVolume = MAX_VOLUME;
|
2019-08-02 22:20:12 +02:00
|
|
|
|
|
|
|
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_SAMPLEBANKS; 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;
|
|
|
|
}
|
|
|
|
|
2019-08-03 17:15:31 +02:00
|
|
|
nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)AIL_mem_alloc_lock(nSampleBankSize[SAMPLEBANK_MAIN]);
|
|
|
|
if ( !nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] )
|
2019-08-02 22:20:12 +02:00
|
|
|
{
|
|
|
|
Terminate();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-08-03 17:15:31 +02:00
|
|
|
nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX);
|
2019-08-02 22:20:12 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
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 !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
|
|
|
|
FrontEndMenuManager.WaitForUserCD();
|
|
|
|
if ( FrontEndMenuManager.m_bQuitGameNoCD )
|
|
|
|
{
|
|
|
|
Terminate();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
#else
|
|
|
|
m_bInitialised = true;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#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++ )
|
|
|
|
{
|
|
|
|
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
|
|
|
|
|
|
|
|
TRACE("stream");
|
|
|
|
{
|
|
|
|
for ( int32 i = 0; i < MAX_MP3STREAMS; 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");
|
|
|
|
|
2019-08-03 17:15:31 +02:00
|
|
|
LoadSampleBank(SAMPLEBANK_MAIN);
|
2019-08-02 22:20:12 +02:00
|
|
|
|
|
|
|
// 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
|
|
|
|
{
|
2019-08-03 17:15:31 +02:00
|
|
|
bUseRandomTable = false;
|
2019-08-02 22:20:12 +02:00
|
|
|
localtm = localtime(&t);
|
|
|
|
}
|
|
|
|
|
|
|
|
int32 randval;
|
|
|
|
if ( bUseRandomTable )
|
2019-08-15 03:43:00 +02:00
|
|
|
randval = AudioManager.GetRandomNumber(1);
|
2019-08-02 22:20:12 +02:00
|
|
|
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 )
|
2019-08-15 03:43:00 +02:00
|
|
|
_CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
|
2019-08-02 22:20:12 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( localtm->tm_sec > 0 )
|
|
|
|
{
|
|
|
|
int32 s = localtm->tm_sec;
|
2019-08-15 03:43:00 +02:00
|
|
|
_CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength;
|
2019-08-02 22:20:12 +02:00
|
|
|
}
|
|
|
|
else
|
2019-08-15 03:43:00 +02:00
|
|
|
_CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
|
2019-08-02 22:20:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
_CurMP3Pos = 0;
|
|
|
|
|
|
|
|
_bIsMp3Active = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
TRACE("end");
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cSampleManager::Terminate(void)
|
|
|
|
{
|
|
|
|
for ( int32 i = 0; i < MAX_MP3STREAMS; 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();
|
|
|
|
|
2019-08-03 17:15:31 +02:00
|
|
|
if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != 0 )
|
2019-08-02 22:20:12 +02:00
|
|
|
{
|
2019-08-03 17:15:31 +02:00
|
|
|
AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN]);
|
|
|
|
nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = 0;
|
2019-08-02 22:20:12 +02:00
|
|
|
}
|
|
|
|
|
2019-08-03 17:15:31 +02:00
|
|
|
if ( nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != 0 )
|
2019-08-02 22:20:12 +02:00
|
|
|
{
|
2019-08-03 17:15:31 +02:00
|
|
|
AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]);
|
|
|
|
nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = 0;
|
2019-08-02 22:20:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( DIG )
|
|
|
|
{
|
|
|
|
AIL_close_digital_driver(DIG);
|
|
|
|
DIG = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
AIL_shutdown();
|
|
|
|
|
|
|
|
_bSampmanInitialised = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
cSampleManager::CheckForAnAudioFileOnCD(void)
|
|
|
|
{
|
|
|
|
#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
|
2019-10-17 16:28:24 +02:00
|
|
|
char filepath[MAX_PATH];
|
2019-08-02 22:20:12 +02:00
|
|
|
|
|
|
|
#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)
|
|
|
|
|
2019-08-15 03:43:00 +02:00
|
|
|
strcat(filepath, StreamedNameTable[AudioManager.GetRandomNumber(1) % TOTAL_STREAMED_SOUNDS]);
|
2019-08-02 22:20:12 +02:00
|
|
|
|
|
|
|
FILE *f = fopen(filepath, "rb");
|
|
|
|
|
|
|
|
if ( f )
|
|
|
|
{
|
|
|
|
fclose(f);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
#else
|
|
|
|
return true;
|
|
|
|
#endif // #if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
|
|
|
|
}
|
|
|
|
|
|
|
|
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];
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
cSampleManager::LoadSampleBank(uint8 nBank)
|
|
|
|
{
|
|
|
|
if ( CTimer::GetIsCodePaused() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if ( MusicManager.IsInitialised()
|
|
|
|
&& MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
|
2019-08-03 17:15:31 +02:00
|
|
|
&& nBank != SAMPLEBANK_MAIN )
|
2019-08-02 22:20:12 +02:00
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
2019-11-09 16:17:54 +01:00
|
|
|
uint8 slot;
|
2019-08-02 22:20:12 +02:00
|
|
|
|
|
|
|
for ( int32 i = 0; i < _TODOCONST(3); i++ )
|
|
|
|
{
|
|
|
|
slot = nCurrentPedSlot - i - 1;
|
|
|
|
if ( nComment == nPedSlotSfx[slot] )
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int32
|
|
|
|
cSampleManager::_GetPedCommentSlot(uint32 nComment)
|
|
|
|
{
|
2019-11-09 16:17:54 +01:00
|
|
|
uint8 slot;
|
2019-08-02 22:20:12 +02:00
|
|
|
|
|
|
|
for ( int32 i = 0; i < _TODOCONST(3); i++ )
|
|
|
|
{
|
|
|
|
slot = nCurrentPedSlot - i - 1;
|
|
|
|
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.GetCurrentTrack() == STREAMED_SOUND_GAME_COMPLETED )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 )
|
|
|
|
return false;
|
|
|
|
|
2019-08-03 17:15:31 +02:00
|
|
|
if ( fread((void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize )
|
2019-08-02 22:20:12 +02:00
|
|
|
return false;
|
|
|
|
|
2019-08-03 17:15:31 +02:00
|
|
|
nPedSlotSfxAddr[nCurrentPedSlot] = nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot;
|
2019-08-02 22:20:12 +02:00
|
|
|
nPedSlotSfx [nCurrentPedSlot] = nComment;
|
|
|
|
|
|
|
|
if ( ++nCurrentPedSlot >= MAX_PEDSFX )
|
|
|
|
nCurrentPedSlot = 0;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2019-08-03 17:15:31 +02:00
|
|
|
if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
|
2019-08-02 22:20:12 +02:00
|
|
|
|
|
|
|
nChannelVolume[nChannel] = vol;
|
|
|
|
|
|
|
|
// increase the volume for JB.MP3 and S4_BDBD.MP3
|
|
|
|
if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
|
|
|
|
&& MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
|
|
|
|
&& MusicManager.GetCurrentTrack() != 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;
|
2019-08-03 17:15:31 +02:00
|
|
|
if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
|
2019-08-02 22:20:12 +02:00
|
|
|
|
|
|
|
switch ( nChannel )
|
|
|
|
{
|
|
|
|
case CHANNEL2D:
|
|
|
|
{
|
|
|
|
nChannelVolume[nChannel] = vol;
|
|
|
|
|
|
|
|
// increase the volume for JB.MP3 and S4_BDBD.MP3
|
|
|
|
if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
|
|
|
|
&& MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
|
|
|
|
&& MusicManager.GetCurrentTrack() != 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;
|
|
|
|
|
|
|
|
if ( !_bIsMp3Active ) goto FIND_MP3TRACK;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if ( ++_CurMP3Index >= nNumMP3s )
|
|
|
|
_CurMP3Index = 0;
|
|
|
|
|
|
|
|
_CurMP3Pos = 0;
|
|
|
|
|
|
|
|
tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index);
|
|
|
|
|
|
|
|
if ( mp3 )
|
|
|
|
{
|
|
|
|
mp3 = _pMP3List;
|
|
|
|
if ( mp3 == NULL )
|
|
|
|
{
|
|
|
|
_bIsMp3Active = false;
|
|
|
|
nFile = 0;
|
|
|
|
goto PLAY_STREAMEDTRACK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
goto NEXT_MP3TRACK;
|
|
|
|
|
|
|
|
FIND_MP3TRACK:
|
|
|
|
if ( nPos > nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] )
|
|
|
|
position = 0;
|
|
|
|
|
|
|
|
tMP3Entry *e;
|
|
|
|
if ( !_GetMP3PosFromStreamPos(&position, &e) )
|
|
|
|
{
|
|
|
|
if ( e == NULL )
|
|
|
|
{
|
|
|
|
nFile = 0;
|
|
|
|
goto PLAY_STREAMEDTRACK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
NEXT_MP3TRACK:
|
|
|
|
_bIsMp3Active = false;
|
|
|
|
|
|
|
|
} while ( ++i < nNumMP3s );
|
|
|
|
|
|
|
|
position = 0;
|
|
|
|
nFile = 0;
|
|
|
|
goto PLAY_STREAMEDTRACK;
|
|
|
|
}
|
|
|
|
|
|
|
|
PLAY_STREAMEDTRACK:
|
|
|
|
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 )
|
|
|
|
{
|
2019-08-03 17:15:31 +02:00
|
|
|
if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
|
|
|
|
if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
|
2019-08-02 22:20:12 +02:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2019-08-03 17:15:31 +02:00
|
|
|
int32 nBank = SAMPLEBANK_MAIN;
|
2019-08-02 22:20:12 +02:00
|
|
|
|
|
|
|
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++ )
|
|
|
|
{
|
|
|
|
if ( BankStartOffset[nBank] == BankStartOffset[0] + i )
|
|
|
|
{
|
|
|
|
nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset;
|
|
|
|
nBank++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-03 17:15:31 +02:00
|
|
|
nSampleBankSize[SAMPLEBANK_MAIN] = nSampleBankDiscStartOffset[SAMPLEBANK_PED] - nSampleBankDiscStartOffset[SAMPLEBANK_MAIN];
|
|
|
|
nSampleBankSize[SAMPLEBANK_PED] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SAMPLEBANK_PED];
|
2019-08-02 22:20:12 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
STARTPATCHES
|
|
|
|
//InjectHook(0x565500, cSampleManager::cSampleManager, PATCH_JUMP);
|
|
|
|
//InjectHook(0x565510, cSampleManager::~cSampleManager, PATCH_JUMP);
|
|
|
|
InjectHook(0x565520, comp, PATCH_JUMP);
|
|
|
|
InjectHook(0x565540, add_providers, PATCH_JUMP);
|
|
|
|
InjectHook(0x565680, release_existing, PATCH_JUMP);
|
|
|
|
InjectHook(0x5656F0, set_new_provider, PATCH_JUMP);
|
|
|
|
InjectHook(0x565900, &cSampleManager::SetSpeakerConfig, PATCH_JUMP);
|
|
|
|
InjectHook(0x565970, &cSampleManager::GetMaximumSupportedChannels, PATCH_JUMP);
|
|
|
|
InjectHook(0x565990, &cSampleManager::GetCurrent3DProviderIndex, PATCH_JUMP);
|
|
|
|
InjectHook(0x5659A0, &cSampleManager::SetCurrent3DProvider, PATCH_JUMP);
|
|
|
|
InjectHook(0x565A10, _ResolveLink, PATCH_JUMP);
|
|
|
|
InjectHook(0x565B40, _FindMP3s, PATCH_JUMP);
|
|
|
|
InjectHook(0x566380, _DeleteMP3Entries, PATCH_JUMP);
|
|
|
|
InjectHook(0x566400, _GetMP3EntryByIndex, PATCH_JUMP);
|
|
|
|
InjectHook(0x566490, &cSampleManager::IsMP3RadioChannelAvailable, PATCH_JUMP);
|
|
|
|
InjectHook(0x5664B0, &cSampleManager::ReleaseDigitalHandle, PATCH_JUMP);
|
|
|
|
InjectHook(0x5664F0, &cSampleManager::ReacquireDigitalHandle, PATCH_JUMP);
|
|
|
|
InjectHook(0x566530, &cSampleManager::Initialise, PATCH_JUMP);
|
|
|
|
InjectHook(0x566DC0, &cSampleManager::Terminate, PATCH_JUMP);
|
|
|
|
InjectHook(0x566EA0, &cSampleManager::CheckForAnAudioFileOnCD, PATCH_JUMP);
|
|
|
|
InjectHook(0x566F20, &cSampleManager::GetCDAudioDriveLetter, PATCH_JUMP);
|
|
|
|
InjectHook(0x566F50, &cSampleManager::UpdateEffectsVolume, PATCH_JUMP);
|
|
|
|
InjectHook(0x567010, &cSampleManager::SetEffectsMasterVolume, PATCH_JUMP);
|
|
|
|
InjectHook(0x567020, &cSampleManager::SetMusicMasterVolume, PATCH_JUMP);
|
|
|
|
InjectHook(0x567030, &cSampleManager::SetEffectsFadeVolume, PATCH_JUMP);
|
|
|
|
InjectHook(0x567040, &cSampleManager::SetMusicFadeVolume, PATCH_JUMP);
|
|
|
|
InjectHook(0x567050, &cSampleManager::LoadSampleBank, PATCH_JUMP);
|
|
|
|
InjectHook(0x567110, &cSampleManager::UnloadSampleBank, PATCH_JUMP);
|
|
|
|
InjectHook(0x567130, &cSampleManager::IsSampleBankLoaded, PATCH_JUMP);
|
|
|
|
InjectHook(0x567150, &cSampleManager::IsPedCommentLoaded, PATCH_JUMP);
|
|
|
|
InjectHook(0x5671A0, &cSampleManager::LoadPedComment, PATCH_JUMP);
|
|
|
|
InjectHook(0x5672A0, &cSampleManager::GetSampleBaseFrequency, PATCH_JUMP);
|
|
|
|
InjectHook(0x5672C0, &cSampleManager::GetSampleLoopStartOffset, PATCH_JUMP);
|
|
|
|
InjectHook(0x5672E0, &cSampleManager::GetSampleLoopEndOffset, PATCH_JUMP);
|
|
|
|
InjectHook(0x567300, &cSampleManager::GetSampleLength, PATCH_JUMP);
|
|
|
|
InjectHook(0x567320, &cSampleManager::UpdateReverb, PATCH_JUMP);
|
|
|
|
InjectHook(0x567630, &cSampleManager::SetChannelReverbFlag, PATCH_JUMP);
|
|
|
|
InjectHook(0x5676A0, &cSampleManager::InitialiseChannel, PATCH_JUMP);
|
|
|
|
InjectHook(0x567820, &cSampleManager::SetChannelEmittingVolume, PATCH_JUMP);
|
|
|
|
InjectHook(0x567890, &cSampleManager::SetChannel3DPosition, PATCH_JUMP);
|
|
|
|
InjectHook(0x5678D0, &cSampleManager::SetChannel3DDistances, PATCH_JUMP);
|
|
|
|
InjectHook(0x567900, &cSampleManager::SetChannelVolume, PATCH_JUMP);
|
|
|
|
InjectHook(0x567980, &cSampleManager::SetChannelPan, PATCH_JUMP);
|
|
|
|
InjectHook(0x5679D0, &cSampleManager::SetChannelFrequency, PATCH_JUMP);
|
|
|
|
InjectHook(0x567A30, &cSampleManager::SetChannelLoopPoints, PATCH_JUMP);
|
|
|
|
InjectHook(0x567AA0, &cSampleManager::SetChannelLoopCount, PATCH_JUMP);
|
|
|
|
InjectHook(0x567B00, &cSampleManager::GetChannelUsedFlag, PATCH_JUMP);
|
|
|
|
InjectHook(0x567B80, &cSampleManager::StartChannel, PATCH_JUMP);
|
|
|
|
InjectHook(0x567BE0, &cSampleManager::StopChannel, PATCH_JUMP);
|
|
|
|
InjectHook(0x567C50, &cSampleManager::PreloadStreamedFile, PATCH_JUMP);
|
|
|
|
InjectHook(0x567D30, &cSampleManager::PauseStream, PATCH_JUMP);
|
|
|
|
InjectHook(0x567D60, &cSampleManager::StartPreloadedStreamedFile, PATCH_JUMP);
|
|
|
|
InjectHook(0x567D80, &cSampleManager::StartStreamedFile, PATCH_JUMP);
|
|
|
|
InjectHook(0x5680E0, &cSampleManager::StopStreamedFile, PATCH_JUMP);
|
|
|
|
InjectHook(0x568130, &cSampleManager::GetStreamedFilePosition, PATCH_JUMP);
|
|
|
|
InjectHook(0x5681D0, &cSampleManager::SetStreamedVolumeAndPan, PATCH_JUMP);
|
|
|
|
InjectHook(0x568270, &cSampleManager::GetStreamedFileLength, PATCH_JUMP);
|
|
|
|
InjectHook(0x568290, &cSampleManager::IsStreamPlaying, PATCH_JUMP);
|
|
|
|
InjectHook(0x5682D0, &cSampleManager::InitialiseSampleBanks, PATCH_JUMP);
|
|
|
|
//InjectHook(0x5683F0, `global constructor keyed to'sampman.cpp, PATCH_JUMP);
|
2019-10-27 18:39:17 +01:00
|
|
|
ENDPATCHES
|