diff options
-rw-r--r-- | Alc/alc.cpp | 1 | ||||
-rw-r--r-- | Alc/inprogext.h | 5 | ||||
-rw-r--r-- | OpenAL32/alAuxEffectSlot.cpp | 38 |
3 files changed, 44 insertions, 0 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp index c225eaf2..bde9aa79 100644 --- a/Alc/alc.cpp +++ b/Alc/alc.cpp @@ -786,6 +786,7 @@ constexpr ALchar alExtList[] = "AL_SOFT_block_alignment " "AL_SOFT_deferred_updates " "AL_SOFT_direct_channels " + "AL_SOFTX_effect_chain " "AL_SOFTX_events " "AL_SOFTX_filter_gain_ex " "AL_SOFT_gain_clamp_ex " diff --git a/Alc/inprogext.h b/Alc/inprogext.h index 3025abe2..6921de8c 100644 --- a/Alc/inprogext.h +++ b/Alc/inprogext.h @@ -80,6 +80,11 @@ AL_API void AL_APIENTRY alSourceQueueBufferLayersSOFT(ALuint src, ALsizei nb, co #endif #endif +#ifndef AL_SOFT_effect_chain +#define AL_SOFT_effect_chain +#define AL_EFFECTSLOT_TARGET_SOFT 0xf000 +#endif + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/OpenAL32/alAuxEffectSlot.cpp b/OpenAL32/alAuxEffectSlot.cpp index 4add1668..b91774dc 100644 --- a/OpenAL32/alAuxEffectSlot.cpp +++ b/OpenAL32/alAuxEffectSlot.cpp @@ -295,6 +295,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param if(UNLIKELY(!slot)) SETERR_RETURN(context.get(), AL_INVALID_NAME,, "Invalid effect slot ID %u", effectslot); + ALeffectslot *target{}; ALCdevice *device{}; ALenum err{}; switch(param) @@ -322,6 +323,37 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param slot->AuxSendAuto = value; break; + case AL_EFFECTSLOT_TARGET_SOFT: + target = (value ? LookupEffectSlot(context.get(), value) : nullptr); + if(value && !target) + SETERR_RETURN(context.get(), AL_INVALID_VALUE,, "Invalid effect slot target ID"); + if(target) + { + ALeffectslot *checker{target}; + while(checker && checker != slot) + checker = checker->Target; + if(checker) + SETERR_RETURN(context.get(), AL_INVALID_OPERATION,, + "Setting target of effect slot ID %u to %u creates circular chain", slot->id, + target->id); + } + + if(ALeffectslot *oldtarget{slot->Target}) + { + /* We must force an update if there was an existing effect slot + * target, in case it's about to be deleted. + */ + if(target) IncrementRef(&target->ref); + DecrementRef(&oldtarget->ref); + slot->Target = target; + UpdateEffectSlotProps(slot, context.get()); + return; + } + + if(target) IncrementRef(&target->ref); + slot->Target = target; + break; + default: SETERR_RETURN(context.get(), AL_INVALID_ENUM,, "Invalid effect slot integer property 0x%04x", param); @@ -335,6 +367,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum para { case AL_EFFECTSLOT_EFFECT: case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: + case AL_EFFECTSLOT_TARGET_SOFT: alAuxiliaryEffectSloti(effectslot, param, values[0]); return; } @@ -422,6 +455,10 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum pa *value = slot->AuxSendAuto; break; + case AL_EFFECTSLOT_TARGET_SOFT: + *value = slot->Target ? slot->Target->id : 0; + break; + default: SETERR_RETURN(context.get(), AL_INVALID_ENUM,, "Invalid effect slot integer property 0x%04x", param); @@ -434,6 +471,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum p { case AL_EFFECTSLOT_EFFECT: case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: + case AL_EFFECTSLOT_TARGET_SOFT: alGetAuxiliaryEffectSloti(effectslot, param, values); return; } |