aboutsummaryrefslogtreecommitdiffstats
path: root/al/eax_eax_call.cpp
diff options
context:
space:
mode:
authorBoris I. Bendovsky <[email protected]>2022-01-30 14:47:32 +0200
committerGitHub <[email protected]>2022-01-30 04:47:32 -0800
commit19ed994dc30ed84ea7cbbb5152577669fc25caf6 (patch)
treef68933bf8f778806618bd6c0b1bf9ced1b0ccf08 /al/eax_eax_call.cpp
parent619249371a40f03cf988d1f5750d643df797c485 (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/eax_eax_call.cpp')
-rw-r--r--al/eax_eax_call.cpp370
1 files changed, 370 insertions, 0 deletions
diff --git a/al/eax_eax_call.cpp b/al/eax_eax_call.cpp
new file mode 100644
index 00000000..e6967ded
--- /dev/null
+++ b/al/eax_eax_call.cpp
@@ -0,0 +1,370 @@
+#include "al/eax_eax_call.h"
+
+#include "al/eax_exception.h"
+
+
+namespace
+{
+
+
+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_id,
+ ALuint property_id,
+ ALuint property_source_id,
+ ALvoid* property_buffer,
+ ALuint property_size)
+{
+ if (!property_set_id)
+ {
+ fail("Null property set ID.");
+ }
+
+ is_get_ = is_get;
+
+ constexpr auto deferred_flag = 0x80000000U;
+ is_deferred_ = ((property_id & 0x80000000U) != 0);
+
+ version_ = 0;
+ fx_slot_index_.reset();
+ property_set_id_ = EaxEaxCallPropertySetId::none;
+
+ property_set_guid_ = *property_set_id;
+ 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_ = 0;
+ 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_ = 0;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot_effect;
+ }
+ else if (property_set_guid_ == EAXPROPERTYID_EAX40_FXSlot0)
+ {
+ version_ = 4;
+ fx_slot_index_ = 0;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid_ == EAXPROPERTYID_EAX50_FXSlot0)
+ {
+ version_ = 5;
+ fx_slot_index_ = 0;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid_ == EAXPROPERTYID_EAX40_FXSlot1)
+ {
+ version_ = 4;
+ fx_slot_index_ = 1;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid_ == EAXPROPERTYID_EAX50_FXSlot1)
+ {
+ version_ = 5;
+ fx_slot_index_ = 1;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid_ == EAXPROPERTYID_EAX40_FXSlot2)
+ {
+ version_ = 4;
+ fx_slot_index_ = 2;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid_ == EAXPROPERTYID_EAX50_FXSlot2)
+ {
+ version_ = 5;
+ fx_slot_index_ = 2;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid_ == EAXPROPERTYID_EAX40_FXSlot3)
+ {
+ version_ = 4;
+ fx_slot_index_ = 3;
+ property_set_id_ = EaxEaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid_ == EAXPROPERTYID_EAX50_FXSlot3)
+ {
+ version_ = 5;
+ fx_slot_index_ = 3;
+ 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
+ {
+ fail("Unsupported property set id.");
+ }
+
+ if (version_ < 2 || version_ > 5)
+ {
+ fail("EAX version out of range.");
+ }
+
+ if (is_deferred_)
+ {
+ if (is_get_)
+ {
+ fail("Getting deferred properties not supported.");
+ }
+ }
+ else
+ {
+ 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;
+ }
+ }
+}
+
+bool EaxEaxCall::is_get() const noexcept
+{
+ return is_get_;
+}
+
+bool EaxEaxCall::is_deferred() const noexcept
+{
+ return is_deferred_;
+}
+
+int EaxEaxCall::get_version() const noexcept
+{
+ return version_;
+}
+
+EaxEaxCallPropertySetId EaxEaxCall::get_property_set_id() const noexcept
+{
+ return property_set_id_;
+}
+
+ALuint EaxEaxCall::get_property_id() const noexcept
+{
+ return property_id_;
+}
+
+ALuint EaxEaxCall::get_property_al_name() const noexcept
+{
+ return property_source_id_;
+}
+
+EaxFxSlotIndex EaxEaxCall::get_fx_slot_index() const noexcept
+{
+ return fx_slot_index_;
+}
+
+[[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)
+{
+ return EaxEaxCall{
+ is_get,
+ property_set_id,
+ property_id,
+ property_source_id,
+ property_buffer,
+ property_size
+ };
+}