]> git.tdb.fi Git - ext/openal.git/blob - al/eax/call.cpp
Tweak some types to work around an MSVC compile error
[ext/openal.git] / al / eax / call.cpp
1 #include "config.h"
2 #include "call.h"
3 #include "exception.h"
4
5 namespace {
6
7 constexpr auto deferred_flag = 0x80000000U;
8
9 class EaxCallException : public EaxException {
10 public:
11     explicit EaxCallException(const char* message)
12         : EaxException{"EAX_CALL", message}
13     {}
14 }; // EaxCallException
15
16 } // namespace
17
18 EaxCall::EaxCall(
19     EaxCallType type,
20     const GUID& property_set_guid,
21     ALuint property_id,
22     ALuint property_source_id,
23     ALvoid* property_buffer,
24     ALuint property_size)
25     : mCallType{type}, mVersion{0}, mPropertySetId{EaxCallPropertySetId::none}
26     , mIsDeferred{(property_id & deferred_flag) != 0}
27     , mPropertyId{property_id & ~deferred_flag}, mPropertySourceId{property_source_id}
28     , mPropertyBuffer{property_buffer}, mPropertyBufferSize{property_size}
29 {
30     switch(mCallType)
31     {
32         case EaxCallType::get:
33         case EaxCallType::set:
34             break;
35
36         default:
37             fail("Invalid type.");
38     }
39
40     if (false)
41     {
42     }
43     else if (property_set_guid == EAXPROPERTYID_EAX40_Context)
44     {
45         mVersion = 4;
46         mPropertySetId = EaxCallPropertySetId::context;
47     }
48     else if (property_set_guid == EAXPROPERTYID_EAX50_Context)
49     {
50         mVersion = 5;
51         mPropertySetId = EaxCallPropertySetId::context;
52     }
53     else if (property_set_guid == DSPROPSETID_EAX20_ListenerProperties)
54     {
55         mVersion = 2;
56         mFxSlotIndex = 0u;
57         mPropertySetId = EaxCallPropertySetId::fx_slot_effect;
58     }
59     else if (property_set_guid == DSPROPSETID_EAX30_ListenerProperties)
60     {
61         mVersion = 3;
62         mFxSlotIndex = 0u;
63         mPropertySetId = EaxCallPropertySetId::fx_slot_effect;
64     }
65     else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot0)
66     {
67         mVersion = 4;
68         mFxSlotIndex = 0u;
69         mPropertySetId = EaxCallPropertySetId::fx_slot;
70     }
71     else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot0)
72     {
73         mVersion = 5;
74         mFxSlotIndex = 0u;
75         mPropertySetId = EaxCallPropertySetId::fx_slot;
76     }
77     else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot1)
78     {
79         mVersion = 4;
80         mFxSlotIndex = 1u;
81         mPropertySetId = EaxCallPropertySetId::fx_slot;
82     }
83     else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot1)
84     {
85         mVersion = 5;
86         mFxSlotIndex = 1u;
87         mPropertySetId = EaxCallPropertySetId::fx_slot;
88     }
89     else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot2)
90     {
91         mVersion = 4;
92         mFxSlotIndex = 2u;
93         mPropertySetId = EaxCallPropertySetId::fx_slot;
94     }
95     else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot2)
96     {
97         mVersion = 5;
98         mFxSlotIndex = 2u;
99         mPropertySetId = EaxCallPropertySetId::fx_slot;
100     }
101     else if (property_set_guid == EAXPROPERTYID_EAX40_FXSlot3)
102     {
103         mVersion = 4;
104         mFxSlotIndex = 3u;
105         mPropertySetId = EaxCallPropertySetId::fx_slot;
106     }
107     else if (property_set_guid == EAXPROPERTYID_EAX50_FXSlot3)
108     {
109         mVersion = 5;
110         mFxSlotIndex = 3u;
111         mPropertySetId = EaxCallPropertySetId::fx_slot;
112     }
113     else if (property_set_guid == DSPROPSETID_EAX20_BufferProperties)
114     {
115         mVersion = 2;
116         mPropertySetId = EaxCallPropertySetId::source;
117     }
118     else if (property_set_guid == DSPROPSETID_EAX30_BufferProperties)
119     {
120         mVersion = 3;
121         mPropertySetId = EaxCallPropertySetId::source;
122     }
123     else if (property_set_guid == EAXPROPERTYID_EAX40_Source)
124     {
125         mVersion = 4;
126         mPropertySetId = EaxCallPropertySetId::source;
127     }
128     else if (property_set_guid == EAXPROPERTYID_EAX50_Source)
129     {
130         mVersion = 5;
131         mPropertySetId = EaxCallPropertySetId::source;
132     }
133     else if (property_set_guid == DSPROPSETID_EAX_ReverbProperties)
134     {
135         mVersion = 1;
136         mFxSlotIndex = 0u;
137         mPropertySetId = EaxCallPropertySetId::fx_slot_effect;
138     }
139     else if (property_set_guid == DSPROPSETID_EAXBUFFER_ReverbProperties)
140     {
141         mVersion = 1;
142         mPropertySetId = EaxCallPropertySetId::source;
143     }
144     else
145     {
146         fail("Unsupported property set id.");
147     }
148
149     switch(mPropertyId)
150     {
151     case EAXCONTEXT_LASTERROR:
152     case EAXCONTEXT_SPEAKERCONFIG:
153     case EAXCONTEXT_EAXSESSION:
154     case EAXFXSLOT_NONE:
155     case EAXFXSLOT_ALLPARAMETERS:
156     case EAXFXSLOT_LOADEFFECT:
157     case EAXFXSLOT_VOLUME:
158     case EAXFXSLOT_LOCK:
159     case EAXFXSLOT_FLAGS:
160     case EAXFXSLOT_OCCLUSION:
161     case EAXFXSLOT_OCCLUSIONLFRATIO:
162         // EAX allow to set "defer" flag on immediate-only properties.
163         // If we don't clear our flag then "applyAllUpdates" in EAX context won't be called.
164         mIsDeferred = false;
165         break;
166     }
167
168     if(!mIsDeferred)
169     {
170         if(mPropertySetId != EaxCallPropertySetId::fx_slot && mPropertyId != 0)
171         {
172             if(mPropertyBuffer == nullptr)
173                 fail("Null property buffer.");
174
175             if(mPropertyBufferSize == 0)
176                 fail("Empty property.");
177         }
178     }
179
180     if(mPropertySetId == EaxCallPropertySetId::source && mPropertySourceId == 0)
181         fail("Null AL source id.");
182
183     if(mPropertySetId == EaxCallPropertySetId::fx_slot)
184     {
185         if(mPropertyId < EAXFXSLOT_NONE)
186             mPropertySetId = EaxCallPropertySetId::fx_slot_effect;
187     }
188 }
189
190 [[noreturn]] void EaxCall::fail(const char* message)
191 {
192     throw EaxCallException{message};
193 }
194
195 [[noreturn]] void EaxCall::fail_too_small()
196 {
197     fail("Property buffer too small.");
198 }
199
200 EaxCall create_eax_call(
201     EaxCallType type,
202     const GUID* property_set_id,
203     ALuint property_id,
204     ALuint property_source_id,
205     ALvoid* property_buffer,
206     ALuint property_size)
207 {
208     if(!property_set_id)
209         throw EaxCallException{"Null property set ID."};
210
211     return EaxCall{
212         type,
213         *property_set_id,
214         property_id,
215         property_source_id,
216         property_buffer,
217         property_size
218     };
219 }