Add a basic readme
[dsound-openal.git] / eax.c
blob90338012d137140ff1b357bd71b2d5d96e051ec9
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;
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 #define HANDLE_PROP(P) case DSPROPERTY_EAX20BUFFER_##P: \
666 return EAX4Source_Set(buf, EAXSOURCE_##P, pPropData, cbPropData);
667 HANDLE_PROP(DIRECT)
668 HANDLE_PROP(DIRECTHF)
669 HANDLE_PROP(ROOM)
670 HANDLE_PROP(ROOMHF)
671 HANDLE_PROP(OBSTRUCTION)
672 HANDLE_PROP(OBSTRUCTIONLFRATIO)
673 HANDLE_PROP(OCCLUSION)
674 HANDLE_PROP(OCCLUSIONLFRATIO)
675 HANDLE_PROP(OCCLUSIONROOMRATIO)
676 HANDLE_PROP(OUTSIDEVOLUMEHF)
677 HANDLE_PROP(ROOMROLLOFFFACTOR)
678 HANDLE_PROP(AIRABSORPTIONFACTOR)
679 HANDLE_PROP(FLAGS)
680 #undef HANDLE_PROP
682 FIXME("Unhandled propid: 0x%08lx\n", propid);
683 return E_PROP_ID_UNSUPPORTED;
686 HRESULT EAX2Buffer_Get(DSBuffer *buf, DWORD propid, void *pPropData, ULONG cbPropData, ULONG *pcbReturned)
688 switch(propid)
690 case DSPROPERTY_EAX20BUFFER_NONE:
691 *pcbReturned = 0;
692 return DS_OK;
694 case DSPROPERTY_EAX20BUFFER_ALLPARAMETERS:
695 GET_PROP(EAXSourceTo2(&buf->current.eax), EAX20BUFFERPROPERTIES);
696 case DSPROPERTY_EAX20BUFFER_DIRECT:
697 GET_PROP(buf->current.eax.lDirect, long);
698 case DSPROPERTY_EAX20BUFFER_DIRECTHF:
699 GET_PROP(buf->current.eax.lDirectHF, long);
700 case DSPROPERTY_EAX20BUFFER_ROOM:
701 GET_PROP(buf->current.eax.lRoom, long);
702 case DSPROPERTY_EAX20BUFFER_ROOMHF:
703 GET_PROP(buf->current.eax.lRoomHF, long);
704 case DSPROPERTY_EAX20BUFFER_ROOMROLLOFFFACTOR:
705 GET_PROP(buf->current.eax.flRoomRolloffFactor, float);
706 case DSPROPERTY_EAX20BUFFER_OBSTRUCTION:
707 GET_PROP(buf->current.eax.lObstruction, long);
708 case DSPROPERTY_EAX20BUFFER_OBSTRUCTIONLFRATIO:
709 GET_PROP(buf->current.eax.flObstructionLFRatio, float);
710 case DSPROPERTY_EAX20BUFFER_OCCLUSION:
711 GET_PROP(buf->current.eax.lOcclusion, long);
712 case DSPROPERTY_EAX20BUFFER_OCCLUSIONLFRATIO:
713 GET_PROP(buf->current.eax.flOcclusionLFRatio, float);
714 case DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO:
715 GET_PROP(buf->current.eax.flOcclusionRoomRatio, float);
716 case DSPROPERTY_EAX20BUFFER_OUTSIDEVOLUMEHF:
717 GET_PROP(buf->current.eax.lOutsideVolumeHF, long);
718 case DSPROPERTY_EAX20BUFFER_AIRABSORPTIONFACTOR:
719 GET_PROP(buf->current.eax.flAirAbsorptionFactor, float);
720 case DSPROPERTY_EAX20BUFFER_FLAGS:
721 GET_PROP(buf->current.eax.dwFlags, DWORD);
723 FIXME("Unhandled propid: 0x%08lx\n", propid);
724 return E_PROP_ID_UNSUPPORTED;
728 /*******************
729 * EAX 1 stuff
730 ******************/
732 HRESULT EAX1_Query(DSPrimary *prim, DWORD propid, ULONG *pTypeSupport)
734 if(prim->effect[0] == 0)
735 return E_PROP_ID_UNSUPPORTED;
737 switch(propid)
739 case DSPROPERTY_EAX10LISTENER_ALL:
740 case DSPROPERTY_EAX10LISTENER_ENVIRONMENT:
741 case DSPROPERTY_EAX10LISTENER_VOLUME:
742 case DSPROPERTY_EAX10LISTENER_DECAYTIME:
743 case DSPROPERTY_EAX10LISTENER_DAMPING:
744 *pTypeSupport = KSPROPERTY_SUPPORT_GET | KSPROPERTY_SUPPORT_SET;
745 return DS_OK;
747 FIXME("Unhandled propid: 0x%08lx\n", propid);
748 return E_PROP_ID_UNSUPPORTED;
751 HRESULT EAX1_Set(DSPrimary *prim, DWORD propid, void *pPropData, ULONG cbPropData)
753 static const float eax1_env_volume[EAX_ENVIRONMENT_UNDEFINED] = {
754 0.5f, 0.25f, 0.417f, 0.653f, 0.208f, 0.5f, 0.403f, 0.5f, 0.5f,
755 0.361f, 0.5f, 0.153f, 0.361f, 0.444f, 0.25f, 0.111f, 0.111f,
756 0.194f, 1.0f, 0.097f, 0.208f, 0.652f, 1.0f, 0.875f, 0.139f, 0.486f
758 static const float eax1_env_dampening[EAX_ENVIRONMENT_UNDEFINED] = {
759 0.5f, 0.0f, 0.666f, 0.166f, 0.0f, 0.888f, 0.5f, 0.5f, 1.304f,
760 0.332f, 0.3f, 2.0f, 0.0f, 0.638f, 0.776f, 0.472f, 0.224f, 0.472f,
761 0.5f, 0.224f, 1.5f, 0.25f, 0.0f, 1.388f, 0.666f, 0.806f
763 HRESULT hr;
765 if(prim->effect[0] == 0)
766 return E_PROP_ID_UNSUPPORTED;
767 if(prim->deferred.fxslot[0].effect_type != FXSLOT_EFFECT_REVERB)
769 ERR("Trying to set reverb parameters on non-reverb slot\n");
770 return DSERR_INVALIDCALL;
773 switch(propid)
775 case DSPROPERTY_EAX10LISTENER_ALL:
776 if(cbPropData >= sizeof(EAX10LISTENERPROPERTIES))
778 union {
779 const void *v;
780 const EAX10LISTENERPROPERTIES *props;
781 } data = { pPropData };
782 TRACE("Parameters:\n\tEnvironment: %lu\n\tVolume: %f\n\tDecay Time: %f\n\t"
783 "Damping: %f\n", data.props->dwEnvironment, data.props->fVolume,
784 data.props->fDecayTime, data.props->fDamping
787 if(data.props->dwEnvironment < EAX_ENVIRONMENT_UNDEFINED)
789 /* NOTE: I'm not quite sure how to handle the volume. It's
790 * important to deal with since it can have a notable impact on
791 * the output levels, but given the default EAX1 environment
792 * volumes, they don't align with the gain/room volume for
793 * EAX2+ environments. Presuming the default volumes are
794 * correct, it's possible the reverb implementation was
795 * different and relied on different gains to get the intended
796 * output levels.
798 * Rather than just blindly applying the volume, we take the
799 * difference from the EAX1 environment's default volume and
800 * apply that as an offset to the EAX2 environment's volume.
802 EAXREVERBPROPERTIES env = EnvironmentDefaults[data.props->dwEnvironment];
803 long db_vol = clampI(
804 gain_to_mB(data.props->fVolume / eax1_env_volume[data.props->dwEnvironment]),
805 -10000, 10000
807 env.lRoom = clampI(env.lRoom + db_vol, -10000, 0);
808 env.flDecayTime = data.props->fDecayTime;
810 hr = EAXReverb_Set(prim, 0, EAXREVERB_ALLPARAMETERS, &env, sizeof(env));
811 if(SUCCEEDED(hr))
813 prim->deferred.eax1_volume = data.props->fVolume;
814 prim->deferred.eax1_dampening = data.props->fDamping;
816 return hr;
819 return DSERR_INVALIDPARAM;
821 case DSPROPERTY_EAX10LISTENER_ENVIRONMENT:
822 hr = EAXReverb_Set(prim, 0, EAXREVERB_ENVIRONMENT, pPropData, cbPropData);
823 if(SUCCEEDED(hr))
825 union { const void *v; const DWORD *dw; } data = { pPropData };
826 prim->deferred.eax1_volume = eax1_env_volume[*data.dw];
827 prim->deferred.eax1_dampening = eax1_env_dampening[*data.dw];
829 return hr;
831 case DSPROPERTY_EAX10LISTENER_VOLUME:
832 if(cbPropData >= sizeof(float))
834 union { const void *v; const float *fl; } data = { pPropData };
835 long db_vol = clampI(
836 gain_to_mB(*data.fl / eax1_env_volume[prim->deferred.fxslot[0].fx.reverb.dwEnvironment]),
837 -10000, 10000
839 long room_vol = clampI(
840 EnvironmentDefaults[prim->deferred.fxslot[0].fx.reverb.dwEnvironment].lRoom + db_vol,
841 -10000, 0
843 TRACE("Volume: %f\n", *data.fl);
845 hr = EAXReverb_Set(prim, 0, EAXREVERB_ROOM, &room_vol, sizeof(room_vol));
846 if(SUCCEEDED(hr)) prim->deferred.eax1_volume = *data.fl;
847 return hr;
849 return DSERR_INVALIDPARAM;
850 case DSPROPERTY_EAX10LISTENER_DECAYTIME:
851 return EAXReverb_Set(prim, 0, EAXREVERB_DECAYTIME, pPropData, cbPropData);
852 case DSPROPERTY_EAX10LISTENER_DAMPING:
853 if(cbPropData >= sizeof(float))
855 union { const void *v; const float *fl; } data = { pPropData };
856 TRACE("Damping: %f\n", *data.fl);
858 prim->deferred.eax1_dampening = *data.fl;
859 return DS_OK;
861 return DSERR_INVALIDPARAM;
863 FIXME("Unhandled propid: 0x%08lx\n", propid);
864 return E_PROP_ID_UNSUPPORTED;
867 HRESULT EAX1_Get(DSPrimary *prim, DWORD propid, void *pPropData, ULONG cbPropData, ULONG *pcbReturned)
869 if(prim->effect[0] == 0)
870 return E_PROP_ID_UNSUPPORTED;
871 if(prim->deferred.fxslot[0].effect_type != FXSLOT_EFFECT_REVERB)
873 ERR("Trying to get reverb parameters on non-reverb slot\n");
874 return DSERR_INVALIDCALL;
877 switch(propid)
879 case DSPROPERTY_EAX10LISTENER_ALL:
880 if(cbPropData >= sizeof(EAX10LISTENERPROPERTIES))
882 union {
883 void *v;
884 EAX10LISTENERPROPERTIES *props;
885 } data = { pPropData };
887 data.props->dwEnvironment = prim->deferred.fxslot[0].fx.reverb.dwEnvironment;
888 data.props->fVolume = prim->deferred.eax1_volume;
889 data.props->fDecayTime = prim->deferred.fxslot[0].fx.reverb.flDecayTime;
890 data.props->fDamping = prim->deferred.eax1_dampening;
892 *pcbReturned = sizeof(EAX10LISTENERPROPERTIES);
893 return DS_OK;
895 return DSERR_INVALIDPARAM;
897 case DSPROPERTY_EAX10LISTENER_ENVIRONMENT:
898 return EAXReverb_Get(prim, 0, EAXREVERB_ENVIRONMENT, pPropData, cbPropData, pcbReturned);
900 case DSPROPERTY_EAX10LISTENER_VOLUME:
901 if(cbPropData >= sizeof(float))
903 union { void *v; float *fl; } data = { pPropData };
904 *data.fl = prim->deferred.eax1_volume;
905 *pcbReturned = sizeof(float);
906 return DS_OK;
908 return DSERR_INVALIDPARAM;
910 case DSPROPERTY_EAX10LISTENER_DECAYTIME:
911 return EAXReverb_Get(prim, 0, EAXREVERB_DECAYTIME, pPropData, cbPropData, pcbReturned);
913 case DSPROPERTY_EAX10LISTENER_DAMPING:
914 if(cbPropData >= sizeof(float))
916 union { void *v; float *fl; } data = { pPropData };
917 *data.fl = prim->deferred.eax1_dampening;
918 *pcbReturned = sizeof(float);
919 return DS_OK;
921 return DSERR_INVALIDPARAM;
923 FIXME("Unhandled propid: 0x%08lx\n", propid);
924 return E_PROP_ID_UNSUPPORTED;
928 HRESULT EAX1Buffer_Query(DSBuffer *buf, DWORD propid, ULONG *pTypeSupport)
930 (void)buf;
932 switch(propid)
934 case DSPROPERTY_EAX10BUFFER_ALL:
935 case DSPROPERTY_EAX10BUFFER_REVERBMIX:
936 *pTypeSupport = KSPROPERTY_SUPPORT_GET | KSPROPERTY_SUPPORT_SET;
937 return DS_OK;
939 FIXME("Unhandled propid: 0x%08lx\n", propid);
940 return E_PROP_ID_UNSUPPORTED;
943 HRESULT EAX1Buffer_Set(DSBuffer *buf, DWORD propid, void *pPropData, ULONG cbPropData)
945 switch(propid)
947 /* NOTE: DSPROPERTY_EAX10BUFFER_ALL is for EAX10BUFFERPROPERTIES, however
948 * that struct just contains the single ReverbMix float property.
950 case DSPROPERTY_EAX10BUFFER_ALL:
951 case DSPROPERTY_EAX10BUFFER_REVERBMIX:
952 if(cbPropData >= sizeof(float))
954 union { const void *v; const float *fl; } data = { pPropData };
955 LONG mbvol;
956 HRESULT hr;
958 TRACE("Reverb Mix: %f\n", *data.fl);
959 mbvol = gain_to_mB(*data.fl);
961 hr = EAX4Source_Set(buf, EAXSOURCE_ROOM, &mbvol, sizeof(mbvol));
962 if(SUCCEEDED(hr)) buf->deferred.eax1_reverbmix = *data.fl;
963 return hr;
965 return DSERR_INVALIDPARAM;
967 FIXME("Unhandled propid: 0x%08lx\n", propid);
968 return E_PROP_ID_UNSUPPORTED;
971 HRESULT EAX1Buffer_Get(DSBuffer *buf, DWORD propid, void *pPropData, ULONG cbPropData, ULONG *pcbReturned)
973 switch(propid)
975 case DSPROPERTY_EAX10BUFFER_ALL:
976 case DSPROPERTY_EAX10BUFFER_REVERBMIX:
977 if(cbPropData >= sizeof(float))
979 union { void *v; float *fl; } data = { pPropData };
981 *data.fl = buf->current.eax1_reverbmix;
982 *pcbReturned = sizeof(float);
983 return DS_OK;
985 return DSERR_INVALIDPARAM;
987 FIXME("Unhandled propid: 0x%08lx\n", propid);
988 return E_PROP_ID_UNSUPPORTED;