summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authoraap <aap@papnet.eu>2020-05-11 22:21:26 +0200
committeraap <aap@papnet.eu>2020-05-11 22:21:26 +0200
commit0eb5f93e96bfc4b31c0bde01e9f1296b3b612bc2 (patch)
tree16bf11e0e8a0353448a643322e9511e8ba659fca /src
parentCVisibilityPlugins (diff)
parentMerge remote-tracking branch 'origin/master' into miami (diff)
downloadre3-0eb5f93e96bfc4b31c0bde01e9f1296b3b612bc2.tar
re3-0eb5f93e96bfc4b31c0bde01e9f1296b3b612bc2.tar.gz
re3-0eb5f93e96bfc4b31c0bde01e9f1296b3b612bc2.tar.bz2
re3-0eb5f93e96bfc4b31c0bde01e9f1296b3b612bc2.tar.lz
re3-0eb5f93e96bfc4b31c0bde01e9f1296b3b612bc2.tar.xz
re3-0eb5f93e96bfc4b31c0bde01e9f1296b3b612bc2.tar.zst
re3-0eb5f93e96bfc4b31c0bde01e9f1296b3b612bc2.zip
Diffstat (limited to 'src')
-rw-r--r--src/animation/AnimBlendClumpData.h2
-rw-r--r--src/animation/AnimBlendHierarchy.h3
-rw-r--r--src/animation/AnimBlendNode.h4
-rw-r--r--src/animation/AnimBlendSequence.h2
-rw-r--r--src/audio/AudioCollision.h4
-rw-r--r--src/audio/AudioManager.cpp4
-rw-r--r--src/audio/AudioManager.h17
-rw-r--r--src/audio/AudioScriptObject.h2
-rw-r--r--src/audio/DMAudio.cpp23
-rw-r--r--src/audio/DMAudio.h2
-rw-r--r--src/audio/MusicManager.h2
-rw-r--r--src/audio/PoliceRadio.h4
-rw-r--r--src/audio/miles/sampman_mss.h339
-rw-r--r--src/audio/oal/aldlist.cpp329
-rw-r--r--src/audio/oal/aldlist.h49
-rw-r--r--src/audio/oal/channel.cpp210
-rw-r--r--src/audio/oal/channel.h51
-rw-r--r--src/audio/oal/oal_utils.cpp169
-rw-r--r--src/audio/oal/oal_utils.h48
-rw-r--r--src/audio/oal/stream.cpp520
-rw-r--r--src/audio/oal/stream.h112
-rw-r--r--src/audio/openal/samp_oal.cpp1404
-rw-r--r--src/audio/openal/samp_oal.h340
-rw-r--r--src/audio/sampman.cpp7
-rw-r--r--src/audio/sampman.h348
-rw-r--r--src/audio/sampman_miles.cpp (renamed from src/audio/miles/sampman_mss.cpp)70
-rw-r--r--src/audio/sampman_oal.cpp1404
-rw-r--r--src/control/AutoPilot.h2
-rw-r--r--src/control/Garages.h4
-rw-r--r--src/control/OnscreenTimer.h4
-rw-r--r--src/control/PathFind.h3
-rw-r--r--src/control/Phones.h2
-rw-r--r--src/control/Pickups.h2
-rw-r--r--src/control/Replay.h19
-rw-r--r--src/control/SceneEdit.cpp2
-rw-r--r--src/control/Script.cpp10
-rw-r--r--src/control/Script.h4
-rw-r--r--src/core/Cam.cpp3
-rw-r--r--src/core/Camera.h20
-rw-r--r--src/core/CdStream.cpp1
-rw-r--r--src/core/CdStream.h1
-rw-r--r--src/core/Frontend.h2
-rw-r--r--src/core/Game.cpp19
-rw-r--r--src/core/Placeable.h3
-rw-r--r--src/core/Radar.h2
-rw-r--r--src/core/Wanted.h2
-rw-r--r--src/core/World.h3
-rw-r--r--src/core/common.h6
-rw-r--r--src/core/config.h3
-rw-r--r--src/core/re3.cpp14
-rw-r--r--src/modelinfo/BaseModelInfo.h2
-rw-r--r--src/objects/ObjectData.h2
-rw-r--r--src/peds/CivilianPed.h2
-rw-r--r--src/peds/CopPed.h2
-rw-r--r--src/peds/EmergencyPed.h2
-rw-r--r--src/peds/Gangs.h2
-rw-r--r--src/peds/Ped.h15
-rw-r--r--src/peds/PedIK.h3
-rw-r--r--src/peds/PedStats.h3
-rw-r--r--src/peds/PedType.h2
-rw-r--r--src/peds/PlayerPed.h2
-rw-r--r--src/render/2dEffect.h3
-rw-r--r--src/render/Coronas.h3
-rw-r--r--src/render/Particle.h2
-rw-r--r--src/render/ParticleMgr.h6
-rw-r--r--src/render/PointLights.h2
-rw-r--r--src/render/Shadows.h10
-rw-r--r--src/render/WaterCannon.h2
-rw-r--r--src/text/Text.h3
-rw-r--r--src/vehicles/Cranes.h2
-rw-r--r--src/weapons/WeaponInfo.h2
71 files changed, 3460 insertions, 2212 deletions
diff --git a/src/animation/AnimBlendClumpData.h b/src/animation/AnimBlendClumpData.h
index 10652d4a..b953ee88 100644
--- a/src/animation/AnimBlendClumpData.h
+++ b/src/animation/AnimBlendClumpData.h
@@ -27,7 +27,7 @@ struct AnimBlendFrameData
#endif
};
#ifndef PED_SKIN
-static_assert(sizeof(AnimBlendFrameData) == 0x14, "AnimBlendFrameData: error");
+VALIDATE_SIZE(AnimBlendFrameData, 0x14);
#endif
diff --git a/src/animation/AnimBlendHierarchy.h b/src/animation/AnimBlendHierarchy.h
index 018160ac..45c9217e 100644
--- a/src/animation/AnimBlendHierarchy.h
+++ b/src/animation/AnimBlendHierarchy.h
@@ -26,4 +26,5 @@ public:
void Uncompress(void);
void RemoveUncompressedData(void);
};
-static_assert(sizeof(CAnimBlendHierarchy) == 0x28, "CAnimBlendHierarchy: error");
+
+VALIDATE_SIZE(CAnimBlendHierarchy, 0x28); \ No newline at end of file
diff --git a/src/animation/AnimBlendNode.h b/src/animation/AnimBlendNode.h
index 38610ff3..9446e1ae 100644
--- a/src/animation/AnimBlendNode.h
+++ b/src/animation/AnimBlendNode.h
@@ -28,4 +28,6 @@ public:
void GetCurrentTranslation(CVector &trans, float weight);
void GetEndTranslation(CVector &trans, float weight);
};
-static_assert(sizeof(CAnimBlendNode) == 0x1C, "CAnimBlendNode: error");
+
+
+VALIDATE_SIZE(CAnimBlendNode, 0x1C);
diff --git a/src/animation/AnimBlendSequence.h b/src/animation/AnimBlendSequence.h
index 3d467078..6d8c98aa 100644
--- a/src/animation/AnimBlendSequence.h
+++ b/src/animation/AnimBlendSequence.h
@@ -56,5 +56,5 @@ public:
#endif
};
#ifndef PED_SKIN
-static_assert(sizeof(CAnimBlendSequence) == 0x2C, "CAnimBlendSequence: error");
+VALIDATE_SIZE(CAnimBlendSequence, 0x2C);
#endif
diff --git a/src/audio/AudioCollision.h b/src/audio/AudioCollision.h
index 324bab0e..0a058916 100644
--- a/src/audio/AudioCollision.h
+++ b/src/audio/AudioCollision.h
@@ -20,7 +20,7 @@ public:
// no methods
};
-static_assert(sizeof(cAudioCollision) == 40, "cAudioCollision: error");
+VALIDATE_SIZE(cAudioCollision, 40);
class cAudioCollisionManager
{
@@ -35,4 +35,4 @@ public:
void AddCollisionToRequestedQueue();
};
-static_assert(sizeof(cAudioCollisionManager) == 852, "cAudioCollisionManager: error"); \ No newline at end of file
+VALIDATE_SIZE(cAudioCollisionManager, 852);
diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp
index f82020bd..63b73a9f 100644
--- a/src/audio/AudioManager.cpp
+++ b/src/audio/AudioManager.cpp
@@ -9336,7 +9336,7 @@ cAudioManager::ResetTimers(uint32 time)
SampleManager.SetEffectsFadeVolume(0);
SampleManager.SetMusicFadeVolume(0);
MusicManager.ResetMusicAfterReload();
-#ifdef OPENAL
+#ifdef AUDIO_OAL
SampleManager.Service();
#endif
}
@@ -9392,7 +9392,7 @@ cAudioManager::ServiceSoundEffects()
ProcessMissionAudio();
AdjustSamplesVolume();
ProcessActiveQueues();
-#ifdef OPENAL
+#ifdef AUDIO_OAL
SampleManager.Service();
#endif
for (int32 i = 0; i < m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal; ++i) {
diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h
index 0d0c5d91..99d67444 100644
--- a/src/audio/AudioManager.h
+++ b/src/audio/AudioManager.h
@@ -35,7 +35,7 @@ public:
int8 m_nVolumeChange;
};
-static_assert(sizeof(tSound) == 92, "tSound: error");
+VALIDATE_SIZE(tSound, 92);
class CPhysical;
class CAutomobile;
@@ -52,7 +52,7 @@ public:
uint8 m_AudioEvents;
};
-static_assert(sizeof(tAudioEntity) == 40, "tAudioEntity: error");
+VALIDATE_SIZE(tAudioEntity, 40);
class tPedComment
{
@@ -65,7 +65,7 @@ public:
int8 m_nProcess;
};
-static_assert(sizeof(tPedComment) == 28, "tPedComment: error");
+VALIDATE_SIZE(tPedComment, 28);
class cPedComments
{
@@ -80,7 +80,7 @@ public:
void Process();
};
-static_assert(sizeof(cPedComments) == 1164, "cPedComments: error");
+VALIDATE_SIZE(cPedComments, 1164);
class CEntity;
@@ -96,8 +96,7 @@ public:
int32 m_nMissionAudioCounter;
bool m_bIsPlayed;
};
-
-static_assert(sizeof(cMissionAudio) == 32, "cMissionAudio: error");
+VALIDATE_SIZE(cMissionAudio, 32);
// name made up
class cAudioScriptObjectManager
@@ -135,7 +134,7 @@ public:
float m_fVelocityChange;
};
-static_assert(sizeof(cVehicleParams) == 0x18, "cVehicleParams: error");
+VALIDATE_SIZE(cVehicleParams, 0x18);
enum {
/*
@@ -472,6 +471,8 @@ public:
void DebugShit();
};
-//dstatic_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error");
+#ifdef AUDIO_MSS
+static_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error");
+#endif
extern cAudioManager AudioManager;
diff --git a/src/audio/AudioScriptObject.h b/src/audio/AudioScriptObject.h
index 4308faee..ecc07fdf 100644
--- a/src/audio/AudioScriptObject.h
+++ b/src/audio/AudioScriptObject.h
@@ -148,6 +148,6 @@ public:
static void SaveAllAudioScriptObjects(uint8 *buf, uint32 *size);
};
-static_assert(sizeof(cAudioScriptObject) == 20, "cAudioScriptObject: error");
+VALIDATE_SIZE(cAudioScriptObject, 20);
extern void PlayOneShotScriptObject(uint8 id, CVector const &pos); \ No newline at end of file
diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp
index 11c85dbd..f1b9707b 100644
--- a/src/audio/DMAudio.cpp
+++ b/src/audio/DMAudio.cpp
@@ -5,6 +5,7 @@
#include "AudioManager.h"
#include "AudioScriptObject.h"
#include "sampman.h"
+#include "Text.h"
cDMAudio DMAudio;
@@ -104,6 +105,28 @@ cDMAudio::Get3DProviderName(uint8 id)
return AudioManager.Get3DProviderName(id);
}
+int8 cDMAudio::AutoDetect3DProviders(void)
+{
+ for ( int32 i = 0; i < GetNum3DProvidersAvailable(); i++ )
+ {
+ wchar buff[64];
+
+ char *name = Get3DProviderName(i);
+ AsciiToUnicode(name, buff);
+ char *providername = UnicodeToAscii(buff);
+ strupr(providername);
+#if defined(AUDIO_MSS)
+ if ( !strcmp(providername, "MILES FAST 2D POSITIONAL AUDIO") )
+ return i;
+#elif defined(AUDIO_OAL)
+ if ( !strcmp(providername, "OPENAL SOFT") )
+ return i;
+#endif
+ }
+
+ return -1;
+}
+
int8
cDMAudio::GetCurrent3DProviderIndex(void)
{
diff --git a/src/audio/DMAudio.h b/src/audio/DMAudio.h
index 428f08b4..052fdb81 100644
--- a/src/audio/DMAudio.h
+++ b/src/audio/DMAudio.h
@@ -34,6 +34,8 @@ public:
uint8 GetNum3DProvidersAvailable(void);
char *Get3DProviderName(uint8 id);
+ int8 AutoDetect3DProviders(void);
+
int8 GetCurrent3DProviderIndex(void);
int8 SetCurrent3DProvider(uint8 which);
diff --git a/src/audio/MusicManager.h b/src/audio/MusicManager.h
index 5d6f41cf..e8b94da6 100644
--- a/src/audio/MusicManager.h
+++ b/src/audio/MusicManager.h
@@ -84,6 +84,6 @@ public:
bool ChangeRadioChannel();
};
-static_assert(sizeof(cMusicManager) == 0x95C, "cMusicManager: error");
+VALIDATE_SIZE(cMusicManager, 0x95C);
extern cMusicManager MusicManager;
diff --git a/src/audio/PoliceRadio.h b/src/audio/PoliceRadio.h
index 0f351f52..c01f21ce 100644
--- a/src/audio/PoliceRadio.h
+++ b/src/audio/PoliceRadio.h
@@ -15,7 +15,7 @@ struct cAMCrime {
}
};
-static_assert(sizeof(cAMCrime) == 20, "cAMCrime: error ");
+VALIDATE_SIZE(cAMCrime, 20);
class cPoliceRadioQueue
{
@@ -43,4 +43,4 @@ public:
}
};
-static_assert(sizeof(cPoliceRadioQueue) == 444, "cPoliceRadioQueue: error "); \ No newline at end of file
+VALIDATE_SIZE(cPoliceRadioQueue, 444);
diff --git a/src/audio/miles/sampman_mss.h b/src/audio/miles/sampman_mss.h
deleted file mode 100644
index ebedfb63..00000000
--- a/src/audio/miles/sampman_mss.h
+++ /dev/null
@@ -1,339 +0,0 @@
-#pragma once
-#include "common.h"
-#include "AudioSamples.h"
-
-#define MAX_VOLUME 127
-
-struct tSample {
- int32 nOffset;
- uint32 nSize;
- int32 nFrequency;
- int32 nLoopStart;
- int32 nLoopEnd;
-};
-
-enum
-{
- SAMPLEBANK_MAIN,
- SAMPLEBANK_PED,
- MAX_SAMPLEBANKS,
- SAMPLEBANK_INVALID
-};
-
-#define MAX_PEDSFX 7
-#define PED_BLOCKSIZE 79000
-
-#define MAXPROVIDERS 64
-
-#define MAXCHANNELS 28
-#define MAXCHANNELS_SURROUND 24
-#define MAX2DCHANNELS 1
-#define CHANNEL2D MAXCHANNELS
-
-#define MAX_MP3STREAMS 2
-
-#define DIGITALRATE 32000
-#define DIGITALBITS 16
-#define DIGITALCHANNELS 2
-
-#define MAX_DIGITAL_MIXER_CHANNELS 32
-
-class cSampleManager
-{
- uint8 m_nEffectsVolume;
- uint8 m_nMusicVolume;
- uint8 m_nEffectsFadeVolume;
- uint8 m_nMusicFadeVolume;
- uint8 m_nMonoMode;
- char unk;
- char m_szCDRomRootPath[80];
- bool m_bInitialised;
- uint8 m_nNumberOfProviders;
- char *m_aAudioProviders[MAXPROVIDERS];
- tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
-
-public:
-
-
-
- cSampleManager(void) :
- m_nNumberOfProviders(0)
- { }
-
- ~cSampleManager(void)
- { }
-
- void SetSpeakerConfig(int32 nConfig);
- uint32 GetMaximumSupportedChannels(void);
-
- uint32 GetNum3DProvidersAvailable() { return m_nNumberOfProviders; }
- void SetNum3DProvidersAvailable(uint32 num) { m_nNumberOfProviders = num; }
-
- char *Get3DProviderName(uint8 id) { return m_aAudioProviders[id]; }
- void Set3DProviderName(uint8 id, char *name) { m_aAudioProviders[id] = name; }
-
- int8 GetCurrent3DProviderIndex(void);
- int8 SetCurrent3DProvider(uint8 which);
-
- bool IsMP3RadioChannelAvailable(void);
-
- void ReleaseDigitalHandle (void);
- void ReacquireDigitalHandle(void);
-
- bool Initialise(void);
- void Terminate (void);
-
- bool CheckForAnAudioFileOnCD(void);
- char GetCDAudioDriveLetter (void);
-
- void UpdateEffectsVolume(void);
-
- void SetEffectsMasterVolume(uint8 nVolume);
- void SetMusicMasterVolume (uint8 nVolume);
- void SetEffectsFadeVolume (uint8 nVolume);
- void SetMusicFadeVolume (uint8 nVolume);
-
- bool LoadSampleBank (uint8 nBank);
- void UnloadSampleBank (uint8 nBank);
- bool IsSampleBankLoaded(uint8 nBank);
-
- bool IsPedCommentLoaded(uint32 nComment);
- bool LoadPedComment (uint32 nComment);
-
- int32 _GetPedCommentSlot(uint32 nComment);
-
- int32 GetSampleBaseFrequency (uint32 nSample);
- int32 GetSampleLoopStartOffset(uint32 nSample);
- int32 GetSampleLoopEndOffset (uint32 nSample);
- uint32 GetSampleLength (uint32 nSample);
-
- bool UpdateReverb(void);
-
- void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag);
- bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank);
- void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
- void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ);
- void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin);
- void SetChannelVolume (uint32 nChannel, uint32 nVolume);
- void SetChannelPan (uint32 nChannel, uint32 nPan);
- void SetChannelFrequency (uint32 nChannel, uint32 nFreq);
- void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd);
- void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount);
- bool GetChannelUsedFlag (uint32 nChannel);
- void StartChannel (uint32 nChannel);
- void StopChannel (uint32 nChannel);
-
- void PreloadStreamedFile (uint8 nFile, uint8 nStream);
- void PauseStream (uint8 nPauseFlag, uint8 nStream);
- void StartPreloadedStreamedFile (uint8 nStream);
- bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream);
- void StopStreamedFile (uint8 nStream);
- int32 GetStreamedFilePosition (uint8 nStream);
- void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream);
- int32 GetStreamedFileLength (uint8 nStream);
- bool IsStreamPlaying (uint8 nStream);
- bool InitialiseSampleBanks(void);
-};
-
-extern cSampleManager SampleManager;
-extern int32 BankStartOffset[MAX_SAMPLEBANKS];
-
-static char StreamedNameTable[][25]=
-{
- "AUDIO\\HEAD.WAV",
- "AUDIO\\CLASS.WAV",
- "AUDIO\\KJAH.WAV",
- "AUDIO\\RISE.WAV",
- "AUDIO\\LIPS.WAV",
- "AUDIO\\GAME.WAV",
- "AUDIO\\MSX.WAV",
- "AUDIO\\FLASH.WAV",
- "AUDIO\\CHAT.WAV",
- "AUDIO\\HEAD.WAV",
- "AUDIO\\POLICE.WAV",
- "AUDIO\\CITY.WAV",
- "AUDIO\\WATER.WAV",
- "AUDIO\\COMOPEN.WAV",
- "AUDIO\\SUBOPEN.WAV",
- "AUDIO\\JB.MP3",
- "AUDIO\\BET.MP3",
- "AUDIO\\L1_LG.MP3",
- "AUDIO\\L2_DSB.MP3",
- "AUDIO\\L3_DM.MP3",
- "AUDIO\\L4_PAP.MP3",
- "AUDIO\\L5_TFB.MP3",
- "AUDIO\\J0_DM2.MP3",
- "AUDIO\\J1_LFL.MP3",
- "AUDIO\\J2_KCL.MP3",
- "AUDIO\\J3_VH.MP3",
- "AUDIO\\J4_ETH.MP3",
- "AUDIO\\J5_DST.MP3",
- "AUDIO\\J6_TBJ.MP3",
- "AUDIO\\T1_TOL.MP3",
- "AUDIO\\T2_TPU.MP3",
- "AUDIO\\T3_MAS.MP3",
- "AUDIO\\T4_TAT.MP3",
- "AUDIO\\T5_BF.MP3",
- "AUDIO\\S0_MAS.MP3",
- "AUDIO\\S1_PF.MP3",
- "AUDIO\\S2_CTG.MP3",
- "AUDIO\\S3_RTC.MP3",
- "AUDIO\\S5_LRQ.MP3",
- "AUDIO\\S4_BDBA.MP3",
- "AUDIO\\S4_BDBB.MP3",
- "AUDIO\\S2_CTG2.MP3",
- "AUDIO\\S4_BDBD.MP3",
- "AUDIO\\S5_LRQB.MP3",
- "AUDIO\\S5_LRQC.MP3",
- "AUDIO\\A1_SSO.WAV",
- "AUDIO\\A2_PP.WAV",
- "AUDIO\\A3_SS.WAV",
- "AUDIO\\A4_PDR.WAV",
- "AUDIO\\A5_K2FT.WAV",
- "AUDIO\\K1_KBO.MP3",
- "AUDIO\\K2_GIS.MP3",
- "AUDIO\\K3_DS.MP3",
- "AUDIO\\K4_SHI.MP3",
- "AUDIO\\K5_SD.MP3",
- "AUDIO\\R0_PDR2.MP3",
- "AUDIO\\R1_SW.MP3",
- "AUDIO\\R2_AP.MP3",
- "AUDIO\\R3_ED.MP3",
- "AUDIO\\R4_GF.MP3",
- "AUDIO\\R5_PB.MP3",
- "AUDIO\\R6_MM.MP3",
- "AUDIO\\D1_STOG.MP3",
- "AUDIO\\D2_KK.MP3",
- "AUDIO\\D3_ADO.MP3",
- "AUDIO\\D5_ES.MP3",
- "AUDIO\\D7_MLD.MP3",
- "AUDIO\\D4_GTA.MP3",
- "AUDIO\\D4_GTA2.MP3",
- "AUDIO\\D6_STS.MP3",
- "AUDIO\\A6_BAIT.WAV",
- "AUDIO\\A7_ETG.WAV",
- "AUDIO\\A8_PS.WAV",
- "AUDIO\\A9_ASD.WAV",
- "AUDIO\\K4_SHI2.MP3",
- "AUDIO\\C1_TEX.MP3",
- "AUDIO\\EL_PH1.MP3",
- "AUDIO\\EL_PH2.MP3",
- "AUDIO\\EL_PH3.MP3",
- "AUDIO\\EL_PH4.MP3",
- "AUDIO\\YD_PH1.MP3",
- "AUDIO\\YD_PH2.MP3",
- "AUDIO\\YD_PH3.MP3",
- "AUDIO\\YD_PH4.MP3",
- "AUDIO\\HD_PH1.MP3",
- "AUDIO\\HD_PH2.MP3",
- "AUDIO\\HD_PH3.MP3",
- "AUDIO\\HD_PH4.MP3",
- "AUDIO\\HD_PH5.MP3",
- "AUDIO\\MT_PH1.MP3",
- "AUDIO\\MT_PH2.MP3",
- "AUDIO\\MT_PH3.MP3",
- "AUDIO\\MT_PH4.MP3",
- "AUDIO\\MISCOM.WAV",
- "AUDIO\\END.MP3",
- "AUDIO\\lib_a1.WAV",
- "AUDIO\\lib_a2.WAV",
- "AUDIO\\lib_a.WAV",
- "AUDIO\\lib_b.WAV",
- "AUDIO\\lib_c.WAV",
- "AUDIO\\lib_d.WAV",
- "AUDIO\\l2_a.WAV",
- "AUDIO\\j4t_1.WAV",
- "AUDIO\\j4t_2.WAV",
- "AUDIO\\j4t_3.WAV",
- "AUDIO\\j4t_4.WAV",
- "AUDIO\\j4_a.WAV",
- "AUDIO\\j4_b.WAV",
- "AUDIO\\j4_c.WAV",
- "AUDIO\\j4_d.WAV",
- "AUDIO\\j4_e.WAV",
- "AUDIO\\j4_f.WAV",
- "AUDIO\\j6_1.WAV",
- "AUDIO\\j6_a.WAV",
- "AUDIO\\j6_b.WAV",
- "AUDIO\\j6_c.WAV",
- "AUDIO\\j6_d.WAV",
- "AUDIO\\t4_a.WAV",
- "AUDIO\\s1_a.WAV",
- "AUDIO\\s1_a1.WAV",
- "AUDIO\\s1_b.WAV",
- "AUDIO\\s1_c.WAV",
- "AUDIO\\s1_c1.WAV",
- "AUDIO\\s1_d.WAV",
- "AUDIO\\s1_e.WAV",
- "AUDIO\\s1_f.WAV",
- "AUDIO\\s1_g.WAV",
- "AUDIO\\s1_h.WAV",
- "AUDIO\\s1_i.WAV",
- "AUDIO\\s1_j.WAV",
- "AUDIO\\s1_k.WAV",
- "AUDIO\\s1_l.WAV",
- "AUDIO\\s3_a.WAV",
- "AUDIO\\s3_b.WAV",
- "AUDIO\\el3_a.WAV",
- "AUDIO\\mf1_a.WAV",
- "AUDIO\\mf2_a.WAV",
- "AUDIO\\mf3_a.WAV",
- "AUDIO\\mf3_b.WAV",
- "AUDIO\\mf3_b1.WAV",
- "AUDIO\\mf3_c.WAV",
- "AUDIO\\mf4_a.WAV",
- "AUDIO\\mf4_b.WAV",
- "AUDIO\\mf4_c.WAV",
- "AUDIO\\a1_a.WAV",
- "AUDIO\\a3_a.WAV",
- "AUDIO\\a5_a.WAV",
- "AUDIO\\a4_a.WAV",
- "AUDIO\\a4_b.WAV",
- "AUDIO\\a4_c.WAV",
- "AUDIO\\a4_d.WAV",
- "AUDIO\\k1_a.WAV",
- "AUDIO\\k3_a.WAV",
- "AUDIO\\r1_a.WAV",
- "AUDIO\\r2_a.WAV",
- "AUDIO\\r2_b.WAV",
- "AUDIO\\r2_c.WAV",
- "AUDIO\\r2_d.WAV",
- "AUDIO\\r2_e.WAV",
- "AUDIO\\r2_f.WAV",
- "AUDIO\\r2_g.WAV",
- "AUDIO\\r2_h.WAV",
- "AUDIO\\r5_a.WAV",
- "AUDIO\\r6_a.WAV",
- "AUDIO\\r6_a1.WAV",
- "AUDIO\\r6_b.WAV",
- "AUDIO\\lo2_a.WAV",
- "AUDIO\\lo6_a.WAV",
- "AUDIO\\yd2_a.WAV",
- "AUDIO\\yd2_b.WAV",
- "AUDIO\\yd2_c.WAV",
- "AUDIO\\yd2_c1.WAV",
- "AUDIO\\yd2_d.WAV",
- "AUDIO\\yd2_e.WAV",
- "AUDIO\\yd2_f.WAV",
- "AUDIO\\yd2_g.WAV",
- "AUDIO\\yd2_h.WAV",
- "AUDIO\\yd2_ass.WAV",
- "AUDIO\\yd2_ok.WAV",
- "AUDIO\\h5_a.WAV",
- "AUDIO\\h5_b.WAV",
- "AUDIO\\h5_c.WAV",
- "AUDIO\\ammu_a.WAV",
- "AUDIO\\ammu_b.WAV",
- "AUDIO\\ammu_c.WAV",
- "AUDIO\\door_1.WAV",
- "AUDIO\\door_2.WAV",
- "AUDIO\\door_3.WAV",
- "AUDIO\\door_4.WAV",
- "AUDIO\\door_5.WAV",
- "AUDIO\\door_6.WAV",
- "AUDIO\\t3_a.WAV",
- "AUDIO\\t3_b.WAV",
- "AUDIO\\t3_c.WAV",
- "AUDIO\\k1_b.WAV",
- "AUDIO\\cat1.WAV"
-};
diff --git a/src/audio/oal/aldlist.cpp b/src/audio/oal/aldlist.cpp
new file mode 100644
index 00000000..2c2f13a8
--- /dev/null
+++ b/src/audio/oal/aldlist.cpp
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2006, Creative Labs Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of conditions and
+ * the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
+ * and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * * Neither the name of Creative Labs Inc. nor the names of its contributors may be used to endorse or
+ * promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "aldlist.h"
+#ifdef AUDIO_OAL
+/*
+ * Init call
+ */
+ALDeviceList::ALDeviceList()
+{
+ ALDEVICEINFO ALDeviceInfo;
+ char *devices;
+ int index;
+ const char *defaultDeviceName;
+ const char *actualDeviceName;
+
+ // DeviceInfo vector stores, for each enumerated device, it's device name, selection status, spec version #, and extension support
+ vDeviceInfo.empty();
+ vDeviceInfo.reserve(10);
+
+ defaultDeviceIndex = 0;
+
+ if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")) {
+ devices = (char *)alcGetString(NULL, ALC_DEVICE_SPECIFIER);
+ defaultDeviceName = (char *)alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
+
+ index = 0;
+ // go through device list (each device terminated with a single NULL, list terminated with double NULL)
+ while (*devices != NULL) {
+ if (strcmp(defaultDeviceName, devices) == 0) {
+ defaultDeviceIndex = index;
+ }
+ ALCdevice *device = alcOpenDevice(devices);
+ if (device) {
+ ALCcontext *context = alcCreateContext(device, NULL);
+ if (context) {
+ alcMakeContextCurrent(context);
+ // if new actual device name isn't already in the list, then add it...
+ actualDeviceName = alcGetString(device, ALC_DEVICE_SPECIFIER);
+ bool bNewName = true;
+ for (int i = 0; i < GetNumDevices(); i++) {
+ if (strcmp(GetDeviceName(i), actualDeviceName) == 0) {
+ bNewName = false;
+ }
+ }
+ if ((bNewName) && (actualDeviceName != NULL) && (strlen(actualDeviceName) > 0)) {
+ memset(&ALDeviceInfo, 0, sizeof(ALDEVICEINFO));
+ ALDeviceInfo.bSelected = true;
+ ALDeviceInfo.strDeviceName = std::string(actualDeviceName, strlen(actualDeviceName));
+ alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(int), &ALDeviceInfo.iMajorVersion);
+ alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(int), &ALDeviceInfo.iMinorVersion);
+
+ ALDeviceInfo.pvstrExtensions = new std::vector<std::string>;
+
+ // Check for ALC Extensions
+ if (alcIsExtensionPresent(device, "ALC_EXT_CAPTURE") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_CAPTURE");
+ if (alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_EFX");
+
+ // Check for AL Extensions
+ if (alIsExtensionPresent("AL_EXT_OFFSET") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_OFFSET");
+
+ if (alIsExtensionPresent("AL_EXT_LINEAR_DISTANCE") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_LINEAR_DISTANCE");
+ if (alIsExtensionPresent("AL_EXT_EXPONENT_DISTANCE") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_EXPONENT_DISTANCE");
+
+ if (alIsExtensionPresent("EAX2.0") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("EAX2.0");
+ if (alIsExtensionPresent("EAX3.0") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("EAX3.0");
+ if (alIsExtensionPresent("EAX4.0") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("EAX4.0");
+ if (alIsExtensionPresent("EAX5.0") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("EAX5.0");
+
+ if (alIsExtensionPresent("EAX-RAM") == AL_TRUE)
+ ALDeviceInfo.pvstrExtensions->push_back("EAX-RAM");
+
+ // Get Source Count
+ ALDeviceInfo.uiSourceCount = GetMaxNumSources();
+
+ vDeviceInfo.push_back(ALDeviceInfo);
+ }
+ alcMakeContextCurrent(NULL);
+ alcDestroyContext(context);
+ }
+ alcCloseDevice(device);
+ }
+ devices += strlen(devices) + 1;
+ index += 1;
+ }
+ }
+
+ ResetFilters();
+}
+
+/*
+ * Exit call
+ */
+ALDeviceList::~ALDeviceList()
+{
+ for (unsigned int i = 0; i < vDeviceInfo.size(); i++) {
+ if (vDeviceInfo[i].pvstrExtensions) {
+ vDeviceInfo[i].pvstrExtensions->empty();
+ delete vDeviceInfo[i].pvstrExtensions;
+ }
+ }
+
+ vDeviceInfo.empty();
+}
+
+/*
+ * Returns the number of devices in the complete device list
+ */
+int ALDeviceList::GetNumDevices()
+{
+ return (int)vDeviceInfo.size();
+}
+
+/*
+ * Returns the device name at an index in the complete device list
+ */
+char * ALDeviceList::GetDeviceName(int index)
+{
+ if (index < GetNumDevices())
+ return (char *)vDeviceInfo[index].strDeviceName.c_str();
+ else
+ return NULL;
+}
+
+/*
+ * Returns the major and minor version numbers for a device at a specified index in the complete list
+ */
+void ALDeviceList::GetDeviceVersion(int index, int *major, int *minor)
+{
+ if (index < GetNumDevices()) {
+ if (major)
+ *major = vDeviceInfo[index].iMajorVersion;
+ if (minor)
+ *minor = vDeviceInfo[index].iMinorVersion;
+ }
+ return;
+}
+
+/*
+ * Returns the maximum number of Sources that can be generate on the given device
+ */
+unsigned int ALDeviceList::GetMaxNumSources(int index)
+{
+ if (index < GetNumDevices())
+ return vDeviceInfo[index].uiSourceCount;
+ else
+ return 0;
+}
+
+/*
+ * Checks if the extension is supported on the given device
+ */
+bool ALDeviceList::IsExtensionSupported(int index, char *szExtName)
+{
+ bool bReturn = false;
+
+ if (index < GetNumDevices()) {
+ for (unsigned int i = 0; i < vDeviceInfo[index].pvstrExtensions->size(); i++) {
+ if (!_stricmp(vDeviceInfo[index].pvstrExtensions->at(i).c_str(), szExtName)) {
+ bReturn = true;
+ break;
+ }
+ }
+ }
+
+ return bReturn;
+}
+
+/*
+ * returns the index of the default device in the complete device list
+ */
+int ALDeviceList::GetDefaultDevice()
+{
+ return defaultDeviceIndex;
+}
+
+/*
+ * Deselects devices which don't have the specified minimum version
+ */
+void ALDeviceList::FilterDevicesMinVer(int major, int minor)
+{
+ int dMajor, dMinor;
+ for (unsigned int i = 0; i < vDeviceInfo.size(); i++) {
+ GetDeviceVersion(i, &dMajor, &dMinor);
+ if ((dMajor < major) || ((dMajor == major) && (dMinor < minor))) {
+ vDeviceInfo[i].bSelected = false;
+ }
+ }
+}
+
+/*
+ * Deselects devices which don't have the specified maximum version
+ */
+void ALDeviceList::FilterDevicesMaxVer(int major, int minor)
+{
+ int dMajor, dMinor;
+ for (unsigned int i = 0; i < vDeviceInfo.size(); i++) {
+ GetDeviceVersion(i, &dMajor, &dMinor);
+ if ((dMajor > major) || ((dMajor == major) && (dMinor > minor))) {
+ vDeviceInfo[i].bSelected = false;
+ }
+ }
+}
+
+/*
+ * Deselects device which don't support the given extension name
+ */
+void ALDeviceList::FilterDevicesExtension(char *szExtName)
+{
+ bool bFound;
+
+ for (unsigned int i = 0; i < vDeviceInfo.size(); i++) {
+ bFound = false;
+ for (unsigned int j = 0; j < vDeviceInfo[i].pvstrExtensions->size(); j++) {
+ if (!_stricmp(vDeviceInfo[i].pvstrExtensions->at(j).c_str(), szExtName)) {
+ bFound = true;
+ break;
+ }
+ }
+ if (!bFound)
+ vDeviceInfo[i].bSelected = false;
+ }
+}
+
+/*
+ * Resets all filtering, such that all devices are in the list
+ */
+void ALDeviceList::ResetFilters()
+{
+ for (int i = 0; i < GetNumDevices(); i++) {
+ vDeviceInfo[i].bSelected = true;
+ }
+ filterIndex = 0;
+}
+
+/*
+ * Gets index of first filtered device
+ */
+int ALDeviceList::GetFirstFilteredDevice()
+{
+ int i;
+
+ for (i = 0; i < GetNumDevices(); i++) {
+ if (vDeviceInfo[i].bSelected == true) {
+ break;
+ }
+ }
+ filterIndex = i + 1;
+ return i;
+}
+
+/*
+ * Gets index of next filtered device
+ */
+int ALDeviceList::GetNextFilteredDevice()
+{
+ int i;
+
+ for (i = filterIndex; i < GetNumDevices(); i++) {
+ if (vDeviceInfo[i].bSelected == true) {
+ break;
+ }
+ }
+ filterIndex = i + 1;
+ return i;
+}
+
+/*
+ * Internal function to detemine max number of Sources that can be generated
+ */
+unsigned int ALDeviceList::GetMaxNumSources()
+{
+ ALuint uiSources[256];
+ unsigned int iSourceCount = 0;
+
+ // Clear AL Error Code
+ alGetError();
+
+ // Generate up to 256 Sources, checking for any errors
+ for (iSourceCount = 0; iSourceCount < 256; iSourceCount++)
+ {
+ alGenSources(1, &uiSources[iSourceCount]);
+ if (alGetError() != AL_NO_ERROR)
+ break;
+ }
+
+ // Release the Sources
+ alDeleteSources(iSourceCount, uiSources);
+ if (alGetError() != AL_NO_ERROR)
+ {
+ for (unsigned int i = 0; i < 256; i++)
+ {
+ alDeleteSources(1, &uiSources[i]);
+ }
+ }
+
+ return iSourceCount;
+}
+#endif \ No newline at end of file
diff --git a/src/audio/oal/aldlist.h b/src/audio/oal/aldlist.h
new file mode 100644
index 00000000..b8f1b31a
--- /dev/null
+++ b/src/audio/oal/aldlist.h
@@ -0,0 +1,49 @@
+#ifndef ALDEVICELIST_H
+#define ALDEVICELIST_H
+
+#include "oal_utils.h"
+
+#ifdef AUDIO_OAL
+#pragma warning(disable: 4786) //disable warning "identifier was truncated to '255' characters in the browser information"
+#include <vector>
+#include <string>
+
+typedef struct
+{
+ std::string strDeviceName;
+ int iMajorVersion;
+ int iMinorVersion;
+ unsigned int uiSourceCount;
+ std::vector<std::string> *pvstrExtensions;
+ bool bSelected;
+} ALDEVICEINFO, *LPALDEVICEINFO;
+
+class ALDeviceList
+{
+private:
+ std::vector<ALDEVICEINFO> vDeviceInfo;
+ int defaultDeviceIndex;
+ int filterIndex;
+
+public:
+ ALDeviceList ();
+ ~ALDeviceList ();
+ int GetNumDevices();
+ char *GetDeviceName(int index);
+ void GetDeviceVersion(int index, int *major, int *minor);
+ unsigned int GetMaxNumSources(int index);
+ bool IsExtensionSupported(int index, char *szExtName);
+ int GetDefaultDevice();
+ void FilterDevicesMinVer(int major, int minor);
+ void FilterDevicesMaxVer(int major, int minor);
+ void FilterDevicesExtension(char *szExtName);
+ void ResetFilters();
+ int GetFirstFilteredDevice();
+ int GetNextFilteredDevice();
+
+private:
+ unsigned int GetMaxNumSources();
+};
+#endif
+
+#endif // ALDEVICELIST_H \ No newline at end of file
diff --git a/src/audio/oal/channel.cpp b/src/audio/oal/channel.cpp
new file mode 100644
index 00000000..7742a06a
--- /dev/null
+++ b/src/audio/oal/channel.cpp
@@ -0,0 +1,210 @@
+#include "channel.h"
+
+#ifdef AUDIO_OAL
+#include "common.h"
+#include "sampman.h"
+
+extern bool IsFXSupported();
+
+CChannel::CChannel()
+{
+ alSource = AL_NONE;
+ alFilter = AL_FILTER_NULL;
+ SetDefault();
+}
+
+void CChannel::SetDefault()
+{
+ alBuffer = AL_NONE;
+
+ Pitch = 1.0f;
+ Gain = 1.0f;
+ Mix = 0.0f;
+
+ Position[0] = 0.0f; Position[1] = 0.0f; Position[2] = 0.0f;
+ Distances[0] = 0.0f; Distances[1] = FLT_MAX;
+ LoopCount = 1;
+ LoopPoints[0] = 0; LoopPoints[1] = -1;
+
+ Frequency = MAX_FREQ;
+}
+
+void CChannel::Reset()
+{
+ ClearBuffer();
+ SetDefault();
+}
+
+void CChannel::Init(bool Is2D)
+{
+ ASSERT(!HasSource());
+ alGenSources(1, &alSource);
+ if ( HasSource() )
+ {
+ alSourcei(alSource, AL_SOURCE_RELATIVE, AL_TRUE);
+ if ( IsFXSupported() )
+ alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL);
+
+ if ( Is2D )
+ {
+ alSource3f(alSource, AL_POSITION, 0.0f, 0.0f, 0.0f);
+ alSourcef (alSource, AL_GAIN, 1.0f);
+ }
+ else
+ {
+ if ( IsFXSupported() )
+ alGenFilters(1,&alFilter);
+ }
+ }
+}
+
+void CChannel::Term()
+{
+ Stop();
+ if ( HasSource() )
+ {
+ if ( IsFXSupported() )
+ {
+ alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL);
+
+ if(alFilter != AL_FILTER_NULL)
+ alDeleteFilters(1,&alFilter);
+ }
+
+ alDeleteSources(1, &alSource);
+ }
+ alSource = AL_NONE;
+ alFilter = AL_FILTER_NULL;
+}
+
+void CChannel::Start()
+{
+ if ( !HasSource() ) return;
+
+ if ( LoopPoints[0] != 0 && LoopPoints[0] != -1 )
+ alBufferiv(alBuffer, AL_LOOP_POINTS_SOFT, LoopPoints);
+ alSourcei (alSource, AL_BUFFER, alBuffer);
+ alSourcePlay(alSource);
+}
+
+void CChannel::Stop()
+{
+ if ( HasSource() )
+ alSourceStop(alSource);
+
+ Reset();
+}
+
+bool CChannel::HasSource()
+{
+ return alSource != AL_NONE;
+}
+
+bool CChannel::IsUsed()
+{
+ if ( HasSource() )
+ {
+ ALint sourceState;
+ alGetSourcei(alSource, AL_SOURCE_STATE, &sourceState);
+ return sourceState == AL_PLAYING;
+ }
+ return false;
+}
+
+void CChannel::SetPitch(float pitch)
+{
+ if ( !HasSource() ) return;
+ alSourcef(alSource, AL_PITCH, pitch);
+}
+
+void CChannel::SetGain(float gain)
+{
+ if ( !HasSource() ) return;
+ alSourcef(alSource, AL_GAIN, gain);
+}
+
+void CChannel::SetVolume(int32 vol)
+{
+ SetGain(ALfloat(vol) / MAX_VOLUME);
+}
+
+void CChannel::SetSampleID(uint32 nSfx)
+{
+ Sample = nSfx;
+}
+
+void CChannel::SetFreq(int32 freq)
+{
+ Frequency = freq;
+}
+
+void CChannel::SetCurrentFreq(uint32 freq)
+{
+ SetPitch(ALfloat(freq) / Frequency);
+}
+
+void CChannel::SetLoopCount(int32 loopCount) // fake. TODO:
+{
+ if ( !HasSource() ) return;
+ alSourcei(alSource, AL_LOOPING, loopCount == 1 ? AL_FALSE : AL_TRUE);
+}
+
+void CChannel::SetLoopPoints(ALint start, ALint end)
+{
+ LoopPoints[0] = start;
+ LoopPoints[1] = end;
+}
+
+void CChannel::SetPosition(float x, float y, float z)
+{
+ if ( !HasSource() ) return;
+ alSource3f(alSource, AL_POSITION, x, y, z);
+}
+
+void CChannel::SetDistances(float max, float min)
+{
+ if ( !HasSource() ) return;
+ alSourcef (alSource, AL_MAX_DISTANCE, max);
+ alSourcef (alSource, AL_REFERENCE_DISTANCE, min);
+ alSourcef (alSource, AL_MAX_GAIN, 1.0f);
+ alSourcef (alSource, AL_ROLLOFF_FACTOR, 1.0f);
+}
+
+void CChannel::SetPan(uint32 pan)
+{
+ SetPosition((pan-63)/64.0f, 0.0f, Sqrt(1.0f-SQR((pan-63)/64.0f)));
+}
+
+void CChannel::SetBuffer(ALuint buffer)
+{
+ alBuffer = buffer;
+}
+
+void CChannel::ClearBuffer()
+{
+ if ( !HasSource() ) return;
+ SetBuffer(AL_NONE);
+ alSourcei(alSource, AL_BUFFER, AL_NONE);
+}
+
+void CChannel::SetReverbMix(ALuint slot, float mix)
+{
+ if ( !IsFXSupported() ) return;
+ if ( !HasSource() ) return;
+ if ( alFilter == AL_FILTER_NULL ) return;
+
+ Mix = mix;
+ EAX3_SetReverbMix(alFilter, mix);
+ alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter);
+}
+
+void CChannel::UpdateReverb(ALuint slot)
+{
+ if ( !IsFXSupported() ) return;
+ if ( !HasSource() ) return;
+ if ( alFilter == AL_FILTER_NULL ) return;
+ EAX3_SetReverbMix(alFilter, Mix);
+ alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter);
+}
+
+#endif \ No newline at end of file
diff --git a/src/audio/oal/channel.h b/src/audio/oal/channel.h
new file mode 100644
index 00000000..4dd09ca1
--- /dev/null
+++ b/src/audio/oal/channel.h
@@ -0,0 +1,51 @@
+#pragma once
+#include "common.h"
+
+#ifdef AUDIO_OAL
+#include "oal/oal_utils.h"
+#include <AL/al.h>
+#include <AL/alext.h>
+#include <AL/efx.h>
+
+
+class CChannel
+{
+ ALuint alSource;
+ ALuint alFilter;
+ ALuint alBuffer;
+ float Pitch, Gain;
+ float Mix;
+ int32 Frequency;
+ float Position[3];
+ float Distances[2];
+ int32 LoopCount;
+ ALint LoopPoints[2];
+ uint32 Sample;
+public:
+ CChannel();
+ void SetDefault();
+ void Reset();
+ void Init(bool Is2D = false);
+ void Term();
+ void Start();
+ void Stop();
+ bool HasSource();
+ bool IsUsed();
+ void SetPitch(float pitch);
+ void SetGain(float gain);
+ void SetVolume(int32 vol);
+ void SetSampleID(uint32 nSfx);
+ void SetFreq(int32 freq);
+ void SetCurrentFreq(uint32 freq);
+ void SetLoopCount(int32 loopCount); // fake
+ void SetLoopPoints(ALint start, ALint end);
+ void SetPosition(float x, float y, float z);
+ void SetDistances(float max, float min);
+ void SetPan(uint32 pan);
+ void SetBuffer(ALuint buffer);
+ void ClearBuffer();
+ void SetReverbMix(ALuint slot, float mix);
+ void UpdateReverb(ALuint slot);
+};
+
+#endif \ No newline at end of file
diff --git a/src/audio/oal/oal_utils.cpp b/src/audio/oal/oal_utils.cpp
new file mode 100644
index 00000000..4119672f
--- /dev/null
+++ b/src/audio/oal/oal_utils.cpp
@@ -0,0 +1,169 @@
+#include "oal_utils.h"
+
+#ifdef AUDIO_OAL
+
+LPALGENEFFECTS alGenEffects;
+LPALDELETEEFFECTS alDeleteEffects;
+LPALISEFFECT alIsEffect;
+LPALEFFECTI alEffecti;
+LPALEFFECTIV alEffectiv;
+LPALEFFECTF alEffectf;
+LPALEFFECTFV alEffectfv;
+LPALGETEFFECTI alGetEffecti;
+LPALGETEFFECTIV alGetEffectiv;
+LPALGETEFFECTF alGetEffectf;
+LPALGETEFFECTFV alGetEffectfv;
+LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
+LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
+LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot;
+LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
+LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv;
+LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf;
+LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv;
+LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti;
+LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv;
+LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf;
+LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv;
+LPALGENFILTERS alGenFilters;
+LPALDELETEFILTERS alDeleteFilters;
+LPALISFILTER alIsFilter;
+LPALFILTERI alFilteri;
+LPALFILTERIV alFilteriv;
+LPALFILTERF alFilterf;
+LPALFILTERFV alFilterfv;
+LPALGETFILTERI alGetFilteri;
+LPALGETFILTERIV alGetFilteriv;
+LPALGETFILTERF alGetFilterf;
+LPALGETFILTERFV alGetFilterfv;
+
+
+void EFXInit()
+{
+ /* Define a macro to help load the function pointers. */
+#define LOAD_PROC(T, x) ((x) = (T)alGetProcAddress(#x))
+ LOAD_PROC(LPALGENEFFECTS, alGenEffects);
+ LOAD_PROC(LPALDELETEEFFECTS, alDeleteEffects);
+ LOAD_PROC(LPALISEFFECT, alIsEffect);
+ LOAD_PROC(LPALEFFECTI, alEffecti);
+ LOAD_PROC(LPALEFFECTIV, alEffectiv);
+ LOAD_PROC(LPALEFFECTF, alEffectf);
+ LOAD_PROC(LPALEFFECTFV, alEffectfv);
+ LOAD_PROC(LPALGETEFFECTI, alGetEffecti);
+ LOAD_PROC(LPALGETEFFECTIV, alGetEffectiv);
+ LOAD_PROC(LPALGETEFFECTF, alGetEffectf);
+ LOAD_PROC(LPALGETEFFECTFV, alGetEffectfv);
+
+ LOAD_PROC(LPALGENFILTERS, alGenFilters);
+ LOAD_PROC(LPALDELETEFILTERS, alDeleteFilters);
+ LOAD_PROC(LPALISFILTER, alIsFilter);
+ LOAD_PROC(LPALFILTERI, alFilteri);
+ LOAD_PROC(LPALFILTERIV, alFilteriv);
+ LOAD_PROC(LPALFILTERF, alFilterf);
+ LOAD_PROC(LPALFILTERFV, alFilterfv);
+ LOAD_PROC(LPALGETFILTERI, alGetFilteri);
+ LOAD_PROC(LPALGETFILTERIV, alGetFilteriv);
+ LOAD_PROC(LPALGETFILTERF, alGetFilterf);
+ LOAD_PROC(LPALGETFILTERFV, alGetFilterfv);
+
+ LOAD_PROC(LPALGENAUXILIARYEFFECTSLOTS, alGenAuxiliaryEffectSlots);
+ LOAD_PROC(LPALDELETEAUXILIARYEFFECTSLOTS, alDeleteAuxiliaryEffectSlots);
+ LOAD_PROC(LPALISAUXILIARYEFFECTSLOT, alIsAuxiliaryEffectSlot);
+ LOAD_PROC(LPALAUXILIARYEFFECTSLOTI, alAuxiliaryEffectSloti);
+ LOAD_PROC(LPALAUXILIARYEFFECTSLOTIV, alAuxiliaryEffectSlotiv);
+ LOAD_PROC(LPALAUXILIARYEFFECTSLOTF, alAuxiliaryEffectSlotf);
+ LOAD_PROC(LPALAUXILIARYEFFECTSLOTFV, alAuxiliaryEffectSlotfv);
+ LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTI, alGetAuxiliaryEffectSloti);
+ LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTIV, alGetAuxiliaryEffectSlotiv);
+ LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTF, alGetAuxiliaryEffectSlotf);
+ LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTFV, alGetAuxiliaryEffectSlotfv);
+#undef LOAD_PROC
+}
+
+void SetEffectsLevel(ALuint uiFilter, float level)
+{
+ alFilteri(uiFilter, AL_FILTER_TYPE, AL_FILTER_LOWPASS);
+ alFilterf(uiFilter, AL_LOWPASS_GAIN, 1.0f);
+ alFilterf(uiFilter, AL_LOWPASS_GAINHF, level);
+}
+
+static inline float gain_to_mB(float gain)
+{
+ return (gain > 1e-5f) ? (float)(log10f(gain) * 2000.0f) : -10000l;
+}
+
+static inline float mB_to_gain(float millibels)
+{
+ return (millibels > -10000.0f) ? powf(10.0f, millibels/2000.0f) : 0.0f;
+}
+
+static inline float clampF(float val, float minval, float maxval)
+{
+ if(val >= maxval) return maxval;
+ if(val <= minval) return minval;
+ return val;
+}
+
+void EAX3_Set(ALuint effect, const EAXLISTENERPROPERTIES *props)
+{
+ alEffecti (effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
+ alEffectf (effect, AL_EAXREVERB_DENSITY, clampF(powf(props->flEnvironmentSize, 3.0f) / 16.0f, 0.0f, 1.0f));
+ alEffectf (effect, AL_EAXREVERB_DIFFUSION, props->flEnvironmentDiffusion);
+ alEffectf (effect, AL_EAXREVERB_GAIN, mB_to_gain((float)props->lRoom));
+ alEffectf (effect, AL_EAXREVERB_GAINHF, mB_to_gain((float)props->lRoomHF));
+ alEffectf (effect, AL_EAXREVERB_GAINLF, mB_to_gain((float)props->lRoomLF));
+ alEffectf (effect, AL_EAXREVERB_DECAY_TIME, props->flDecayTime);
+ alEffectf (effect, AL_EAXREVERB_DECAY_HFRATIO, props->flDecayHFRatio);
+ alEffectf (effect, AL_EAXREVERB_DECAY_LFRATIO, props->flDecayLFRatio);
+ alEffectf (effect, AL_EAXREVERB_REFLECTIONS_GAIN, clampF(mB_to_gain((float)props->lReflections), AL_EAXREVERB_MIN_REFLECTIONS_GAIN, AL_EAXREVERB_MAX_REFLECTIONS_GAIN));
+ alEffectf (effect, AL_EAXREVERB_REFLECTIONS_DELAY, props->flReflectionsDelay);
+ alEffectfv(effect, AL_EAXREVERB_REFLECTIONS_PAN, &props->vReflectionsPan.x);
+ alEffectf (effect, AL_EAXREVERB_LATE_REVERB_GAIN, clampF(mB_to_gain((float)props->lReverb), AL_EAXREVERB_MIN_LATE_REVERB_GAIN, AL_EAXREVERB_MAX_LATE_REVERB_GAIN));
+ alEffectf (effect, AL_EAXREVERB_LATE_REVERB_DELAY, props->flReverbDelay);
+ alEffectfv(effect, AL_EAXREVERB_LATE_REVERB_PAN, &props->vReverbPan.x);
+ alEffectf (effect, AL_EAXREVERB_ECHO_TIME, props->flEchoTime);
+ alEffectf (effect, AL_EAXREVERB_ECHO_DEPTH, props->flEchoDepth);
+ alEffectf (effect, AL_EAXREVERB_MODULATION_TIME, props->flModulationTime);
+ alEffectf (effect, AL_EAXREVERB_MODULATION_DEPTH, props->flModulationDepth);
+ alEffectf (effect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, clampF(mB_to_gain(props->flAirAbsorptionHF), AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF, AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF));
+ alEffectf (effect, AL_EAXREVERB_HFREFERENCE, props->flHFReference);
+ alEffectf (effect, AL_EAXREVERB_LFREFERENCE, props->flLFReference);
+ alEffectf (effect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, props->flRoomRolloffFactor);
+ alEffecti (effect, AL_EAXREVERB_DECAY_HFLIMIT, (props->ulFlags&EAXLISTENERFLAGS_DECAYHFLIMIT) ? AL_TRUE : AL_FALSE);
+}
+
+void EFX_Set(ALuint effect, const EAXLISTENERPROPERTIES *props)
+{
+ alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB);
+
+ alEffectf(effect, AL_REVERB_DENSITY, clampF(powf(props->flEnvironmentSize, 3.0f) / 16.0f, 0.0f, 1.0f));
+ alEffectf(effect, AL_REVERB_DIFFUSION, props->flEnvironmentDiffusion);
+ alEffectf(effect, AL_REVERB_GAIN, mB_to_gain((float)props->lRoom));
+ alEffectf(effect, AL_REVERB_GAINHF, mB_to_gain((float)props->lRoomHF));
+ alEffectf(effect, AL_REVERB_DECAY_TIME, props->flDecayTime);
+ alEffectf(effect, AL_REVERB_DECAY_HFRATIO, props->flDecayHFRatio);
+ alEffectf(effect, AL_REVERB_REFLECTIONS_GAIN, clampF(mB_to_gain((float)props->lReflections), AL_EAXREVERB_MIN_REFLECTIONS_GAIN, AL_EAXREVERB_MAX_REFLECTIONS_GAIN));
+ alEffectf(effect, AL_REVERB_REFLECTIONS_DELAY, props->flReflectionsDelay);
+ alEffectf(effect, AL_REVERB_LATE_REVERB_GAIN, clampF(mB_to_gain((float)props->lReverb), AL_EAXREVERB_MIN_LATE_REVERB_GAIN, AL_EAXREVERB_MAX_LATE_REVERB_GAIN));
+ alEffectf(effect, AL_REVERB_LATE_REVERB_DELAY, props->flReverbDelay);
+ alEffectf(effect, AL_REVERB_AIR_ABSORPTION_GAINHF, clampF(mB_to_gain(props->flAirAbsorptionHF), AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF, AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF));
+ alEffectf(effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, props->flRoomRolloffFactor);
+ alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, (props->ulFlags&EAXLISTENERFLAGS_DECAYHFLIMIT) ? AL_TRUE : AL_FALSE);
+}
+
+void EAX3_SetReverbMix(ALuint filter, float mix)
+{
+ //long vol=(long)linear_to_dB(mix);
+ //DSPROPERTY_EAXBUFFER_ROOMHF,
+ //DSPROPERTY_EAXBUFFER_ROOM,
+ //DSPROPERTY_EAXBUFFER_REVERBMIX,
+
+ long mbvol = gain_to_mB(mix);
+ float mb = mbvol;
+ float mbhf = mbvol;
+
+ alFilteri(filter, AL_FILTER_TYPE, AL_FILTER_LOWPASS);
+ alFilterf(filter, AL_LOWPASS_GAIN, mB_to_gain(Min(mb, 0.0f)));
+ alFilterf(filter, AL_LOWPASS_GAINHF, mB_to_gain(mbhf));
+}
+
+#endif \ No newline at end of file
diff --git a/src/audio/oal/oal_utils.h b/src/audio/oal/oal_utils.h
new file mode 100644
index 00000000..af45a944
--- /dev/null
+++ b/src/audio/oal/oal_utils.h
@@ -0,0 +1,48 @@
+#pragma once
+#include "common.h"
+
+#ifdef AUDIO_OAL
+#include "eax.h"
+#include "AL/efx.h"
+
+
+void EFXInit();
+void EAX3_Set(ALuint effect, const EAXLISTENERPROPERTIES *props);
+void EFX_Set(ALuint effect, const EAXLISTENERPROPERTIES *props);
+void EAX3_SetReverbMix(ALuint filter, float mix);
+void SetEffectsLevel(ALuint uiFilter, float level);
+
+extern LPALGENEFFECTS alGenEffects;
+extern LPALDELETEEFFECTS alDeleteEffects;
+extern LPALISEFFECT alIsEffect;
+extern LPALEFFECTI alEffecti;
+extern LPALEFFECTIV alEffectiv;
+extern LPALEFFECTF alEffectf;
+extern LPALEFFECTFV alEffectfv;
+extern LPALGETEFFECTI alGetEffecti;
+extern LPALGETEFFECTIV alGetEffectiv;
+extern LPALGETEFFECTF alGetEffectf;
+extern LPALGETEFFECTFV alGetEffectfv;
+extern LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
+extern LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
+extern LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot;
+extern LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
+extern LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv;
+extern LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf;
+extern LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv;
+extern LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti;
+extern LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv;
+extern LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf;
+extern LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv;
+extern LPALGENFILTERS alGenFilters;
+extern LPALDELETEFILTERS alDeleteFilters;
+extern LPALISFILTER alIsFilter;
+extern LPALFILTERI alFilteri;
+extern LPALFILTERIV alFilteriv;
+extern LPALFILTERF alFilterf;
+extern LPALFILTERFV alFilterfv;
+extern LPALGETFILTERI alGetFilteri;
+extern LPALGETFILTERIV alGetFilteriv;
+extern LPALGETFILTERF alGetFilterf;
+extern LPALGETFILTERFV alGetFilterfv;
+#endif
diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp
new file mode 100644
index 00000000..9bca0546
--- /dev/null
+++ b/src/audio/oal/stream.cpp
@@ -0,0 +1,520 @@
+#include "stream.h"
+
+#ifdef AUDIO_OAL
+#include "common.h"
+#include "sampman.h"
+
+typedef long ssize_t;
+
+#include <sndfile.h>
+#include <mpg123.h>
+
+#pragma comment( lib, "libsndfile-1.lib" )
+#pragma comment( lib, "libmpg123.lib" )
+
+class CSndFile : public IDecoder
+{
+ SNDFILE *m_pfSound;
+ SF_INFO m_soundInfo;
+public:
+ CSndFile(const char *path) :
+ m_pfSound(nil)
+ {
+ memset(&m_soundInfo, 0, sizeof(m_soundInfo));
+ m_pfSound = sf_open(path, SFM_READ, &m_soundInfo);
+ }
+
+ ~CSndFile()
+ {
+ if ( m_pfSound )
+ {
+ sf_close(m_pfSound);
+ m_pfSound = nil;
+ }
+ }
+
+ bool IsOpened()
+ {
+ return m_pfSound != nil;
+ }
+
+ uint32 GetSampleSize()
+ {
+ return sizeof(uint16);
+ }
+
+ uint32 GetSampleCount()
+ {
+ return m_soundInfo.frames;
+ }
+
+ uint32 GetSampleRate()
+ {
+ return m_soundInfo.samplerate;
+ }
+
+ uint32 GetChannels()
+ {
+ return m_soundInfo.channels;
+ }
+
+ void Seek(uint32 milliseconds)
+ {
+ if ( !IsOpened() ) return;
+ sf_seek(m_pfSound, ms2samples(milliseconds), SF_SEEK_SET);
+ }
+
+ uint32 Tell()
+ {
+ if ( !IsOpened() ) return 0;
+ return samples2ms(sf_seek(m_pfSound, 0, SF_SEEK_CUR));
+ }
+
+ uint32 Decode(void *buffer)
+ {
+ if ( !IsOpened() ) return 0;
+ return sf_read_short(m_pfSound, (short *)buffer, GetBufferSamples()) * GetSampleSize();
+ }
+};
+
+class CMP3File : public IDecoder
+{
+ mpg123_handle *m_pMH;
+ bool m_bOpened;
+ uint32 m_nRate;
+ uint32 m_nChannels;
+public:
+ CMP3File(const char *path) :
+ m_pMH(nil),
+ m_bOpened(false),
+ m_nRate(0),
+ m_nChannels(0)
+ {
+ m_pMH = mpg123_new(nil, nil);
+ if ( m_pMH )
+ {
+ long rate = 0;
+ int channels = 0;
+ int encoding = 0;
+
+ m_bOpened = mpg123_open(m_pMH, path) == MPG123_OK
+ && mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK;
+ m_nRate = rate;
+ m_nChannels = channels;
+
+ if ( IsOpened() )
+ {
+ mpg123_format_none(m_pMH);
+ mpg123_format(m_pMH, rate, channels, encoding);
+ }
+ }
+ }
+
+ ~CMP3File()
+ {
+ if ( m_pMH )
+ {
+ mpg123_close(m_pMH);
+ mpg123_delete(m_pMH);
+ m_pMH = nil;
+ }
+ }
+
+ bool IsOpened()
+ {
+ return m_bOpened;
+ }
+
+ uint32 GetSampleSize()
+ {
+ return sizeof(uint16);
+ }
+
+ uint32 GetSampleCount()
+ {
+ if ( !IsOpened() ) return 0;
+ return mpg123_length(m_pMH);
+ }
+
+ uint32 GetSampleRate()
+ {
+ return m_nRate;
+ }
+
+ uint32 GetChannels()
+ {
+ return m_nChannels;
+ }
+
+ void Seek(uint32 milliseconds)
+ {
+ if ( !IsOpened() ) return;
+ mpg123_seek(m_pMH, ms2samples(milliseconds)*GetSampleSize(), SEEK_SET);
+ }
+
+ uint32 Tell()
+ {
+ if ( !IsOpened() ) return 0;
+ return samples2ms(mpg123_tell(m_pMH)/GetSampleSize());
+ }
+
+ uint32 Decode(void *buffer)
+ {
+ if ( !IsOpened() ) return 0;
+
+ size_t size;
+ int err = mpg123_read(m_pMH, (unsigned char *)buffer, GetBufferSize(), &size);
+ if (err != MPG123_OK && err != MPG123_DONE) return 0;
+ return size;
+ }
+};
+
+void CStream::Initialise()
+{
+ mpg123_init();
+}
+
+void CStream::Terminate()
+{
+ mpg123_exit();
+}
+
+CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]) :
+ m_alSource(source),
+ m_alBuffers(buffers),
+ m_pBuffer(nil),
+ m_bPaused(false),
+ m_bActive(false),
+ m_pSoundFile(nil),
+ m_bReset(false),
+ m_nVolume(0),
+ m_nPan(0),
+ m_nPosBeforeReset(0)
+
+{
+ strcpy(m_aFilename, filename);
+
+ DEV("Stream %s\n", m_aFilename);
+
+ if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".mp3")], ".mp3"))
+ m_pSoundFile = new CMP3File(m_aFilename);
+ else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".wav")], ".wav"))
+ m_pSoundFile = new CSndFile(m_aFilename);
+ else
+ m_pSoundFile = nil;
+ ASSERT(m_pSoundFile != nil);
+ if (m_pSoundFile && m_pSoundFile->IsOpened() )
+ {
+ m_pBuffer = malloc(m_pSoundFile->GetBufferSize());
+ ASSERT(m_pBuffer!=nil);
+
+ DEV("AvgSamplesPerSec: %d\n", m_pSoundFile->GetAvgSamplesPerSec());
+ DEV("SampleCount: %d\n", m_pSoundFile->GetSampleCount());
+ DEV("SampleRate: %d\n", m_pSoundFile->GetSampleRate());
+ DEV("Channels: %d\n", m_pSoundFile->GetChannels());
+ DEV("Buffer Samples: %d\n", m_pSoundFile->GetBufferSamples());
+ DEV("Buffer sec: %f\n", (float(m_pSoundFile->GetBufferSamples()) / float(m_pSoundFile->GetChannels())/ float(m_pSoundFile->GetSampleRate())));
+ DEV("Length MS: %02d:%02d\n", (m_pSoundFile->GetLength() / 1000) / 60, (m_pSoundFile->GetLength() / 1000) % 60);
+
+ return;
+ }
+}
+
+CStream::~CStream()
+{
+ Delete();
+}
+
+void CStream::Delete()
+{
+ Stop();
+ ClearBuffers();
+
+ if ( m_pSoundFile )
+ {
+ delete m_pSoundFile;
+ m_pSoundFile = nil;
+ }
+
+ if ( m_pBuffer )
+ {
+ free(m_pBuffer);
+ m_pBuffer = nil;
+ }
+}
+
+bool CStream::HasSource()
+{
+ return m_alSource != AL_NONE;
+}
+
+bool CStream::IsOpened()
+{
+ return m_pSoundFile->IsOpened();
+}
+
+bool CStream::IsPlaying()
+{
+ if ( !HasSource() || !IsOpened() ) return false;
+
+ if ( m_pSoundFile->IsOpened() && !m_bPaused )
+ {
+ ALint sourceState;
+ alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
+ if ( m_bActive || sourceState == AL_PLAYING )
+ return true;
+ }
+
+ return false;
+}
+
+void CStream::Pause()
+{
+ if ( !HasSource() ) return;
+ ALint sourceState = AL_PAUSED;
+ alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
+ if (sourceState != AL_PAUSED )
+ alSourcePause(m_alSource);
+}
+
+void CStream::SetPause(bool bPause)
+{
+ if ( !HasSource() ) return;
+ if ( bPause )
+ {
+ Pause();
+ m_bPaused = true;
+ }
+ else
+ {
+ if (m_bPaused)
+ SetPlay(true);
+ m_bPaused = false;
+ }
+}
+
+void CStream::SetPitch(float pitch)
+{
+ if ( !HasSource() ) return;
+ alSourcef(m_alSource, AL_PITCH, pitch);
+}
+
+void CStream::SetGain(float gain)
+{
+ if ( !HasSource() ) return;
+ alSourcef(m_alSource, AL_GAIN, gain);
+}
+
+void CStream::SetPosition(float x, float y, float z)
+{
+ if ( !HasSource() ) return;
+ alSource3f(m_alSource, AL_POSITION, x, y, z);
+}
+
+void CStream::SetVolume(uint32 nVol)
+{
+ m_nVolume = nVol;
+ SetGain(ALfloat(nVol) / MAX_VOLUME);
+}
+
+void CStream::SetPan(uint8 nPan)
+{
+ m_nPan = nPan;
+ SetPosition((nPan - 63)/64.0f, 0.0f, Sqrt(1.0f-SQR((nPan-63)/64.0f)));
+}
+
+void CStream::SetPosMS(uint32 nPos)
+{
+ if ( !m_pSoundFile->IsOpened() ) return;
+ m_pSoundFile->Seek(nPos);
+ ClearBuffers();
+}
+
+uint32 CStream::GetPosMS()
+{
+ if ( !HasSource() ) return 0;
+ if ( !m_pSoundFile->IsOpened() ) return 0;
+
+ ALint offset;
+ //alGetSourcei(m_alSource, AL_SAMPLE_OFFSET, &offset);
+ alGetSourcei(m_alSource, AL_BYTE_OFFSET, &offset);
+
+ return m_pSoundFile->Tell()
+ - m_pSoundFile->samples2ms(m_pSoundFile->GetBufferSamples() * (NUM_STREAMBUFFERS-1))
+ + m_pSoundFile->samples2ms(offset/m_pSoundFile->GetSampleSize());
+}
+
+uint32 CStream::GetLengthMS()
+{
+ if ( !m_pSoundFile->IsOpened() ) return 0;
+ return m_pSoundFile->GetLength();
+}
+
+bool CStream::FillBuffer(ALuint alBuffer)
+{
+ if ( !HasSource() )
+ return false;
+ if ( !m_pSoundFile->IsOpened() )
+ return false;
+ if ( !(alBuffer != AL_NONE && alIsBuffer(alBuffer)) )
+ return false;
+
+ uint32 size = m_pSoundFile->Decode(m_pBuffer);
+ if( size == 0 )
+ return false;
+
+ alBufferData(alBuffer, m_pSoundFile->GetChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16,
+ m_pBuffer, size, m_pSoundFile->GetSampleRate());
+
+ return true;
+}
+
+int32 CStream::FillBuffers()
+{
+ int32 i = 0;
+ for ( i = 0; i < NUM_STREAMBUFFERS; i++ )
+ {
+ if ( !FillBuffer(m_alBuffers[i]) )
+ break;
+ alSourceQueueBuffers(m_alSource, 1, &m_alBuffers[i]);
+ }
+
+ return i;
+}
+
+void CStream::ClearBuffers()
+{
+ if ( !HasSource() ) return;
+
+ ALint buffersQueued;
+ alGetSourcei(m_alSource, AL_BUFFERS_QUEUED, &buffersQueued);
+
+ ALuint value;
+ while (buffersQueued--)
+ alSourceUnqueueBuffers(m_alSource, 1, &value);
+}
+
+bool CStream::Setup()
+{
+ if ( m_pSoundFile->IsOpened() )
+ {
+ m_pSoundFile->Seek(0);
+ alSourcei(m_alSource, AL_SOURCE_RELATIVE, AL_TRUE);
+ //SetPosition(0.0f, 0.0f, 0.0f);
+ SetPitch(1.0f);
+ //SetPan(m_nPan);
+ //SetVolume(100);
+ }
+
+ return IsOpened();
+}
+
+void CStream::SetPlay(bool state)
+{
+ if ( !HasSource() ) return;
+ if ( state )
+ {
+ ALint sourceState = AL_PLAYING;
+ alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
+ if (sourceState != AL_PLAYING )
+ alSourcePlay(m_alSource);
+ m_bActive = true;
+ }
+ else
+ {
+ ALint sourceState = AL_STOPPED;
+ alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
+ if (sourceState != AL_STOPPED )
+ alSourceStop(m_alSource);
+ m_bActive = false;
+ }
+}
+
+void CStream::Start()
+{
+ if ( !HasSource() ) return;
+ if ( FillBuffers() != 0 )
+ SetPlay(true);
+}
+
+void CStream::Stop()
+{
+ if ( !HasSource() ) return;
+ SetPlay(false);
+}
+
+void CStream::Update()
+{
+ if ( !IsOpened() )
+ return;
+
+ if ( !HasSource() )
+ return;
+
+ if ( m_bReset )
+ return;
+
+ if ( !m_bPaused )
+ {
+ ALint sourceState;
+ ALint buffersProcessed = 0;
+
+ alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
+ alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed);
+
+ ALint looping = AL_FALSE;
+ alGetSourcei(m_alSource, AL_LOOPING, &looping);
+
+ if ( looping == AL_TRUE )
+ {
+ TRACE("stream set looping");
+ alSourcei(m_alSource, AL_LOOPING, AL_TRUE);
+ }
+
+ while( buffersProcessed-- )
+ {
+ ALuint buffer;
+
+ alSourceUnqueueBuffers(m_alSource, 1, &buffer);
+
+ if ( m_bActive && FillBuffer(buffer) )
+ alSourceQueueBuffers(m_alSource, 1, &buffer);
+ }
+
+ if ( sourceState != AL_PLAYING )
+ {
+ alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed);
+ SetPlay(buffersProcessed!=0);
+ }
+ }
+}
+
+void CStream::ProviderInit()
+{
+ if ( m_bReset )
+ {
+ if ( Setup() )
+ {
+ SetPan(m_nPan);
+ SetVolume(m_nVolume);
+ SetPosMS(m_nPosBeforeReset);
+ if (m_bActive)
+ FillBuffers();
+ SetPlay(m_bActive);
+ if ( m_bPaused )
+ Pause();
+ }
+
+ m_bReset = false;
+ }
+}
+
+void CStream::ProviderTerm()
+{
+ m_bReset = true;
+ m_nPosBeforeReset = GetPosMS();
+
+ ClearBuffers();
+}
+
+#endif \ No newline at end of file
diff --git a/src/audio/oal/stream.h b/src/audio/oal/stream.h
new file mode 100644
index 00000000..f1e5f458
--- /dev/null
+++ b/src/audio/oal/stream.h
@@ -0,0 +1,112 @@
+#pragma once
+#include "common.h"
+
+#ifdef AUDIO_OAL
+#include <AL/al.h>
+
+#define NUM_STREAMBUFFERS 4
+
+class IDecoder
+{
+public:
+ virtual ~IDecoder() { }
+
+ virtual bool IsOpened() = 0;
+
+ virtual uint32 GetSampleSize() = 0;
+ virtual uint32 GetSampleCount() = 0;
+ virtual uint32 GetSampleRate() = 0;
+ virtual uint32 GetChannels() = 0;
+
+ uint32 GetAvgSamplesPerSec()
+ {
+ return GetChannels() * GetSampleRate();
+ }
+
+ uint32 ms2samples(uint32 ms)
+ {
+ return float(ms) / 1000.0f * float(GetChannels()) * float(GetSampleRate());
+ }
+
+ uint32 samples2ms(uint32 sm)
+ {
+ return float(sm) * 1000.0f / float(GetChannels()) / float(GetSampleRate());
+ }
+
+ uint32 GetBufferSamples()
+ {
+ //return (GetAvgSamplesPerSec() >> 2) - (GetSampleCount() % GetChannels());
+ return (GetAvgSamplesPerSec() / 4); // 250ms
+ }
+
+ uint32 GetBufferSize()
+ {
+ return GetBufferSamples() * GetSampleSize();
+ }
+
+ virtual void Seek(uint32 milliseconds) = 0;
+ virtual uint32 Tell() = 0;
+
+ uint32 GetLength()
+ {
+ return float(GetSampleCount()) * 1000.0f / float(GetSampleRate());
+ }
+
+ virtual uint32 Decode(void *buffer) = 0;
+};
+
+class CStream
+{
+ char m_aFilename[128];
+ ALuint &m_alSource;
+ ALuint (&m_alBuffers)[NUM_STREAMBUFFERS];
+
+ bool m_bPaused;
+ bool m_bActive;
+
+ void *m_pBuffer;
+
+ bool m_bReset;
+ uint32 m_nVolume;
+ uint8 m_nPan;
+ uint32 m_nPosBeforeReset;
+
+ IDecoder *m_pSoundFile;
+
+ bool HasSource();
+ void SetPosition(float x, float y, float z);
+ void SetPitch(float pitch);
+ void SetGain(float gain);
+ void Pause();
+ void SetPlay(bool state);
+
+ bool FillBuffer(ALuint alBuffer);
+ int32 FillBuffers();
+ void ClearBuffers();
+public:
+ static void Initialise();
+ static void Terminate();
+
+ CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]);
+ ~CStream();
+ void Delete();
+
+ bool IsOpened();
+ bool IsPlaying();
+ void SetPause (bool bPause);
+ void SetVolume(uint32 nVol);
+ void SetPan (uint8 nPan);
+ void SetPosMS (uint32 nPos);
+ uint32 GetPosMS();
+ uint32 GetLengthMS();
+
+ bool Setup();
+ void Start();
+ void Stop();
+ void Update(void);
+
+ void ProviderInit();
+ void ProviderTerm();
+};
+
+#endif \ No newline at end of file
diff --git a/src/audio/openal/samp_oal.cpp b/src/audio/openal/samp_oal.cpp
deleted file mode 100644
index e8213cd9..00000000
--- a/src/audio/openal/samp_oal.cpp
+++ /dev/null
@@ -1,1404 +0,0 @@
-#include <al.h>
-#include <alc.h>
-#include <mpg123_pre.h>
-//#include <mpg123.h>
-#include <time.h>
-#include <io.h>
-#include "samp_oal.h"
-#include "AudioManager.h"
-#include "MusicManager.h"
-#include "Frontend.h"
-#include "Timer.h"
-
-#pragma comment( lib, "libmpg123.lib" )
-#pragma comment( lib, "OpenAL32.lib" )
-
-cSampleManager SampleManager;
-int32 BankStartOffset[MAX_SAMPLEBANKS];
-
-
-///////////////////////////////////////////////////////////////
-class MP3Stream
-{
-public:
- mpg123_handle *m_pMPG;
- FILE *m_fpFile;
- unsigned char *m_pBuf;
- char m_aFilename[128];
- size_t m_nBufSize;
- size_t m_nLengthInBytes;
- long m_nRate;
- int m_nBitRate;
- int m_nChannels;
- int m_nEncoding;
- int m_nLength;
- int m_nBlockSize;
- int m_nNumBlocks;
- ALuint m_alSource;
- ALuint m_alBuffers[5];
- unsigned char *m_pBlocks;
- bool m_bIsFree;
- bool m_bIsOpened;
- bool m_bIsPaused;
- int m_nVolume;
-
- void Initialize(void);
- bool FillBuffer(ALuint alBuffer);
- void Update(void);
- void SetPos(uint32 nPos);
- int32 FillBuffers();
- MP3Stream(char *filename, ALuint source, ALuint *buffers);
- ~MP3Stream() { Delete(); }
- void Delete();
-
-};
-///////////////////////////////////////////////////////////////
-
-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];
-uint8 nCurrentPedSlot;
-
-
-
-uint32 nStreamLength[TOTAL_STREAMED_SOUNDS];
-
-///////////////////////////////////////////////////////////////
-ALuint alChannel[MAXCHANNELS+MAX2DCHANNELS];
-ALuint ALStreamSources[MAX_STREAMS];
-ALuint ALStreamBuffers[MAX_STREAMS][5];
-struct
-{
- ALuint buffer;
- ALuint timer;
-}ALBuffers[SAMPLEBANK_MAX];
-
-ALuint pedBuffers[MAX_PEDSFX];
-//bank0Buffers
-
-uint32 nNumMP3s;
-
-MP3Stream *mp3Stream[MAX_STREAMS];
-int8 nStreamPan [MAX_STREAMS];
-int8 nStreamVolume[MAX_STREAMS];
-
-float ChannelPitch[MAXCHANNELS+MAX2DCHANNELS];
-uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
-uint32 ChannelSample[MAXCHANNELS+MAX2DCHANNELS];
-int32 currentChannelMaxFrontDistance[MAXCHANNELS+MAX2DCHANNELS];
-int32 currentChannelFrequency[MAXCHANNELS+MAX2DCHANNELS];
-int32 currentChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
-
-
-cSampleManager::cSampleManager(void)
-{
- ;
-}
-
-cSampleManager::~cSampleManager(void)
-{
- ASSERT((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED] == NULL);
- free((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]);
-
- if ( fpSampleDescHandle != NULL )
- {
- fclose(fpSampleDescHandle);
- fpSampleDescHandle = NULL;
- }
-
- if ( fpSampleDataHandle != NULL )
- {
- fclose(fpSampleDataHandle);
- fpSampleDataHandle = NULL;
- }
-}
-
-void cSampleManager::SetSpeakerConfig(int32 nConfig)
-{
-
-}
-
-uint32 cSampleManager::GetMaximumSupportedChannels(void)
-{
- return 20;
-}
-
-uint32 cSampleManager::GetNum3DProvidersAvailable()
-{
- return 1;
-}
-
-void cSampleManager::SetNum3DProvidersAvailable(uint32 num)
-{
- ;
-}
-
-char *cSampleManager::Get3DProviderName(uint8 id)
-{
- static char PROVIDER[256] = "OpenAL";
- return PROVIDER;
-}
-
-void cSampleManager::Set3DProviderName(uint8 id, char *name)
-{
- ;
-}
-
-int8 cSampleManager::GetCurrent3DProviderIndex(void)
-{
- return 0;
-}
-
-int8 cSampleManager::SetCurrent3DProvider(uint8 which)
-{
- return 0;
-}
-
-bool
-cSampleManager::IsMP3RadioChannelAvailable(void)
-{
- return nNumMP3s != 0;
-}
-
-
-void cSampleManager::ReleaseDigitalHandle(void)
-{
-
-}
-
-void cSampleManager::ReacquireDigitalHandle(void)
-{
-
-}
-
-bool
-cSampleManager::Initialise(void)
-{
- ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ,0};
-
- m_pDevice = alcOpenDevice(NULL);
- ASSERT(m_pDevice != NULL);
-
- m_pContext = alcCreateContext(m_pDevice, attr);
- ASSERT(m_pContext != NULL);
-
- alcMakeContextCurrent(m_pContext);
-
- mpg123_init();
-
-
-
- for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
- {
- m_aSamples[i].nOffset = 0;
- m_aSamples[i].nSize = 0;
- m_aSamples[i].nFrequency = MAX_FREQ;
- m_aSamples[i].nLoopStart = 0;
- m_aSamples[i].nLoopEnd = -1;
- }
-
- for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
- nStreamLength[i] = 3600000;
-
- for ( int32 i = 0; i < MAX_STREAMS; i++ )
- {
- mp3Stream[i] = NULL;
- nStreamVolume[i] = 100;
- nStreamPan[i] = 63;
- }
-
- alGenSources(MAX_STREAMS, (ALuint *)ALStreamSources);
- alGenBuffers(MAX_STREAMS*5, (ALuint *)ALStreamBuffers);
-
- m_nMonoMode = 0;
-
- m_nEffectsVolume = MAX_VOLUME;
- m_nMusicVolume = MAX_VOLUME;
- m_nEffectsFadeVolume = MAX_VOLUME;
- m_nMusicFadeVolume = MAX_VOLUME;
-
-
- memset(alChannel, 0, sizeof(alChannel));
- memset(nChannelVolume, 0, sizeof(nChannelVolume));
- memset(ChannelSample, 0, sizeof(ChannelSample));
-
- for ( int32 i = 0; i < ARRAY_SIZE(ChannelPitch); i++ )
- ChannelPitch[i] = 1.0f;
-
-
- fpSampleDescHandle = NULL;
- fpSampleDataHandle = NULL;
-
- for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ )
- {
- bSampleBankLoaded[i] = false;
- nSampleBankDiscStartOffset[i] = 0;
- nSampleBankSize[i] = 0;
- nSampleBankMemoryStartAddress[i] = 0;
- }
-
- alGenBuffers(MAX_PEDSFX, pedBuffers);
-
- for ( int32 i = 0; i < MAX_PEDSFX; i++ )
- {
- nPedSlotSfx[i] = NO_SAMPLE;
- nPedSlotSfxAddr[i] = 0;
- }
-
- nCurrentPedSlot = 0;
-
- for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
- {
- ALBuffers[i].buffer = 0;
- ALBuffers[i].timer = 0;
- }
-
- alListenerf (AL_GAIN, 1.0f);
- alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f);
- alListener3f(AL_VELOCITY, 0.0f, 0.0f, 0.0f);
- ALfloat orientation[6] = { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f };
- alListenerfv(AL_ORIENTATION, orientation);
-
- if ( !InitialiseSampleBanks() )
- {
- Terminate();
- return false;
- }
-
- nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)malloc(nSampleBankSize[SAMPLEBANK_MAIN]);
- ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != NULL);
-
- if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] == NULL )
- {
- Terminate();
- return false;
- }
-
- nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)malloc(PED_BLOCKSIZE*MAX_PEDSFX);
- ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != NULL);
-
- alGenSources(MAXCHANNELS, alChannel);
- for ( int32 i = 0; i < MAXCHANNELS; i++ )
- {
- if ( alChannel[i] )
- alSourcei(alChannel[i], AL_SOURCE_RELATIVE, AL_TRUE);
- }
-
- alGenSources(MAX2DCHANNELS, &alChannel[CHANNEL2D]);
- if ( alChannel[CHANNEL2D] )
- {
- alSourcei (alChannel[CHANNEL2D], AL_SOURCE_RELATIVE, AL_TRUE);
- alSource3f(alChannel[CHANNEL2D], AL_POSITION, 0.0f, 0.0f, 0.0f);
- alSourcef (alChannel[CHANNEL2D], AL_GAIN, 1.0f);
- }
-
- LoadSampleBank(SAMPLEBANK_MAIN);
-
- return true;
-}
-
-void
-cSampleManager::Terminate(void)
-{
- mpg123_exit();
- alcMakeContextCurrent(NULL);
- alcDestroyContext(m_pContext);
- alcCloseDevice(m_pDevice);
-}
-
-void
-cSampleManager::UpdateSoundBuffers(void)
-{
- for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
- {
- if ( ALBuffers[i].timer > 0 )
- {
- ALBuffers[i].timer -= ALuint(CTimer::GetTimeStep() * 20.0f);
-
- if ( ALBuffers[i].timer <= 0 )
- {
- if ( ALBuffers[i].buffer != 0 && alIsBuffer(ALBuffers[i].buffer) )
- {
- alDeleteBuffers(1, &ALBuffers[i].buffer);
-
- if ( alGetError() == AL_NO_ERROR )
- ALBuffers[i].buffer = 0;
- else
- ALBuffers[i].buffer = 120000;
- }
- }
- }
- }
-}
-
-bool cSampleManager::CheckForAnAudioFileOnCD(void)
-{
- return true;
-}
-
-char cSampleManager::GetCDAudioDriveLetter(void)
-{
- return '\0';
-}
-
-void
-cSampleManager::SetEffectsMasterVolume(uint8 nVolume)
-{
- m_nEffectsVolume = nVolume;
-}
-
-void
-cSampleManager::SetMusicMasterVolume(uint8 nVolume)
-{
- m_nMusicVolume = nVolume;
-}
-
-void
-cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
-{
- m_nEffectsFadeVolume = nVolume;
-}
-
-void
-cSampleManager::SetMusicFadeVolume(uint8 nVolume)
-{
- m_nMusicFadeVolume = nVolume;
-}
-
-void
-cSampleManager::SetMonoMode(uint8 nMode)
-{
- m_nMonoMode = nMode;
-}
-
-bool
-cSampleManager::LoadSampleBank(uint8 nBank)
-{
- ASSERT( nBank < MAX_SAMPLEBANKS );
-
- if ( CTimer::GetIsCodePaused() )
- return false;
-
- if ( MusicManager.IsInitialised()
- && MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
- && nBank != SAMPLEBANK_MAIN )
- {
- 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)
-{
- ASSERT( nBank < MAX_SAMPLEBANKS );
-
- ; // NOIMP
-}
-
-bool
-cSampleManager::IsSampleBankLoaded(uint8 nBank)
-{
- ASSERT( nBank < MAX_SAMPLEBANKS );
- return true;
-}
-
-bool
-cSampleManager::IsPedCommentLoaded(uint32 nComment)
-{
- ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
-
- uint8 slot;
-
- 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)
-{
- uint8 slot;
-
- 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)
-{
- ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
-
- 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;
-
- if ( fread((void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize )
- return false;
-
- nPedSlotSfx[nCurrentPedSlot] = nComment;
-
- alBufferData(pedBuffers[nCurrentPedSlot],
- AL_FORMAT_MONO16,
- (void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot),
- m_aSamples[nComment].nSize,
- MAX_FREQ);
-
- if ( ++nCurrentPedSlot >= MAX_PEDSFX )
- nCurrentPedSlot = 0;
-
- return true;
-}
-
-int32
-cSampleManager::GetBankContainingSound(uint32 offset)
-{
- if ( offset >= BankStartOffset[SAMPLEBANK_PED] )
- return SAMPLEBANK_PED;
-
- if ( offset >= BankStartOffset[SAMPLEBANK_MAIN] )
- return SAMPLEBANK_MAIN;
-
- return SAMPLEBANK_INVALID;
-}
-
-int32
-cSampleManager::GetSampleBaseFrequency(uint32 nSample)
-{
- ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
- return m_aSamples[nSample].nFrequency;
-}
-
-int32
-cSampleManager::GetSampleLoopStartOffset(uint32 nSample)
-{
- ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
- return m_aSamples[nSample].nLoopStart;
-}
-
-int32
-cSampleManager::GetSampleLoopEndOffset(uint32 nSample)
-{
- ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
- return m_aSamples[nSample].nLoopEnd;
-}
-
-uint32
-cSampleManager::GetSampleLength(uint32 nSample)
-{
- ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
- return m_aSamples[nSample].nSize >> 1;
-}
-
-bool cSampleManager::UpdateReverb(void)
-{
- return false;
-}
-
-void
-cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag)
-{
- ; // NOIMP
-}
-
-bool
-cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
-{
- ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-
- ALuint buffer;
-
- if ( nSfx < SAMPLEBANK_MAX )
- {
- int32 offset = (m_aSamples[nSfx].nLoopStart > 0) ? (m_aSamples[nSfx].nOffset - m_aSamples[nSfx].nLoopStart) : m_aSamples[nSfx].nOffset;
- int32 size = (m_aSamples[nSfx].nLoopStart > 0) ? (m_aSamples[nSfx].nLoopEnd - m_aSamples[nSfx].nLoopStart) : m_aSamples[nSfx].nSize;
-
- void *data = malloc(size);
- ASSERT(data != NULL);
-
- if ( fseek(fpSampleDataHandle, offset + nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 )
- {
- free(data);
- return false;
- }
-
- if ( fread(data, 1, size, fpSampleDataHandle) != size )
- {
- free(data);
- return false;
- }
-
- ALuint buf;
- alGenBuffers(1, &buf);
- alBufferData(buf, AL_FORMAT_MONO16, data, size, MAX_FREQ);
- free(data);
-
- if ( !IsSampleBankLoaded(nBank) )
- return false;
-
- ALBuffers[nSfx].buffer = buf;
- ALBuffers[nSfx].timer = 120000;
-
- buffer = ALBuffers[nSfx].buffer;
-
- ChannelSample[nChannel] = nSfx;
- }
- else
- {
- if ( !IsPedCommentLoaded(nSfx) )
- return false;
-
- int32 slot = _GetPedCommentSlot(nSfx);
-
- buffer = pedBuffers[slot];
- }
-
- if ( buffer == 0 )
- {
- TRACE("No buffer to play id %d", nSfx);
- return false;
- }
-
- if ( GetChannelUsedFlag(nChannel) )
- {
- TRACE("Stopping channel %d - really!!!", nChannel);
- StopChannel(nChannel);
- }
-
- alSourcei(alChannel[nChannel], AL_BUFFER, 0);
- currentChannelVolume [nChannel] = -1;
- currentChannelFrequency [nChannel] = -1;
- currentChannelMaxFrontDistance[nChannel] = -1;
-
- if ( alChannel[nChannel] )
- {
- alSourcei(alChannel[nChannel], AL_BUFFER, buffer);
- alSourcef(alChannel[nChannel], AL_PITCH, 1.0f);
- ChannelPitch[nChannel] = 1.0f;
- return true;
- }
-
- return false;
-}
-
-void
-cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
-{
- ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-
- uint32 vol = nVolume;
- if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
-
- nChannelVolume[nChannel] = vol;
-
- // reduce 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;
- }
-
- uint32 channelVol = m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14;
- if ( ChannelSample[nChannel] >= SFX_CAR_REV_1 && SFX_CAR_REV_10 >= ChannelSample[nChannel] ) // nice hack
- channelVol >>= 1;
-
- if ( alChannel[nChannel] )
- {
- if ( currentChannelVolume[nChannel] != channelVol )
- {
- ALfloat gain = ALfloat(channelVol) / MAX_VOLUME;
- alSourcef(alChannel[nChannel], AL_GAIN, gain);
- currentChannelVolume[nChannel] = channelVol;
- }
- }
-}
-
-void
-cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ)
-{
- ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-
- if ( alChannel[nChannel] )
- {
- alSource3f(alChannel[nChannel], AL_POSITION, -fX, fY, fZ);
- }
-}
-
-void
-cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin)
-{
- ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-
- if ( alChannel[nChannel] )
- {
- if ( float(currentChannelMaxFrontDistance[nChannel]) != fMax )
- {
- alSourcef(alChannel[nChannel], AL_MAX_DISTANCE, fMax);
- alSourcef(alChannel[nChannel], AL_REFERENCE_DISTANCE, 5.0f);
- alSourcef(alChannel[nChannel], AL_MAX_GAIN, 1.0f);
- currentChannelMaxFrontDistance[nChannel] = int32(fMax);
- }
- }
-}
-
-void
-cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
-{
- ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-
- if ( nChannel == CHANNEL2D )
- {
- 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.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
- && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
- {
- nChannelVolume[nChannel] >>= 2;
- }
-
- uint32 channelVol = m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14;
- if ( ChannelSample[nChannel] >= SFX_CAR_REV_1 && SFX_CAR_IDLE_10 >= ChannelSample[nChannel] ) // nice hack
- channelVol >>= 1;
-
- if ( alChannel[nChannel] )
- {
- if ( currentChannelVolume[nChannel] != channelVol )
- {
- ALfloat gain = ALfloat(channelVol) / MAX_VOLUME;
- alSourcef(alChannel[nChannel], AL_GAIN, gain);
- currentChannelVolume[nChannel] = channelVol;
- }
- }
- }
-}
-
-void
-cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan)
-{
- ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
- ; // NOIMP
-}
-
-void
-cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq)
-{
- ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-
- if ( alChannel[nChannel] )
- {
- if ( currentChannelFrequency[nChannel] != nFreq )
- {
- ALfloat pitch = ALfloat(nFreq) / MAX_FREQ;
- alSourcef(alChannel[nChannel], AL_PITCH, pitch);
- currentChannelFrequency[nChannel] = nFreq;
-
- if ( Abs(1.0f - pitch) < 0.01f )
- ChannelPitch[nChannel] = 1.0f;
- else
- ChannelPitch[nChannel] = pitch;
- }
- }
-}
-
-void
-cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd)
-{
- ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-
- ; // NOIMP
-}
-
-void
-cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount)
-{
- ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-
- if ( nLoopCount != 0 )
- alSourcei(alChannel[nChannel], AL_LOOPING, AL_FALSE);
- else
- alSourcei(alChannel[nChannel], AL_LOOPING, AL_TRUE);
-}
-
-bool
-cSampleManager::GetChannelUsedFlag(uint32 nChannel)
-{
- ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-
- if ( alChannel[nChannel] )
- {
- ALint sourceState;
- alGetSourcei(alChannel[nChannel], AL_SOURCE_STATE, &sourceState);
- return sourceState == AL_PLAYING;
- }
-
- return false;
-}
-
-void
-cSampleManager::StartChannel(uint32 nChannel)
-{
- ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-
- if ( alChannel[nChannel] )
- {
- if ( ChannelSample[nChannel] > SAMPLEBANK_END ) // PED's Bank
- {
- if ( ChannelPitch[nChannel] != 1.0f )
- ChannelPitch[nChannel] = 1.0f;
- }
-
- alSourcef (alChannel[nChannel], AL_PITCH, ChannelPitch[nChannel]);
- alSourcePlay(alChannel[nChannel]);
- }
-}
-
-void
-cSampleManager::StopChannel(uint32 nChannel)
-{
- ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-
- if ( alChannel[nChannel] )
- {
- alSourceStop(alChannel[nChannel]);
-
- currentChannelVolume [nChannel] = -1;
- currentChannelFrequency [nChannel] = -1;
- currentChannelMaxFrontDistance[nChannel] = -1;
- ChannelPitch [nChannel] = 1.0f;
- }
-}
-
-void
-cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
-{
- char filename[256];
-
- ASSERT( nStream < MAX_STREAMS );
-
- if ( nFile < TOTAL_STREAMED_SOUNDS )
- {
- if ( mp3Stream[nStream] )
- {
- delete mp3Stream[nStream];
- mp3Stream[nStream] = NULL;
- }
-
- strcpy(filename, StreamedNameTable[nFile]);
-
- MP3Stream *stream = new MP3Stream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
- ASSERT(stream != NULL);
-
- mp3Stream[nStream] = stream;
-
- if ( stream->m_bIsOpened )
- {
- ;
- }
- else
- {
- delete stream;
- mp3Stream[nStream] = NULL;
- }
- }
-}
-
-void
-cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream)
-{
- ASSERT( nStream < MAX_STREAMS );
-
- MP3Stream *stream = mp3Stream[nStream];
-
- if ( stream )
- {
- if ( nPauseFlag != 0 )
- {
- if ( !stream->m_bIsPaused )
- {
- alSourcePause(stream->m_alSource);
- stream->m_bIsPaused = true;
- }
- }
- else
- {
- if ( stream->m_bIsPaused )
- {
- alSourcef(stream->m_alSource, AL_PITCH, 1.0f);
- alSourcePlay(stream->m_alSource);
- stream->m_bIsPaused = false;
- }
- }
- }
-}
-
-void
-cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
-{
- ASSERT( nStream < MAX_STREAMS );
-
- MP3Stream *stream = mp3Stream[nStream];
-
- if ( stream )
- {
- stream->Initialize();
- if ( stream->m_bIsOpened )
- {
- //NOTE: set pos here on mobile
-
- if ( stream->FillBuffers() != 0 )
- {
- alSourcef(stream->m_alSource, AL_PITCH, 1.0f);
- alSourcePlay(stream->m_alSource);
- stream->m_bIsFree = false;
- }
- }
- }
-}
-
-bool
-cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
-{
- char filename[256];
-
- ASSERT( nStream < MAX_STREAMS );
-
- if ( nFile < TOTAL_STREAMED_SOUNDS )
- {
- if ( mp3Stream[nStream] )
- {
- delete mp3Stream[nStream];
- mp3Stream[nStream] = NULL;
- }
-
- strcpy(filename, StreamedNameTable[nFile]);
-
- MP3Stream *stream = new MP3Stream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
- ASSERT(stream != NULL);
-
- mp3Stream[nStream] = stream;
-
- if ( stream->m_bIsOpened )
- {
- stream->Initialize();
- nStreamLength[nFile] = stream->m_nLength;
- //MusicManager.SetTrackInfoLength(nFile, stream->m_nLength);
-
- if ( stream->m_bIsOpened )
- {
- if ( nPos != 0 )
- {
- stream->SetPos(nPos);
- }
-
- if ( stream->FillBuffers() != 0 )
- {
- alSourcef(stream->m_alSource, AL_PITCH, 1.0f);
- alSourcePlay(stream->m_alSource);
- stream->m_bIsFree = false;
- }
- }
-
- return true;
- }
- else
- {
- delete stream;
- mp3Stream[nStream] = NULL;
- }
- }
-
- return false;
-}
-
-void
-cSampleManager::StopStreamedFile(uint8 nStream)
-{
- ASSERT( nStream < MAX_STREAMS );
-
- MP3Stream *stream = mp3Stream[nStream];
-
- if ( stream )
- {
- delete stream;
- mp3Stream[nStream] = NULL;
- }
-}
-
-int32
-cSampleManager::GetStreamedFilePosition(uint8 nStream)
-{
- ASSERT( nStream < MAX_STREAMS );
-
- MP3Stream *stream = mp3Stream[nStream];
-
- if ( stream )
- {
- return (ftell(stream->m_fpFile) * 8) / stream->m_nBitRate;
- }
-
- return 0;
-}
-
-void
-cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream)
-{
- ASSERT( nStream < MAX_STREAMS );
-
- if ( nVolume > MAX_VOLUME )
- nVolume = MAX_VOLUME;
-
- if ( nPan > MAX_VOLUME )
- nPan = MAX_VOLUME;
-
- nStreamVolume[nStream] = m_nMusicFadeVolume * nVolume;
- nStreamPan [nStream] = nPan;
-
- MP3Stream *stream = mp3Stream[nStream];
-
- if ( stream )
- {
- uint32 vol;
- if ( nEffectFlag )
- vol = m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14;
- else
- vol = m_nMusicFadeVolume*nVolume*m_nMusicVolume >> 14;
-
- if ( stream->m_nVolume != vol )
- {
- if ( stream->m_bIsOpened )
- {
- ALuint source = stream->m_alSource;
- if ( source )
- {
- ALfloat gain = ALfloat(vol) / MAX_VOLUME;
- alSourcef(source, AL_GAIN, gain);
- stream = mp3Stream[nStream];
- }
- }
-
- stream->m_nVolume = vol;
- }
- }
-}
-
-int32
-cSampleManager::GetStreamedFileLength(uint8 nStream)
-{
- ASSERT( nStream < TOTAL_STREAMED_SOUNDS );
-
- return nStreamLength[nStream];
-}
-
-bool
-cSampleManager::IsStreamPlaying(uint8 nStream)
-{
- ASSERT( nStream < MAX_STREAMS );
-
- MP3Stream *stream = mp3Stream[nStream];
-
- if ( stream && stream->m_bIsOpened && !stream->m_bIsPaused )
- {
- ALint sourceState;
- alGetSourcei(stream->m_alSource, AL_SOURCE_STATE, &sourceState);
- if ( !stream->m_bIsFree || sourceState == AL_PLAYING )
- return true;
- }
-
- return false;
-}
-
-void
-cSampleManager::Service(void)
-{
- for ( int32 i = 0; i < MAX_STREAMS; i++ )
- {
- if ( mp3Stream[i] )
- mp3Stream[i]->Update();
- }
-
- UpdateSoundBuffers();
-}
-
-bool
-cSampleManager::InitialiseSampleBanks(void)
-{
- int32 nBank = SAMPLEBANK_MAIN;
-
- 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);
- int32 _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[SAMPLEBANK_MAIN] + i )
- {
- nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset;
- nBank++;
- }
- }
-
- nSampleBankSize[SAMPLEBANK_MAIN] = nSampleBankDiscStartOffset[SAMPLEBANK_PED] - nSampleBankDiscStartOffset[SAMPLEBANK_MAIN];
- nSampleBankSize[SAMPLEBANK_PED] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SAMPLEBANK_PED];
-
- return true;
-}
-
-/*
-sub_1D8D40
-PreloadSoundBank(tSample *,uchar)
-CheckOpenALChannels(void)
-*/
-
-void MP3Stream::Initialize(void)
-{
- if ( !m_bIsOpened )
- return;
-
- mpg123_format_none(m_pMPG);
-
- mpg123_format(m_pMPG, 11000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16);
- mpg123_format(m_pMPG, 24000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16);
- mpg123_format(m_pMPG, 32000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16);
- mpg123_format(m_pMPG, 44100, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16);
-
- if ( mpg123_open_feed(m_pMPG) != MPG123_OK )
- return;
-
- const uint32 CHUNK_SIZE = 1024*5;
-
- if ( fread(m_pBuf, 1, CHUNK_SIZE, m_fpFile) != CHUNK_SIZE )
- {
- Delete();
- return;
- }
-
- m_nBufSize -= CHUNK_SIZE;
-
- mpg123_feed(m_pMPG, m_pBuf, CHUNK_SIZE);
-
- if ( mpg123_getformat(m_pMPG, &m_nRate, &m_nChannels, &m_nEncoding) != MPG123_OK )
- {
- Delete();
- return;
- }
-
- mpg123_frameinfo info;
- if ( mpg123_info(m_pMPG, &info) != MPG123_OK )
- {
- Delete();
- return;
- }
-
- m_nBitRate = info.bitrate;
- m_nLength = 8 * m_nLengthInBytes / info.bitrate;
- m_nBlockSize = mpg123_outblock(m_pMPG);
- m_nNumBlocks = 5;
- m_pBlocks = (unsigned char *)malloc(m_nNumBlocks * m_nBlockSize);
-}
-
-bool MP3Stream::FillBuffer(ALuint alBuffer)
-{
- size_t done;
-
- uint8 *pBlockBuff = (uint8 *)m_pBlocks;
-
- bool fail = !(m_nBufSize > 1);
-
- int err = mpg123_read(m_pMPG, m_pBlocks, m_nBlockSize, &done);
- if ( alBuffer == 0 )
- {
- if ( err == MPG123_OK )
- {
- while ( mpg123_read(m_pMPG, pBlockBuff, m_nBlockSize, &done) == MPG123_OK )
- ;
- }
-
- return true;
- }
-
- int32 blocks = 0;
- for ( blocks = 0; blocks < m_nNumBlocks; blocks++ )
- {
- if ( err == MPG123_NEED_MORE )
- {
- if ( fail )
- break;
-
- size_t readSize = m_nBufSize;
- if ( readSize > 0x4000 )
- {
- if ( fread(m_pBuf, 1, 0x4000, m_fpFile) != 0x4000 )
- {
- fail = true;
- TRACE("MP3 ************* : MP3 read unsuccessful mid file, stopping queuing");
- break;
- }
-
- m_nBufSize -= 0x4000;
- mpg123_feed(m_pMPG, m_pBuf, 0x4000);
- }
- else
- {
- if ( fread(m_pBuf, 1, readSize, m_fpFile) != readSize )
- {
- fail = true;
- break;
- }
-
- m_nBufSize -= readSize;
- mpg123_feed(m_pMPG, m_pBuf, readSize);
- }
- }
- else if ( err == MPG123_OK )
- {
- pBlockBuff += m_nBlockSize;
- }
- else
- {
- fail = true;
- break;
- }
-
- err = mpg123_read(m_pMPG, pBlockBuff, m_nBlockSize, &done);
- }
-
- if ( blocks != 0 )
- {
- if ( m_nChannels == 1 )
- alBufferData(alBuffer, AL_FORMAT_MONO16, m_pBlocks, m_nBlockSize*blocks, m_nRate);
- else
- alBufferData(alBuffer, AL_FORMAT_STEREO16, m_pBlocks, m_nBlockSize*blocks, m_nRate);
- }
-
- if ( fail && blocks < m_nNumBlocks )
- m_bIsFree = true;
-
- return blocks != 0;
-}
-
-void MP3Stream::Update(void)
-{
- if ( !m_bIsOpened )
- return;
-
- if ( m_bIsFree )
- return;
-
- if ( !m_bIsPaused )
- {
- ALint sourceState;
- ALint buffersProcessed = 0;
-
- alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
- alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed);
-
- ALint looping = AL_FALSE;
- alGetSourcei(m_alSource, AL_LOOPING, &looping);
-
- if ( looping == AL_TRUE )
- {
- TRACE("stream set looping");
- alSourcei(m_alSource, AL_LOOPING, AL_TRUE);
- }
-
- while( buffersProcessed-- )
- {
- ALuint buffer;
-
- alSourceUnqueueBuffers(m_alSource, 1, &buffer);
-
- if ( !m_bIsFree && FillBuffer(buffer) )
- alSourceQueueBuffers(m_alSource, 1, &buffer);
- }
-
- if ( sourceState != AL_PLAYING )
- {
- alSourcef(m_alSource, AL_PITCH, 1.0f);
- alSourcePlay(m_alSource);
- }
- }
-}
-
-void MP3Stream::SetPos(uint32 nPos)
-{
- uint32 pos = nPos;
- if ( nPos > m_nLength )
- pos %= m_nLength;
-
- uint32 blockPos = m_nBitRate * pos / 8;
- if ( blockPos > m_nLengthInBytes )
- blockPos %= m_nLengthInBytes;
-
- fseek(m_fpFile, blockPos, SEEK_SET);
-
- size_t done;
- while ( mpg123_read(m_pMPG, m_pBlocks, m_nBlockSize, &done) == MPG123_OK )
- ;
-}
-
-int32 MP3Stream::FillBuffers()
-{
- int32 i = 0;
- for ( i = 0; i < ARRAY_SIZE(m_alBuffers); i++ )
- {
- if ( !FillBuffer(m_alBuffers[i]) )
- break;
- alSourceQueueBuffers(m_alSource, 1, &m_alBuffers[i]);
- }
-
- return i;
-}
-
-MP3Stream::MP3Stream(char *filename, ALuint source, ALuint *buffers)
-{
- strcpy(m_aFilename, filename);
- memset(m_alBuffers, 0, sizeof(m_alBuffers));
- m_alSource = source;
- memcpy(m_alBuffers, buffers, sizeof(m_alBuffers));
- m_nVolume = -1;
- m_pBlocks = NULL;
- m_pBuf = NULL;
- m_pMPG = NULL;
- m_bIsPaused = false;
- m_bIsOpened = true;
- m_bIsFree = true;
- m_fpFile = fopen(m_aFilename, "rb");
-
- if ( m_fpFile )
- {
- m_nBufSize = filelength(fileno(m_fpFile));
- m_nLengthInBytes = m_nBufSize;
- m_pMPG = mpg123_new(NULL, NULL);
- m_pBuf = (unsigned char *)malloc(0x4000);
- }
- else
- {
- m_bIsOpened = false;
- Delete();
- }
-}
-
-void MP3Stream::Delete()
-{
- if ( m_pMPG )
- {
- mpg123_delete(m_pMPG);
- m_pMPG = NULL;
- }
-
- if ( m_fpFile )
- {
- fclose(m_fpFile);
- m_fpFile = NULL;
- }
-
- if ( m_alSource )
- {
- ALint sourceState = AL_STOPPED;
- alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
- if (sourceState != AL_STOPPED )
- alSourceStop(m_alSource);
-
- ALint buffersQueued;
- alGetSourcei(m_alSource, AL_BUFFERS_QUEUED, &buffersQueued);
-
- ALuint value;
- while (buffersQueued--)
- alSourceUnqueueBuffers(m_alSource, 1, &value);
-
- m_alSource = 0;
- }
-
- if ( m_pBlocks )
- {
- free(m_pBlocks);
- m_pBlocks = NULL;
- }
-
- if ( m_pBuf )
- {
- free(m_pBuf);
- m_pBuf = NULL;
- }
-
- m_bIsOpened = false;
-} \ No newline at end of file
diff --git a/src/audio/openal/samp_oal.h b/src/audio/openal/samp_oal.h
deleted file mode 100644
index 8bbdbcc9..00000000
--- a/src/audio/openal/samp_oal.h
+++ /dev/null
@@ -1,340 +0,0 @@
-#pragma once
-#include "common.h"
-#include "AudioSamples.h"
-
-#define MAX_VOLUME 127
-//#define MAX_FREQ 22050
-#define MAX_FREQ 32000
-
-struct tSample {
- int32 nOffset;
- uint32 nSize;
- int32 nFrequency;
- int32 nLoopStart;
- int32 nLoopEnd;
-};
-
-enum
-{
- SAMPLEBANK_MAIN,
- SAMPLEBANK_PED,
- MAX_SAMPLEBANKS,
- SAMPLEBANK_INVALID
-};
-
-#define MAX_PEDSFX 7
-#define PED_BLOCKSIZE 79000
-
-
-//#define MAXCHANNELS 21 android
-#define MAXCHANNELS 28
-#define MAX2DCHANNELS 1
-#define CHANNEL2D MAXCHANNELS
-
-#define MAX_STREAMS 2
-
-struct ALCdevice_struct;
-struct ALCcontext_struct;
-typedef struct ALCdevice_struct ALCdevice;
-typedef struct ALCcontext_struct ALCcontext;
-
-class cSampleManager
-{
- int field_0;
- ALCdevice *m_pDevice;
- ALCcontext *m_pContext;
-
- uint8 m_nEffectsVolume;
- uint8 m_nMusicVolume;
- uint8 m_nEffectsFadeVolume;
- uint8 m_nMusicFadeVolume;
- uint8 m_nMonoMode;
- char _pad0[3];
- tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
-
-public:
-
-
-
- cSampleManager(void);
- ~cSampleManager(void);
-
- void SetSpeakerConfig(int32 nConfig);
- uint32 GetMaximumSupportedChannels(void);
-
- uint32 GetNum3DProvidersAvailable();
- void SetNum3DProvidersAvailable(uint32 num);
-
- char *Get3DProviderName(uint8 id);
- void Set3DProviderName(uint8 id, char *name);
-
- int8 GetCurrent3DProviderIndex(void);
- int8 SetCurrent3DProvider(uint8 which);
-
- bool IsMP3RadioChannelAvailable(void);
-
- void ReleaseDigitalHandle (void);
- void ReacquireDigitalHandle(void);
-
- bool Initialise(void);
- void Terminate (void);
-
- void UpdateSoundBuffers(void);
-
- bool CheckForAnAudioFileOnCD(void);
- char GetCDAudioDriveLetter (void);
-
- void UpdateEffectsVolume(void);
-
- void SetEffectsMasterVolume(uint8 nVolume);
- void SetMusicMasterVolume (uint8 nVolume);
- void SetEffectsFadeVolume (uint8 nVolume);
- void SetMusicFadeVolume (uint8 nVolume);
- void SetMonoMode (uint8 nMode);
-
- bool LoadSampleBank (uint8 nBank);
- void UnloadSampleBank (uint8 nBank);
- bool IsSampleBankLoaded(uint8 nBank);
-
- bool IsPedCommentLoaded(uint32 nComment);
- bool LoadPedComment (uint32 nComment);
- int32 GetBankContainingSound(uint32 offset);
-
- int32 _GetPedCommentSlot(uint32 nComment);
-
- int32 GetSampleBaseFrequency (uint32 nSample);
- int32 GetSampleLoopStartOffset(uint32 nSample);
- int32 GetSampleLoopEndOffset (uint32 nSample);
- uint32 GetSampleLength (uint32 nSample);
-
- bool UpdateReverb(void);
-
- void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag);
- bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank);
- void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
- void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ);
- void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin);
- void SetChannelVolume (uint32 nChannel, uint32 nVolume);
- void SetChannelPan (uint32 nChannel, uint32 nPan);
- void SetChannelFrequency (uint32 nChannel, uint32 nFreq);
- void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd);
- void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount);
- bool GetChannelUsedFlag (uint32 nChannel);
- void StartChannel (uint32 nChannel);
- void StopChannel (uint32 nChannel);
-
- void PreloadStreamedFile (uint8 nFile, uint8 nStream);
- void PauseStream (uint8 nPauseFlag, uint8 nStream);
- void StartPreloadedStreamedFile (uint8 nStream);
- bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream);
- void StopStreamedFile (uint8 nStream);
- int32 GetStreamedFilePosition (uint8 nStream);
- void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream);
- int32 GetStreamedFileLength (uint8 nStream);
- bool IsStreamPlaying (uint8 nStream);
- void Service(void);
- bool InitialiseSampleBanks(void);
-};
-
-extern cSampleManager SampleManager;
-extern int32 BankStartOffset[MAX_SAMPLEBANKS];
-
-static char StreamedNameTable[][25]=
-{
- "AUDIO\\HEAD.MP3",
- "AUDIO\\CLASS.MP3",
- "AUDIO\\KJAH.MP3",
- "AUDIO\\RISE.MP3",
- "AUDIO\\LIPS.MP3",
- "AUDIO\\GAME.MP3",
- "AUDIO\\MSX.MP3",
- "AUDIO\\FLASH.MP3",
- "AUDIO\\CHAT.MP3",
- "AUDIO\\HEAD.MP3",
- "AUDIO\\POLICE.MP3",
- "AUDIO\\CITY.MP3",
- "AUDIO\\WATER.MP3",
- "AUDIO\\COMOPEN.MP3",
- "AUDIO\\SUBOPEN.MP3",
- "AUDIO\\JB.MP3",
- "AUDIO\\BET.MP3",
- "AUDIO\\L1_LG.MP3",
- "AUDIO\\L2_DSB.MP3",
- "AUDIO\\L3_DM.MP3",
- "AUDIO\\L4_PAP.MP3",
- "AUDIO\\L5_TFB.MP3",
- "AUDIO\\J0_DM2.MP3",
- "AUDIO\\J1_LFL.MP3",
- "AUDIO\\J2_KCL.MP3",
- "AUDIO\\J3_VH.MP3",
- "AUDIO\\J4_ETH.MP3",
- "AUDIO\\J5_DST.MP3",
- "AUDIO\\J6_TBJ.MP3",
- "AUDIO\\T1_TOL.MP3",
- "AUDIO\\T2_TPU.MP3",
- "AUDIO\\T3_MAS.MP3",
- "AUDIO\\T4_TAT.MP3",
- "AUDIO\\T5_BF.MP3",
- "AUDIO\\S0_MAS.MP3",
- "AUDIO\\S1_PF.MP3",
- "AUDIO\\S2_CTG.MP3",
- "AUDIO\\S3_RTC.MP3",
- "AUDIO\\S5_LRQ.MP3",
- "AUDIO\\S4_BDBA.MP3",
- "AUDIO\\S4_BDBB.MP3",
- "AUDIO\\S2_CTG2.MP3",
- "AUDIO\\S4_BDBD.MP3",
- "AUDIO\\S5_LRQB.MP3",
- "AUDIO\\S5_LRQC.MP3",
- "AUDIO\\A1_SSO.MP3",
- "AUDIO\\A2_PP.MP3",
- "AUDIO\\A3_SS.MP3",
- "AUDIO\\A4_PDR.MP3",
- "AUDIO\\A5_K2FT.MP3",
- "AUDIO\\K1_KBO.MP3",
- "AUDIO\\K2_GIS.MP3",
- "AUDIO\\K3_DS.MP3",
- "AUDIO\\K4_SHI.MP3",
- "AUDIO\\K5_SD.MP3",
- "AUDIO\\R0_PDR2.MP3",
- "AUDIO\\R1_SW.MP3",
- "AUDIO\\R2_AP.MP3",
- "AUDIO\\R3_ED.MP3",
- "AUDIO\\R4_GF.MP3",
- "AUDIO\\R5_PB.MP3",
- "AUDIO\\R6_MM.MP3",
- "AUDIO\\D1_STOG.MP3",
- "AUDIO\\D2_KK.MP3",
- "AUDIO\\D3_ADO.MP3",
- "AUDIO\\D5_ES.MP3",
- "AUDIO\\D7_MLD.MP3",
- "AUDIO\\D4_GTA.MP3",
- "AUDIO\\D4_GTA2.MP3",
- "AUDIO\\D6_STS.MP3",
- "AUDIO\\A6_BAIT.MP3",
- "AUDIO\\A7_ETG.MP3",
- "AUDIO\\A8_PS.MP3",
- "AUDIO\\A9_ASD.MP3",
- "AUDIO\\K4_SHI2.MP3",
- "AUDIO\\C1_TEX.MP3",
- "AUDIO\\EL_PH1.MP3",
- "AUDIO\\EL_PH2.MP3",
- "AUDIO\\EL_PH3.MP3",
- "AUDIO\\EL_PH4.MP3",
- "AUDIO\\YD_PH1.MP3",
- "AUDIO\\YD_PH2.MP3",
- "AUDIO\\YD_PH3.MP3",
- "AUDIO\\YD_PH4.MP3",
- "AUDIO\\HD_PH1.MP3",
- "AUDIO\\HD_PH2.MP3",
- "AUDIO\\HD_PH3.MP3",
- "AUDIO\\HD_PH4.MP3",
- "AUDIO\\HD_PH5.MP3",
- "AUDIO\\MT_PH1.MP3",
- "AUDIO\\MT_PH2.MP3",
- "AUDIO\\MT_PH3.MP3",
- "AUDIO\\MT_PH4.MP3",
- "AUDIO\\MISCOM.MP3",
- "AUDIO\\END.MP3",
- "AUDIO\\lib_a1.MP3",
- "AUDIO\\lib_a2.MP3",
- "AUDIO\\lib_a.MP3",
- "AUDIO\\lib_b.MP3",
- "AUDIO\\lib_c.MP3",
- "AUDIO\\lib_d.MP3",
- "AUDIO\\l2_a.MP3",
- "AUDIO\\j4t_1.MP3",
- "AUDIO\\j4t_2.MP3",
- "AUDIO\\j4t_3.MP3",
- "AUDIO\\j4t_4.MP3",
- "AUDIO\\j4_a.MP3",
- "AUDIO\\j4_b.MP3",
- "AUDIO\\j4_c.MP3",
- "AUDIO\\j4_d.MP3",
- "AUDIO\\j4_e.MP3",
- "AUDIO\\j4_f.MP3",
- "AUDIO\\j6_1.MP3",
- "AUDIO\\j6_a.MP3",
- "AUDIO\\j6_b.MP3",
- "AUDIO\\j6_c.MP3",
- "AUDIO\\j6_d.MP3",
- "AUDIO\\t4_a.MP3",
- "AUDIO\\s1_a.MP3",
- "AUDIO\\s1_a1.MP3",
- "AUDIO\\s1_b.MP3",
- "AUDIO\\s1_c.MP3",
- "AUDIO\\s1_c1.MP3",
- "AUDIO\\s1_d.MP3",
- "AUDIO\\s1_e.MP3",
- "AUDIO\\s1_f.MP3",
- "AUDIO\\s1_g.MP3",
- "AUDIO\\s1_h.MP3",
- "AUDIO\\s1_i.MP3",
- "AUDIO\\s1_j.MP3",
- "AUDIO\\s1_k.MP3",
- "AUDIO\\s1_l.MP3",
- "AUDIO\\s3_a.MP3",
- "AUDIO\\s3_b.MP3",
- "AUDIO\\el3_a.MP3",
- "AUDIO\\mf1_a.MP3",
- "AUDIO\\mf2_a.MP3",
- "AUDIO\\mf3_a.MP3",
- "AUDIO\\mf3_b.MP3",
- "AUDIO\\mf3_b1.MP3",
- "AUDIO\\mf3_c.MP3",
- "AUDIO\\mf4_a.MP3",
- "AUDIO\\mf4_b.MP3",
- "AUDIO\\mf4_c.MP3",
- "AUDIO\\a1_a.MP3",
- "AUDIO\\a3_a.MP3",
- "AUDIO\\a5_a.MP3",
- "AUDIO\\a4_a.MP3",
- "AUDIO\\a4_b.MP3",
- "AUDIO\\a4_c.MP3",
- "AUDIO\\a4_d.MP3",
- "AUDIO\\k1_a.MP3",
- "AUDIO\\k3_a.MP3",
- "AUDIO\\r1_a.MP3",
- "AUDIO\\r2_a.MP3",
- "AUDIO\\r2_b.MP3",
- "AUDIO\\r2_c.MP3",
- "AUDIO\\r2_d.MP3",
- "AUDIO\\r2_e.MP3",
- "AUDIO\\r2_f.MP3",
- "AUDIO\\r2_g.MP3",
- "AUDIO\\r2_h.MP3",
- "AUDIO\\r5_a.MP3",
- "AUDIO\\r6_a.MP3",
- "AUDIO\\r6_a1.MP3",
- "AUDIO\\r6_b.MP3",
- "AUDIO\\lo2_a.MP3",
- "AUDIO\\lo6_a.MP3",
- "AUDIO\\yd2_a.MP3",
- "AUDIO\\yd2_b.MP3",
- "AUDIO\\yd2_c.MP3",
- "AUDIO\\yd2_c1.MP3",
- "AUDIO\\yd2_d.MP3",
- "AUDIO\\yd2_e.MP3",
- "AUDIO\\yd2_f.MP3",
- "AUDIO\\yd2_g.MP3",
- "AUDIO\\yd2_h.MP3",
- "AUDIO\\yd2_ass.MP3",
- "AUDIO\\yd2_ok.MP3",
- "AUDIO\\h5_a.MP3",
- "AUDIO\\h5_b.MP3",
- "AUDIO\\h5_c.MP3",
- "AUDIO\\ammu_a.MP3",
- "AUDIO\\ammu_b.MP3",
- "AUDIO\\ammu_c.MP3",
- "AUDIO\\door_1.MP3",
- "AUDIO\\door_2.MP3",
- "AUDIO\\door_3.MP3",
- "AUDIO\\door_4.MP3",
- "AUDIO\\door_5.MP3",
- "AUDIO\\door_6.MP3",
- "AUDIO\\t3_a.MP3",
- "AUDIO\\t3_b.MP3",
- "AUDIO\\t3_c.MP3",
- "AUDIO\\k1_b.MP3",
- "AUDIO\\cat1.MP3"
-};
diff --git a/src/audio/sampman.cpp b/src/audio/sampman.cpp
deleted file mode 100644
index aa6b67dc..00000000
--- a/src/audio/sampman.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-#include "common.h"
-#ifndef OPENAL
-#include "miles\sampman_mss.cpp"
-#else
-#include "openal\samp_oal.cpp"
-#endif \ No newline at end of file
diff --git a/src/audio/sampman.h b/src/audio/sampman.h
index f454d236..d3c82943 100644
--- a/src/audio/sampman.h
+++ b/src/audio/sampman.h
@@ -1,7 +1,345 @@
#pragma once
#include "common.h"
-#ifndef OPENAL
-#include "miles\sampman_mss.h"
-#else
-#include "openal\samp_oal.h"
-#endif \ No newline at end of file
+#include "AudioSamples.h"
+
+#define MAX_VOLUME 127
+#define MAX_FREQ 22050
+
+struct tSample {
+ int32 nOffset;
+ uint32 nSize;
+ int32 nFrequency;
+ int32 nLoopStart;
+ int32 nLoopEnd;
+};
+
+enum
+{
+ SAMPLEBANK_MAIN,
+ SAMPLEBANK_PED,
+ MAX_SAMPLEBANKS,
+ SAMPLEBANK_INVALID
+};
+
+#define MAX_PEDSFX 7
+#define PED_BLOCKSIZE 79000
+
+#define MAXPROVIDERS 64
+
+#define MAXCHANNELS 28
+#define MAXCHANNELS_SURROUND 24
+#define MAX2DCHANNELS 1
+#define CHANNEL2D MAXCHANNELS
+
+#define MAX_STREAMS 2
+
+#define DIGITALRATE 32000
+#define DIGITALBITS 16
+#define DIGITALCHANNELS 2
+
+#define MAX_DIGITAL_MIXER_CHANNELS 32
+
+class cSampleManager
+{
+ uint8 m_nEffectsVolume;
+ uint8 m_nMusicVolume;
+ uint8 m_nEffectsFadeVolume;
+ uint8 m_nMusicFadeVolume;
+ uint8 m_nMonoMode;
+ char unk;
+ char m_szCDRomRootPath[80];
+ bool m_bInitialised;
+ uint8 m_nNumberOfProviders;
+ char *m_aAudioProviders[MAXPROVIDERS];
+ tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
+
+public:
+
+
+
+ cSampleManager(void);
+ ~cSampleManager(void);
+
+ void SetSpeakerConfig(int32 nConfig);
+ uint32 GetMaximumSupportedChannels(void);
+
+ uint32 GetNum3DProvidersAvailable(void);
+ void SetNum3DProvidersAvailable(uint32 num);
+
+ char *Get3DProviderName(uint8 id);
+ void Set3DProviderName(uint8 id, char *name);
+
+ int8 GetCurrent3DProviderIndex(void);
+ int8 SetCurrent3DProvider(uint8 which);
+
+ bool IsMP3RadioChannelAvailable(void);
+
+ void ReleaseDigitalHandle (void);
+ void ReacquireDigitalHandle(void);
+
+ bool Initialise(void);
+ void Terminate (void);
+
+#ifdef AUDIO_OAL
+ void UpdateSoundBuffers(void);
+#endif
+
+ bool CheckForAnAudioFileOnCD(void);
+ char GetCDAudioDriveLetter (void);
+
+ void UpdateEffectsVolume(void);
+
+ void SetEffectsMasterVolume(uint8 nVolume);
+ void SetMusicMasterVolume (uint8 nVolume);
+ void SetEffectsFadeVolume (uint8 nVolume);
+ void SetMusicFadeVolume (uint8 nVolume);
+ void SetMonoMode (uint8 nMode);
+
+ bool LoadSampleBank (uint8 nBank);
+ void UnloadSampleBank (uint8 nBank);
+ bool IsSampleBankLoaded(uint8 nBank);
+
+ bool IsPedCommentLoaded(uint32 nComment);
+ bool LoadPedComment (uint32 nComment);
+ int32 GetBankContainingSound(uint32 offset);
+
+ int32 _GetPedCommentSlot(uint32 nComment);
+
+ int32 GetSampleBaseFrequency (uint32 nSample);
+ int32 GetSampleLoopStartOffset(uint32 nSample);
+ int32 GetSampleLoopEndOffset (uint32 nSample);
+ uint32 GetSampleLength (uint32 nSample);
+
+ bool UpdateReverb(void);
+
+ void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag);
+ bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank);
+ void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
+ void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ);
+ void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin);
+ void SetChannelVolume (uint32 nChannel, uint32 nVolume);
+ void SetChannelPan (uint32 nChannel, uint32 nPan);
+ void SetChannelFrequency (uint32 nChannel, uint32 nFreq);
+ void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd);
+ void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount);
+ bool GetChannelUsedFlag (uint32 nChannel);
+ void StartChannel (uint32 nChannel);
+ void StopChannel (uint32 nChannel);
+
+ void PreloadStreamedFile (uint8 nFile, uint8 nStream);
+ void PauseStream (uint8 nPauseFlag, uint8 nStream);
+ void StartPreloadedStreamedFile (uint8 nStream);
+ bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream);
+ void StopStreamedFile (uint8 nStream);
+ int32 GetStreamedFilePosition (uint8 nStream);
+ void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream);
+ int32 GetStreamedFileLength (uint8 nStream);
+ bool IsStreamPlaying (uint8 nStream);
+#ifdef AUDIO_OAL
+ void Service(void);
+#endif
+ bool InitialiseSampleBanks(void);
+};
+
+extern cSampleManager SampleManager;
+extern uint32 BankStartOffset[MAX_SAMPLEBANKS];
+
+static char StreamedNameTable[][25]=
+{
+ "AUDIO\\HEAD.WAV",
+ "AUDIO\\CLASS.WAV",
+ "AUDIO\\KJAH.WAV",
+ "AUDIO\\RISE.WAV",
+ "AUDIO\\LIPS.WAV",
+ "AUDIO\\GAME.WAV",
+ "AUDIO\\MSX.WAV",
+ "AUDIO\\FLASH.WAV",
+ "AUDIO\\CHAT.WAV",
+ "AUDIO\\HEAD.WAV",
+ "AUDIO\\POLICE.WAV",
+ "AUDIO\\CITY.WAV",
+ "AUDIO\\WATER.WAV",
+ "AUDIO\\COMOPEN.WAV",
+ "AUDIO\\SUBOPEN.WAV",
+ "AUDIO\\JB.MP3",
+ "AUDIO\\BET.MP3",
+ "AUDIO\\L1_LG.MP3",
+ "AUDIO\\L2_DSB.MP3",
+ "AUDIO\\L3_DM.MP3",
+ "AUDIO\\L4_PAP.MP3",
+ "AUDIO\\L5_TFB.MP3",
+ "AUDIO\\J0_DM2.MP3",
+ "AUDIO\\J1_LFL.MP3",
+ "AUDIO\\J2_KCL.MP3",
+ "AUDIO\\J3_VH.MP3",
+ "AUDIO\\J4_ETH.MP3",
+ "AUDIO\\J5_DST.MP3",
+ "AUDIO\\J6_TBJ.MP3",
+ "AUDIO\\T1_TOL.MP3",
+ "AUDIO\\T2_TPU.MP3",
+ "AUDIO\\T3_MAS.MP3",
+ "AUDIO\\T4_TAT.MP3",
+ "AUDIO\\T5_BF.MP3",
+ "AUDIO\\S0_MAS.MP3",
+ "AUDIO\\S1_PF.MP3",
+ "AUDIO\\S2_CTG.MP3",
+ "AUDIO\\S3_RTC.MP3",
+ "AUDIO\\S5_LRQ.MP3",
+ "AUDIO\\S4_BDBA.MP3",
+ "AUDIO\\S4_BDBB.MP3",
+ "AUDIO\\S2_CTG2.MP3",
+ "AUDIO\\S4_BDBD.MP3",
+ "AUDIO\\S5_LRQB.MP3",
+ "AUDIO\\S5_LRQC.MP3",
+ "AUDIO\\A1_SSO.WAV",
+ "AUDIO\\A2_PP.WAV",
+ "AUDIO\\A3_SS.WAV",
+ "AUDIO\\A4_PDR.WAV",
+ "AUDIO\\A5_K2FT.WAV",
+ "AUDIO\\K1_KBO.MP3",
+ "AUDIO\\K2_GIS.MP3",
+ "AUDIO\\K3_DS.MP3",
+ "AUDIO\\K4_SHI.MP3",
+ "AUDIO\\K5_SD.MP3",
+ "AUDIO\\R0_PDR2.MP3",
+ "AUDIO\\R1_SW.MP3",
+ "AUDIO\\R2_AP.MP3",
+ "AUDIO\\R3_ED.MP3",
+ "AUDIO\\R4_GF.MP3",
+ "AUDIO\\R5_PB.MP3",
+ "AUDIO\\R6_MM.MP3",
+ "AUDIO\\D1_STOG.MP3",
+ "AUDIO\\D2_KK.MP3",
+ "AUDIO\\D3_ADO.MP3",
+ "AUDIO\\D5_ES.MP3",
+ "AUDIO\\D7_MLD.MP3",
+ "AUDIO\\D4_GTA.MP3",
+ "AUDIO\\D4_GTA2.MP3",
+ "AUDIO\\D6_STS.MP3",
+ "AUDIO\\A6_BAIT.WAV",
+ "AUDIO\\A7_ETG.WAV",
+ "AUDIO\\A8_PS.WAV",
+ "AUDIO\\A9_ASD.WAV",
+ "AUDIO\\K4_SHI2.MP3",
+ "AUDIO\\C1_TEX.MP3",
+ "AUDIO\\EL_PH1.MP3",
+ "AUDIO\\EL_PH2.MP3",
+ "AUDIO\\EL_PH3.MP3",
+ "AUDIO\\EL_PH4.MP3",
+ "AUDIO\\YD_PH1.MP3",
+ "AUDIO\\YD_PH2.MP3",
+ "AUDIO\\YD_PH3.MP3",
+ "AUDIO\\YD_PH4.MP3",
+ "AUDIO\\HD_PH1.MP3",
+ "AUDIO\\HD_PH2.MP3",
+ "AUDIO\\HD_PH3.MP3",
+ "AUDIO\\HD_PH4.MP3",
+ "AUDIO\\HD_PH5.MP3",
+ "AUDIO\\MT_PH1.MP3",
+ "AUDIO\\MT_PH2.MP3",
+ "AUDIO\\MT_PH3.MP3",
+ "AUDIO\\MT_PH4.MP3",
+ "AUDIO\\MISCOM.WAV",
+ "AUDIO\\END.MP3",
+ "AUDIO\\lib_a1.WAV",
+ "AUDIO\\lib_a2.WAV",
+ "AUDIO\\lib_a.WAV",
+ "AUDIO\\lib_b.WAV",
+ "AUDIO\\lib_c.WAV",
+ "AUDIO\\lib_d.WAV",
+ "AUDIO\\l2_a.WAV",
+ "AUDIO\\j4t_1.WAV",
+ "AUDIO\\j4t_2.WAV",
+ "AUDIO\\j4t_3.WAV",
+ "AUDIO\\j4t_4.WAV",
+ "AUDIO\\j4_a.WAV",
+ "AUDIO\\j4_b.WAV",
+ "AUDIO\\j4_c.WAV",
+ "AUDIO\\j4_d.WAV",
+ "AUDIO\\j4_e.WAV",
+ "AUDIO\\j4_f.WAV",
+ "AUDIO\\j6_1.WAV",
+ "AUDIO\\j6_a.WAV",
+ "AUDIO\\j6_b.WAV",
+ "AUDIO\\j6_c.WAV",
+ "AUDIO\\j6_d.WAV",
+ "AUDIO\\t4_a.WAV",
+ "AUDIO\\s1_a.WAV",
+ "AUDIO\\s1_a1.WAV",
+ "AUDIO\\s1_b.WAV",
+ "AUDIO\\s1_c.WAV",
+ "AUDIO\\s1_c1.WAV",
+ "AUDIO\\s1_d.WAV",
+ "AUDIO\\s1_e.WAV",
+ "AUDIO\\s1_f.WAV",
+ "AUDIO\\s1_g.WAV",
+ "AUDIO\\s1_h.WAV",
+ "AUDIO\\s1_i.WAV",
+ "AUDIO\\s1_j.WAV",
+ "AUDIO\\s1_k.WAV",
+ "AUDIO\\s1_l.WAV",
+ "AUDIO\\s3_a.WAV",
+ "AUDIO\\s3_b.WAV",
+ "AUDIO\\el3_a.WAV",
+ "AUDIO\\mf1_a.WAV",
+ "AUDIO\\mf2_a.WAV",
+ "AUDIO\\mf3_a.WAV",
+ "AUDIO\\mf3_b.WAV",
+ "AUDIO\\mf3_b1.WAV",
+ "AUDIO\\mf3_c.WAV",
+ "AUDIO\\mf4_a.WAV",
+ "AUDIO\\mf4_b.WAV",
+ "AUDIO\\mf4_c.WAV",
+ "AUDIO\\a1_a.WAV",
+ "AUDIO\\a3_a.WAV",
+ "AUDIO\\a5_a.WAV",
+ "AUDIO\\a4_a.WAV",
+ "AUDIO\\a4_b.WAV",
+ "AUDIO\\a4_c.WAV",
+ "AUDIO\\a4_d.WAV",
+ "AUDIO\\k1_a.WAV",
+ "AUDIO\\k3_a.WAV",
+ "AUDIO\\r1_a.WAV",
+ "AUDIO\\r2_a.WAV",
+ "AUDIO\\r2_b.WAV",
+ "AUDIO\\r2_c.WAV",
+ "AUDIO\\r2_d.WAV",
+ "AUDIO\\r2_e.WAV",
+ "AUDIO\\r2_f.WAV",
+ "AUDIO\\r2_g.WAV",
+ "AUDIO\\r2_h.WAV",
+ "AUDIO\\r5_a.WAV",
+ "AUDIO\\r6_a.WAV",
+ "AUDIO\\r6_a1.WAV",
+ "AUDIO\\r6_b.WAV",
+ "AUDIO\\lo2_a.WAV",
+ "AUDIO\\lo6_a.WAV",
+ "AUDIO\\yd2_a.WAV",
+ "AUDIO\\yd2_b.WAV",
+ "AUDIO\\yd2_c.WAV",
+ "AUDIO\\yd2_c1.WAV",
+ "AUDIO\\yd2_d.WAV",
+ "AUDIO\\yd2_e.WAV",
+ "AUDIO\\yd2_f.WAV",
+ "AUDIO\\yd2_g.WAV",
+ "AUDIO\\yd2_h.WAV",
+ "AUDIO\\yd2_ass.WAV",
+ "AUDIO\\yd2_ok.WAV",
+ "AUDIO\\h5_a.WAV",
+ "AUDIO\\h5_b.WAV",
+ "AUDIO\\h5_c.WAV",
+ "AUDIO\\ammu_a.WAV",
+ "AUDIO\\ammu_b.WAV",
+ "AUDIO\\ammu_c.WAV",
+ "AUDIO\\door_1.WAV",
+ "AUDIO\\door_2.WAV",
+ "AUDIO\\door_3.WAV",
+ "AUDIO\\door_4.WAV",
+ "AUDIO\\door_5.WAV",
+ "AUDIO\\door_6.WAV",
+ "AUDIO\\t3_a.WAV",
+ "AUDIO\\t3_b.WAV",
+ "AUDIO\\t3_c.WAV",
+ "AUDIO\\k1_b.WAV",
+ "AUDIO\\cat1.WAV"
+};
diff --git a/src/audio/miles/sampman_mss.cpp b/src/audio/sampman_miles.cpp
index f3a6ba80..caf2917f 100644
--- a/src/audio/miles/sampman_mss.cpp
+++ b/src/audio/sampman_miles.cpp
@@ -1,3 +1,6 @@
+#include "common.h"
+
+#ifdef AUDIO_MSS
#include <windows.h>
#include <shobjidl.h>
#include <shlguid.h>
@@ -8,7 +11,7 @@
#include "eax-util.h"
#include "mss.h"
-#include "sampman_mss.h"
+#include "sampman.h"
#include "AudioManager.h"
#include "MusicManager.h"
#include "Frontend.h"
@@ -18,7 +21,7 @@
#pragma comment( lib, "mss32.lib" )
cSampleManager SampleManager;
-int32 BankStartOffset[MAX_SAMPLEBANKS];
+uint32 BankStartOffset[MAX_SAMPLEBANKS];
///////////////////////////////////////////////////////////////
char SampleBankDescFilename[] = "AUDIO\\SFX.SDT";
@@ -55,9 +58,9 @@ struct tMP3Entry
uint32 nNumMP3s;
tMP3Entry *_pMP3List;
char _mp3DirectoryPath[MAX_PATH];
-HSTREAM mp3Stream [MAX_MP3STREAMS];
-int8 nStreamPan [MAX_MP3STREAMS];
-int8 nStreamVolume[MAX_MP3STREAMS];
+HSTREAM mp3Stream [MAX_STREAMS];
+int8 nStreamPan [MAX_STREAMS];
+int8 nStreamVolume[MAX_STREAMS];
uint32 _CurMP3Index;
int32 _CurMP3Pos;
bool _bIsMp3Active;
@@ -261,6 +264,17 @@ set_new_provider(S32 index)
return false;
}
+cSampleManager::cSampleManager(void) :
+ m_nNumberOfProviders(0)
+{
+ ;
+}
+
+cSampleManager::~cSampleManager(void)
+{
+
+}
+
void
cSampleManager::SetSpeakerConfig(int32 which)
{
@@ -296,6 +310,26 @@ cSampleManager::GetMaximumSupportedChannels(void)
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)
{
@@ -1084,7 +1118,7 @@ cSampleManager::Initialise(void)
TRACE("stream");
{
- for ( int32 i = 0; i < MAX_MP3STREAMS; i++ )
+ for ( int32 i = 0; i < MAX_STREAMS; i++ )
{
mp3Stream [i] = NULL;
nStreamPan [i] = 63;
@@ -1199,7 +1233,7 @@ cSampleManager::Initialise(void)
void
cSampleManager::Terminate(void)
{
- for ( int32 i = 0; i < MAX_MP3STREAMS; i++ )
+ for ( int32 i = 0; i < MAX_STREAMS; i++ )
{
if ( mp3Stream[i] )
{
@@ -1366,6 +1400,12 @@ cSampleManager::SetMusicFadeVolume(uint8 nVolume)
m_nMusicFadeVolume = nVolume;
}
+void
+cSampleManager::SetMonoMode(uint8 nMode)
+{
+ m_nMonoMode = nMode;
+}
+
bool
cSampleManager::LoadSampleBank(uint8 nBank)
{
@@ -1476,6 +1516,18 @@ cSampleManager::LoadPedComment(uint32 nComment)
}
int32
+cSampleManager::GetBankContainingSound(uint32 offset)
+{
+ if ( offset >= BankStartOffset[SAMPLEBANK_PED] )
+ return SAMPLEBANK_PED;
+
+ if ( offset >= BankStartOffset[SAMPLEBANK_MAIN] )
+ return SAMPLEBANK_MAIN;
+
+ return SAMPLEBANK_INVALID;
+}
+
+int32
cSampleManager::GetSampleBaseFrequency(uint32 nSample)
{
return m_aSamples[nSample].nFrequency;
@@ -1664,7 +1716,7 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
OutputDebugString(AIL_last_error());
return false;
}
-
+
return true;
}
}
@@ -2255,3 +2307,5 @@ cSampleManager::InitialiseSampleBanks(void)
return true;
}
+
+#endif \ No newline at end of file
diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp
new file mode 100644
index 00000000..bbaeae4c
--- /dev/null
+++ b/src/audio/sampman_oal.cpp
@@ -0,0 +1,1404 @@
+#include "common.h"
+//#define JUICY_OAL
+
+#ifdef AUDIO_OAL
+#include "sampman.h"
+
+#include <time.h>
+#include <io.h>
+
+#include "eax.h"
+#include "eax-util.h"
+
+#include <AL/al.h>
+#include <AL/alc.h>
+#include <AL/alext.h>
+#include <AL/efx.h>
+#include <AL/efx-presets.h>
+
+#include "oal/oal_utils.h"
+#include "oal/aldlist.h"
+#include "oal/channel.h"
+#include "oal/stream.h"
+
+#include "AudioManager.h"
+#include "MusicManager.h"
+#include "Frontend.h"
+#include "Timer.h"
+
+//TODO: fix eax3 reverb
+//TODO: max channals
+//TODO: loop count
+//TODO: mp3 player
+
+#pragma comment( lib, "OpenAL32.lib" )
+
+cSampleManager SampleManager;
+bool _bSampmanInitialised = false;
+
+uint32 BankStartOffset[MAX_SAMPLEBANKS];
+
+int prevprovider=-1;
+int curprovider=-1;
+int usingEAX=0;
+int usingEAX3=0;
+//int speaker_type=0;
+ALCdevice *ALDevice = NULL;
+ALCcontext *ALContext = NULL;
+unsigned int _maxSamples;
+float _fPrevEaxRatioDestination;
+bool _usingEFX;
+float _fEffectsLevel;
+ALuint ALEffect = AL_EFFECT_NULL;
+ALuint ALEffectSlot = AL_EFFECTSLOT_NULL;
+struct
+{
+ char id[256];
+ char name[256];
+ int sources;
+}providers[MAXPROVIDERS];
+
+int defaultProvider;
+
+
+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];
+uint8 nCurrentPedSlot;
+
+ALuint pedBuffers[MAX_PEDSFX];
+
+CChannel aChannel[MAXCHANNELS+MAX2DCHANNELS];
+uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
+
+uint32 nStreamLength[TOTAL_STREAMED_SOUNDS];
+ALuint ALStreamSources[MAX_STREAMS];
+ALuint ALStreamBuffers[MAX_STREAMS][NUM_STREAMBUFFERS];
+struct
+{
+ ALuint buffer;
+ ALuint timer;
+
+ bool IsEmpty() { return timer == 0; }
+ void Set(ALuint buf) { buffer = buf; }
+ void Wait() { timer = 10000; }
+ void Init()
+ {
+ buffer = 0;
+ timer = 0;
+ }
+ void Term()
+ {
+ if ( buffer != 0 && alIsBuffer(buffer) )
+ alDeleteBuffers(1, &buffer);
+ timer = 0;
+ }
+ void Update()
+ {
+ if ( !(timer > 0) ) return;
+ timer -= ALuint(CTimer::GetTimeStepInMilliseconds());
+ if ( timer > 0 ) return;
+ if ( buffer != 0 && alIsBuffer(buffer) )
+ {
+ alDeleteBuffers(1, &buffer);
+ timer = ( alGetError() == AL_NO_ERROR ) ? 0 : 10000;
+ }
+ }
+}ALBuffers[SAMPLEBANK_MAX];
+
+uint32 nNumMP3s;
+CStream *aStream[MAX_STREAMS];
+uint8 nStreamPan [MAX_STREAMS];
+uint8 nStreamVolume[MAX_STREAMS];
+
+///////////////////////////////////////////////////////////////
+// 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;
+
+
+bool IsFXSupported()
+{
+ return usingEAX || usingEAX3 || _usingEFX;
+}
+
+void EAX_SetAll(const EAXLISTENERPROPERTIES *allparameters)
+{
+ if ( usingEAX || usingEAX3 )
+ EAX3_Set(ALEffect, allparameters);
+ else
+ EFX_Set(ALEffect, allparameters);
+}
+
+static void
+add_providers()
+{
+ SampleManager.SetNum3DProvidersAvailable(0);
+
+ ALDeviceList *pDeviceList = NULL;
+ pDeviceList = new ALDeviceList();
+
+ if ((pDeviceList) && (pDeviceList->GetNumDevices()))
+ {
+ const int devNumber = Min(pDeviceList->GetNumDevices(), MAXPROVIDERS);
+ int n = 0;
+
+ for (int i = 0; i < devNumber; i++)
+ {
+ if ( n < MAXPROVIDERS )
+ {
+ strcpy(providers[n].id, pDeviceList->GetDeviceName(i));
+ strncpy(providers[n].name, pDeviceList->GetDeviceName(i), sizeof(providers[n].name));
+ providers[n].sources = pDeviceList->GetMaxNumSources(i);
+ SampleManager.Set3DProviderName(n, providers[n].name);
+ n++;
+ }
+
+ if ( alGetEnumValue("AL_EFFECT_EAXREVERB") != 0
+ || pDeviceList->IsExtensionSupported(i, "EAX2.0")
+ || pDeviceList->IsExtensionSupported(i, "EAX3.0")
+ || pDeviceList->IsExtensionSupported(i, "EAX4.0")
+ || pDeviceList->IsExtensionSupported(i, "EAX5.0") )
+ {
+ if ( n < MAXPROVIDERS )
+ {
+ strcpy(providers[n].id, pDeviceList->GetDeviceName(i));
+ strncpy(providers[n].name, pDeviceList->GetDeviceName(i), sizeof(providers[n].name));
+ strcat(providers[n].name, " EAX");
+ providers[n].sources = pDeviceList->GetMaxNumSources(i);
+ SampleManager.Set3DProviderName(n, providers[n].name);
+ n++;
+ }
+
+ if ( n < MAXPROVIDERS )
+ {
+ strcpy(providers[n].id, pDeviceList->GetDeviceName(i));
+ strncpy(providers[n].name, pDeviceList->GetDeviceName(i), sizeof(providers[n].name));
+ strcat(providers[n].name, " EAX3");
+ providers[n].sources = pDeviceList->GetMaxNumSources(i);
+ SampleManager.Set3DProviderName(n, providers[n].name);
+ n++;
+ }
+ }
+ }
+ SampleManager.SetNum3DProvidersAvailable(n);
+
+ for(int j=n;j<MAXPROVIDERS;j++)
+ SampleManager.Set3DProviderName(j, NULL);
+
+ defaultProvider = pDeviceList->GetDefaultDevice();
+ if ( defaultProvider > MAXPROVIDERS )
+ defaultProvider = 0;
+ }
+
+ delete pDeviceList;
+}
+
+static void
+release_existing()
+{
+ for ( int32 i = 0; i < MAXCHANNELS; i++ )
+ aChannel[i].Term();
+ aChannel[CHANNEL2D].Term();
+
+ if ( IsFXSupported() )
+ {
+ if ( alIsEffect(ALEffect) )
+ {
+ alEffecti(ALEffect, AL_EFFECT_TYPE, AL_EFFECT_NULL);
+ alDeleteEffects(1, &ALEffect);
+ ALEffect = AL_EFFECT_NULL;
+ }
+
+ if (alIsAuxiliaryEffectSlot(ALEffectSlot))
+ {
+ alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, AL_EFFECT_NULL);
+
+ alDeleteAuxiliaryEffectSlots(1, &ALEffectSlot);
+ ALEffectSlot = AL_EFFECTSLOT_NULL;
+ }
+ }
+
+ for ( int32 i = 0; i < MAX_STREAMS; i++ )
+ {
+ CStream *stream = aStream[i];
+ if (stream)
+ stream->ProviderTerm();
+
+ alDeleteSources(1, &ALStreamSources[i]);
+ alDeleteBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
+ }
+
+ alDeleteBuffers(MAX_PEDSFX, pedBuffers);
+
+ for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
+ {
+ ALBuffers[i].Term();
+ }
+
+ if ( ALContext )
+ {
+ alcMakeContextCurrent(NULL);
+ alcSuspendContext(ALContext);
+ alcDestroyContext(ALContext);
+ }
+ if ( ALDevice )
+ alcCloseDevice(ALDevice);
+
+ ALDevice = NULL;
+ ALContext = NULL;
+
+ _fPrevEaxRatioDestination = 0.0f;
+ _usingEFX = false;
+ _fEffectsLevel = 0.0f;
+
+ DEV("release_existing()\n");
+}
+
+static bool
+set_new_provider(int index)
+{
+ if ( curprovider == index )
+ return true;
+
+ curprovider = index;
+
+ release_existing();
+
+ if ( curprovider != -1 )
+ {
+ DEV("set_new_provider()\n");
+
+ //TODO:
+ _maxSamples = MAXCHANNELS;
+
+ ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ,0};
+
+ ALDevice = alcOpenDevice(providers[index].id);
+ ASSERT(ALDevice != NULL);
+
+ ALContext = alcCreateContext(ALDevice, attr);
+ ASSERT(ALContext != NULL);
+
+ alcMakeContextCurrent(ALContext);
+
+ const char* ext=(const char*)alGetString(AL_EXTENSIONS);
+ ASSERT(strstr(ext,"AL_SOFT_loop_points")!=NULL);
+ if ( strstr(ext,"AL_SOFT_loop_points")==NULL )
+ {
+ curprovider=-1;
+ release_existing();
+ return false;
+ }
+
+ alListenerf (AL_GAIN, 1.0f);
+ alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f);
+ alListener3f(AL_VELOCITY, 0.0f, 0.0f, 0.0f);
+ ALfloat orientation[6] = { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f };
+ alListenerfv(AL_ORIENTATION, orientation);
+
+ alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
+
+ if ( alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) )
+ {
+ alGenAuxiliaryEffectSlots(1, &ALEffectSlot);
+ alGenEffects(1, &ALEffect);
+ }
+
+ for ( int32 i = 0; i < MAX_STREAMS; i++ )
+ {
+ alGenSources(1, &ALStreamSources[i]);
+ alGenBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
+
+ CStream *stream = aStream[i];
+ if (stream)
+ stream->ProviderInit();
+ }
+
+ for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
+ {
+ ALBuffers[i].Init();
+ }
+
+ alGenBuffers(MAX_PEDSFX, pedBuffers);
+
+ usingEAX = 0;
+ usingEAX3 = 0;
+ _usingEFX = false;
+
+ if ( !strcmp(&providers[index].name[strlen(providers[index].name) - strlen(" EAX3")], " EAX3")
+ && alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) )
+ {
+ EAX_SetAll(&FinishEAX3);
+
+ usingEAX = 1;
+ usingEAX3 = 1;
+
+ DEV("EAX3\n");
+ }
+ else if ( alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) )
+ {
+ EAX_SetAll(&EAX30_ORIGINAL_PRESETS[EAX_ENVIRONMENT_CAVE]);
+
+ if ( !strcmp(&providers[index].name[strlen(providers[index].name) - strlen(" EAX")], " EAX"))
+ {
+ usingEAX = 1;
+ DEV("EAX1\n");
+ }
+ else
+ {
+ _usingEFX = true;
+ DEV("EFX\n");
+ }
+ }
+
+ //SampleManager.SetSpeakerConfig(speaker_type);
+
+ for ( int32 i = 0; i < MAXCHANNELS; i++ )
+ aChannel[i].Init();
+ aChannel[CHANNEL2D].Init(true);
+
+ if ( IsFXSupported() )
+ {
+ /**/
+ alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect);
+ /**/
+
+ for ( int32 i = 0; i < MAXCHANNELS; i++ )
+ aChannel[i].SetReverbMix(ALEffectSlot, 0.0f);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+cSampleManager::cSampleManager(void)
+{
+ ;
+}
+
+cSampleManager::~cSampleManager(void)
+{
+
+}
+
+void cSampleManager::SetSpeakerConfig(int32 nConfig)
+{
+
+}
+
+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)
+{
+ ASSERT( nProvider < m_nNumberOfProviders );
+ int savedprovider = curprovider;
+
+ if ( nProvider < m_nNumberOfProviders )
+ {
+ if ( set_new_provider(nProvider) )
+ return curprovider;
+ else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) )
+ return curprovider;
+ else
+ return -1;
+ }
+ else
+ return curprovider;
+}
+
+bool
+cSampleManager::IsMP3RadioChannelAvailable(void)
+{
+ return nNumMP3s != 0;
+}
+
+
+void cSampleManager::ReleaseDigitalHandle(void)
+{
+ if ( ALDevice )
+ {
+ prevprovider = curprovider;
+ release_existing();
+ curprovider = -1;
+ }
+}
+
+void cSampleManager::ReacquireDigitalHandle(void)
+{
+ if ( ALDevice )
+ {
+ if ( prevprovider != -1 )
+ set_new_provider(prevprovider);
+ }
+}
+
+bool
+cSampleManager::Initialise(void)
+{
+ if ( _bSampmanInitialised )
+ return true;
+
+ EFXInit();
+ CStream::Initialise();
+
+ {
+ for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
+ {
+ m_aSamples[i].nOffset = 0;
+ m_aSamples[i].nSize = 0;
+ m_aSamples[i].nFrequency = MAX_FREQ;
+ 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;
+ }
+
+ {
+ curprovider = -1;
+ prevprovider = -1;
+
+ _usingEFX = false;
+ usingEAX =0;
+ usingEAX3=0;
+
+ _fEffectsLevel = 0.0f;
+
+ _maxSamples = 0;
+
+ ALDevice = NULL;
+ ALContext = NULL;
+ }
+
+ {
+ fpSampleDescHandle = NULL;
+ fpSampleDataHandle = NULL;
+
+ for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ )
+ {
+ bSampleBankLoaded[i] = false;
+ nSampleBankDiscStartOffset[i] = 0;
+ nSampleBankSize[i] = 0;
+ nSampleBankMemoryStartAddress[i] = 0;
+ }
+ }
+
+ {
+ for ( int32 i = 0; i < MAX_PEDSFX; i++ )
+ {
+ nPedSlotSfx[i] = NO_SAMPLE;
+ nPedSlotSfxAddr[i] = 0;
+ }
+
+ nCurrentPedSlot = 0;
+ }
+
+ {
+ for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ )
+ nChannelVolume[i] = 0;
+ }
+
+ {
+ for ( int32 i = 0; i < MAX_STREAMS; i++ )
+ {
+ aStream[i] = NULL;
+ nStreamVolume[i] = 100;
+ nStreamPan[i] = 63;
+ }
+
+ for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
+ nStreamLength[i] = 0;
+ }
+
+ {
+ add_providers();
+
+ if ( !InitialiseSampleBanks() )
+ {
+ Terminate();
+ return false;
+ }
+
+ nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)malloc(nSampleBankSize[SAMPLEBANK_MAIN]);
+ ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != NULL);
+
+ if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] == NULL )
+ {
+ Terminate();
+ return false;
+ }
+
+ nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)malloc(PED_BLOCKSIZE*MAX_PEDSFX);
+ ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != NULL);
+ }
+
+
+ {
+ _bSampmanInitialised = true;
+
+ if ( 0 >= defaultProvider && defaultProvider < m_nNumberOfProviders )
+ {
+ set_new_provider(defaultProvider);
+ }
+ else
+ {
+ Terminate();
+ return false;
+ }
+ }
+
+ {
+
+ for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
+ {
+ aStream[0] = new CStream(StreamedNameTable[i], ALStreamSources[0], ALStreamBuffers[0]);
+
+ if ( aStream[0] && aStream[0]->IsOpened() )
+ {
+ uint32 tatalms = aStream[0]->GetLengthMS();
+ delete aStream[0];
+ aStream[0] = NULL;
+
+ nStreamLength[i] = tatalms;
+ }
+ else
+ USERERROR("Can't open '%s'\n", StreamedNameTable[i]);
+ }
+ }
+
+ LoadSampleBank(SAMPLEBANK_MAIN);
+
+ return true;
+}
+
+void
+cSampleManager::Terminate(void)
+{
+ release_existing();
+
+ for (int32 i = 0; i < MAX_STREAMS; i++)
+ {
+ CStream *stream = aStream[i];
+ if (stream)
+ {
+ delete stream;
+ aStream[i] = NULL;
+ }
+ }
+
+ CStream::Terminate();
+
+ if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != 0 )
+ {
+ free((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN]);
+ nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = 0;
+ }
+
+ if ( nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != 0 )
+ {
+ free((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]);
+ nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = 0;
+ }
+
+ _bSampmanInitialised = false;
+}
+
+void
+cSampleManager::UpdateSoundBuffers(void)
+{
+ for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
+ {
+ ALBuffers[i].Update();
+ }
+}
+
+bool cSampleManager::CheckForAnAudioFileOnCD(void)
+{
+ return true;
+}
+
+char cSampleManager::GetCDAudioDriveLetter(void)
+{
+ return '\0';
+}
+
+void
+cSampleManager::UpdateEffectsVolume(void)
+{
+ if ( _bSampmanInitialised )
+ {
+ for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ )
+ {
+ if ( GetChannelUsedFlag(i) )
+ {
+ if ( nChannelVolume[i] != 0 )
+ aChannel[i].SetVolume(m_nEffectsFadeVolume*nChannelVolume[i]*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)
+{
+ ASSERT( nBank < MAX_SAMPLEBANKS );
+
+ if ( CTimer::GetIsCodePaused() )
+ return false;
+
+ if ( MusicManager.IsInitialised()
+ && MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
+ && nBank != SAMPLEBANK_MAIN )
+ {
+ 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)
+{
+ ASSERT( nBank < MAX_SAMPLEBANKS );
+
+ bSampleBankLoaded[nBank] = false;
+}
+
+bool
+cSampleManager::IsSampleBankLoaded(uint8 nBank)
+{
+ ASSERT( nBank < MAX_SAMPLEBANKS );
+
+ return bSampleBankLoaded[nBank];
+}
+
+bool
+cSampleManager::IsPedCommentLoaded(uint32 nComment)
+{
+ ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
+
+ uint8 slot;
+
+ 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)
+{
+ uint8 slot;
+
+ 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)
+{
+ ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
+
+ 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;
+
+ if ( fread((void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize )
+ return false;
+
+ nPedSlotSfx[nCurrentPedSlot] = nComment;
+
+ alBufferData(pedBuffers[nCurrentPedSlot],
+ AL_FORMAT_MONO16,
+ (void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot),
+ m_aSamples[nComment].nSize,
+ m_aSamples[nComment].nFrequency);
+
+ if ( ++nCurrentPedSlot >= MAX_PEDSFX )
+ nCurrentPedSlot = 0;
+
+ return true;
+}
+
+int32
+cSampleManager::GetBankContainingSound(uint32 offset)
+{
+ if ( offset >= BankStartOffset[SAMPLEBANK_PED] )
+ return SAMPLEBANK_PED;
+
+ if ( offset >= BankStartOffset[SAMPLEBANK_MAIN] )
+ return SAMPLEBANK_MAIN;
+
+ return SAMPLEBANK_INVALID;
+}
+
+int32
+cSampleManager::GetSampleBaseFrequency(uint32 nSample)
+{
+ ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
+ return m_aSamples[nSample].nFrequency;
+}
+
+int32
+cSampleManager::GetSampleLoopStartOffset(uint32 nSample)
+{
+ ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
+ return m_aSamples[nSample].nLoopStart;
+}
+
+int32
+cSampleManager::GetSampleLoopEndOffset(uint32 nSample)
+{
+ ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
+ return m_aSamples[nSample].nLoopEnd;
+}
+
+uint32
+cSampleManager::GetSampleLength(uint32 nSample)
+{
+ ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
+ return m_aSamples[nSample].nSize / sizeof(uint16);
+}
+
+bool cSampleManager::UpdateReverb(void)
+{
+ if ( !usingEAX && !_usingEFX )
+ 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);
+
+ #define ZR(v, a, b) (((v)==0)?(a):(b))
+ #define CALCRATIO(x,y,z,min,max,val) (ZR(y, ZR(x, ZR(z, min, max), min), ZR(x, ZR(z, min, max), ZR(z, min, val))))
+
+ float fRatio = CALCRATIO(normx, normy, normz, 0.3f, 0.5f, (normy+normx+normz)/3.0f);
+
+ #undef CALCRATIO
+ #undef ZE
+
+ fRatio = clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f);
+
+ if ( fRatio == _fPrevEaxRatioDestination )
+ return false;
+
+#ifdef JUICY_OAL
+ if ( usingEAX3 || _usingEFX )
+#else
+ if ( usingEAX3 )
+#endif
+ {
+ if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) )
+ {
+ EAX_SetAll(&EAX3Params);
+
+ /*
+ if ( IsFXSupported() )
+ {
+ alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect);
+
+ for ( int32 i = 0; i < MAXCHANNELS; i++ )
+ aChannel[i].UpdateReverb(ALEffectSlot);
+ }
+ */
+
+ _fEffectsLevel = 1.0f - fRatio * 0.5f;
+ }
+ }
+ else
+ {
+ if ( _usingEFX )
+ _fEffectsLevel = (1.0f - fRatio) * 0.4f;
+ else
+ _fEffectsLevel = (1.0f - fRatio) * 0.7f;
+ }
+
+ _fPrevEaxRatioDestination = fRatio;
+
+ return true;
+}
+
+void
+cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( usingEAX || _usingEFX )
+ {
+ if ( IsFXSupported() )
+ {
+ alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect);
+
+ if ( nReverbFlag != 0 )
+ aChannel[nChannel].SetReverbMix(ALEffectSlot, _fEffectsLevel);
+ else
+ aChannel[nChannel].SetReverbMix(ALEffectSlot, 0.0f);
+ }
+ }
+}
+
+bool
+cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ ALuint buffer;
+
+ if ( nSfx < SAMPLEBANK_MAX )
+ {
+ if ( !IsSampleBankLoaded(nBank) )
+ return false;
+
+ int32 addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset;
+
+ if ( ALBuffers[nSfx].IsEmpty() )
+ {
+ ALuint buf;
+ alGenBuffers(1, &buf);
+ alBufferData(buf, AL_FORMAT_MONO16, (void *)addr, m_aSamples[nSfx].nSize, m_aSamples[nSfx].nFrequency);
+ ALBuffers[nSfx].Set(buf);
+ }
+ ALBuffers[nSfx].Wait();
+
+ buffer = ALBuffers[nSfx].buffer;
+ }
+ else
+ {
+ if ( !IsPedCommentLoaded(nSfx) )
+ return false;
+
+ int32 slot = _GetPedCommentSlot(nSfx);
+
+ buffer = pedBuffers[slot];
+ }
+
+ if ( buffer == 0 )
+ {
+ TRACE("No buffer to play id %d", nSfx);
+ return false;
+ }
+
+ if ( GetChannelUsedFlag(nChannel) )
+ {
+ TRACE("Stopping channel %d - really!!!", nChannel);
+ StopChannel(nChannel);
+ }
+
+ aChannel[nChannel].Reset();
+ if ( aChannel[nChannel].HasSource() )
+ {
+ aChannel[nChannel].SetSampleID (nSfx);
+ aChannel[nChannel].SetFreq (m_aSamples[nSfx].nFrequency);
+ aChannel[nChannel].SetLoopPoints (0, -1);
+ aChannel[nChannel].SetBuffer (buffer);
+ aChannel[nChannel].SetPitch (1.0f);
+ return true;
+ }
+
+ return false;
+}
+
+void
+cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
+{
+ ASSERT( nChannel != CHANNEL2D );
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ uint32 vol = nVolume;
+ if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+
+ nChannelVolume[nChannel] = vol;
+
+ // reduce channel volume when JB.MP3 or S4_BDBD.MP3 playing
+ if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
+ {
+ nChannelVolume[nChannel] = vol / 4;
+ }
+
+ // no idea, does this one looks like a bug or it's SetChannelVolume ?
+ aChannel[nChannel].SetVolume(m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14);
+}
+
+void
+cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ)
+{
+ ASSERT( nChannel != CHANNEL2D );
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ aChannel[nChannel].SetPosition(-fX, fY, fZ);
+}
+
+void
+cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin)
+{
+ ASSERT( nChannel != CHANNEL2D );
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+ aChannel[nChannel].SetDistances(fMax, fMin);
+}
+
+void
+cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
+{
+ ASSERT( nChannel == CHANNEL2D );
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( nChannel == CHANNEL2D )
+ {
+ uint32 vol = nVolume;
+ if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+
+ nChannelVolume[nChannel] = vol;
+
+ // reduce 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] = vol / 4;
+ }
+
+ aChannel[nChannel].SetVolume(m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
+ }
+}
+
+void
+cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan)
+{
+ ASSERT(nChannel == CHANNEL2D);
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( nChannel == CHANNEL2D )
+ {
+ aChannel[nChannel].SetPan(nPan);
+ }
+}
+
+void
+cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ aChannel[nChannel].SetCurrentFreq(nFreq);
+}
+
+void
+cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ aChannel[nChannel].SetLoopPoints(nLoopStart / (DIGITALBITS / 8), nLoopEnd / (DIGITALBITS / 8));
+}
+
+void
+cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ aChannel[nChannel].SetLoopCount(nLoopCount);
+}
+
+bool
+cSampleManager::GetChannelUsedFlag(uint32 nChannel)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ return aChannel[nChannel].IsUsed();
+}
+
+void
+cSampleManager::StartChannel(uint32 nChannel)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ aChannel[nChannel].Start();
+}
+
+void
+cSampleManager::StopChannel(uint32 nChannel)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ aChannel[nChannel].Stop();
+}
+
+void
+cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
+{
+ char filename[256];
+
+ ASSERT( nStream < MAX_STREAMS );
+
+ if ( nFile < TOTAL_STREAMED_SOUNDS )
+ {
+ if ( aStream[nStream] )
+ {
+ delete aStream[nStream];
+ aStream[nStream] = NULL;
+ }
+
+ strcpy(filename, StreamedNameTable[nFile]);
+
+ CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
+ ASSERT(stream != NULL);
+
+ aStream[nStream] = stream;
+ if ( !stream->IsOpened() )
+ {
+ delete stream;
+ aStream[nStream] = NULL;
+ }
+ }
+}
+
+void
+cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ CStream *stream = aStream[nStream];
+
+ if ( stream )
+ {
+ stream->SetPause(nPauseFlag != 0);
+ }
+}
+
+void
+cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ CStream *stream = aStream[nStream];
+
+ if ( stream )
+ {
+ if ( stream->Setup() )
+ {
+ stream->Start();
+ }
+ }
+}
+
+bool
+cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
+{
+ char filename[256];
+
+ ASSERT( nStream < MAX_STREAMS );
+
+ if ( nFile < TOTAL_STREAMED_SOUNDS )
+ {
+ if ( aStream[nStream] )
+ {
+ delete aStream[nStream];
+ aStream[nStream] = NULL;
+ }
+
+ strcpy(filename, StreamedNameTable[nFile]);
+
+ CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
+ ASSERT(stream != NULL);
+
+ aStream[nStream] = stream;
+
+ if ( stream->IsOpened() )
+ {
+ nStreamLength[nFile] = stream->GetLengthMS();
+ if ( stream->Setup() )
+ {
+ if ( nPos != 0 )
+ stream->SetPosMS(nPos);
+
+ stream->Start();
+ }
+
+ return true;
+ }
+ else
+ {
+ delete stream;
+ aStream[nStream] = NULL;
+ }
+ }
+
+ return false;
+}
+
+void
+cSampleManager::StopStreamedFile(uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ CStream *stream = aStream[nStream];
+
+ if ( stream )
+ {
+ delete stream;
+ aStream[nStream] = NULL;
+ }
+}
+
+int32
+cSampleManager::GetStreamedFilePosition(uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ CStream *stream = aStream[nStream];
+
+ if ( stream )
+ {
+ return stream->GetPosMS();
+ }
+
+ return 0;
+}
+
+void
+cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ if ( nVolume > MAX_VOLUME )
+ nVolume = MAX_VOLUME;
+
+ if ( nPan > MAX_VOLUME )
+ nPan = MAX_VOLUME;
+
+ nStreamVolume[nStream] = nVolume;
+ nStreamPan [nStream] = nPan;
+
+ CStream *stream = aStream[nStream];
+
+ if ( stream )
+ {
+ if ( nEffectFlag )
+ stream->SetVolume(m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14);
+ else
+ stream->SetVolume(m_nMusicFadeVolume*nVolume*m_nMusicVolume >> 14);
+
+ stream->SetPan(nPan);
+ }
+}
+
+int32
+cSampleManager::GetStreamedFileLength(uint8 nStream)
+{
+ ASSERT( nStream < TOTAL_STREAMED_SOUNDS );
+
+ return nStreamLength[nStream];
+}
+
+bool
+cSampleManager::IsStreamPlaying(uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ CStream *stream = aStream[nStream];
+
+ if ( stream )
+ {
+ if ( stream->IsPlaying() )
+ return true;
+ }
+
+ return false;
+}
+
+void
+cSampleManager::Service(void)
+{
+ for ( int32 i = 0; i < MAX_STREAMS; i++ )
+ {
+ CStream *stream = aStream[i];
+
+ if ( stream )
+ stream->Update();
+ }
+
+ UpdateSoundBuffers();
+}
+
+bool
+cSampleManager::InitialiseSampleBanks(void)
+{
+ int32 nBank = SAMPLEBANK_MAIN;
+
+ 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);
+ int32 _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_SAMPLEBANKS) break;
+#endif
+ if ( BankStartOffset[nBank] == BankStartOffset[SAMPLEBANK_MAIN] + i )
+ {
+ nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset;
+ nBank++;
+ }
+ }
+
+ nSampleBankSize[SAMPLEBANK_MAIN] = nSampleBankDiscStartOffset[SAMPLEBANK_PED] - nSampleBankDiscStartOffset[SAMPLEBANK_MAIN];
+ nSampleBankSize[SAMPLEBANK_PED] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SAMPLEBANK_PED];
+
+ return true;
+}
+
+#endif \ No newline at end of file
diff --git a/src/control/AutoPilot.h b/src/control/AutoPilot.h
index 282f1418..25feb72d 100644
--- a/src/control/AutoPilot.h
+++ b/src/control/AutoPilot.h
@@ -133,3 +133,5 @@ public:
float GetCruiseSpeed(void) { return m_nCruiseSpeed * m_fCruiseSpeedMultiplier; }
};
+
+VALIDATE_SIZE(CAutoPilot, 0x70);
diff --git a/src/control/Garages.h b/src/control/Garages.h
index c54c41df..44d28ba9 100644
--- a/src/control/Garages.h
+++ b/src/control/Garages.h
@@ -86,7 +86,7 @@ public:
CVehicle* RestoreCar();
};
-static_assert(sizeof(CStoredCar) == 0x28, "CStoredCar");
+VALIDATE_SIZE(CStoredCar, 0x28);
#define SWITCH_GARAGE_DISTANCE_CLOSE 40.0f
@@ -183,7 +183,7 @@ class CGarage
friend class CCamera;
};
-static_assert(sizeof(CGarage) == 140, "CGarage");
+VALIDATE_SIZE(CGarage, 140);
class CGarages
{
diff --git a/src/control/OnscreenTimer.h b/src/control/OnscreenTimer.h
index fb139266..3ef7764a 100644
--- a/src/control/OnscreenTimer.h
+++ b/src/control/OnscreenTimer.h
@@ -26,7 +26,7 @@ public:
void ProcessForDisplayCounter();
};
-static_assert(sizeof(COnscreenTimerEntry) == 0x74, "COnscreenTimerEntry: error");
+VALIDATE_SIZE(COnscreenTimerEntry, 0x74);
class COnscreenTimer
{
@@ -46,4 +46,4 @@ public:
void AddClock(uint32 offset, char* text);
};
-static_assert(sizeof(COnscreenTimer) == 0x78, "COnscreenTimer: error"); \ No newline at end of file
+VALIDATE_SIZE(COnscreenTimer, 0x78);
diff --git a/src/control/PathFind.h b/src/control/PathFind.h
index 5f5de3e1..7abc455a 100644
--- a/src/control/PathFind.h
+++ b/src/control/PathFind.h
@@ -38,7 +38,8 @@ struct CPedPathNode
CPedPathNode* prev;
CPedPathNode* next;
};
-static_assert(sizeof(CPedPathNode) == 0x10, "CPedPathNode: error");
+
+VALIDATE_SIZE(CPedPathNode, 0x10);
class CPedPath {
public:
diff --git a/src/control/Phones.h b/src/control/Phones.h
index 7fbf403f..14d47ed1 100644
--- a/src/control/Phones.h
+++ b/src/control/Phones.h
@@ -32,7 +32,7 @@ public:
~CPhone() { }
};
-static_assert(sizeof(CPhone) == 0x34, "CPhone: error");
+VALIDATE_SIZE(CPhone, 0x34);
class CPhoneInfo {
public:
diff --git a/src/control/Pickups.h b/src/control/Pickups.h
index 0c617f9e..51c6ab64 100644
--- a/src/control/Pickups.h
+++ b/src/control/Pickups.h
@@ -51,7 +51,7 @@ private:
void Remove();
};
-static_assert(sizeof(CPickup) == 0x1C, "CPickup: error");
+VALIDATE_SIZE(CPickup, 0x1C);
struct tPickupMessage
{
diff --git a/src/control/Replay.h b/src/control/Replay.h
index 6a07e593..09cf601e 100644
--- a/src/control/Replay.h
+++ b/src/control/Replay.h
@@ -108,7 +108,8 @@ class CReplay
CMatrix camera_pos;
CVector player_pos;
};
- static_assert(sizeof(tGeneralPacket) == 88, "tGeneralPacket: error");
+
+ VALIDATE_SIZE(tGeneralPacket, 88);
struct tClockPacket
{
@@ -118,7 +119,7 @@ class CReplay
private:
uint8 __align;
};
- static_assert(sizeof(tClockPacket) == 4, "tClockPacket: error");
+ VALIDATE_SIZE(tClockPacket, 4);
struct tWeatherPacket
{
@@ -127,14 +128,14 @@ class CReplay
uint8 new_weather;
float interpolation;
};
- static_assert(sizeof(tWeatherPacket) == 8, "tWeatherPacket: error");
+ VALIDATE_SIZE(tWeatherPacket, 8);
struct tTimerPacket
{
uint8 type;
uint32 timer;
};
- static_assert(sizeof(tTimerPacket) == 8, "tTimerPacket: error");
+ VALIDATE_SIZE(tTimerPacket, 8);
struct tPedHeaderPacket
{
@@ -145,7 +146,7 @@ class CReplay
private:
uint8 __align[3];
};
- static_assert(sizeof(tPedHeaderPacket) == 8, "tPedHeaderPacket: error");
+ VALIDATE_SIZE(tPedHeaderPacket, 8);
struct tBulletTracePacket
{
@@ -156,7 +157,7 @@ class CReplay
CVector inf;
CVector sup;
};
- static_assert(sizeof(tBulletTracePacket) == 28, "tBulletTracePacket: error");
+ VALIDATE_SIZE(tBulletTracePacket, 28);
struct tEndOfFramePacket
{
@@ -164,7 +165,7 @@ class CReplay
private:
uint8 __align[3];
};
- static_assert(sizeof(tEndOfFramePacket) == 4, "tEndOfFramePacket: error");
+ VALIDATE_SIZE(tEndOfFramePacket, 4);
struct tPedUpdatePacket
{
@@ -177,7 +178,7 @@ class CReplay
int8 assoc_group_id;
uint8 weapon_model;
};
- static_assert(sizeof(tPedUpdatePacket) == 40, "tPedUpdatePacket: error");
+ VALIDATE_SIZE(tPedUpdatePacket, 40);
struct tVehicleUpdatePacket
{
@@ -202,7 +203,7 @@ class CReplay
uint8 primary_color;
uint8 secondary_color;
};
- static_assert(sizeof(tVehicleUpdatePacket) == 48, "tVehicleUpdatePacket: error");
+ VALIDATE_SIZE(tVehicleUpdatePacket, 48);
private:
static uint8 Mode;
diff --git a/src/control/SceneEdit.cpp b/src/control/SceneEdit.cpp
index bdb93f33..1b6292b8 100644
--- a/src/control/SceneEdit.cpp
+++ b/src/control/SceneEdit.cpp
@@ -68,7 +68,9 @@ static const char* pCommandStrings[] = {
"Save Movie", "Load Movie", "Play Movie", "END"
};
+#ifdef CHECK_STRUCT_SIZES
static_assert(ARRAY_SIZE(pCommandStrings) == CSceneEdit::MOVIE_TOTAL_COMMANDS, "Scene edit: not all commands have names");
+#endif
static int32 NextValidModelId(int32 mi, int32 step)
{
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index 10dcda90..dbe2b090 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -11611,7 +11611,9 @@ INITSAVEBUF
WriteSaveBuf(buf, varSpace);
for (uint32 i = 0; i < varSpace; i++)
WriteSaveBuf(buf, ScriptSpace[i]);
+#ifdef CHECK_STRUCT_SIZES
static_assert(SCRIPT_DATA_SIZE == 968, "CTheScripts::SaveAllScripts");
+#endif
uint32 script_data_size = SCRIPT_DATA_SIZE;
WriteSaveBuf(buf, script_data_size);
WriteSaveBuf(buf, OnAMissionFlag);
@@ -12037,12 +12039,16 @@ void CRunningScript::Save(uint8*& buf)
for (int i = 0; i < 8; i++)
WriteSaveBuf<char>(buf, m_abScriptName[i]);
WriteSaveBuf<uint32>(buf, m_nIp);
+#ifdef CHECK_STRUCT_SIZES
static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6");
+#endif
for (int i = 0; i < MAX_STACK_DEPTH; i++)
WriteSaveBuf<uint32>(buf, m_anStack[i]);
WriteSaveBuf<uint16>(buf, m_nStackPointer);
SkipSaveBuf(buf, 2);
+#ifdef CHECK_STRUCT_SIZES
static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18");
+#endif
for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
WriteSaveBuf<int32>(buf, m_anLocalVariables[i]);
WriteSaveBuf<bool>(buf, m_bCondResult);
@@ -12068,12 +12074,16 @@ void CRunningScript::Load(uint8*& buf)
for (int i = 0; i < 8; i++)
m_abScriptName[i] = ReadSaveBuf<char>(buf);
m_nIp = ReadSaveBuf<uint32>(buf);
+#ifdef CHECK_STRUCT_SIZES
static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6");
+#endif
for (int i = 0; i < MAX_STACK_DEPTH; i++)
m_anStack[i] = ReadSaveBuf<uint32>(buf);
m_nStackPointer = ReadSaveBuf<uint16>(buf);
SkipSaveBuf(buf, 2);
+#ifdef CHECK_STRUCT_SIZES
static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18");
+#endif
for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
m_anLocalVariables[i] = ReadSaveBuf<int32>(buf);
m_bCondResult = ReadSaveBuf<bool>(buf);
diff --git a/src/control/Script.h b/src/control/Script.h
index fe6a2f31..9931f13e 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -28,7 +28,7 @@ struct intro_script_rectangle
~intro_script_rectangle() { }
};
-static_assert(sizeof(intro_script_rectangle) == 0x18, "Script.h: error");
+VALIDATE_SIZE(intro_script_rectangle, 0x18);
enum {
SCRIPT_TEXT_MAX_LENGTH = 500
@@ -79,7 +79,7 @@ struct intro_text_line
}
};
-static_assert(sizeof(intro_text_line) == 0x414, "Script.h: error");
+VALIDATE_SIZE(intro_text_line, 0x414);
struct script_sphere_struct
{
diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp
index e6a10267..3357c5c0 100644
--- a/src/core/Cam.cpp
+++ b/src/core/Cam.cpp
@@ -4542,6 +4542,9 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient
if(TheCamera.m_bUseTransitionBeta)
Beta = CGeneral::GetATanOfXY(-Cos(m_fTransitionBeta), -Sin(m_fTransitionBeta));
+ if(TheCamera.m_bUseTransitionBeta)
+ Beta = CGeneral::GetATanOfXY(-Cos(m_fTransitionBeta), -Sin(m_fTransitionBeta));
+
Front = CVector(Cos(Alpha) * Cos(Beta), Cos(Alpha) * Sin(Beta), Sin(Alpha));
Source = TargetCoors - Front*CamDist;
TargetCoors.z -= BaseOffset; // now get back to the real target coors again
diff --git a/src/core/Camera.h b/src/core/Camera.h
index 51138f99..94bcbd23 100644
--- a/src/core/Camera.h
+++ b/src/core/Camera.h
@@ -260,9 +260,8 @@ public:
void Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_FollowCar_SA(const CVector &CameraTarget, float TargetOrientation, float, float);
};
-static_assert(sizeof(CCam) == 0x1A4, "CCam: wrong size");
-static_assert(offsetof(CCam, Alpha) == 0xA8, "CCam: error");
-static_assert(offsetof(CCam, Front) == 0x140, "CCam: error");
+
+VALIDATE_SIZE(CCam, 0x1A4);
class CCamPathSplines
{
@@ -637,19 +636,8 @@ uint32 unknown; // some counter having to do with music
bool IsSphereVisible(const CVector &center, float radius);
bool IsBoxVisible(RwV3d *box, const CMatrix *mat);
};
-static_assert(offsetof(CCamera, DistanceToWater) == 0xe4, "CCamera: error");
-static_assert(offsetof(CCamera, m_WideScreenOn) == 0x70, "CCamera: error");
-static_assert(offsetof(CCamera, WorldViewerBeingUsed) == 0x75, "CCamera: error");
-static_assert(offsetof(CCamera, m_uiNumberOfTrainCamNodes) == 0x84, "CCamera: error");
-static_assert(offsetof(CCamera, m_uiTransitionState) == 0x89, "CCamera: error");
-static_assert(offsetof(CCamera, m_uiTimeTransitionStart) == 0x94, "CCamera: error");
-static_assert(offsetof(CCamera, m_BlurBlue) == 0x9C, "CCamera: error");
-static_assert(offsetof(CCamera, Cams) == 0x1A4, "CCamera: error");
-static_assert(offsetof(CCamera, pToGarageWeAreIn) == 0x690, "CCamera: error");
-static_assert(offsetof(CCamera, m_PreviousCameraPosition) == 0x6B0, "CCamera: error");
-static_assert(offsetof(CCamera, m_vecCutSceneOffset) == 0x6F8, "CCamera: error");
-static_assert(offsetof(CCamera, m_arrPathArray) == 0x7a8, "CCamera: error");
-static_assert(sizeof(CCamera) == 0xE9D8, "CCamera: wrong size");
+
+VALIDATE_SIZE(CCamera, 0xE9D8);
extern CCamera TheCamera;
diff --git a/src/core/CdStream.cpp b/src/core/CdStream.cpp
index ea79fb9a..666041e1 100644
--- a/src/core/CdStream.cpp
+++ b/src/core/CdStream.cpp
@@ -22,6 +22,7 @@ struct CdReadInfo
HANDLE hFile;
OVERLAPPED Overlapped;
};
+
VALIDATE_SIZE(CdReadInfo, 0x30);
char gCdImageNames[MAX_CDIMAGES+1][64];
diff --git a/src/core/CdStream.h b/src/core/CdStream.h
index 9ef71b65..ba6c63a3 100644
--- a/src/core/CdStream.h
+++ b/src/core/CdStream.h
@@ -27,7 +27,6 @@ struct Queue
VALIDATE_SIZE(Queue, 0x10);
-
void CdStreamInitThread(void);
void CdStreamInit(int32 numChannels);
uint32 GetGTA3ImgSize(void);
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index a6ca4aa0..99597a15 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -660,7 +660,7 @@ public:
};
#ifndef IMPROVED_VIDEOMODE
-static_assert(sizeof(CMenuManager) == 0x564, "CMenuManager: error");
+VALIDATE_SIZE(CMenuManager, 0x564);
#endif
extern CMenuManager FrontEndMenuManager;
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index 3ea85659..2ba3ae3a 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -221,22 +221,9 @@ bool CGame::InitialiseOnceAfterRW(void)
if ( FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -99 || FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -2 )
{
CMenuManager::m_PrefsSpeakers = 0;
-
- for ( int32 i = 0; i < DMAudio.GetNum3DProvidersAvailable(); i++ )
- {
- wchar buff[64];
-
- char *name = DMAudio.Get3DProviderName(i);
- AsciiToUnicode(name, buff);
- char *providername = UnicodeToAscii(buff);
- strupr(providername);
-
- if ( !strcmp(providername, "MILES FAST 2D POSITIONAL AUDIO") )
- {
- FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = i;
- break;
- }
- }
+ int8 provider = DMAudio.AutoDetect3DProviders();
+ if ( provider != -1 )
+ FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = provider;
}
DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_nPrefsAudio3DProviderIndex);
diff --git a/src/core/Placeable.h b/src/core/Placeable.h
index 7e858283..970c0d48 100644
--- a/src/core/Placeable.h
+++ b/src/core/Placeable.h
@@ -31,4 +31,5 @@ public:
bool IsWithinArea(float x1, float y1, float x2, float y2);
bool IsWithinArea(float x1, float y1, float z1, float x2, float y2, float z2);
};
-static_assert(sizeof(CPlaceable) == 0x4C, "CPlaceable: error"); \ No newline at end of file
+
+VALIDATE_SIZE(CPlaceable, 0x4C);
diff --git a/src/core/Radar.h b/src/core/Radar.h
index e39a17f0..7d07671d 100644
--- a/src/core/Radar.h
+++ b/src/core/Radar.h
@@ -71,7 +71,7 @@ struct sRadarTrace
uint16 m_eBlipDisplay; // eBlipDisplay
uint16 m_eRadarSprite; // eRadarSprite
};
-static_assert(sizeof(sRadarTrace) == 0x30, "sRadarTrace: error");
+VALIDATE_SIZE(sRadarTrace, 0x30);
// Values for screen space
#define RADAR_LEFT (40.0f)
diff --git a/src/core/Wanted.h b/src/core/Wanted.h
index 0e0e70c3..99ca6e4b 100644
--- a/src/core/Wanted.h
+++ b/src/core/Wanted.h
@@ -55,4 +55,4 @@ public:
static void SetMaximumWantedLevel(int32 level);
};
-static_assert(sizeof(CWanted) == 0x204, "CWanted: error");
+VALIDATE_SIZE(CWanted, 0x204);
diff --git a/src/core/World.h b/src/core/World.h
index 19d480ff..bc905bf5 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -45,7 +45,8 @@ class CSector
public:
CPtrList m_lists[NUMSECTORENTITYLISTS];
};
-static_assert(sizeof(CSector) == 0x28, "CSector: error");
+
+VALIDATE_SIZE(CSector, 0x28);
class CEntity;
struct CColPoint;
diff --git a/src/core/common.h b/src/core/common.h
index 8f400a46..ed331bbb 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -213,6 +213,7 @@ void mysrand(unsigned int seed);
void re3_debug(const char *format, ...);
void re3_trace(const char *filename, unsigned int lineno, const char *func, const char *format, ...);
void re3_assert(const char *expr, const char *filename, unsigned int lineno, const char *func);
+void re3_usererror(const char *format, ...);
#define DEBUGBREAK() __debugbreak();
@@ -220,6 +221,7 @@ void re3_assert(const char *expr, const char *filename, unsigned int lineno, con
#define DEV(f, ...) re3_debug("[DEV]: " f, ## __VA_ARGS__)
#define TRACE(f, ...) re3_trace(__FILE__, __LINE__, __FUNCTION__, f, ## __VA_ARGS__)
#define Error(f, ...) re3_debug("[ERROR]: " f, ## __VA_ARGS__)
+#define USERERROR(f, ...) re3_usererror(f, ## __VA_ARGS__)
#define assert(_Expression) (void)( (!!(_Expression)) || (re3_assert(#_Expression, __FILE__, __LINE__, __FUNCTION__), 0) )
#define ASSERT assert
@@ -227,7 +229,11 @@ void re3_assert(const char *expr, const char *filename, unsigned int lineno, con
#define _TODO(x)
#define _TODOCONST(x) (x)
+#ifdef CHECK_STRUCT_SIZES
#define VALIDATE_SIZE(struc, size) static_assert(sizeof(struc) == size, "Invalid structure size of " #struc)
+#else
+#define VALIDATE_SIZE(struc, size)
+#endif
#define VALIDATE_OFFSET(struc, member, offset) static_assert(offsetof(struc, member) == offset, "The offset of " #member " in " #struc " is not " #offset "...")
#define PERCENT(x, p) ((float(x) * (float(p) / 100.0f)))
diff --git a/src/core/config.h b/src/core/config.h
index 78fca69b..816d3771 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -199,7 +199,8 @@ enum Config {
#define USE_TXD_CDIMAGE // generate and load textures from txd.img
#define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number
//#define USE_TEXTURE_POOL
-//#define OPENAL
+//#define AUDIO_OAL
+#define AUDIO_MSS
// Particle
//#define PC_PARTICLE
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index 1915e135..bbac265f 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -465,6 +465,20 @@ void re3_trace(const char *filename, unsigned int lineno, const char *func, cons
OutputDebugStringA(buff);
}
+void re3_usererror(const char *format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ vsprintf_s(re3_buff, re3_buffsize, format, va);
+ va_end(va);
+
+ ::MessageBoxA(nil, re3_buff, "RE3 Error!",
+ MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
+
+ raise(SIGABRT);
+ _exit(3);
+}
+
#ifdef VALIDATE_SAVE_SIZE
int32 _saveBufCount;
#endif
diff --git a/src/modelinfo/BaseModelInfo.h b/src/modelinfo/BaseModelInfo.h
index c196aa5a..e7dd9e4b 100644
--- a/src/modelinfo/BaseModelInfo.h
+++ b/src/modelinfo/BaseModelInfo.h
@@ -17,7 +17,7 @@ enum ModelInfoType : uint8
MITYPE_XTRACOMPS, // unused but still in enum
MITYPE_HAND // xbox and mobile
};
-static_assert(sizeof(ModelInfoType) == 1, "ModeInfoType: error");
+VALIDATE_SIZE(ModelInfoType, 1);
class C2dEffect;
diff --git a/src/objects/ObjectData.h b/src/objects/ObjectData.h
index e3a5c1bd..e25c1aeb 100644
--- a/src/objects/ObjectData.h
+++ b/src/objects/ObjectData.h
@@ -16,7 +16,7 @@ public:
uint8 m_nSpecialCollisionResponseCases;
bool m_bCameraToAvoidThisObject;
};
-static_assert(sizeof(CObjectInfo) == 0x20, "CObjectInfo: error");
+VALIDATE_SIZE(CObjectInfo, 0x20);
class CObjectData
{
diff --git a/src/peds/CivilianPed.h b/src/peds/CivilianPed.h
index 88d034c8..8418a99f 100644
--- a/src/peds/CivilianPed.h
+++ b/src/peds/CivilianPed.h
@@ -12,5 +12,5 @@ public:
void ProcessControl(void);
};
#ifndef PED_SKIN
-static_assert(sizeof(CCivilianPed) == 0x53C, "CCivilianPed: error");
+VALIDATE_SIZE(CCivilianPed, 0x53C);
#endif
diff --git a/src/peds/CopPed.h b/src/peds/CopPed.h
index c88dffcd..945f78b8 100644
--- a/src/peds/CopPed.h
+++ b/src/peds/CopPed.h
@@ -38,5 +38,5 @@ public:
};
#ifndef PED_SKIN
-static_assert(sizeof(CCopPed) == 0x558, "CCopPed: error");
+VALIDATE_SIZE(CCopPed, 0x558);
#endif
diff --git a/src/peds/EmergencyPed.h b/src/peds/EmergencyPed.h
index 6d3dac79..390ba0bd 100644
--- a/src/peds/EmergencyPed.h
+++ b/src/peds/EmergencyPed.h
@@ -37,5 +37,5 @@ public:
void MedicAI(void);
};
#ifndef PED_SKIN
-static_assert(sizeof(CEmergencyPed) == 0x554, "CEmergencyPed: error");
+VALIDATE_SIZE(CEmergencyPed, 0x554);
#endif
diff --git a/src/peds/Gangs.h b/src/peds/Gangs.h
index dd7a7f93..c8ea2916 100644
--- a/src/peds/Gangs.h
+++ b/src/peds/Gangs.h
@@ -10,7 +10,7 @@ struct CGangInfo
CGangInfo();
};
-static_assert(sizeof(CGangInfo) == 0x10, "CGangInfo: error");
+VALIDATE_SIZE(CGangInfo, 0x10);
enum {
GANG_MAFIA = 0,
diff --git a/src/peds/Ped.h b/src/peds/Ped.h
index b33be407..ccffc3cb 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -82,7 +82,7 @@ struct FightMove
uint8 damage;
uint8 flags;
};
-static_assert(sizeof(FightMove) == 0x18, "FightMove: error");
+VALIDATE_SIZE(FightMove, 0x18);
// TODO: This is eFightState on mobile.
enum PedFightMoves
@@ -899,16 +899,5 @@ public:
void FinishFuckUCB(CAnimBlendAssociation *assoc, void *arg);
#ifndef PED_SKIN
-static_assert(offsetof(CPed, m_nPedState) == 0x224, "CPed: error");
-static_assert(offsetof(CPed, m_pCurSurface) == 0x2FC, "CPed: error");
-static_assert(offsetof(CPed, m_pMyVehicle) == 0x310, "CPed: error");
-static_assert(offsetof(CPed, m_nPedType) == 0x32C, "CPed: error");
-static_assert(offsetof(CPed, m_pCollidingEntity) == 0x34C, "CPed: error");
-static_assert(offsetof(CPed, m_weapons) == 0x35C, "CPed: error");
-static_assert(offsetof(CPed, m_currentWeapon) == 0x498, "CPed: error");
-static_assert(offsetof(CPed, m_lookTimer) == 0x4CC, "CPed: error");
-static_assert(offsetof(CPed, m_bodyPartBleeding) == 0x4F2, "CPed: error");
-static_assert(offsetof(CPed, m_pedInObjective) == 0x16C, "CPed: error");
-static_assert(offsetof(CPed, m_pEventEntity) == 0x19C, "CPed: error");
-static_assert(sizeof(CPed) == 0x53C, "CPed: error");
+VALIDATE_SIZE(CPed, 0x53C);
#endif
diff --git a/src/peds/PedIK.h b/src/peds/PedIK.h
index fd9e4702..a1cb5d13 100644
--- a/src/peds/PedIK.h
+++ b/src/peds/PedIK.h
@@ -64,4 +64,5 @@ public:
bool LookAtPosition(CVector const& pos);
bool RestoreLookAt(void);
};
-static_assert(sizeof(CPedIK) == 0x28, "CPedIK: error");
+
+VALIDATE_SIZE(CPedIK, 0x28);
diff --git a/src/peds/PedStats.h b/src/peds/PedStats.h
index 02f09c0d..7fc8cdbf 100644
--- a/src/peds/PedStats.h
+++ b/src/peds/PedStats.h
@@ -81,4 +81,5 @@ public:
static void LoadPedStats(void);
static ePedStats GetPedStatType(char *name);
};
-static_assert(sizeof(CPedStats) == 0x34, "CPedStats: error");
+
+VALIDATE_SIZE(CPedStats, 0x34);
diff --git a/src/peds/PedType.h b/src/peds/PedType.h
index c0c72550..3a765da1 100644
--- a/src/peds/PedType.h
+++ b/src/peds/PedType.h
@@ -91,4 +91,4 @@ public:
static bool IsThreat(int type, int threat) { return ms_apPedType[type]->m_threats & threat; }
};
-static_assert(sizeof(CPedType) == 0x20, "CPedType: error");
+VALIDATE_SIZE(CPedType, 0x20);
diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h
index 61b70f89..e8173c8c 100644
--- a/src/peds/PlayerPed.h
+++ b/src/peds/PlayerPed.h
@@ -85,5 +85,5 @@ public:
};
#ifndef PED_SKIN
-static_assert(sizeof(CPlayerPed) == 0x5F0, "CPlayerPed: error");
+VALIDATE_SIZE(CPlayerPed, 0x5F0);
#endif
diff --git a/src/render/2dEffect.h b/src/render/2dEffect.h
index a24a3f4f..2a71a8d5 100644
--- a/src/render/2dEffect.h
+++ b/src/render/2dEffect.h
@@ -89,4 +89,5 @@ public:
}
}
};
-static_assert(sizeof(C2dEffect) == 0x34, "C2dEffect: error");
+
+VALIDATE_SIZE(C2dEffect, 0x34);
diff --git a/src/render/Coronas.h b/src/render/Coronas.h
index 4b49e40e..46eb4315 100644
--- a/src/render/Coronas.h
+++ b/src/render/Coronas.h
@@ -38,7 +38,8 @@ struct CRegisteredCorona
void Update(void);
};
-static_assert(sizeof(CRegisteredCorona) == 0x80, "CRegisteredCorona: error");
+
+VALIDATE_SIZE(CRegisteredCorona, 0x80);
class CCoronas
{
diff --git a/src/render/Particle.h b/src/render/Particle.h
index b71dc717..7f02e318 100644
--- a/src/render/Particle.h
+++ b/src/render/Particle.h
@@ -91,4 +91,4 @@ public:
static void AddYardieDoorSmoke(CVector const &vecPos, CMatrix const &matMatrix);
};
-VALIDATE_SIZE(CParticle, 0x68); \ No newline at end of file
+VALIDATE_SIZE(CParticle, 0x68);
diff --git a/src/render/ParticleMgr.h b/src/render/ParticleMgr.h
index 70845a56..42e3f132 100644
--- a/src/render/ParticleMgr.h
+++ b/src/render/ParticleMgr.h
@@ -64,8 +64,10 @@ struct tParticleSystemData
RwRaster **m_ppRaster;
CParticle *m_pParticles;
};
-VALIDATE_SIZE(tParticleSystemData, 0x88);
+#ifdef CHECK_STRUCT_SIZES
+VALIDATE_SIZE(tParticleSystemData, 0x88);
+#endif
class cParticleSystemMgr
{
@@ -125,6 +127,8 @@ public:
void RangeCheck(tParticleSystemData *pData) { }
};
+#ifdef CHECK_STRUCT_SIZES
VALIDATE_SIZE(cParticleSystemMgr, 0x2420);
+#endif
extern cParticleSystemMgr mod_ParticleSystemManager; \ No newline at end of file
diff --git a/src/render/PointLights.h b/src/render/PointLights.h
index 56b84f71..9e94328f 100644
--- a/src/render/PointLights.h
+++ b/src/render/PointLights.h
@@ -13,7 +13,7 @@ public:
int8 fogType;
bool castExtraShadows;
};
-static_assert(sizeof(CRegisteredPointLight) == 0x2C, "CRegisteredPointLight: error");
+VALIDATE_SIZE(CRegisteredPointLight, 0x2C);
class CPointLights
{
diff --git a/src/render/Shadows.h b/src/render/Shadows.h
index 39be343e..ef56d336 100644
--- a/src/render/Shadows.h
+++ b/src/render/Shadows.h
@@ -51,7 +51,10 @@ public:
CStoredShadow()
{ }
};
+
+#ifdef CHECK_STRUCT_SIZES
VALIDATE_SIZE(CStoredShadow, 0x30);
+#endif
class CPolyBunch
{
@@ -65,7 +68,10 @@ public:
CPolyBunch()
{ }
};
+
+#ifdef CHECK_STRUCT_SIZES
VALIDATE_SIZE(CPolyBunch, 0x6C);
+#endif
class CStaticShadow
{
@@ -93,7 +99,10 @@ public:
void Free();
};
+
+#ifdef CHECK_STRUCT_SIZES
VALIDATE_SIZE(CStaticShadow, 0x40);
+#endif
class CPermanentShadow
{
@@ -115,6 +124,7 @@ public:
CPermanentShadow()
{ }
};
+
VALIDATE_SIZE(CPermanentShadow, 0x38);
class CPtrList;
diff --git a/src/render/WaterCannon.h b/src/render/WaterCannon.h
index d2d20863..a37bdd12 100644
--- a/src/render/WaterCannon.h
+++ b/src/render/WaterCannon.h
@@ -25,7 +25,7 @@ public:
void PushPeds(void);
};
-static_assert(sizeof(CWaterCannon) == 412, "CWaterCannon: error");
+VALIDATE_SIZE(CWaterCannon, 412);
class CWaterCannons
{
diff --git a/src/text/Text.h b/src/text/Text.h
index 00d1c5e6..4255e2a5 100644
--- a/src/text/Text.h
+++ b/src/text/Text.h
@@ -12,8 +12,9 @@ struct CKeyEntry
wchar *value;
char key[8];
};
+
// If this fails, CKeyArray::Load will have to be fixed
-static_assert(sizeof(CKeyEntry) == 12, "CKeyEntry: error");
+VALIDATE_SIZE(CKeyEntry, 12);
class CKeyArray
{
diff --git a/src/vehicles/Cranes.h b/src/vehicles/Cranes.h
index c0502638..6d877d82 100644
--- a/src/vehicles/Cranes.h
+++ b/src/vehicles/Cranes.h
@@ -72,7 +72,7 @@ public:
float GetHeightToDropoffHeight() { return m_fDropoffHeight + (m_bIsCrusher ? 7.0f : 2.0f); }
};
-static_assert(sizeof(CCrane) == 128, "CCrane: error");
+VALIDATE_SIZE(CCrane, 128);
class CCranes
{
diff --git a/src/weapons/WeaponInfo.h b/src/weapons/WeaponInfo.h
index 3bafd324..b5882082 100644
--- a/src/weapons/WeaponInfo.h
+++ b/src/weapons/WeaponInfo.h
@@ -46,4 +46,4 @@ public:
static void Shutdown(void);
};
-static_assert(sizeof(CWeaponInfo) == 0x54, "CWeaponInfo: error"); \ No newline at end of file
+VALIDATE_SIZE(CWeaponInfo, 0x54); \ No newline at end of file