Store source send properties for all possible effect slots
[dsound-openal.git] / eax.c
blob89db5ae8eedde52811d36a0ed938135bbe1b3bff
1 /* DirectSound EAX interface
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 #define CONST_VTABLE
19 #include <stdarg.h>
20 #include <string.h>
22 #include "windows.h"
23 #include "dsound.h"
25 #include "dsound_private.h"
26 #include "eax-presets.h"
29 /*******************
30 * EAX 3 stuff
31 ******************/
33 static EAXOBSTRUCTIONPROPERTIES EAXSourceObstruction(const EAXSOURCEPROPERTIES *props)
35 EAXOBSTRUCTIONPROPERTIES ret;
36 ret.lObstruction = props->lObstruction;
37 ret.flObstructionLFRatio = props->flObstructionLFRatio;
38 return ret;
41 static EAXOCCLUSIONPROPERTIES EAXSourceOcclusion(const EAXSOURCEPROPERTIES *props)
43 EAXOCCLUSIONPROPERTIES ret;
44 ret.lOcclusion = props->lOcclusion;
45 ret.flOcclusionLFRatio = props->flOcclusionLFRatio;
46 ret.flOcclusionRoomRatio = props->flOcclusionRoomRatio;
47 ret.flOcclusionDirectRatio = props->flOcclusionDirectRatio;
48 return ret;
51 static EAXEXCLUSIONPROPERTIES EAXSourceExclusion(const EAXSOURCEPROPERTIES *props)
53 EAXEXCLUSIONPROPERTIES ret;
54 ret.lExclusion = props->lExclusion;
55 ret.flExclusionLFRatio = props->flExclusionLFRatio;
56 return ret;
59 HRESULT EAX3_Query(DSPrimary *prim, DWORD propid, ULONG *pTypeSupport)
61 if(prim->effect[0] == 0)
62 return E_PROP_ID_UNSUPPORTED;
64 switch((propid&~DSPROPERTY_EAX30LISTENER_DEFERRED))
66 case DSPROPERTY_EAX30LISTENER_NONE:
67 case DSPROPERTY_EAX30LISTENER_ALLPARAMETERS:
68 case DSPROPERTY_EAX30LISTENER_ENVIRONMENT:
69 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTSIZE:
70 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTDIFFUSION:
71 case DSPROPERTY_EAX30LISTENER_ROOM:
72 case DSPROPERTY_EAX30LISTENER_ROOMHF:
73 case DSPROPERTY_EAX30LISTENER_ROOMLF:
74 case DSPROPERTY_EAX30LISTENER_DECAYTIME:
75 case DSPROPERTY_EAX30LISTENER_DECAYHFRATIO:
76 case DSPROPERTY_EAX30LISTENER_DECAYLFRATIO:
77 case DSPROPERTY_EAX30LISTENER_REFLECTIONS:
78 case DSPROPERTY_EAX30LISTENER_REFLECTIONSDELAY:
79 case DSPROPERTY_EAX30LISTENER_REFLECTIONSPAN:
80 case DSPROPERTY_EAX30LISTENER_REVERB:
81 case DSPROPERTY_EAX30LISTENER_REVERBDELAY:
82 case DSPROPERTY_EAX30LISTENER_REVERBPAN:
83 case DSPROPERTY_EAX30LISTENER_ECHOTIME:
84 case DSPROPERTY_EAX30LISTENER_ECHODEPTH:
85 case DSPROPERTY_EAX30LISTENER_MODULATIONTIME:
86 case DSPROPERTY_EAX30LISTENER_MODULATIONDEPTH:
87 case DSPROPERTY_EAX30LISTENER_AIRABSORPTIONHF:
88 case DSPROPERTY_EAX30LISTENER_HFREFERENCE:
89 case DSPROPERTY_EAX30LISTENER_LFREFERENCE:
90 case DSPROPERTY_EAX30LISTENER_ROOMROLLOFFFACTOR:
91 case DSPROPERTY_EAX30LISTENER_FLAGS:
92 *pTypeSupport = KSPROPERTY_SUPPORT_GET | KSPROPERTY_SUPPORT_SET;
93 return DS_OK;
95 FIXME("Unhandled propid: 0x%08lx\n", propid);
96 return E_PROP_ID_UNSUPPORTED;
99 HRESULT EAX3_Set(DSPrimary *prim, DWORD propid, void *pPropData, ULONG cbPropData)
101 /* Should this be using slot 0 or the primary slot? */
102 if(prim->effect[0] == 0)
103 return E_PROP_ID_UNSUPPORTED;
104 if(prim->deferred.fxslot[0].effect_type != FXSLOT_EFFECT_REVERB)
106 ERR("Trying to set reverb parameters on non-reverb slot\n");
107 return DSERR_INVALIDCALL;
110 switch(propid)
112 case DSPROPERTY_EAX30LISTENER_NONE: /* not setting any property, just applying */
113 return DS_OK;
115 case DSPROPERTY_EAX30LISTENER_ALLPARAMETERS:
116 if(cbPropData >= sizeof(EAX30LISTENERPROPERTIES))
118 /* Ensure compatible types (should generate a warning if not). */
119 union { void *v; EAX30LISTENERPROPERTIES *props; } data = { pPropData };
120 EAXREVERBPROPERTIES *revprops = data.props;
121 return EAXReverb_Set(prim, 0, EAXREVERB_ALLPARAMETERS, revprops, cbPropData);
123 return DSERR_INVALIDPARAM;
125 #define HANDLE_PROP(P) case DSPROPERTY_EAX30LISTENER_##P: \
126 return EAXReverb_Set(prim, 0, EAXREVERB_##P, pPropData, cbPropData);
127 HANDLE_PROP(ENVIRONMENT)
128 HANDLE_PROP(ENVIRONMENTSIZE)
129 HANDLE_PROP(ENVIRONMENTDIFFUSION)
130 HANDLE_PROP(ROOM)
131 HANDLE_PROP(ROOMHF)
132 HANDLE_PROP(ROOMLF)
133 HANDLE_PROP(DECAYTIME)
134 HANDLE_PROP(DECAYHFRATIO)
135 HANDLE_PROP(DECAYLFRATIO)
136 HANDLE_PROP(REFLECTIONS)
137 HANDLE_PROP(REFLECTIONSDELAY)
138 HANDLE_PROP(REFLECTIONSPAN)
139 HANDLE_PROP(REVERB)
140 HANDLE_PROP(REVERBDELAY)
141 HANDLE_PROP(REVERBPAN)
142 HANDLE_PROP(ECHOTIME)
143 HANDLE_PROP(ECHODEPTH)
144 HANDLE_PROP(MODULATIONTIME)
145 HANDLE_PROP(MODULATIONDEPTH)
146 HANDLE_PROP(AIRABSORPTIONHF)
147 HANDLE_PROP(HFREFERENCE)
148 HANDLE_PROP(LFREFERENCE)
149 HANDLE_PROP(ROOMROLLOFFFACTOR)
150 HANDLE_PROP(FLAGS)
151 #undef HANDLE_PROP
153 FIXME("Unhandled propid: 0x%08lx\n", propid);
154 return DSERR_INVALIDPARAM;
157 #define GET_PROP(src, T) do { \
158 if(cbPropData >= sizeof(T)) \
160 union { void *v; T *props; } data = { pPropData }; \
161 *data.props = src; \
162 *pcbReturned = sizeof(T); \
163 return DS_OK; \
165 return DSERR_INVALIDPARAM; \
166 } while(0)
168 HRESULT EAX3_Get(DSPrimary *prim, DWORD propid, void *pPropData, ULONG cbPropData, ULONG *pcbReturned)
170 if(prim->effect[0] == 0)
171 return E_PROP_ID_UNSUPPORTED;
172 if(prim->deferred.fxslot[0].effect_type != FXSLOT_EFFECT_REVERB)
174 ERR("Trying to get reverb parameters on non-reverb slot\n");
175 return DSERR_INVALIDCALL;
178 switch(propid)
180 case DSPROPERTY_EAX30LISTENER_NONE:
181 *pcbReturned = 0;
182 return DS_OK;
184 case DSPROPERTY_EAX30LISTENER_ALLPARAMETERS:
185 GET_PROP(prim->deferred.fxslot[0].fx.reverb, EAX30LISTENERPROPERTIES);
186 case DSPROPERTY_EAX30LISTENER_ENVIRONMENT:
187 GET_PROP(prim->deferred.fxslot[0].fx.reverb.dwEnvironment, DWORD);
188 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTSIZE:
189 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flEnvironmentSize, float);
190 case DSPROPERTY_EAX30LISTENER_ENVIRONMENTDIFFUSION:
191 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flEnvironmentDiffusion, float);
192 case DSPROPERTY_EAX30LISTENER_ROOM:
193 GET_PROP(prim->deferred.fxslot[0].fx.reverb.lRoom, long);
194 case DSPROPERTY_EAX30LISTENER_ROOMHF:
195 GET_PROP(prim->deferred.fxslot[0].fx.reverb.lRoomHF, long);
196 case DSPROPERTY_EAX30LISTENER_ROOMLF:
197 GET_PROP(prim->deferred.fxslot[0].fx.reverb.lRoomLF, long);
198 case DSPROPERTY_EAX30LISTENER_DECAYTIME:
199 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flDecayTime, float);
200 case DSPROPERTY_EAX30LISTENER_DECAYHFRATIO:
201 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flDecayHFRatio, float);
202 case DSPROPERTY_EAX30LISTENER_DECAYLFRATIO:
203 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flDecayLFRatio, float);
204 case DSPROPERTY_EAX30LISTENER_REFLECTIONS:
205 GET_PROP(prim->deferred.fxslot[0].fx.reverb.lReflections, long);
206 case DSPROPERTY_EAX30LISTENER_REFLECTIONSDELAY:
207 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flReflectionsDelay, float);
208 case DSPROPERTY_EAX30LISTENER_REFLECTIONSPAN:
209 GET_PROP(prim->deferred.fxslot[0].fx.reverb.vReflectionsPan, EAXVECTOR);
210 case DSPROPERTY_EAX30LISTENER_REVERB:
211 GET_PROP(prim->deferred.fxslot[0].fx.reverb.lReverb, long);
212 case DSPROPERTY_EAX30LISTENER_REVERBDELAY:
213 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flReverbDelay, float);
214 case DSPROPERTY_EAX30LISTENER_REVERBPAN:
215 GET_PROP(prim->deferred.fxslot[0].fx.reverb.vReverbPan, EAXVECTOR);
216 case DSPROPERTY_EAX30LISTENER_ECHOTIME:
217 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flEchoTime, float);
218 case DSPROPERTY_EAX30LISTENER_ECHODEPTH:
219 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flEchoDepth, float);
220 case DSPROPERTY_EAX30LISTENER_MODULATIONTIME:
221 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flModulationTime, float);
222 case DSPROPERTY_EAX30LISTENER_MODULATIONDEPTH:
223 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flModulationDepth, float);
224 case DSPROPERTY_EAX30LISTENER_AIRABSORPTIONHF:
225 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flAirAbsorptionHF, float);
226 case DSPROPERTY_EAX30LISTENER_HFREFERENCE:
227 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flHFReference, float);
228 case DSPROPERTY_EAX30LISTENER_LFREFERENCE:
229 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flLFReference, float);
230 case DSPROPERTY_EAX30LISTENER_ROOMROLLOFFFACTOR:
231 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flRoomRolloffFactor, float);
232 case DSPROPERTY_EAX30LISTENER_FLAGS:
233 GET_PROP(prim->deferred.fxslot[0].fx.reverb.dwFlags, DWORD);
235 FIXME("Unhandled propid: 0x%08lx\n", propid);
236 return DSERR_INVALIDPARAM;
240 HRESULT EAX3Buffer_Query(DSBuffer *buf, DWORD propid, ULONG *pTypeSupport)
242 (void)buf;
244 switch((propid&~DSPROPERTY_EAX30BUFFER_DEFERRED))
246 case DSPROPERTY_EAX30BUFFER_NONE:
247 case DSPROPERTY_EAX30BUFFER_ALLPARAMETERS:
248 case DSPROPERTY_EAX30BUFFER_OBSTRUCTIONPARAMETERS:
249 case DSPROPERTY_EAX30BUFFER_OCCLUSIONPARAMETERS:
250 case DSPROPERTY_EAX30BUFFER_EXCLUSIONPARAMETERS:
251 case DSPROPERTY_EAX30BUFFER_DIRECT:
252 case DSPROPERTY_EAX30BUFFER_DIRECTHF:
253 case DSPROPERTY_EAX30BUFFER_ROOM:
254 case DSPROPERTY_EAX30BUFFER_ROOMHF:
255 case DSPROPERTY_EAX30BUFFER_OBSTRUCTION:
256 case DSPROPERTY_EAX30BUFFER_OBSTRUCTIONLFRATIO:
257 case DSPROPERTY_EAX30BUFFER_OCCLUSION:
258 case DSPROPERTY_EAX30BUFFER_OCCLUSIONLFRATIO:
259 case DSPROPERTY_EAX30BUFFER_OCCLUSIONROOMRATIO:
260 case DSPROPERTY_EAX30BUFFER_OCCLUSIONDIRECTRATIO:
261 case DSPROPERTY_EAX30BUFFER_EXCLUSION:
262 case DSPROPERTY_EAX30BUFFER_EXCLUSIONLFRATIO:
263 case DSPROPERTY_EAX30BUFFER_OUTSIDEVOLUMEHF:
264 case DSPROPERTY_EAX30BUFFER_DOPPLERFACTOR:
265 case DSPROPERTY_EAX30BUFFER_ROLLOFFFACTOR:
266 case DSPROPERTY_EAX30BUFFER_ROOMROLLOFFFACTOR:
267 case DSPROPERTY_EAX30BUFFER_AIRABSORPTIONFACTOR:
268 case DSPROPERTY_EAX30BUFFER_FLAGS:
269 *pTypeSupport = KSPROPERTY_SUPPORT_GET | KSPROPERTY_SUPPORT_SET;
270 return DS_OK;
272 FIXME("Unhandled propid: 0x%08lx\n", propid);
273 return E_PROP_ID_UNSUPPORTED;
277 HRESULT EAX3Buffer_Set(DSBuffer *buf, DWORD propid, void *pPropData, ULONG cbPropData)
279 switch(propid)
281 case DSPROPERTY_EAX30BUFFER_NONE: /* not setting any property, just applying */
282 return DS_OK;
284 case DSPROPERTY_EAX30BUFFER_ALLPARAMETERS:
285 if(cbPropData >= sizeof(EAX30BUFFERPROPERTIES))
287 /* Ensure compatible types (should generate a warning if not). */
288 union { void *v; EAX30BUFFERPROPERTIES *props; } data = { pPropData };
289 EAXSOURCEPROPERTIES *srcprops = data.props;
290 return EAX4Source_Set(buf, EAXSOURCE_ALLPARAMETERS, srcprops, cbPropData);
292 return DSERR_INVALIDPARAM;
294 #define HANDLE_PROP(P) case DSPROPERTY_EAX30BUFFER_##P: \
295 return EAX4Source_Set(buf, EAXSOURCE_##P, pPropData, cbPropData);
296 HANDLE_PROP(OBSTRUCTIONPARAMETERS)
297 HANDLE_PROP(OCCLUSIONPARAMETERS)
298 HANDLE_PROP(EXCLUSIONPARAMETERS)
299 HANDLE_PROP(DIRECT)
300 HANDLE_PROP(DIRECTHF)
301 HANDLE_PROP(ROOM)
302 HANDLE_PROP(ROOMHF)
303 HANDLE_PROP(OBSTRUCTION)
304 HANDLE_PROP(OBSTRUCTIONLFRATIO)
305 HANDLE_PROP(OCCLUSION)
306 HANDLE_PROP(OCCLUSIONLFRATIO)
307 HANDLE_PROP(OCCLUSIONROOMRATIO)
308 HANDLE_PROP(OCCLUSIONDIRECTRATIO)
309 HANDLE_PROP(EXCLUSION)
310 HANDLE_PROP(EXCLUSIONLFRATIO)
311 HANDLE_PROP(OUTSIDEVOLUMEHF)
312 HANDLE_PROP(DOPPLERFACTOR)
313 HANDLE_PROP(ROLLOFFFACTOR)
314 HANDLE_PROP(ROOMROLLOFFFACTOR)
315 HANDLE_PROP(AIRABSORPTIONFACTOR)
316 HANDLE_PROP(FLAGS)
317 #undef HANDLE_PROP
319 FIXME("Unhandled propid: 0x%08lx\n", propid);
320 return E_PROP_ID_UNSUPPORTED;
323 HRESULT EAX3Buffer_Get(DSBuffer *buf, DWORD propid, void *pPropData, ULONG cbPropData, ULONG *pcbReturned)
325 switch(propid)
327 case DSPROPERTY_EAX30BUFFER_NONE:
328 *pcbReturned = 0;
329 return DS_OK;
331 case DSPROPERTY_EAX30BUFFER_ALLPARAMETERS:
332 GET_PROP(buf->current.eax, EAX30BUFFERPROPERTIES);
333 case DSPROPERTY_EAX30BUFFER_OBSTRUCTIONPARAMETERS:
334 GET_PROP(EAXSourceObstruction(&buf->current.eax), EAXOBSTRUCTIONPROPERTIES);
335 case DSPROPERTY_EAX30BUFFER_OCCLUSIONPARAMETERS:
336 GET_PROP(EAXSourceOcclusion(&buf->current.eax), EAXOCCLUSIONPROPERTIES);
337 case DSPROPERTY_EAX30BUFFER_EXCLUSIONPARAMETERS:
338 GET_PROP(EAXSourceExclusion(&buf->current.eax), EAXEXCLUSIONPROPERTIES);
339 case DSPROPERTY_EAX30BUFFER_DIRECT:
340 GET_PROP(buf->current.eax.lDirect, long);
341 case DSPROPERTY_EAX30BUFFER_DIRECTHF:
342 GET_PROP(buf->current.eax.lDirectHF, long);
343 case DSPROPERTY_EAX30BUFFER_ROOM:
344 GET_PROP(buf->current.eax.lRoom, long);
345 case DSPROPERTY_EAX30BUFFER_ROOMHF:
346 GET_PROP(buf->current.eax.lRoomHF, long);
347 case DSPROPERTY_EAX30BUFFER_OBSTRUCTION:
348 GET_PROP(buf->current.eax.lObstruction, long);
349 case DSPROPERTY_EAX30BUFFER_OBSTRUCTIONLFRATIO:
350 GET_PROP(buf->current.eax.flObstructionLFRatio, float);
351 case DSPROPERTY_EAX30BUFFER_OCCLUSION:
352 GET_PROP(buf->current.eax.lOcclusion, long);
353 case DSPROPERTY_EAX30BUFFER_OCCLUSIONLFRATIO:
354 GET_PROP(buf->current.eax.flOcclusionLFRatio, float);
355 case DSPROPERTY_EAX30BUFFER_OCCLUSIONROOMRATIO:
356 GET_PROP(buf->current.eax.flOcclusionRoomRatio, float);
357 case DSPROPERTY_EAX30BUFFER_OCCLUSIONDIRECTRATIO:
358 GET_PROP(buf->current.eax.flOcclusionDirectRatio, float);
359 case DSPROPERTY_EAX30BUFFER_EXCLUSION:
360 GET_PROP(buf->current.eax.lExclusion, long);
361 case DSPROPERTY_EAX30BUFFER_EXCLUSIONLFRATIO:
362 GET_PROP(buf->current.eax.flExclusionLFRatio, float);
363 case DSPROPERTY_EAX30BUFFER_OUTSIDEVOLUMEHF:
364 GET_PROP(buf->current.eax.lOutsideVolumeHF, long);
365 case DSPROPERTY_EAX30BUFFER_DOPPLERFACTOR:
366 GET_PROP(buf->current.eax.flDopplerFactor, float);
367 case DSPROPERTY_EAX30BUFFER_ROLLOFFFACTOR:
368 GET_PROP(buf->current.eax.flRolloffFactor, float);
369 case DSPROPERTY_EAX30BUFFER_ROOMROLLOFFFACTOR:
370 GET_PROP(buf->current.eax.flRoomRolloffFactor, float);
371 case DSPROPERTY_EAX30BUFFER_AIRABSORPTIONFACTOR:
372 GET_PROP(buf->current.eax.flAirAbsorptionFactor, float);
373 case DSPROPERTY_EAX30BUFFER_FLAGS:
374 GET_PROP(buf->current.eax.dwFlags, DWORD);
376 FIXME("Unhandled propid: 0x%08lx\n", propid);
377 return DSERR_INVALIDPARAM;
381 /*******************
382 * EAX 2 stuff
383 ******************/
385 #define EAX2LISTENERFLAGS_MASK (EAX20LISTENERFLAGS_DECAYTIMESCALE | \
386 EAX20LISTENERFLAGS_REFLECTIONSSCALE | \
387 EAX20LISTENERFLAGS_REFLECTIONSDELAYSCALE | \
388 EAX20LISTENERFLAGS_REVERBSCALE | \
389 EAX20LISTENERFLAGS_REVERBDELAYSCALE | \
390 EAX20LISTENERFLAGS_DECAYHFLIMIT)
392 static EAX20LISTENERPROPERTIES EAXRevTo2(const EAXREVERBPROPERTIES *props)
394 EAX20LISTENERPROPERTIES ret;
395 ret.lRoom = props->lRoom;
396 ret.lRoomHF = props->lRoomHF;
397 ret.flRoomRolloffFactor = props->flRoomRolloffFactor;
398 ret.flDecayTime = props->flDecayTime;
399 ret.flDecayHFRatio = props->flDecayHFRatio;
400 ret.lReflections = props->lReflections;
401 ret.flReflectionsDelay = props->flReflectionsDelay;
402 ret.lReverb = props->lReverb;
403 ret.flReverbDelay = props->flReverbDelay;
404 ret.dwEnvironment = props->dwEnvironment;
405 ret.flEnvironmentSize = props->flEnvironmentSize;
406 ret.flEnvironmentDiffusion = props->flEnvironmentDiffusion;
407 ret.flAirAbsorptionHF = props->flAirAbsorptionHF;
408 ret.dwFlags = props->dwFlags & EAX2LISTENERFLAGS_MASK;
409 return ret;
412 static EAX20BUFFERPROPERTIES EAXSourceTo2(const EAXSOURCEPROPERTIES *props)
414 EAX20BUFFERPROPERTIES ret;
415 ret.lDirect = props->lDirect;
416 ret.lDirectHF = props->lDirectHF;
417 ret.lRoom = props->lRoom;
418 ret.lRoomHF = props->lRoomHF;
419 ret.flRoomRolloffFactor = props->flRoomRolloffFactor;
420 ret.lObstruction = props->lObstruction;
421 ret.flObstructionLFRatio = props->flObstructionLFRatio;
422 ret.lOcclusion = props->lOcclusion;
423 ret.flOcclusionLFRatio = props->flOcclusionLFRatio;
424 ret.flOcclusionRoomRatio = props->flOcclusionRoomRatio;
425 ret.lOutsideVolumeHF = props->lOutsideVolumeHF;
426 ret.flAirAbsorptionFactor = props->flAirAbsorptionFactor;
427 ret.dwFlags = props->dwFlags;
428 return ret;
432 HRESULT EAX2_Query(DSPrimary *prim, DWORD propid, ULONG *pTypeSupport)
434 if(prim->effect[0] == 0)
435 return E_PROP_ID_UNSUPPORTED;
437 switch((propid&~DSPROPERTY_EAX20LISTENER_DEFERRED))
439 case DSPROPERTY_EAX20LISTENER_NONE:
440 case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS:
441 case DSPROPERTY_EAX20LISTENER_ROOM:
442 case DSPROPERTY_EAX20LISTENER_ROOMHF:
443 case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR:
444 case DSPROPERTY_EAX20LISTENER_DECAYTIME:
445 case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO:
446 case DSPROPERTY_EAX20LISTENER_REFLECTIONS:
447 case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY:
448 case DSPROPERTY_EAX20LISTENER_REVERB:
449 case DSPROPERTY_EAX20LISTENER_REVERBDELAY:
450 case DSPROPERTY_EAX20LISTENER_ENVIRONMENT:
451 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE:
452 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION:
453 case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF:
454 case DSPROPERTY_EAX20LISTENER_FLAGS:
455 *pTypeSupport = KSPROPERTY_SUPPORT_GET | KSPROPERTY_SUPPORT_SET;
456 return DS_OK;
458 FIXME("Unhandled propid: 0x%08lx\n", propid);
459 return E_PROP_ID_UNSUPPORTED;
462 HRESULT EAX2_Set(DSPrimary *prim, DWORD propid, void *pPropData, ULONG cbPropData)
464 if(prim->effect[0] == 0)
465 return E_PROP_ID_UNSUPPORTED;
466 if(prim->deferred.fxslot[0].effect_type != FXSLOT_EFFECT_REVERB)
468 ERR("Trying to set reverb parameters on non-reverb slot\n");
469 return DSERR_INVALIDCALL;
472 switch(propid)
474 case DSPROPERTY_EAX20LISTENER_NONE: /* not setting any property, just applying */
475 return DS_OK;
477 case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS:
478 if(cbPropData >= sizeof(EAX20LISTENERPROPERTIES))
480 union {
481 const void *v;
482 const EAX20LISTENERPROPERTIES *props;
483 } data = { pPropData };
484 EAXREVERBPROPERTIES props = REVERB_PRESET_GENERIC;
485 TRACE("Parameters:\n\tEnvironment: %lu\n\tEnvSize: %f\n\tEnvDiffusion: %f\n\t"
486 "Room: %ld\n\tRoom HF: %ld\n\tDecay Time: %f\n\tDecay HF Ratio: %f\n\t"
487 "Reflections: %ld\n\tReflections Delay: %f\n\tReverb: %ld\n\tReverb Delay: %f\n\t"
488 "Air Absorption: %f\n\tRoom Rolloff: %f\n\tFlags: 0x%02lx\n",
489 data.props->dwEnvironment, data.props->flEnvironmentSize,
490 data.props->flEnvironmentDiffusion, data.props->lRoom, data.props->lRoomHF,
491 data.props->flDecayTime, data.props->flDecayHFRatio, data.props->lReflections,
492 data.props->flReflectionsDelay, data.props->lReverb, data.props->flReverbDelay,
493 data.props->flAirAbsorptionHF, data.props->flRoomRolloffFactor, data.props->dwFlags
496 if(data.props->dwEnvironment < EAX_ENVIRONMENT_UNDEFINED)
498 props = EnvironmentDefaults[data.props->dwEnvironment];
499 props.dwEnvironment = data.props->dwEnvironment;
501 props.flEnvironmentSize = data.props->flEnvironmentSize;
502 props.flEnvironmentDiffusion = data.props->flEnvironmentDiffusion;
503 props.lRoom = data.props->lRoom;
504 props.lRoomHF = data.props->lRoomHF;
505 props.flDecayTime = data.props->flDecayTime;
506 props.flDecayHFRatio = data.props->flDecayHFRatio;
507 props.lReflections = data.props->lReflections;
508 props.flReflectionsDelay = data.props->flReflectionsDelay;
509 props.lReverb = data.props->lReverb;
510 props.flReverbDelay = data.props->flReverbDelay;
511 props.flAirAbsorptionHF = data.props->flAirAbsorptionHF;
512 props.flRoomRolloffFactor = data.props->flRoomRolloffFactor;
513 props.dwFlags = data.props->dwFlags;
514 return EAXReverb_Set(prim, 0, EAXREVERB_ALLPARAMETERS, &props, sizeof(props));
516 return DSERR_INVALIDPARAM;
518 #define HANDLE_PROP(P) case DSPROPERTY_EAX20LISTENER_##P: \
519 return EAXReverb_Set(prim, 0, EAXREVERB_##P, pPropData, cbPropData);
520 HANDLE_PROP(ROOM)
521 HANDLE_PROP(ROOMHF)
522 HANDLE_PROP(DECAYTIME)
523 HANDLE_PROP(DECAYHFRATIO)
524 HANDLE_PROP(REFLECTIONS)
525 HANDLE_PROP(REFLECTIONSDELAY)
526 HANDLE_PROP(REVERB)
527 HANDLE_PROP(REVERBDELAY)
528 HANDLE_PROP(ENVIRONMENT)
529 HANDLE_PROP(ENVIRONMENTSIZE)
530 HANDLE_PROP(ENVIRONMENTDIFFUSION)
531 HANDLE_PROP(AIRABSORPTIONHF)
532 HANDLE_PROP(ROOMROLLOFFFACTOR)
533 HANDLE_PROP(FLAGS)
534 #undef HANDLE_PROP
536 FIXME("Unhandled propid: 0x%08lx\n", propid);
537 return E_PROP_ID_UNSUPPORTED;
540 HRESULT EAX2_Get(DSPrimary *prim, DWORD propid, void *pPropData, ULONG cbPropData, ULONG *pcbReturned)
542 if(prim->effect[0] == 0)
543 return E_PROP_ID_UNSUPPORTED;
544 if(prim->deferred.fxslot[0].effect_type != FXSLOT_EFFECT_REVERB)
546 ERR("Trying to get reverb parameters on non-reverb slot\n");
547 return DSERR_INVALIDCALL;
550 switch(propid)
552 case DSPROPERTY_EAX20LISTENER_NONE:
553 *pcbReturned = 0;
554 return DS_OK;
556 case DSPROPERTY_EAX20LISTENER_ALLPARAMETERS:
557 GET_PROP(EAXRevTo2(&prim->deferred.fxslot[0].fx.reverb), EAX20LISTENERPROPERTIES);
558 case DSPROPERTY_EAX20LISTENER_ROOM:
559 GET_PROP(prim->deferred.fxslot[0].fx.reverb.lRoom, long);
560 case DSPROPERTY_EAX20LISTENER_ROOMHF:
561 GET_PROP(prim->deferred.fxslot[0].fx.reverb.lRoomHF, long);
562 case DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR:
563 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flRoomRolloffFactor, float);
564 case DSPROPERTY_EAX20LISTENER_DECAYTIME:
565 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flDecayTime, float);
566 case DSPROPERTY_EAX20LISTENER_DECAYHFRATIO:
567 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flDecayHFRatio, float);
568 case DSPROPERTY_EAX20LISTENER_REFLECTIONS:
569 GET_PROP(prim->deferred.fxslot[0].fx.reverb.lReflections, long);
570 case DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY:
571 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flReflectionsDelay, float);
572 case DSPROPERTY_EAX20LISTENER_REVERB:
573 GET_PROP(prim->deferred.fxslot[0].fx.reverb.lReverb, long);
574 case DSPROPERTY_EAX20LISTENER_REVERBDELAY:
575 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flReverbDelay, float);
576 case DSPROPERTY_EAX20LISTENER_ENVIRONMENT:
577 GET_PROP(prim->deferred.fxslot[0].fx.reverb.dwEnvironment, DWORD);
578 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE:
579 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flEnvironmentSize, float);
580 case DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION:
581 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flEnvironmentDiffusion, float);
582 case DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF:
583 GET_PROP(prim->deferred.fxslot[0].fx.reverb.flAirAbsorptionHF, float);
584 case DSPROPERTY_EAX20LISTENER_FLAGS:
585 GET_PROP(prim->deferred.fxslot[0].fx.reverb.dwFlags&EAX2LISTENERFLAGS_MASK, DWORD);
587 FIXME("Unhandled listener propid: 0x%08lx\n", propid);
588 return E_PROP_ID_UNSUPPORTED;
592 HRESULT EAX2Buffer_Query(DSBuffer *buf, DWORD propid, ULONG *pTypeSupport)
594 (void)buf;
596 switch((propid&~DSPROPERTY_EAX20BUFFER_DEFERRED))
598 case DSPROPERTY_EAX20BUFFER_NONE:
599 case DSPROPERTY_EAX20BUFFER_ALLPARAMETERS:
600 case DSPROPERTY_EAX20BUFFER_DIRECT:
601 case DSPROPERTY_EAX20BUFFER_DIRECTHF:
602 case DSPROPERTY_EAX20BUFFER_ROOM:
603 case DSPROPERTY_EAX20BUFFER_ROOMHF:
604 case DSPROPERTY_EAX20BUFFER_ROOMROLLOFFFACTOR:
605 case DSPROPERTY_EAX20BUFFER_OBSTRUCTION:
606 case DSPROPERTY_EAX20BUFFER_OBSTRUCTIONLFRATIO:
607 case DSPROPERTY_EAX20BUFFER_OCCLUSION:
608 case DSPROPERTY_EAX20BUFFER_OCCLUSIONLFRATIO:
609 case DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO:
610 case DSPROPERTY_EAX20BUFFER_OUTSIDEVOLUMEHF:
611 case DSPROPERTY_EAX20BUFFER_AIRABSORPTIONFACTOR:
612 case DSPROPERTY_EAX20BUFFER_FLAGS:
613 *pTypeSupport = KSPROPERTY_SUPPORT_GET | KSPROPERTY_SUPPORT_SET;
614 return DS_OK;
616 FIXME("Unhandled propid: 0x%08lx\n", propid);
617 return E_PROP_ID_UNSUPPORTED;
620 HRESULT EAX2Buffer_Set(DSBuffer *buf, DWORD propid, void *pPropData, ULONG cbPropData)
622 switch(propid)
624 case DSPROPERTY_EAX20BUFFER_NONE: /* not setting any property, just applying */
625 return DS_OK;
627 case DSPROPERTY_EAX20BUFFER_ALLPARAMETERS:
628 if(cbPropData >= sizeof(EAX20BUFFERPROPERTIES))
630 union {
631 const void *v;
632 const EAX20BUFFERPROPERTIES *props;
633 } data = { pPropData };
634 EAXSOURCEPROPERTIES props;
635 TRACE("Parameters:\n\tDirect: %ld\n\tDirect HF: %ld\n\tRoom: %ld\n\tRoom HF: %ld\n\t"
636 "Room Rolloff Factor: %f\n\tObstruction: %ld\n\tObstruction LF Ratio: %f\n\t"
637 "Occlusion: %ld\n\tOcclusion LF Ratio: %f\n\tOcclusion Room Ratio: %f\n\t"
638 "Outside Volume HF: %ld\n\tAir Absorb Factor: %f\n\tFlags: 0x%02lx\n",
639 data.props->lDirect, data.props->lDirectHF, data.props->lRoom, data.props->lRoomHF,
640 data.props->flRoomRolloffFactor, data.props->lObstruction,
641 data.props->flObstructionLFRatio, data.props->lOcclusion,
642 data.props->flOcclusionLFRatio, data.props->flOcclusionRoomRatio,
643 data.props->lOutsideVolumeHF, data.props->flAirAbsorptionFactor,
644 data.props->dwFlags
647 props = buf->deferred.eax;
648 props.lDirect = data.props->lDirect;
649 props.lDirectHF = data.props->lDirectHF;
650 props.lRoom = data.props->lRoom;
651 props.lRoomHF = data.props->lRoomHF;
652 props.flRoomRolloffFactor = data.props->flRoomRolloffFactor;
653 props.lObstruction = data.props->lObstruction;
654 props.flObstructionLFRatio = data.props->flObstructionLFRatio;
655 props.lOcclusion = data.props->lOcclusion;
656 props.flOcclusionLFRatio = data.props->flOcclusionLFRatio;
657 props.flOcclusionRoomRatio = data.props->flOcclusionRoomRatio + 1.0f;
658 props.lOutsideVolumeHF = data.props->lOutsideVolumeHF;
659 props.flAirAbsorptionFactor = data.props->flAirAbsorptionFactor;
660 props.dwFlags = data.props->dwFlags;
661 return EAX4Source_Set(buf, EAXSOURCE_ALLPARAMETERS, &props, sizeof(props));
663 return DSERR_INVALIDPARAM;
665 /* Special-case occlusion room ratio, since its behavior changed with EAX3
666 * and up.
668 case DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO:
669 if(cbPropData >= sizeof(float))
671 union { const void *v; const float *fl; } data = { pPropData };
672 float f = *data.fl + 1.0f;
673 return EAX4Source_Set(buf, EAXSOURCE_OCCLUSIONROOMRATIO, &f, sizeof(f));
675 return DSERR_INVALIDPARAM;
677 #define HANDLE_PROP(P) case DSPROPERTY_EAX20BUFFER_##P: \
678 return EAX4Source_Set(buf, EAXSOURCE_##P, pPropData, cbPropData);
679 HANDLE_PROP(DIRECT)
680 HANDLE_PROP(DIRECTHF)
681 HANDLE_PROP(ROOM)
682 HANDLE_PROP(ROOMHF)
683 HANDLE_PROP(OBSTRUCTION)
684 HANDLE_PROP(OBSTRUCTIONLFRATIO)
685 HANDLE_PROP(OCCLUSION)
686 HANDLE_PROP(OCCLUSIONLFRATIO)
687 HANDLE_PROP(OUTSIDEVOLUMEHF)
688 HANDLE_PROP(ROOMROLLOFFFACTOR)
689 HANDLE_PROP(AIRABSORPTIONFACTOR)
690 HANDLE_PROP(FLAGS)
691 #undef HANDLE_PROP
693 FIXME("Unhandled propid: 0x%08lx\n", propid);
694 return E_PROP_ID_UNSUPPORTED;
697 HRESULT EAX2Buffer_Get(DSBuffer *buf, DWORD propid, void *pPropData, ULONG cbPropData, ULONG *pcbReturned)
699 switch(propid)
701 case DSPROPERTY_EAX20BUFFER_NONE:
702 *pcbReturned = 0;
703 return DS_OK;
705 case DSPROPERTY_EAX20BUFFER_ALLPARAMETERS:
706 GET_PROP(EAXSourceTo2(&buf->current.eax), EAX20BUFFERPROPERTIES);
707 case DSPROPERTY_EAX20BUFFER_DIRECT:
708 GET_PROP(buf->current.eax.lDirect, long);
709 case DSPROPERTY_EAX20BUFFER_DIRECTHF:
710 GET_PROP(buf->current.eax.lDirectHF, long);
711 case DSPROPERTY_EAX20BUFFER_ROOM:
712 GET_PROP(buf->current.eax.lRoom, long);
713 case DSPROPERTY_EAX20BUFFER_ROOMHF:
714 GET_PROP(buf->current.eax.lRoomHF, long);
715 case DSPROPERTY_EAX20BUFFER_ROOMROLLOFFFACTOR:
716 GET_PROP(buf->current.eax.flRoomRolloffFactor, float);
717 case DSPROPERTY_EAX20BUFFER_OBSTRUCTION:
718 GET_PROP(buf->current.eax.lObstruction, long);
719 case DSPROPERTY_EAX20BUFFER_OBSTRUCTIONLFRATIO:
720 GET_PROP(buf->current.eax.flObstructionLFRatio, float);
721 case DSPROPERTY_EAX20BUFFER_OCCLUSION:
722 GET_PROP(buf->current.eax.lOcclusion, long);
723 case DSPROPERTY_EAX20BUFFER_OCCLUSIONLFRATIO:
724 GET_PROP(buf->current.eax.flOcclusionLFRatio, float);
725 case DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO:
726 GET_PROP(maxF(buf->current.eax.flOcclusionRoomRatio-1.0f, 0.0f), float);
727 case DSPROPERTY_EAX20BUFFER_OUTSIDEVOLUMEHF:
728 GET_PROP(buf->current.eax.lOutsideVolumeHF, long);
729 case DSPROPERTY_EAX20BUFFER_AIRABSORPTIONFACTOR:
730 GET_PROP(buf->current.eax.flAirAbsorptionFactor, float);
731 case DSPROPERTY_EAX20BUFFER_FLAGS:
732 GET_PROP(buf->current.eax.dwFlags, DWORD);
734 FIXME("Unhandled propid: 0x%08lx\n", propid);
735 return E_PROP_ID_UNSUPPORTED;
739 /*******************
740 * EAX 1 stuff
741 ******************/
743 HRESULT EAX1_Query(DSPrimary *prim, DWORD propid, ULONG *pTypeSupport)
745 if(prim->effect[0] == 0)
746 return E_PROP_ID_UNSUPPORTED;
748 switch(propid)
750 case DSPROPERTY_EAX10LISTENER_ALL:
751 case DSPROPERTY_EAX10LISTENER_ENVIRONMENT:
752 case DSPROPERTY_EAX10LISTENER_VOLUME:
753 case DSPROPERTY_EAX10LISTENER_DECAYTIME:
754 case DSPROPERTY_EAX10LISTENER_DAMPING:
755 *pTypeSupport = KSPROPERTY_SUPPORT_GET | KSPROPERTY_SUPPORT_SET;
756 return DS_OK;
758 FIXME("Unhandled propid: 0x%08lx\n", propid);
759 return E_PROP_ID_UNSUPPORTED;
762 HRESULT EAX1_Set(DSPrimary *prim, DWORD propid, void *pPropData, ULONG cbPropData)
764 static const float eax1_env_volume[EAX_ENVIRONMENT_UNDEFINED] = {
765 0.5f, 0.25f, 0.417f, 0.653f, 0.208f, 0.5f, 0.403f, 0.5f, 0.5f,
766 0.361f, 0.5f, 0.153f, 0.361f, 0.444f, 0.25f, 0.111f, 0.111f,
767 0.194f, 1.0f, 0.097f, 0.208f, 0.652f, 1.0f, 0.875f, 0.139f, 0.486f
769 static const float eax1_env_dampening[EAX_ENVIRONMENT_UNDEFINED] = {
770 0.5f, 0.0f, 0.666f, 0.166f, 0.0f, 0.888f, 0.5f, 0.5f, 1.304f,
771 0.332f, 0.3f, 2.0f, 0.0f, 0.638f, 0.776f, 0.472f, 0.224f, 0.472f,
772 0.5f, 0.224f, 1.5f, 0.25f, 0.0f, 1.388f, 0.666f, 0.806f
774 HRESULT hr;
776 if(prim->effect[0] == 0)
777 return E_PROP_ID_UNSUPPORTED;
778 if(prim->deferred.fxslot[0].effect_type != FXSLOT_EFFECT_REVERB)
780 ERR("Trying to set reverb parameters on non-reverb slot\n");
781 return DSERR_INVALIDCALL;
784 switch(propid)
786 case DSPROPERTY_EAX10LISTENER_ALL:
787 if(cbPropData >= sizeof(EAX10LISTENERPROPERTIES))
789 union {
790 const void *v;
791 const EAX10LISTENERPROPERTIES *props;
792 } data = { pPropData };
793 TRACE("Parameters:\n\tEnvironment: %lu\n\tVolume: %f\n\tDecay Time: %f\n\t"
794 "Damping: %f\n", data.props->dwEnvironment, data.props->fVolume,
795 data.props->fDecayTime, data.props->fDamping
798 if(data.props->dwEnvironment < EAX_ENVIRONMENT_UNDEFINED)
800 /* NOTE: I'm not quite sure how to handle the volume. It's
801 * important to deal with since it can have a notable impact on
802 * the output levels, but given the default EAX1 environment
803 * volumes, they don't align with the gain/room volume for
804 * EAX2+ environments. Presuming the default volumes are
805 * correct, it's possible the reverb implementation was
806 * different and relied on different gains to get the intended
807 * output levels.
809 * Rather than just blindly applying the volume, we take the
810 * difference from the EAX1 environment's default volume and
811 * apply that as an offset to the EAX2 environment's volume.
813 EAXREVERBPROPERTIES env = EnvironmentDefaults[data.props->dwEnvironment];
814 long db_vol = clampI(
815 gain_to_mB(data.props->fVolume / eax1_env_volume[data.props->dwEnvironment]),
816 -10000, 10000
818 env.lRoom = clampI(env.lRoom + db_vol, -10000, 0);
819 env.flDecayTime = data.props->fDecayTime;
821 hr = EAXReverb_Set(prim, 0, EAXREVERB_ALLPARAMETERS, &env, sizeof(env));
822 if(SUCCEEDED(hr))
824 prim->deferred.eax1_volume = data.props->fVolume;
825 prim->deferred.eax1_dampening = data.props->fDamping;
827 return hr;
830 return DSERR_INVALIDPARAM;
832 case DSPROPERTY_EAX10LISTENER_ENVIRONMENT:
833 hr = EAXReverb_Set(prim, 0, EAXREVERB_ENVIRONMENT, pPropData, cbPropData);
834 if(SUCCEEDED(hr))
836 union { const void *v; const DWORD *dw; } data = { pPropData };
837 prim->deferred.eax1_volume = eax1_env_volume[*data.dw];
838 prim->deferred.eax1_dampening = eax1_env_dampening[*data.dw];
840 return hr;
842 case DSPROPERTY_EAX10LISTENER_VOLUME:
843 if(cbPropData >= sizeof(float))
845 union { const void *v; const float *fl; } data = { pPropData };
846 long db_vol = clampI(
847 gain_to_mB(*data.fl / eax1_env_volume[prim->deferred.fxslot[0].fx.reverb.dwEnvironment]),
848 -10000, 10000
850 long room_vol = clampI(
851 EnvironmentDefaults[prim->deferred.fxslot[0].fx.reverb.dwEnvironment].lRoom + db_vol,
852 -10000, 0
854 TRACE("Volume: %f\n", *data.fl);
856 hr = EAXReverb_Set(prim, 0, EAXREVERB_ROOM, &room_vol, sizeof(room_vol));
857 if(SUCCEEDED(hr)) prim->deferred.eax1_volume = *data.fl;
858 return hr;
860 return DSERR_INVALIDPARAM;
861 case DSPROPERTY_EAX10LISTENER_DECAYTIME:
862 return EAXReverb_Set(prim, 0, EAXREVERB_DECAYTIME, pPropData, cbPropData);
863 case DSPROPERTY_EAX10LISTENER_DAMPING:
864 if(cbPropData >= sizeof(float))
866 union { const void *v; const float *fl; } data = { pPropData };
867 TRACE("Damping: %f\n", *data.fl);
869 prim->deferred.eax1_dampening = *data.fl;
870 return DS_OK;
872 return DSERR_INVALIDPARAM;
874 FIXME("Unhandled propid: 0x%08lx\n", propid);
875 return E_PROP_ID_UNSUPPORTED;
878 HRESULT EAX1_Get(DSPrimary *prim, DWORD propid, void *pPropData, ULONG cbPropData, ULONG *pcbReturned)
880 if(prim->effect[0] == 0)
881 return E_PROP_ID_UNSUPPORTED;
882 if(prim->deferred.fxslot[0].effect_type != FXSLOT_EFFECT_REVERB)
884 ERR("Trying to get reverb parameters on non-reverb slot\n");
885 return DSERR_INVALIDCALL;
888 switch(propid)
890 case DSPROPERTY_EAX10LISTENER_ALL:
891 if(cbPropData >= sizeof(EAX10LISTENERPROPERTIES))
893 union {
894 void *v;
895 EAX10LISTENERPROPERTIES *props;
896 } data = { pPropData };
898 data.props->dwEnvironment = prim->deferred.fxslot[0].fx.reverb.dwEnvironment;
899 data.props->fVolume = prim->deferred.eax1_volume;
900 data.props->fDecayTime = prim->deferred.fxslot[0].fx.reverb.flDecayTime;
901 data.props->fDamping = prim->deferred.eax1_dampening;
903 *pcbReturned = sizeof(EAX10LISTENERPROPERTIES);
904 return DS_OK;
906 return DSERR_INVALIDPARAM;
908 case DSPROPERTY_EAX10LISTENER_ENVIRONMENT:
909 return EAXReverb_Get(prim, 0, EAXREVERB_ENVIRONMENT, pPropData, cbPropData, pcbReturned);
911 case DSPROPERTY_EAX10LISTENER_VOLUME:
912 if(cbPropData >= sizeof(float))
914 union { void *v; float *fl; } data = { pPropData };
915 *data.fl = prim->deferred.eax1_volume;
916 *pcbReturned = sizeof(float);
917 return DS_OK;
919 return DSERR_INVALIDPARAM;
921 case DSPROPERTY_EAX10LISTENER_DECAYTIME:
922 return EAXReverb_Get(prim, 0, EAXREVERB_DECAYTIME, pPropData, cbPropData, pcbReturned);
924 case DSPROPERTY_EAX10LISTENER_DAMPING:
925 if(cbPropData >= sizeof(float))
927 union { void *v; float *fl; } data = { pPropData };
928 *data.fl = prim->deferred.eax1_dampening;
929 *pcbReturned = sizeof(float);
930 return DS_OK;
932 return DSERR_INVALIDPARAM;
934 FIXME("Unhandled propid: 0x%08lx\n", propid);
935 return E_PROP_ID_UNSUPPORTED;
939 HRESULT EAX1Buffer_Query(DSBuffer *buf, DWORD propid, ULONG *pTypeSupport)
941 (void)buf;
943 switch(propid)
945 case DSPROPERTY_EAX10BUFFER_ALL:
946 case DSPROPERTY_EAX10BUFFER_REVERBMIX:
947 *pTypeSupport = KSPROPERTY_SUPPORT_GET | KSPROPERTY_SUPPORT_SET;
948 return DS_OK;
950 FIXME("Unhandled propid: 0x%08lx\n", propid);
951 return E_PROP_ID_UNSUPPORTED;
954 HRESULT EAX1Buffer_Set(DSBuffer *buf, DWORD propid, void *pPropData, ULONG cbPropData)
956 switch(propid)
958 /* NOTE: DSPROPERTY_EAX10BUFFER_ALL is for EAX10BUFFERPROPERTIES, however
959 * that struct just contains the single ReverbMix float property.
961 case DSPROPERTY_EAX10BUFFER_ALL:
962 case DSPROPERTY_EAX10BUFFER_REVERBMIX:
963 if(cbPropData >= sizeof(float))
965 union { const void *v; const float *fl; } data = { pPropData };
966 LONG mbvol;
967 HRESULT hr;
969 TRACE("Reverb Mix: %f\n", *data.fl);
970 mbvol = gain_to_mB(*data.fl);
972 hr = EAX4Source_Set(buf, EAXSOURCE_ROOM, &mbvol, sizeof(mbvol));
973 if(SUCCEEDED(hr)) buf->deferred.eax1_reverbmix = *data.fl;
974 return hr;
976 return DSERR_INVALIDPARAM;
978 FIXME("Unhandled propid: 0x%08lx\n", propid);
979 return E_PROP_ID_UNSUPPORTED;
982 HRESULT EAX1Buffer_Get(DSBuffer *buf, DWORD propid, void *pPropData, ULONG cbPropData, ULONG *pcbReturned)
984 switch(propid)
986 case DSPROPERTY_EAX10BUFFER_ALL:
987 case DSPROPERTY_EAX10BUFFER_REVERBMIX:
988 if(cbPropData >= sizeof(float))
990 union { void *v; float *fl; } data = { pPropData };
992 *data.fl = buf->current.eax1_reverbmix;
993 *pcbReturned = sizeof(float);
994 return DS_OK;
996 return DSERR_INVALIDPARAM;
998 FIXME("Unhandled propid: 0x%08lx\n", propid);
999 return E_PROP_ID_UNSUPPORTED;