aboutsummaryrefslogtreecommitdiffstats
path: root/al/eax/eax_call.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'al/eax/eax_call.cpp')
-rw-r--r--al/eax/eax_call.cpp323
1 files changed, 323 insertions, 0 deletions
diff --git a/al/eax/eax_call.cpp b/al/eax/eax_call.cpp
new file mode 100644
index 00000000..19565852
--- /dev/null
+++ b/al/eax/eax_call.cpp
@@ -0,0 +1,323 @@
+#include "config.h"
+
+#include "eax_call.h"
+#include "exception.h"
+
+
+namespace {
+
+constexpr auto deferred_flag = 0x80000000U;
+
+class EaxEaxCallException :
+ public EaxException
+{
+public:
+ explicit EaxEaxCallException(
+ const char* message)
+ :
+ EaxException{"EAX_EAX_CALL", message}
+ {
+ }
+}; // EaxEaxCallException
+
+} // namespace
+
+
+EaxEaxCall::EaxEaxCall(
+ bool is_get,
+ const GUID& property_set_guid,
+ ALuint property_id,
+ ALuint property_source_id,
+ ALvoid* property_buffer,
+ ALuint property_size)
+ : is_get_{is_get}, version_{0}, property_set_id_{EaxEaxCallPropertySetId::none}
+ , property_id_{property_id & ~deferred_flag}, property_source_id_{property_source_id}
+ , property_buffer_{property_buffer}, property_size_{property_size}
+{
+ if (false)
+ {
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX40_Context)
+ {
+ version_ = 4;
+ property_set_id_ = EaxEaxCallPropertySetId::context;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX50_Context)
+ {
+ version_ = 5;
+ property_set_id_ = EaxEaxCallPropertySetId::context;
+ }
+ else if (property_set_guid == DSPROPSETID_EAX20_ListenerProperties)
+ {
+ version_ = 2;
+ fx_slot_index_ = 0u;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
+ property_id_ = convert_eax_v2_0_listener_property_id(property_id_);
+ }
+ else if (property_set_guid == DSPROPSETID_EAX30_ListenerProperties)
+ {
+ version_ = 3;
+ fx_slot_index_ = 0u;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot0)
+ {
+ version_ = 4;
+ fx_slot_index_ = 0u;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot0)
+ {
+ version_ = 5;
+ fx_slot_index_ = 0u;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot1)
+ {
+ version_ = 4;
+ fx_slot_index_ = 1u;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot1)
+ {
+ version_ = 5;
+ fx_slot_index_ = 1u;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot2)
+ {
+ version_ = 4;
+ fx_slot_index_ = 2u;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot2)
+ {
+ version_ = 5;
+ fx_slot_index_ = 2u;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot3)
+ {
+ version_ = 4;
+ fx_slot_index_ = 3u;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot3)
+ {
+ version_ = 5;
+ fx_slot_index_ = 3u;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid == DSPROPSETID_EAX20_BufferProperties)
+ {
+ version_ = 2;
+ property_set_id_ = EaxEaxCallPropertySetId::source;
+ property_id_ = convert_eax_v2_0_buffer_property_id(property_id_);
+ }
+ else if (property_set_guid == DSPROPSETID_EAX30_BufferProperties)
+ {
+ version_ = 3;
+ property_set_id_ = EaxEaxCallPropertySetId::source;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX40_Source)
+ {
+ version_ = 4;
+ property_set_id_ = EaxEaxCallPropertySetId::source;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX50_Source)
+ {
+ version_ = 5;
+ property_set_id_ = EaxEaxCallPropertySetId::source;
+ }
+ else if (property_set_guid == DSPROPSETID_EAX_ReverbProperties)
+ {
+ version_ = 1;
+ fx_slot_index_ = 0u;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
+ }
+ else if (property_set_guid == DSPROPSETID_EAXBUFFER_ReverbProperties)
+ {
+ version_ = 1;
+ property_set_id_ = EaxEaxCallPropertySetId::source;
+ }
+ else
+ {
+ fail("Unsupported property set id.");
+ }
+
+ if (version_ < 1 || version_ > 5)
+ {
+ fail("EAX version out of range.");
+ }
+
+ if(!(property_id&deferred_flag))
+ {
+ if(property_set_id_ != EaxEaxCallPropertySetId::fx_slot && property_id_ != 0)
+ {
+ if (!property_buffer)
+ {
+ fail("Null property buffer.");
+ }
+
+ if (property_size == 0)
+ {
+ fail("Empty property.");
+ }
+ }
+ }
+
+ if(property_set_id_ == EaxEaxCallPropertySetId::source && property_source_id_ == 0)
+ {
+ fail("Null AL source id.");
+ }
+
+ if (property_set_id_ == EaxEaxCallPropertySetId::fx_slot)
+ {
+ if (property_id_ < EAXFXSLOT_NONE)
+ {
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
+ }
+ }
+}
+
+[[noreturn]]
+void EaxEaxCall::fail(
+ const char* message)
+{
+ throw EaxEaxCallException{message};
+}
+
+ALuint EaxEaxCall::convert_eax_v2_0_listener_property_id(
+ ALuint property_id)
+{
+ switch (property_id)
+ {
+ case DSPROPERTY_EAX20LISTENER_NONE:
+ return EAXREVERB_NONE;
+
+ case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS:
+ return EAXREVERB_ALLPARAMETERS;
+
+ case DSPROPERTY_EAX20LISTENER_ROOM:
+ return EAXREVERB_ROOM;
+
+ case DSPROPERTY_EAX20LISTENER_ROOMHF:
+ return EAXREVERB_ROOMHF;
+
+ case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR:
+ return EAXREVERB_ROOMROLLOFFFACTOR;
+
+ case DSPROPERTY_EAX20LISTENER_DECAYTIME:
+ return EAXREVERB_DECAYTIME;
+
+ case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO:
+ return EAXREVERB_DECAYHFRATIO;
+
+ case DSPROPERTY_EAX20LISTENER_REFLECTIONS:
+ return EAXREVERB_REFLECTIONS;
+
+ case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY:
+ return EAXREVERB_REFLECTIONSDELAY;
+
+ case DSPROPERTY_EAX20LISTENER_REVERB:
+ return EAXREVERB_REVERB;
+
+ case DSPROPERTY_EAX20LISTENER_REVERBDELAY:
+ return EAXREVERB_REVERBDELAY;
+
+ case DSPROPERTY_EAX20LISTENER_ENVIRONMENT:
+ return EAXREVERB_ENVIRONMENT;
+
+ case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE:
+ return EAXREVERB_ENVIRONMENTSIZE;
+
+ case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION:
+ return EAXREVERB_ENVIRONMENTDIFFUSION;
+
+ case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF:
+ return EAXREVERB_AIRABSORPTIONHF;
+
+ case DSPROPERTY_EAX20LISTENER_FLAGS:
+ return EAXREVERB_FLAGS;
+
+ default:
+ fail("Unsupported EAX 2.0 listener property id.");
+ }
+}
+
+ALuint EaxEaxCall::convert_eax_v2_0_buffer_property_id(
+ ALuint property_id)
+{
+ switch (property_id)
+ {
+ case DSPROPERTY_EAX20BUFFER_NONE:
+ return EAXSOURCE_NONE;
+
+ case DSPROPERTY_EAX20BUFFER_ALLPARAMETERS:
+ return EAXSOURCE_ALLPARAMETERS;
+
+ case DSPROPERTY_EAX20BUFFER_DIRECT:
+ return EAXSOURCE_DIRECT;
+
+ case DSPROPERTY_EAX20BUFFER_DIRECTHF:
+ return EAXSOURCE_DIRECTHF;
+
+ case DSPROPERTY_EAX20BUFFER_ROOM:
+ return EAXSOURCE_ROOM;
+
+ case DSPROPERTY_EAX20BUFFER_ROOMHF:
+ return EAXSOURCE_ROOMHF;
+
+ case DSPROPERTY_EAX20BUFFER_ROOMROLLOFFFACTOR:
+ return EAXSOURCE_ROOMROLLOFFFACTOR;
+
+ case DSPROPERTY_EAX20BUFFER_OBSTRUCTION:
+ return EAXSOURCE_OBSTRUCTION;
+
+ case DSPROPERTY_EAX20BUFFER_OBSTRUCTIONLFRATIO:
+ return EAXSOURCE_OBSTRUCTIONLFRATIO;
+
+ case DSPROPERTY_EAX20BUFFER_OCCLUSION:
+ return EAXSOURCE_OCCLUSION;
+
+ case DSPROPERTY_EAX20BUFFER_OCCLUSIONLFRATIO:
+ return EAXSOURCE_OCCLUSIONLFRATIO;
+
+ case DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO:
+ return EAXSOURCE_OCCLUSIONROOMRATIO;
+
+ case DSPROPERTY_EAX20BUFFER_OUTSIDEVOLUMEHF:
+ return EAXSOURCE_OUTSIDEVOLUMEHF;
+
+ case DSPROPERTY_EAX20BUFFER_AIRABSORPTIONFACTOR:
+ return EAXSOURCE_AIRABSORPTIONFACTOR;
+
+ case DSPROPERTY_EAX20BUFFER_FLAGS:
+ return EAXSOURCE_FLAGS;
+
+ default:
+ fail("Unsupported EAX 2.0 buffer property id.");
+ }
+}
+
+
+EaxEaxCall create_eax_call(
+ bool is_get,
+ const GUID* property_set_id,
+ ALuint property_id,
+ ALuint property_source_id,
+ ALvoid* property_buffer,
+ ALuint property_size)
+{
+ if(!property_set_id)
+ throw EaxEaxCallException{"Null property set ID."};
+
+ return EaxEaxCall{
+ is_get,
+ *property_set_id,
+ property_id,
+ property_source_id,
+ property_buffer,
+ property_size
+ };
+}