aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/alc.cpp1
-rw-r--r--Alc/inprogext.h5
-rw-r--r--OpenAL32/alAuxEffectSlot.cpp38
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;
}