diff options
author | Boris I. Bendovsky <[email protected]> | 2022-01-30 14:47:32 +0200 |
---|---|---|
committer | GitHub <[email protected]> | 2022-01-30 04:47:32 -0800 |
commit | 19ed994dc30ed84ea7cbbb5152577669fc25caf6 (patch) | |
tree | f68933bf8f778806618bd6c0b1bf9ced1b0ccf08 /al/effect.cpp | |
parent | 619249371a40f03cf988d1f5750d643df797c485 (diff) |
Add EAX extensions (EAX 2.0-5.0, X-RAM) (#632)
* Add EAX extensions (EAX 2.0-5.0, X-RAM)
* Comment out C++17 leftovers
* Remove everything related to patching
* Update alsoftrc.sample
* Rewrite integration
* Fix GCC compilation under Linux
* Always reset EAX effect properties when loading it into FX slot
Diffstat (limited to 'al/effect.cpp')
-rw-r--r-- | al/effect.cpp | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/al/effect.cpp b/al/effect.cpp index 217cc1c2..79cd7fab 100644 --- a/al/effect.cpp +++ b/al/effect.cpp @@ -51,6 +51,11 @@ #include "opthelpers.h" #include "vector.h" +#if ALSOFT_EAX +#include <cassert> + +#include "eax_exception.h" +#endif // ALSOFT_EAX const EffectList gEffectList[16]{ { "eaxreverb", EAXREVERB_EFFECT, AL_EFFECT_EAXREVERB }, @@ -745,3 +750,141 @@ void LoadReverbPreset(const char *name, ALeffect *effect) WARN("Reverb preset '%s' not found\n", name); } + +#if ALSOFT_EAX +namespace +{ + +class EaxAlEffectException : + public EaxException +{ +public: + explicit EaxAlEffectException( + const char* message) + : + EaxException{"[EAX_AL_EFFECT]", message} + { + } +}; // EaxAlEffectException + + +} // namespace + + +void ALeffect::eax_initialize() +{ + eax_effect = nullptr; + eax_effect = eax_create_eax_effect(type, Props); +} + +void ALeffect::eax_al_set_effect( + ALenum al_effect_type) +{ + if (al_effect_type != AL_EFFECT_NULL) + { + auto has_effect = false; + + for (const auto &effect_item : gEffectList) + { + if (al_effect_type == effect_item.val && !DisabledEffects[effect_item.type]) + { + has_effect = true; + break; + } + } + + if (!has_effect) + { + eax_fail("Effect not available."); + } + } + + InitEffectParams(this, al_effect_type); +} + +[[noreturn]] +void ALeffect::eax_fail( + const char* message) +{ + throw EaxAlEffectException{message}; +} + +EaxAlEffectDeleter::EaxAlEffectDeleter( + ALCcontext& context) noexcept + : + context_{&context} +{ +} + +void EaxAlEffectDeleter::operator()( + ALeffect* effect) const +{ + assert(effect); + + eax_al_delete_effect(*context_, *effect); +} + +EaxAlEffectUPtr eax_create_al_effect( + ALCcontext& context, + ALenum effect_type) +{ +#define EAX_PREFIX "[EAX_MAKE_EFFECT] " + + auto& device = *context.mALDevice; + std::lock_guard<std::mutex> effect_lock{device.EffectLock}; + + // Allocate. + // + if (!EnsureEffects(&device, 1)) + { + ERR(EAX_PREFIX "%s\n", "Failed to ensure."); + return nullptr; + } + + auto effect = EaxAlEffectUPtr{AllocEffect(&device), EaxAlEffectDeleter{context}}; + + if (!effect) + { + ERR(EAX_PREFIX "%s\n", "Failed to allocate."); + return nullptr; + } + + // Set the type. + // + auto is_supported = (effect_type == AL_EFFECT_NULL); + + if (!is_supported) + { + for (const auto& effect_item : gEffectList) + { + if(effect_type == effect_item.val && !DisabledEffects[effect_item.type]) + { + is_supported = true; + break; + } + } + } + + if (!is_supported) + { + ERR(EAX_PREFIX "Effect type 0x%04x not supported.\n", effect_type); + return nullptr; + } + + InitEffectParams(effect.get(), effect_type); + + return effect; + +#undef EAX_PREFIX +} + +void eax_al_delete_effect( + ALCcontext& context, + ALeffect& effect) +{ + auto& device = *context.mALDevice; + std::lock_guard<std::mutex> effect_lock{device.EffectLock}; + + FreeEffect(&device, &effect); +} +#endif // ALSOFT_EAX |