aboutsummaryrefslogtreecommitdiffstats
path: root/al/eax/call.cpp
diff options
context:
space:
mode:
authorBoris I. Bendovsky <[email protected]>2022-05-24 12:19:14 +0300
committerGitHub <[email protected]>2022-05-24 02:19:14 -0700
commit074dbef2e3129e9f7ee4895c44721c2a0a4b045b (patch)
tree72087ad2df3a5293d6aec82e762797b69de64111 /al/eax/call.cpp
parent54d72d17ad64809aeaf7a840447e398b2d38cbc9 (diff)
[EAX] Add separate effect state for each version (#705)
* [EAX] Add separate effect state for each version * [EAX] Don't use EAX call as data member
Diffstat (limited to 'al/eax/call.cpp')
-rw-r--r--al/eax/call.cpp212
1 files changed, 212 insertions, 0 deletions
diff --git a/al/eax/call.cpp b/al/eax/call.cpp
new file mode 100644
index 00000000..1fd05968
--- /dev/null
+++ b/al/eax/call.cpp
@@ -0,0 +1,212 @@
+#include "config.h"
+#include "call.h"
+#include "exception.h"
+
+namespace {
+
+constexpr auto deferred_flag = 0x80000000U;
+
+class EaxCallException : public EaxException {
+public:
+ explicit EaxCallException(const char* message)
+ : EaxException{"EAX_CALL", message}
+ {}
+}; // EaxCallException
+
+} // namespace
+
+EaxCall::EaxCall(
+ EaxCallType type,
+ const GUID& property_set_guid,
+ ALuint property_id,
+ ALuint property_source_id,
+ ALvoid* property_buffer,
+ ALuint property_size)
+ : type_{type}, version_{0}, property_set_id_{EaxCallPropertySetId::none}
+ , property_id_{property_id & ~deferred_flag}, property_source_id_{property_source_id}
+ , property_buffer_{property_buffer}, property_size_{property_size}
+{
+ switch (type_)
+ {
+ case EaxCallType::get:
+ case EaxCallType::set:
+ break;
+
+ default:
+ fail("Invalid type.");
+ }
+
+ if (false)
+ {
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX40_Context)
+ {
+ version_ = 4;
+ property_set_id_ = EaxCallPropertySetId::context;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX50_Context)
+ {
+ version_ = 5;
+ property_set_id_ = EaxCallPropertySetId::context;
+ }
+ else if (property_set_guid == DSPROPSETID_EAX20_ListenerProperties)
+ {
+ version_ = 2;
+ fx_slot_index_ = 0u;
+ property_set_id_ = EaxCallPropertySetId::fx_slot_effect;
+ }
+ else if (property_set_guid == DSPROPSETID_EAX30_ListenerProperties)
+ {
+ version_ = 3;
+ fx_slot_index_ = 0u;
+ property_set_id_ = EaxCallPropertySetId::fx_slot_effect;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot0)
+ {
+ version_ = 4;
+ fx_slot_index_ = 0u;
+ property_set_id_ = EaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot0)
+ {
+ version_ = 5;
+ fx_slot_index_ = 0u;
+ property_set_id_ = EaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot1)
+ {
+ version_ = 4;
+ fx_slot_index_ = 1u;
+ property_set_id_ = EaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot1)
+ {
+ version_ = 5;
+ fx_slot_index_ = 1u;
+ property_set_id_ = EaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot2)
+ {
+ version_ = 4;
+ fx_slot_index_ = 2u;
+ property_set_id_ = EaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot2)
+ {
+ version_ = 5;
+ fx_slot_index_ = 2u;
+ property_set_id_ = EaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot3)
+ {
+ version_ = 4;
+ fx_slot_index_ = 3u;
+ property_set_id_ = EaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot3)
+ {
+ version_ = 5;
+ fx_slot_index_ = 3u;
+ property_set_id_ = EaxCallPropertySetId::fx_slot;
+ }
+ else if (property_set_guid == DSPROPSETID_EAX20_BufferProperties)
+ {
+ version_ = 2;
+ property_set_id_ = EaxCallPropertySetId::source;
+ }
+ else if (property_set_guid == DSPROPSETID_EAX30_BufferProperties)
+ {
+ version_ = 3;
+ property_set_id_ = EaxCallPropertySetId::source;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX40_Source)
+ {
+ version_ = 4;
+ property_set_id_ = EaxCallPropertySetId::source;
+ }
+ else if (property_set_guid == EAXPROPERTYID_EAX50_Source)
+ {
+ version_ = 5;
+ property_set_id_ = EaxCallPropertySetId::source;
+ }
+ else if (property_set_guid == DSPROPSETID_EAX_ReverbProperties)
+ {
+ version_ = 1;
+ fx_slot_index_ = 0u;
+ property_set_id_ = EaxCallPropertySetId::fx_slot_effect;
+ }
+ else if (property_set_guid == DSPROPSETID_EAXBUFFER_ReverbProperties)
+ {
+ version_ = 1;
+ property_set_id_ = EaxCallPropertySetId::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_ != EaxCallPropertySetId::fx_slot && property_id_ != 0)
+ {
+ if (property_buffer == nullptr)
+ {
+ fail("Null property buffer.");
+ }
+
+ if (property_size == 0)
+ {
+ fail("Empty property.");
+ }
+ }
+ }
+
+ if(property_set_id_ == EaxCallPropertySetId::source && property_source_id_ == 0)
+ {
+ fail("Null AL source id.");
+ }
+
+ if (property_set_id_ == EaxCallPropertySetId::fx_slot)
+ {
+ if (property_id_ < EAXFXSLOT_NONE)
+ {
+ property_set_id_ = EaxCallPropertySetId::fx_slot_effect;
+ }
+ }
+}
+
+[[noreturn]] void EaxCall::fail(const char* message)
+{
+ throw EaxCallException{message};
+}
+
+[[noreturn]] void EaxCall::fail_too_small()
+{
+ fail("Property buffer too small.");
+}
+
+EaxCall create_eax_call(
+ EaxCallType type,
+ const GUID* property_set_id,
+ ALuint property_id,
+ ALuint property_source_id,
+ ALvoid* property_buffer,
+ ALuint property_size)
+{
+ if(!property_set_id)
+ throw EaxCallException{"Null property set ID."};
+
+ return EaxCall{
+ type,
+ *property_set_id,
+ property_id,
+ property_source_id,
+ property_buffer,
+ property_size
+ };
+}