diff options
author | aap <aap@papnet.eu> | 2020-05-11 22:21:26 +0200 |
---|---|---|
committer | aap <aap@papnet.eu> | 2020-05-11 22:21:26 +0200 |
commit | 0eb5f93e96bfc4b31c0bde01e9f1296b3b612bc2 (patch) | |
tree | 16bf11e0e8a0353448a643322e9511e8ba659fca /src | |
parent | 6e4710b71737119705516d44c743cfac7c9923f2 (diff) | |
parent | d9db03d606020f07c7907dffcf7b278e98eefeae (diff) |
Merge branch 'miami' of github.com:GTAmodding/re3 into miami
Diffstat (limited to 'src')
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 ¢er, 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 |