diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 6ac8bbd..44b9ad7 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -13,4 +13,6 @@ target_link_libraries(sound PRIVATE ui util + PUBLIC + fmod ) diff --git a/src/sound/SESound.cpp b/src/sound/SESound.cpp new file mode 100644 index 0000000..9021dc4 --- /dev/null +++ b/src/sound/SESound.cpp @@ -0,0 +1,143 @@ +#include "sound/SESound.hpp" +#include + +#define LOG_WRITE(result, ...) \ + SESound::Log_Write(__LINE__, __FILE__, result, __VA_ARGS__); + +FMOD::System* SESound::s_pGameSystem; + +void* FSoundAllocCallback(uint32_t size, FMOD_MEMORY_TYPE type, const char* sourcestr) { + return SMemAlloc(size, "FMod", 0, 0x8); +}; + +void* FSoundReallocCallback(void* ptr, uint32_t size, FMOD_MEMORY_TYPE type, const char* sourcestr) { + return SMemReAlloc(ptr, size, "FMod", 0, 0x0); +} + +void FSoundFreeCallback(void* ptr, FMOD_MEMORY_TYPE type, const char *sourcestr) { + SMemFree(ptr, "FMod", 0, 0x0); +} + +void SESound::Init(int32_t maxChannels, int32_t* a2, int32_t enableReverb, int32_t enableSoftwareHRTF, int32_t* numChannels, int32_t* outputDriverIndex, const char* outputDriverName, void* a8, int32_t a9) { + // TODO + + FMOD_INITFLAGS fmodFlags = FMOD_INIT_NORMAL; + FMOD_RESULT result; + + if (!a9) { + LOG_WRITE(FMOD_OK, "=> Version %s (%s) %s", "3.3.5", "12340", "Jun 24 2010"); + } + + LOG_WRITE(FMOD_OK, " "); + LOG_WRITE(FMOD_OK, "=> Setting up Game Sound:"); + LOG_WRITE(FMOD_OK, " - SESound Engine Init"); + + // Initialize FMOD memory + + LOG_WRITE(FMOD_OK, " - FMOD Memory Init"); + + FMOD::Memory_Initialize(nullptr, 0, &FSoundAllocCallback, &FSoundReallocCallback, &FSoundFreeCallback); + + // TODO + + // Create FMOD system + + SESound::s_pGameSystem = nullptr; + + LOG_WRITE(FMOD_OK, " - FMOD System Create"); + + result = FMOD::System_Create(&SESound::s_pGameSystem); + + if (result != FMOD_OK) { + // TODO + + LOG_WRITE( FMOD_OK, " -###########################################################################################" ); + LOG_WRITE( result, " -######## ERROR INITIALIZING. ALL GAME SOUND DISABLED." ); + LOG_WRITE( FMOD_OK, " -###########################################################################################" ); + + SESound::s_pGameSystem->setOutput(FMOD_OUTPUTTYPE_NOSOUND); + + LOG_WRITE(FMOD_OK, "=> Game Sound Init Failed."); + LOG_WRITE(FMOD_OK, " "); + + SESound::s_pGameSystem->init(32, FMOD_INIT_NORMAL | FMOD_INIT_3D_RIGHTHANDED, nullptr); + + return; + } + + // TODO + + SESound::s_pGameSystem->setOutput(FMOD_OUTPUTTYPE_AUTODETECT); + + // TODO + + // Get FMOD version + + uint32_t fmodVersion; + + result = SESound::s_pGameSystem->getVersion(&fmodVersion); + + if (result != FMOD_OK) { + // TODO + + LOG_WRITE( FMOD_OK, " -###########################################################################################" ); + LOG_WRITE( result, " -######## ERROR INITIALIZING. ALL GAME SOUND DISABLED." ); + LOG_WRITE( FMOD_OK, " -###########################################################################################" ); + + SESound::s_pGameSystem->setOutput(FMOD_OUTPUTTYPE_NOSOUND); + + LOG_WRITE(FMOD_OK, "=> Game Sound Init Failed."); + LOG_WRITE(FMOD_OK, " "); + + SESound::s_pGameSystem->init(32, FMOD_INIT_NORMAL | FMOD_INIT_3D_RIGHTHANDED, nullptr); + + return; + } + + LOG_WRITE(FMOD_OK, " - FMOD version %08x detected", fmodVersion); + + // TODO Check FMOD version + + // TODO + + // Initialize FMOD system + + result = SESound::s_pGameSystem->init(maxChannels, fmodFlags | FMOD_INIT_3D_RIGHTHANDED, nullptr); + + if (result == FMOD_ERR_OUTPUT_CREATEBUFFER) { + // TODO + } + + // TODO + + // Set doppler scale, distance factor, rolloff scale + + result = SESound::s_pGameSystem->set3DSettings(1.0f, 1.0f, 4.0f); + + if (result != FMOD_OK) { + // TODO + + LOG_WRITE( FMOD_OK, " -###########################################################################################" ); + LOG_WRITE( result, " -######## ERROR INITIALIZING. ALL GAME SOUND DISABLED." ); + LOG_WRITE( FMOD_OK, " -###########################################################################################" ); + + SESound::s_pGameSystem->setOutput(FMOD_OUTPUTTYPE_NOSOUND); + + LOG_WRITE(FMOD_OK, "=> Game Sound Init Failed."); + LOG_WRITE(FMOD_OK, " "); + + SESound::s_pGameSystem->init(32, FMOD_INIT_NORMAL | FMOD_INIT_3D_RIGHTHANDED, nullptr); + + return; + } + + // TODO + + LOG_WRITE(FMOD_OK, " - FMOD System Init OK!"); + LOG_WRITE(FMOD_OK, "=> Game Sound is ready."); + LOG_WRITE(FMOD_OK, " "); +} + +void SESound::Log_Write(int32_t line, const char* file, FMOD_RESULT result, const char* fmt, ...) { + // TODO +} diff --git a/src/sound/SESound.hpp b/src/sound/SESound.hpp new file mode 100644 index 0000000..75eed8f --- /dev/null +++ b/src/sound/SESound.hpp @@ -0,0 +1,17 @@ +#ifndef SOUND_SE_SOUND_HPP +#define SOUND_SE_SOUND_HPP + +#include +#include + +class SESound { + public: + // Static variables + static FMOD::System* s_pGameSystem; + + // Static functions + static void Init(int32_t maxChannels, int32_t (*a2), int32_t enableReverb, int32_t enableSoftwareHRTF, int32_t* numChannels, int32_t* outputDriverIndex, const char* outputDriverName, void (*a8), int32_t a9); + static void Log_Write(int32_t line, const char* file, FMOD_RESULT result, const char* fmt, ...); +}; + +#endif diff --git a/src/sound/SI2.cpp b/src/sound/SI2.cpp index b548e03..3738a11 100644 --- a/src/sound/SI2.cpp +++ b/src/sound/SI2.cpp @@ -1,8 +1,17 @@ #include "sound/SI2.hpp" #include "console/CVar.hpp" #include "sound/CVarHandlers.hpp" +#include "sound/SESound.hpp" #include "ui/FrameScript.hpp" +CVar* SI2::s_pCVar_Sound_EnableReverb; +CVar* SI2::s_pCVar_Sound_EnableSoftwareHRTF; +CVar* SI2::s_pCVar_Sound_NumChannels; +CVar* SI2::s_pCVar_Sound_OutputDriverIndex; +CVar* SI2::s_pCVar_Sound_OutputDriverName; + +static int32_t s_initFlags; + int32_t SI2::Init(int32_t a1) { // TODO // if (CmdLineGetBool(26)) { @@ -25,6 +34,93 @@ int32_t SI2::Init(int32_t a1) { SI2::RegisterCVars(); } + // Enable reverb + + int32_t enableReverb = 0; + + if (!(s_initFlags & 0x1)) { + SI2::s_pCVar_Sound_EnableReverb = CVar::Lookup("Sound_EnableReverb"); + s_initFlags |= 0x1; + } + + auto enableReverbVar = SI2::s_pCVar_Sound_EnableReverb; + + if (enableReverbVar) { + enableReverb = enableReverbVar->GetInt(); + } + + // Enable software HRTF + + int32_t enableSoftwareHRTF = 0; + + if (!(s_initFlags & 0x2)) { + SI2::s_pCVar_Sound_EnableSoftwareHRTF = CVar::Lookup("Sound_EnableSoftwareHRTF"); + s_initFlags |= 0x2; + } + + auto enableSoftwareHRTFVar = SI2::s_pCVar_Sound_EnableSoftwareHRTF; + + if (enableSoftwareHRTFVar) { + enableSoftwareHRTF = enableSoftwareHRTFVar->GetInt(); + } + + // Num channels + + int32_t numChannels = 4; + + if (!(s_initFlags & 0x4)) { + SI2::s_pCVar_Sound_NumChannels = CVar::Lookup("Sound_NumChannels"); + s_initFlags |= 0x4; + } + + auto numChannelsVar = SI2::s_pCVar_Sound_NumChannels; + + if (numChannelsVar) { + numChannels = numChannelsVar->GetInt(); + } + + // Output driver index + + int32_t outputDriverIndex = 0; + + if (!(s_initFlags & 0x8)) { + SI2::s_pCVar_Sound_OutputDriverIndex = CVar::Lookup("Sound_OutputDriverIndex"); + s_initFlags |= 0x8; + } + + auto outputDriverIndexVar = SI2::s_pCVar_Sound_OutputDriverIndex; + + if (outputDriverIndexVar) { + outputDriverIndex = outputDriverIndexVar->GetInt(); + } + + // Output driver name + + const char* outputDriverName = ""; + + if (!(s_initFlags & 0x10)) { + SI2::s_pCVar_Sound_OutputDriverName = CVar::Lookup("Sound_OutputDriverName"); + s_initFlags |= 0x10; + } + + auto outputDriverNameVar = SI2::s_pCVar_Sound_OutputDriverName; + + if (outputDriverNameVar) { + outputDriverName = outputDriverNameVar->GetString(); + } + + SESound::Init( + 512, + nullptr, // TODO callback fn + enableReverb, + enableSoftwareHRTF, + &numChannels, + &outputDriverIndex, + outputDriverName, + nullptr, // TODO callback fn + a1 + ); + // TODO return 0; diff --git a/src/sound/SI2.hpp b/src/sound/SI2.hpp index ba4992e..2189671 100644 --- a/src/sound/SI2.hpp +++ b/src/sound/SI2.hpp @@ -5,9 +5,16 @@ #include "ui/Types.hpp" #include +class CVar; + class SI2 { public: // Static variables + static CVar* s_pCVar_Sound_EnableReverb; + static CVar* s_pCVar_Sound_EnableSoftwareHRTF; + static CVar* s_pCVar_Sound_NumChannels; + static CVar* s_pCVar_Sound_OutputDriverIndex; + static CVar* s_pCVar_Sound_OutputDriverName; static FrameScript_Method s_ScriptFunctions[NUM_SCRIPT_FUNCTIONS_SI2]; // Static functions