diff --git a/router/al.cpp b/router/al.cpp index aabb5f30..06c314eb 100644 --- a/router/al.cpp +++ b/router/al.cpp @@ -130,3 +130,42 @@ DECL_THUNK3(void, alGetBufferi, ALuint, ALenum, ALint*) DECL_THUNK5(void, alGetBuffer3i, ALuint, ALenum, ALint*, ALint*, ALint*) DECL_THUNK3(void, alGetBufferiv, ALuint, ALenum, ALint*) DECL_THUNK5(void, alBufferData, ALuint, ALenum, const ALvoid*, ALsizei, ALsizei) + +/* EFX 1.0. Required here to be exported from libOpenAL32.dll.a/OpenAL32.lib + * with the router enabled. + */ +DECL_THUNK2(void, alGenFilters, ALsizei, ALuint*) +DECL_THUNK2(void, alDeleteFilters, ALsizei, const ALuint*) +DECL_THUNK1(ALboolean, alIsFilter, ALuint) +DECL_THUNK3(void, alFilterf, ALuint, ALenum, ALfloat) +DECL_THUNK3(void, alFilterfv, ALuint, ALenum, const ALfloat*) +DECL_THUNK3(void, alFilteri, ALuint, ALenum, ALint) +DECL_THUNK3(void, alFilteriv, ALuint, ALenum, const ALint*) +DECL_THUNK3(void, alGetFilterf, ALuint, ALenum, ALfloat*) +DECL_THUNK3(void, alGetFilterfv, ALuint, ALenum, ALfloat*) +DECL_THUNK3(void, alGetFilteri, ALuint, ALenum, ALint*) +DECL_THUNK3(void, alGetFilteriv, ALuint, ALenum, ALint*) + +DECL_THUNK2(void, alGenEffects, ALsizei, ALuint*) +DECL_THUNK2(void, alDeleteEffects, ALsizei, const ALuint*) +DECL_THUNK1(ALboolean, alIsEffect, ALuint) +DECL_THUNK3(void, alEffectf, ALuint, ALenum, ALfloat) +DECL_THUNK3(void, alEffectfv, ALuint, ALenum, const ALfloat*) +DECL_THUNK3(void, alEffecti, ALuint, ALenum, ALint) +DECL_THUNK3(void, alEffectiv, ALuint, ALenum, const ALint*) +DECL_THUNK3(void, alGetEffectf, ALuint, ALenum, ALfloat*) +DECL_THUNK3(void, alGetEffectfv, ALuint, ALenum, ALfloat*) +DECL_THUNK3(void, alGetEffecti, ALuint, ALenum, ALint*) +DECL_THUNK3(void, alGetEffectiv, ALuint, ALenum, ALint*) + +DECL_THUNK2(void, alGenAuxiliaryEffectSlots, ALsizei, ALuint*) +DECL_THUNK2(void, alDeleteAuxiliaryEffectSlots, ALsizei, const ALuint*) +DECL_THUNK1(ALboolean, alIsAuxiliaryEffectSlot, ALuint) +DECL_THUNK3(void, alAuxiliaryEffectSlotf, ALuint, ALenum, ALfloat) +DECL_THUNK3(void, alAuxiliaryEffectSlotfv, ALuint, ALenum, const ALfloat*) +DECL_THUNK3(void, alAuxiliaryEffectSloti, ALuint, ALenum, ALint) +DECL_THUNK3(void, alAuxiliaryEffectSlotiv, ALuint, ALenum, const ALint*) +DECL_THUNK3(void, alGetAuxiliaryEffectSlotf, ALuint, ALenum, ALfloat*) +DECL_THUNK3(void, alGetAuxiliaryEffectSlotfv, ALuint, ALenum, ALfloat*) +DECL_THUNK3(void, alGetAuxiliaryEffectSloti, ALuint, ALenum, ALint*) +DECL_THUNK3(void, alGetAuxiliaryEffectSlotiv, ALuint, ALenum, ALint*) diff --git a/router/alc.cpp b/router/alc.cpp index 210f683e..3aa3382b 100644 --- a/router/alc.cpp +++ b/router/alc.cpp @@ -118,6 +118,41 @@ static const std::array alcFunctions{{ DECL(alDopplerVelocity), DECL(alSpeedOfSound), DECL(alDistanceModel), + + /* EFX 1.0 */ + DECL(alGenFilters), + DECL(alDeleteFilters), + DECL(alIsFilter), + DECL(alFilterf), + DECL(alFilterfv), + DECL(alFilteri), + DECL(alFilteriv), + DECL(alGetFilterf), + DECL(alGetFilterfv), + DECL(alGetFilteri), + DECL(alGetFilteriv), + DECL(alGenEffects), + DECL(alDeleteEffects), + DECL(alIsEffect), + DECL(alEffectf), + DECL(alEffectfv), + DECL(alEffecti), + DECL(alEffectiv), + DECL(alGetEffectf), + DECL(alGetEffectfv), + DECL(alGetEffecti), + DECL(alGetEffectiv), + DECL(alGenAuxiliaryEffectSlots), + DECL(alDeleteAuxiliaryEffectSlots), + DECL(alIsAuxiliaryEffectSlot), + DECL(alAuxiliaryEffectSlotf), + DECL(alAuxiliaryEffectSlotfv), + DECL(alAuxiliaryEffectSloti), + DECL(alAuxiliaryEffectSlotiv), + DECL(alGetAuxiliaryEffectSlotf), + DECL(alGetAuxiliaryEffectSlotfv), + DECL(alGetAuxiliaryEffectSloti), + DECL(alGetAuxiliaryEffectSlotiv), }}; #undef DECL @@ -309,6 +344,56 @@ static ALint GetDriverIndexForName(const EnumeratedList *list, const ALCchar *na } +static void InitCtxFuncs(DriverIface &iface) +{ + ALCdevice *device{iface.alcGetContextsDevice(iface.alcGetCurrentContext())}; + +#define LOAD_PROC(x) do { \ + iface.x = reinterpret_cast(iface.alGetProcAddress(#x));\ + if(!iface.x) \ + ERR("Failed to find entry point for %s in %ls\n", #x, \ + iface.Name.c_str()); \ +} while(0) + if(iface.alcIsExtensionPresent(device, "ALC_EXT_EFX")) + { + LOAD_PROC(alGenFilters); + LOAD_PROC(alDeleteFilters); + LOAD_PROC(alIsFilter); + LOAD_PROC(alFilterf); + LOAD_PROC(alFilterfv); + LOAD_PROC(alFilteri); + LOAD_PROC(alFilteriv); + LOAD_PROC(alGetFilterf); + LOAD_PROC(alGetFilterfv); + LOAD_PROC(alGetFilteri); + LOAD_PROC(alGetFilteriv); + LOAD_PROC(alGenEffects); + LOAD_PROC(alDeleteEffects); + LOAD_PROC(alIsEffect); + LOAD_PROC(alEffectf); + LOAD_PROC(alEffectfv); + LOAD_PROC(alEffecti); + LOAD_PROC(alEffectiv); + LOAD_PROC(alGetEffectf); + LOAD_PROC(alGetEffectfv); + LOAD_PROC(alGetEffecti); + LOAD_PROC(alGetEffectiv); + LOAD_PROC(alGenAuxiliaryEffectSlots); + LOAD_PROC(alDeleteAuxiliaryEffectSlots); + LOAD_PROC(alIsAuxiliaryEffectSlot); + LOAD_PROC(alAuxiliaryEffectSlotf); + LOAD_PROC(alAuxiliaryEffectSlotfv); + LOAD_PROC(alAuxiliaryEffectSloti); + LOAD_PROC(alAuxiliaryEffectSlotiv); + LOAD_PROC(alGetAuxiliaryEffectSlotf); + LOAD_PROC(alGetAuxiliaryEffectSlotfv); + LOAD_PROC(alGetAuxiliaryEffectSloti); + LOAD_PROC(alGetAuxiliaryEffectSlotiv); + } +#undef LOAD_PROC +} + + ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename) { ALCdevice *device = nullptr; @@ -345,17 +430,17 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename) return nullptr; } TRACE("Found driver %d for name \"%s\"\n", idx, devicename); - device = DriverList[idx].alcOpenDevice(devicename); + device = DriverList[idx]->alcOpenDevice(devicename); } else { for(const auto &drv : DriverList) { - if(drv.ALCVer >= MAKE_ALC_VER(1, 1) || - drv.alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT")) + if(drv->ALCVer >= MAKE_ALC_VER(1, 1) + || drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT")) { TRACE("Using default device from driver %d\n", idx); - device = drv.alcOpenDevice(nullptr); + device = drv->alcOpenDevice(nullptr); break; } ++idx; @@ -366,7 +451,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename) { if(DeviceIfaceMap.insert(device, idx) != ALC_NO_ERROR) { - DriverList[idx].alcCloseDevice(device); + DriverList[idx]->alcCloseDevice(device); device = nullptr; } } @@ -383,7 +468,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device) LastError.store(ALC_INVALID_DEVICE); return ALC_FALSE; } - if(!DriverList[idx].alcCloseDevice(device)) + if(!DriverList[idx]->alcCloseDevice(device)) return ALC_FALSE; DeviceIfaceMap.removeByKey(device); return ALC_TRUE; @@ -400,12 +485,12 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin LastError.store(ALC_INVALID_DEVICE); return nullptr; } - context = DriverList[idx].alcCreateContext(device, attrlist); + context = DriverList[idx]->alcCreateContext(device, attrlist); if(context) { if(ContextIfaceMap.insert(context, idx) != ALC_NO_ERROR) { - DriverList[idx].alcDestroyContext(context); + DriverList[idx]->alcDestroyContext(context); context = nullptr; } } @@ -426,8 +511,11 @@ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context) LastError.store(ALC_INVALID_CONTEXT); return ALC_FALSE; } - if(!DriverList[idx].alcMakeContextCurrent(context)) + if(!DriverList[idx]->alcMakeContextCurrent(context)) return ALC_FALSE; + + auto do_init = [idx]() { InitCtxFuncs(*DriverList[idx]); }; + std::call_once(DriverList[idx]->InitOnceCtx, do_init); } /* Unset the context from the old driver if it's different from the new @@ -443,10 +531,10 @@ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context) else { DriverIface *oldiface = GetThreadDriver(); - if(oldiface && oldiface != &DriverList[idx]) + if(oldiface && oldiface != DriverList[idx].get()) oldiface->alcSetThreadContext(nullptr); - oldiface = CurrentCtxDriver.exchange(&DriverList[idx]); - if(oldiface && oldiface != &DriverList[idx]) + oldiface = CurrentCtxDriver.exchange(DriverList[idx].get()); + if(oldiface && oldiface != DriverList[idx].get()) oldiface->alcMakeContextCurrent(nullptr); } SetThreadDriver(nullptr); @@ -460,7 +548,7 @@ ALC_API void ALC_APIENTRY alcProcessContext(ALCcontext *context) { ALint idx = ContextIfaceMap.lookupByKey(context); if(idx >= 0) - return DriverList[idx].alcProcessContext(context); + return DriverList[idx]->alcProcessContext(context); } LastError.store(ALC_INVALID_CONTEXT); } @@ -471,7 +559,7 @@ ALC_API void ALC_APIENTRY alcSuspendContext(ALCcontext *context) { ALint idx = ContextIfaceMap.lookupByKey(context); if(idx >= 0) - return DriverList[idx].alcSuspendContext(context); + return DriverList[idx]->alcSuspendContext(context); } LastError.store(ALC_INVALID_CONTEXT); } @@ -486,7 +574,7 @@ ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context) return; } - DriverList[idx].alcDestroyContext(context); + DriverList[idx]->alcDestroyContext(context); ContextIfaceMap.removeByKey(context); } @@ -503,7 +591,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *context) { ALint idx = ContextIfaceMap.lookupByKey(context); if(idx >= 0) - return DriverList[idx].alcGetContextsDevice(context); + return DriverList[idx]->alcGetContextsDevice(context); } LastError.store(ALC_INVALID_CONTEXT); return nullptr; @@ -516,7 +604,7 @@ ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device) { ALint idx = DeviceIfaceMap.lookupByKey(device); if(idx < 0) return ALC_INVALID_DEVICE; - return DriverList[idx].alcGetError(device); + return DriverList[idx]->alcGetError(device); } return LastError.exchange(ALC_NO_ERROR); } @@ -534,7 +622,7 @@ ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const A LastError.store(ALC_INVALID_DEVICE); return ALC_FALSE; } - return DriverList[idx].alcIsExtensionPresent(device, extname); + return DriverList[idx]->alcIsExtensionPresent(device, extname); } len = strlen(extname); @@ -563,7 +651,7 @@ ALC_API void* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *f LastError.store(ALC_INVALID_DEVICE); return nullptr; } - return DriverList[idx].alcGetProcAddress(device, funcname); + return DriverList[idx]->alcGetProcAddress(device, funcname); } auto iter = std::find_if(alcFunctions.cbegin(), alcFunctions.cend(), @@ -583,7 +671,7 @@ ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *e LastError.store(ALC_INVALID_DEVICE); return 0; } - return DriverList[idx].alcGetEnumValue(device, enumname); + return DriverList[idx]->alcGetEnumValue(device, enumname); } auto iter = std::find_if(alcEnumerations.cbegin(), alcEnumerations.cend(), @@ -603,7 +691,7 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum para LastError.store(ALC_INVALID_DEVICE); return nullptr; } - return DriverList[idx].alcGetString(device, param); + return DriverList[idx]->alcGetString(device, param); } switch(param) @@ -631,10 +719,10 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum para for(const auto &drv : DriverList) { /* Only enumerate names from drivers that support it. */ - if(drv.ALCVer >= MAKE_ALC_VER(1, 1) - || drv.alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT")) + if(drv->ALCVer >= MAKE_ALC_VER(1, 1) + || drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT")) AppendDeviceList(&DevicesList, - drv.alcGetString(nullptr, ALC_DEVICE_SPECIFIER), idx); + drv->alcGetString(nullptr, ALC_DEVICE_SPECIFIER), idx); ++idx; } /* Ensure the list is double-null termianted. */ @@ -654,13 +742,13 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum para /* If the driver doesn't support ALC_ENUMERATE_ALL_EXT, substitute * standard enumeration. */ - if(drv.alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT")) + if(drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT")) AppendDeviceList(&AllDevicesList, - drv.alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER), idx); - else if(drv.ALCVer >= MAKE_ALC_VER(1, 1) - || drv.alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT")) + drv->alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER), idx); + else if(drv->ALCVer >= MAKE_ALC_VER(1, 1) + || drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT")) AppendDeviceList(&AllDevicesList, - drv.alcGetString(nullptr, ALC_DEVICE_SPECIFIER), idx); + drv->alcGetString(nullptr, ALC_DEVICE_SPECIFIER), idx); ++idx; } /* Ensure the list is double-null termianted. */ @@ -677,10 +765,10 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum para ALint idx{0}; for(const auto &drv : DriverList) { - if(drv.ALCVer >= MAKE_ALC_VER(1, 1) - || drv.alcIsExtensionPresent(nullptr, "ALC_EXT_CAPTURE")) + if(drv->ALCVer >= MAKE_ALC_VER(1, 1) + || drv->alcIsExtensionPresent(nullptr, "ALC_EXT_CAPTURE")) AppendDeviceList(&CaptureDevicesList, - drv.alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER), idx); + drv->alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER), idx); ++idx; } /* Ensure the list is double-null termianted. */ @@ -692,39 +780,33 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum para case ALC_DEFAULT_DEVICE_SPECIFIER: { - auto iter = std::find_if(DriverList.cbegin(), DriverList.cend(), - [](const DriverIface &drv) -> bool - { - return drv.ALCVer >= MAKE_ALC_VER(1, 1) - || drv.alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT"); - } - ); - if(iter != DriverList.cend()) - return iter->alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER); + for(const auto &drv : DriverList) + { + if(drv->ALCVer >= MAKE_ALC_VER(1, 1) + || drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT")) + return drv->alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER); + } return ""; } case ALC_DEFAULT_ALL_DEVICES_SPECIFIER: { - auto iter = std::find_if(DriverList.cbegin(), DriverList.cend(), - [](const DriverIface &drv) -> bool - { return drv.alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT") != ALC_FALSE; }); - if(iter != DriverList.cend()) - return iter->alcGetString(nullptr, ALC_DEFAULT_ALL_DEVICES_SPECIFIER); + for(const auto &drv : DriverList) + { + if(drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT") != ALC_FALSE) + return drv->alcGetString(nullptr, ALC_DEFAULT_ALL_DEVICES_SPECIFIER); + } return ""; } case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER: { - auto iter = std::find_if(DriverList.cbegin(), DriverList.cend(), - [](const DriverIface &drv) -> bool - { - return drv.ALCVer >= MAKE_ALC_VER(1, 1) - || drv.alcIsExtensionPresent(nullptr, "ALC_EXT_CAPTURE"); - } - ); - if(iter != DriverList.cend()) - return iter->alcGetString(nullptr, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER); + for(const auto &drv : DriverList) + { + if(drv->ALCVer >= MAKE_ALC_VER(1, 1) + || drv->alcIsExtensionPresent(nullptr, "ALC_EXT_CAPTURE")) + return drv->alcGetString(nullptr, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER); + } return ""; } @@ -745,7 +827,7 @@ ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsi LastError.store(ALC_INVALID_DEVICE); return; } - return DriverList[idx].alcGetIntegerv(device, param, size, values); + return DriverList[idx]->alcGetIntegerv(device, param, size, values); } if(size <= 0 || values == nullptr) @@ -813,17 +895,17 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *devicename, return nullptr; } TRACE("Found driver %d for name \"%s\"\n", idx, devicename); - device = DriverList[idx].alcCaptureOpenDevice(devicename, frequency, format, buffersize); + device = DriverList[idx]->alcCaptureOpenDevice(devicename, frequency, format, buffersize); } else { for(const auto &drv : DriverList) { - if(drv.ALCVer >= MAKE_ALC_VER(1, 1) - || drv.alcIsExtensionPresent(nullptr, "ALC_EXT_CAPTURE")) + if(drv->ALCVer >= MAKE_ALC_VER(1, 1) + || drv->alcIsExtensionPresent(nullptr, "ALC_EXT_CAPTURE")) { TRACE("Using default capture device from driver %d\n", idx); - device = drv.alcCaptureOpenDevice(nullptr, frequency, format, buffersize); + device = drv->alcCaptureOpenDevice(nullptr, frequency, format, buffersize); break; } ++idx; @@ -834,7 +916,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *devicename, { if(DeviceIfaceMap.insert(device, idx) != ALC_NO_ERROR) { - DriverList[idx].alcCaptureCloseDevice(device); + DriverList[idx]->alcCaptureCloseDevice(device); device = nullptr; } } @@ -851,7 +933,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device) LastError.store(ALC_INVALID_DEVICE); return ALC_FALSE; } - if(!DriverList[idx].alcCaptureCloseDevice(device)) + if(!DriverList[idx]->alcCaptureCloseDevice(device)) return ALC_FALSE; DeviceIfaceMap.removeByKey(device); return ALC_TRUE; @@ -863,7 +945,7 @@ ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device) { ALint idx = DeviceIfaceMap.lookupByKey(device); if(idx >= 0) - return DriverList[idx].alcCaptureStart(device); + return DriverList[idx]->alcCaptureStart(device); } LastError.store(ALC_INVALID_DEVICE); } @@ -874,7 +956,7 @@ ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device) { ALint idx = DeviceIfaceMap.lookupByKey(device); if(idx >= 0) - return DriverList[idx].alcCaptureStop(device); + return DriverList[idx]->alcCaptureStop(device); } LastError.store(ALC_INVALID_DEVICE); } @@ -885,7 +967,7 @@ ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, { ALint idx = DeviceIfaceMap.lookupByKey(device); if(idx >= 0) - return DriverList[idx].alcCaptureSamples(device, buffer, samples); + return DriverList[idx]->alcCaptureSamples(device, buffer, samples); } LastError.store(ALC_INVALID_DEVICE); } @@ -908,17 +990,20 @@ ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context) idx = ContextIfaceMap.lookupByKey(context); if(idx >= 0) { - if(DriverList[idx].alcSetThreadContext(context)) + if(DriverList[idx]->alcSetThreadContext(context)) { + auto do_init = [idx]() { InitCtxFuncs(*DriverList[idx]); }; + std::call_once(DriverList[idx]->InitOnceCtx, do_init); + DriverIface *oldiface = GetThreadDriver(); - if(oldiface != &DriverList[idx]) + if(oldiface != DriverList[idx].get()) { - SetThreadDriver(&DriverList[idx]); + SetThreadDriver(DriverList[idx].get()); if(oldiface) oldiface->alcSetThreadContext(nullptr); } return ALC_TRUE; } - err = DriverList[idx].alcGetError(nullptr); + err = DriverList[idx]->alcGetError(nullptr); } LastError.store(err); return ALC_FALSE; diff --git a/router/router.cpp b/router/router.cpp index 67c34812..a0ce165c 100644 --- a/router/router.cpp +++ b/router/router.cpp @@ -17,7 +17,7 @@ #include "version.h" -std::vector DriverList; +std::vector DriverList; thread_local DriverIface *ThreadCtxDriver; @@ -84,13 +84,13 @@ static void AddModule(HMODULE module, const WCHAR *name) { for(auto &drv : DriverList) { - if(drv.Module == module) + if(drv->Module == module) { TRACE("Skipping already-loaded module %p\n", decltype(std::declval()){module}); FreeLibrary(module); return; } - if(drv.Name == name) + if(drv->Name == name) { TRACE("Skipping similarly-named module %ls\n", name); FreeLibrary(module); @@ -98,8 +98,8 @@ static void AddModule(HMODULE module, const WCHAR *name) } } - DriverList.emplace_back(name, module); - DriverIface &newdrv = DriverList.back(); + DriverList.emplace_back(std::make_unique(name, module)); + DriverIface &newdrv = *DriverList.back(); /* Load required functions. */ int err = 0; diff --git a/router/router.h b/router/router.h index f49a96ef..2a126d42 100644 --- a/router/router.h +++ b/router/router.h @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -24,6 +25,7 @@ struct DriverIface { std::wstring Name; HMODULE Module{nullptr}; int ALCVer{0}; + std::once_flag InitOnceCtx{}; LPALCCREATECONTEXT alcCreateContext{nullptr}; LPALCMAKECONTEXTCURRENT alcMakeContextCurrent{nullptr}; @@ -123,6 +125,41 @@ struct DriverIface { LPALSPEEDOFSOUND alSpeedOfSound{nullptr}; LPALDISTANCEMODEL alDistanceModel{nullptr}; + /* Functions to load after first context creation. */ + LPALGENFILTERS alGenFilters{nullptr}; + LPALDELETEFILTERS alDeleteFilters{nullptr}; + LPALISFILTER alIsFilter{nullptr}; + LPALFILTERF alFilterf{nullptr}; + LPALFILTERFV alFilterfv{nullptr}; + LPALFILTERI alFilteri{nullptr}; + LPALFILTERIV alFilteriv{nullptr}; + LPALGETFILTERF alGetFilterf{nullptr}; + LPALGETFILTERFV alGetFilterfv{nullptr}; + LPALGETFILTERI alGetFilteri{nullptr}; + LPALGETFILTERIV alGetFilteriv{nullptr}; + LPALGENEFFECTS alGenEffects{nullptr}; + LPALDELETEEFFECTS alDeleteEffects{nullptr}; + LPALISEFFECT alIsEffect{nullptr}; + LPALEFFECTF alEffectf{nullptr}; + LPALEFFECTFV alEffectfv{nullptr}; + LPALEFFECTI alEffecti{nullptr}; + LPALEFFECTIV alEffectiv{nullptr}; + LPALGETEFFECTF alGetEffectf{nullptr}; + LPALGETEFFECTFV alGetEffectfv{nullptr}; + LPALGETEFFECTI alGetEffecti{nullptr}; + LPALGETEFFECTIV alGetEffectiv{nullptr}; + LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots{nullptr}; + LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots{nullptr}; + LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot{nullptr}; + LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf{nullptr}; + LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv{nullptr}; + LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti{nullptr}; + LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv{nullptr}; + LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf{nullptr}; + LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv{nullptr}; + LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti{nullptr}; + LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv{nullptr}; + template DriverIface(T&& name, HMODULE mod) : Name(std::forward(name)), Module(mod) @@ -134,8 +171,9 @@ struct DriverIface { Module = nullptr; } }; +using DriverIfacePtr = std::unique_ptr; -extern std::vector DriverList; +extern std::vector DriverList; extern thread_local DriverIface *ThreadCtxDriver; extern std::atomic CurrentCtxDriver;