mirror of https://github.com/axmolengine/axmol.git
220 lines
5.8 KiB
C++
220 lines
5.8 KiB
C++
#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)
|
|
: mCallType{type}, mVersion{0}, mPropertySetId{EaxCallPropertySetId::none}
|
|
, mIsDeferred{(property_id & deferred_flag) != 0}
|
|
, mPropertyId{property_id & ~deferred_flag}, mPropertySourceId{property_source_id}
|
|
, mPropertyBuffer{property_buffer}, mPropertyBufferSize{property_size}
|
|
{
|
|
switch(mCallType)
|
|
{
|
|
case EaxCallType::get:
|
|
case EaxCallType::set:
|
|
break;
|
|
|
|
default:
|
|
fail("Invalid type.");
|
|
}
|
|
|
|
if (false)
|
|
{
|
|
}
|
|
else if (property_set_guid == EAXPROPERTYID_EAX40_Context)
|
|
{
|
|
mVersion = 4;
|
|
mPropertySetId = EaxCallPropertySetId::context;
|
|
}
|
|
else if (property_set_guid == EAXPROPERTYID_EAX50_Context)
|
|
{
|
|
mVersion = 5;
|
|
mPropertySetId = EaxCallPropertySetId::context;
|
|
}
|
|
else if (property_set_guid == DSPROPSETID_EAX20_ListenerProperties)
|
|
{
|
|
mVersion = 2;
|
|
mFxSlotIndex = 0u;
|
|
mPropertySetId = EaxCallPropertySetId::fx_slot_effect;
|
|
}
|
|
else if (property_set_guid == DSPROPSETID_EAX30_ListenerProperties)
|
|
{
|
|
mVersion = 3;
|
|
mFxSlotIndex = 0u;
|
|
mPropertySetId = EaxCallPropertySetId::fx_slot_effect;
|
|
}
|
|
else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot0)
|
|
{
|
|
mVersion = 4;
|
|
mFxSlotIndex = 0u;
|
|
mPropertySetId = EaxCallPropertySetId::fx_slot;
|
|
}
|
|
else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot0)
|
|
{
|
|
mVersion = 5;
|
|
mFxSlotIndex = 0u;
|
|
mPropertySetId = EaxCallPropertySetId::fx_slot;
|
|
}
|
|
else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot1)
|
|
{
|
|
mVersion = 4;
|
|
mFxSlotIndex = 1u;
|
|
mPropertySetId = EaxCallPropertySetId::fx_slot;
|
|
}
|
|
else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot1)
|
|
{
|
|
mVersion = 5;
|
|
mFxSlotIndex = 1u;
|
|
mPropertySetId = EaxCallPropertySetId::fx_slot;
|
|
}
|
|
else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot2)
|
|
{
|
|
mVersion = 4;
|
|
mFxSlotIndex = 2u;
|
|
mPropertySetId = EaxCallPropertySetId::fx_slot;
|
|
}
|
|
else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot2)
|
|
{
|
|
mVersion = 5;
|
|
mFxSlotIndex = 2u;
|
|
mPropertySetId = EaxCallPropertySetId::fx_slot;
|
|
}
|
|
else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot3)
|
|
{
|
|
mVersion = 4;
|
|
mFxSlotIndex = 3u;
|
|
mPropertySetId = EaxCallPropertySetId::fx_slot;
|
|
}
|
|
else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot3)
|
|
{
|
|
mVersion = 5;
|
|
mFxSlotIndex = 3u;
|
|
mPropertySetId = EaxCallPropertySetId::fx_slot;
|
|
}
|
|
else if (property_set_guid == DSPROPSETID_EAX20_BufferProperties)
|
|
{
|
|
mVersion = 2;
|
|
mPropertySetId = EaxCallPropertySetId::source;
|
|
}
|
|
else if (property_set_guid == DSPROPSETID_EAX30_BufferProperties)
|
|
{
|
|
mVersion = 3;
|
|
mPropertySetId = EaxCallPropertySetId::source;
|
|
}
|
|
else if (property_set_guid == EAXPROPERTYID_EAX40_Source)
|
|
{
|
|
mVersion = 4;
|
|
mPropertySetId = EaxCallPropertySetId::source;
|
|
}
|
|
else if (property_set_guid == EAXPROPERTYID_EAX50_Source)
|
|
{
|
|
mVersion = 5;
|
|
mPropertySetId = EaxCallPropertySetId::source;
|
|
}
|
|
else if (property_set_guid == DSPROPSETID_EAX_ReverbProperties)
|
|
{
|
|
mVersion = 1;
|
|
mFxSlotIndex = 0u;
|
|
mPropertySetId = EaxCallPropertySetId::fx_slot_effect;
|
|
}
|
|
else if (property_set_guid == DSPROPSETID_EAXBUFFER_ReverbProperties)
|
|
{
|
|
mVersion = 1;
|
|
mPropertySetId = EaxCallPropertySetId::source;
|
|
}
|
|
else
|
|
{
|
|
fail("Unsupported property set id.");
|
|
}
|
|
|
|
switch(mPropertyId)
|
|
{
|
|
case EAXCONTEXT_LASTERROR:
|
|
case EAXCONTEXT_SPEAKERCONFIG:
|
|
case EAXCONTEXT_EAXSESSION:
|
|
case EAXFXSLOT_NONE:
|
|
case EAXFXSLOT_ALLPARAMETERS:
|
|
case EAXFXSLOT_LOADEFFECT:
|
|
case EAXFXSLOT_VOLUME:
|
|
case EAXFXSLOT_LOCK:
|
|
case EAXFXSLOT_FLAGS:
|
|
case EAXFXSLOT_OCCLUSION:
|
|
case EAXFXSLOT_OCCLUSIONLFRATIO:
|
|
// EAX allow to set "defer" flag on immediate-only properties.
|
|
// If we don't clear our flag then "applyAllUpdates" in EAX context won't be called.
|
|
mIsDeferred = false;
|
|
break;
|
|
}
|
|
|
|
if(!mIsDeferred)
|
|
{
|
|
if(mPropertySetId != EaxCallPropertySetId::fx_slot && mPropertyId != 0)
|
|
{
|
|
if(mPropertyBuffer == nullptr)
|
|
fail("Null property buffer.");
|
|
|
|
if(mPropertyBufferSize == 0)
|
|
fail("Empty property.");
|
|
}
|
|
}
|
|
|
|
if(mPropertySetId == EaxCallPropertySetId::source && mPropertySourceId == 0)
|
|
fail("Null AL source id.");
|
|
|
|
if(mPropertySetId == EaxCallPropertySetId::fx_slot)
|
|
{
|
|
if(mPropertyId < EAXFXSLOT_NONE)
|
|
mPropertySetId = 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
|
|
};
|
|
}
|