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
25 #include "dsound_private.h"
26 #include "eax-presets.h"
29 static const char *debug_fxslot(const GUID
*guid
)
31 #define HANDLE_ID(id) if(IsEqualGUID(guid, &(id))) return #id
32 HANDLE_ID(EAX_NULL_GUID
);
33 HANDLE_ID(EAX_PrimaryFXSlotID
);
34 HANDLE_ID(EAXPROPERTYID_EAX40_FXSlot0
);
35 HANDLE_ID(EAXPROPERTYID_EAX40_FXSlot1
);
36 HANDLE_ID(EAXPROPERTYID_EAX40_FXSlot2
);
37 HANDLE_ID(EAXPROPERTYID_EAX40_FXSlot3
);
39 return debugstr_guid(guid
);
42 static const char *debug_fxguid(const GUID
*guid
)
44 #define HANDLE_ID(id) if(IsEqualGUID(guid, &(id))) return #id
45 HANDLE_ID(EAX_NULL_GUID
);
46 HANDLE_ID(EAX_REVERB_EFFECT
);
47 HANDLE_ID(EAX_AGCCOMPRESSOR_EFFECT
);
48 HANDLE_ID(EAX_AUTOWAH_EFFECT
);
49 HANDLE_ID(EAX_CHORUS_EFFECT
);
50 HANDLE_ID(EAX_DISTORTION_EFFECT
);
51 HANDLE_ID(EAX_ECHO_EFFECT
);
52 HANDLE_ID(EAX_EQUALIZER_EFFECT
);
53 HANDLE_ID(EAX_FLANGER_EFFECT
);
54 HANDLE_ID(EAX_FREQUENCYSHIFTER_EFFECT
);
55 HANDLE_ID(EAX_VOCALMORPHER_EFFECT
);
56 HANDLE_ID(EAX_PITCHSHIFTER_EFFECT
);
57 HANDLE_ID(EAX_RINGMODULATOR_EFFECT
);
59 return debugstr_guid(guid
);
63 HRESULT
EAX4Context_Query(DSPrimary
*prim
, DWORD propid
, ULONG
*pTypeSupport
)
65 if(!HAS_EXTENSION(prim
->share
, EXT_EFX
))
66 return E_PROP_ID_UNSUPPORTED
;
68 switch((propid
&~EAXCONTEXT_PARAMETER_DEFERRED
))
71 case EAXCONTEXT_ALLPARAMETERS
:
72 case EAXCONTEXT_PRIMARYFXSLOTID
:
73 case EAXCONTEXT_DISTANCEFACTOR
:
74 case EAXCONTEXT_AIRABSORPTIONHF
:
75 case EAXCONTEXT_HFREFERENCE
:
76 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
78 case EAXCONTEXT_LASTERROR
:
79 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
;
82 FIXME("Unhandled propid: 0x%08lx\n", propid
);
83 return E_PROP_ID_UNSUPPORTED
;
86 HRESULT
EAX4Context_Set(DSPrimary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
88 if(!HAS_EXTENSION(prim
->share
, EXT_EFX
))
89 return E_PROP_ID_UNSUPPORTED
;
93 case EAXCONTEXT_NONE
: /* not setting any property, just applying */
96 case EAXCONTEXT_ALLPARAMETERS
:
97 if(cbPropData
>= sizeof(EAXCONTEXTPROPERTIES
))
99 union { void *v
; const EAXCONTEXTPROPERTIES
*props
; } data
= { pPropData
};
101 TRACE("Parameters:\n\tPrimary FXSlot: %s\n\tDistance Factor: %f\n\t"
102 "Air Absorption: %f\n\tHF Reference: %f\n",
103 debug_fxslot(&data
.props
->guidPrimaryFXSlotID
), data
.props
->flDistanceFactor
,
104 data
.props
->flAirAbsorptionHF
, data
.props
->flHFReference
108 if(IsEqualGUID(&data
.props
->guidPrimaryFXSlotID
, &EAXPROPERTYID_EAX40_FXSlot0
))
109 prim_slot
= prim
->auxslot
[0];
110 else if(IsEqualGUID(&data
.props
->guidPrimaryFXSlotID
, &EAXPROPERTYID_EAX40_FXSlot1
))
111 prim_slot
= prim
->auxslot
[1];
112 else if(IsEqualGUID(&data
.props
->guidPrimaryFXSlotID
, &EAXPROPERTYID_EAX40_FXSlot2
))
113 prim_slot
= prim
->auxslot
[2];
114 else if(IsEqualGUID(&data
.props
->guidPrimaryFXSlotID
, &EAXPROPERTYID_EAX40_FXSlot3
))
115 prim_slot
= prim
->auxslot
[3];
116 if(prim_slot
== 0 && !IsEqualGUID(&data
.props
->guidPrimaryFXSlotID
, &EAX_NULL_GUID
))
118 ERR("Unexpected primary FXSlot: %s\n",
119 debug_fxslot(&data
.props
->guidPrimaryFXSlotID
));
120 return DSERR_INVALIDPARAM
;
122 if(!(data
.props
->flDistanceFactor
>= DS3D_MINDISTANCEFACTOR
&&
123 data
.props
->flDistanceFactor
<= DS3D_MAXDISTANCEFACTOR
))
125 ERR("Unexpected distance factor: %f\n", data
.props
->flDistanceFactor
);
126 return DSERR_INVALIDPARAM
;
128 if(!(data
.props
->flAirAbsorptionHF
<= 0.0f
&& data
.props
->flAirAbsorptionHF
>= -100.0f
))
130 ERR("Unexpected air absorption: %f\n", data
.props
->flAirAbsorptionHF
);
131 return DSERR_INVALIDPARAM
;
133 if(!(data
.props
->flHFReference
>= 1000.0f
&& data
.props
->flHFReference
<= 20000.0f
))
135 ERR("Unexpected HF reference: %f\n", data
.props
->flAirAbsorptionHF
);
136 return DSERR_INVALIDPARAM
;
139 prim
->deferred
.ctx
= *data
.props
;
140 prim
->primary_slot
= prim_slot
;
142 prim
->dirty
.bit
.prim_slotid
= 1;
143 prim
->dirty
.bit
.distancefactor2
= 1;
144 prim
->dirty
.bit
.air_absorbhf
= 1;
145 prim
->dirty
.bit
.hfreference
= 1;
148 return DSERR_INVALIDPARAM
;
150 case EAXCONTEXT_PRIMARYFXSLOTID
:
151 if(cbPropData
>= sizeof(GUID
))
153 union { void *v
; const GUID
*guid
; } data
= { pPropData
};
155 TRACE("Primary FXSlot: %s\n", debug_fxslot(data
.guid
));
158 if(IsEqualGUID(data
.guid
, &EAXPROPERTYID_EAX40_FXSlot0
))
159 prim_slot
= prim
->auxslot
[0];
160 else if(IsEqualGUID(data
.guid
, &EAXPROPERTYID_EAX40_FXSlot1
))
161 prim_slot
= prim
->auxslot
[1];
162 else if(IsEqualGUID(data
.guid
, &EAXPROPERTYID_EAX40_FXSlot2
))
163 prim_slot
= prim
->auxslot
[2];
164 else if(IsEqualGUID(data
.guid
, &EAXPROPERTYID_EAX40_FXSlot3
))
165 prim_slot
= prim
->auxslot
[3];
166 if(prim_slot
== 0 && !IsEqualGUID(data
.guid
, &EAX_NULL_GUID
))
168 ERR("Unexpected primary FXSlot: %s\n", debug_fxslot(data
.guid
));
169 return DSERR_INVALIDPARAM
;
172 prim
->deferred
.ctx
.guidPrimaryFXSlotID
= *data
.guid
;
173 prim
->primary_slot
= prim_slot
;
175 prim
->dirty
.bit
.prim_slotid
= 1;
178 return DSERR_INVALIDPARAM
;
180 case EAXCONTEXT_DISTANCEFACTOR
:
181 if(cbPropData
>= sizeof(float))
183 union { void *v
; const float *fl
; } data
= { pPropData
};
184 TRACE("Distance Factor: %f\n", *data
.fl
);
186 if(!(*data
.fl
>= DS3D_MINDISTANCEFACTOR
&& *data
.fl
<= DS3D_MAXDISTANCEFACTOR
))
188 ERR("Unexpected distance factor: %f\n", *data
.fl
);
189 return DSERR_INVALIDPARAM
;
192 prim
->deferred
.ctx
.flDistanceFactor
= *data
.fl
;
194 prim
->dirty
.bit
.distancefactor2
= 1;
197 return DSERR_INVALIDPARAM
;
199 case EAXCONTEXT_AIRABSORPTIONHF
:
200 if(cbPropData
>= sizeof(float))
202 union { void *v
; const float *fl
; } data
= { pPropData
};
203 TRACE("Air Absorption: %f\n", *data
.fl
);
205 if(!(*data
.fl
<= 0.0f
&& *data
.fl
>= -100.0f
))
207 ERR("Unexpected air absorption: %f\n", *data
.fl
);
208 return DSERR_INVALIDPARAM
;
211 prim
->deferred
.ctx
.flAirAbsorptionHF
= *data
.fl
;
213 prim
->dirty
.bit
.air_absorbhf
= 1;
216 return DSERR_INVALIDPARAM
;
218 case EAXCONTEXT_HFREFERENCE
:
219 if(cbPropData
>= sizeof(float))
221 union { void *v
; const float *fl
; } data
= { pPropData
};
222 TRACE("HF Reference: %f\n", *data
.fl
);
224 if(!(*data
.fl
>= 1000.0f
&& *data
.fl
<= 20000.0f
))
226 ERR("Unexpected HF reference: %f\n", *data
.fl
);
227 return DSERR_INVALIDPARAM
;
230 prim
->deferred
.ctx
.flHFReference
= *data
.fl
;
232 prim
->dirty
.bit
.hfreference
= 1;
235 return DSERR_INVALIDPARAM
;
237 FIXME("Unhandled propid: 0x%08lx\n", propid
);
238 return E_PROP_ID_UNSUPPORTED
;
241 #define GET_PROP(src, T) do { \
242 if(cbPropData >= sizeof(T)) \
244 union { void *v; T *props; } data = { pPropData }; \
246 *pcbReturned = sizeof(T); \
249 return DSERR_INVALIDPARAM; \
252 HRESULT
EAX4Context_Get(DSPrimary
*prim
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
254 if(!HAS_EXTENSION(prim
->share
, EXT_EFX
))
255 return E_PROP_ID_UNSUPPORTED
;
259 case EAXCONTEXT_NONE
:
263 case EAXCONTEXT_ALLPARAMETERS
:
264 GET_PROP(prim
->current
.ctx
, EAXCONTEXTPROPERTIES
);
265 case EAXCONTEXT_PRIMARYFXSLOTID
:
266 GET_PROP(prim
->current
.ctx
.guidPrimaryFXSlotID
, GUID
);
267 case EAXCONTEXT_DISTANCEFACTOR
:
268 GET_PROP(prim
->current
.ctx
.flDistanceFactor
, float);
269 case EAXCONTEXT_AIRABSORPTIONHF
:
270 GET_PROP(prim
->current
.ctx
.flAirAbsorptionHF
, float);
271 case EAXCONTEXT_HFREFERENCE
:
272 GET_PROP(prim
->current
.ctx
.flHFReference
, float);
274 case EAXCONTEXT_LASTERROR
:
275 GET_PROP(InterlockedExchange(&prim
->eax_error
, EAX_OK
), long);
277 FIXME("Unhandled propid: 0x%08lx\n", propid
);
278 return E_PROP_ID_UNSUPPORTED
;
282 HRESULT
EAX4Slot_Query(DSPrimary
*prim
, LONG idx
, DWORD propid
, ULONG
*pTypeSupport
)
284 if(prim
->auxslot
[idx
] == 0)
285 return E_PROP_ID_UNSUPPORTED
;
287 if((propid
&~EAXFXSLOT_PARAMETER_DEFERRED
) < EAXFXSLOT_NONE
)
289 if(prim
->current
.fxslot
[idx
].effect_type
== FXSLOT_EFFECT_REVERB
)
291 if((propid
&~EAXFXSLOT_PARAMETER_DEFERRED
) <= EAXREVERB_FLAGS
)
293 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
296 FIXME("Unhandled reverb propid: 0x%08lx\n", propid
);
298 else if(prim
->current
.fxslot
[idx
].effect_type
== FXSLOT_EFFECT_CHORUS
)
300 if((propid
&~EAXFXSLOT_PARAMETER_DEFERRED
) <= EAXCHORUS_DELAY
)
302 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
305 FIXME("Unhandled chorus propid: 0x%08lx\n", propid
);
307 else /*if(prim->current.fxslot[idx].effect_type == FXSLOT_EFFECT_NULL)*/
309 FIXME("Unhandled null effect propid: 0x%08lx\n", propid
);
311 return DSERR_INVALIDPARAM
;
313 switch((propid
&~EAXFXSLOT_PARAMETER_DEFERRED
))
316 case EAXFXSLOT_ALLPARAMETERS
:
317 case EAXFXSLOT_LOADEFFECT
:
318 case EAXFXSLOT_VOLUME
:
320 case EAXFXSLOT_FLAGS
:
321 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
324 FIXME("Unhandled propid: 0x%08lx\n", propid
);
325 return E_PROP_ID_UNSUPPORTED
;
329 HRESULT
EAX4Slot_Set(DSPrimary
*prim
, LONG idx
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
331 if(prim
->auxslot
[idx
] == 0)
332 return E_PROP_ID_UNSUPPORTED
;
334 if(propid
< EAXFXSLOT_NONE
)
336 if(prim
->deferred
.fxslot
[idx
].effect_type
== FXSLOT_EFFECT_REVERB
)
337 return EAXReverb_Set(prim
, idx
, propid
, pPropData
, cbPropData
);
338 if(prim
->deferred
.fxslot
[idx
].effect_type
== FXSLOT_EFFECT_CHORUS
)
339 return EAXChorus_Set(prim
, idx
, propid
, pPropData
, cbPropData
);
341 ERR("Unexpected null effect propid 0x%08lx\n", propid
);
342 return E_PROP_ID_UNSUPPORTED
;
346 case EAXFXSLOT_NONE
: /* not setting any property, just applying */
349 case EAXFXSLOT_ALLPARAMETERS
:
350 if(cbPropData
>= sizeof(EAXFXSLOTPROPERTIES
))
352 union { const void *v
; const EAXFXSLOTPROPERTIES
*props
; } data
= { pPropData
};
354 TRACE("Parameters:\n\tLoad Effect: %s\n\tVolume: %ld\n\tLock: %ld\n\tFlags: 0x%lx\n",
355 debug_fxguid(&data
.props
->guidLoadEffect
), data
.props
->lVolume
, data
.props
->lLock
,
359 effect_type
= FXSLOT_EFFECT_NULL
;
360 if(IsEqualGUID(&data
.props
->guidLoadEffect
, &EAX_REVERB_EFFECT
))
361 effect_type
= FXSLOT_EFFECT_REVERB
;
362 else if(IsEqualGUID(&data
.props
->guidLoadEffect
, &EAX_CHORUS_EFFECT
))
363 effect_type
= FXSLOT_EFFECT_CHORUS
;
364 else if(!IsEqualGUID(&data
.props
->guidLoadEffect
, &EAX_NULL_GUID
))
366 ERR("Unhandled effect: %s\n", debug_fxguid(&data
.props
->guidLoadEffect
));
367 return DSERR_INVALIDPARAM
;
370 if(data
.props
->lLock
== EAXFXSLOT_LOCKED
&&
371 prim
->deferred
.fxslot
[idx
].props
.lLock
== EAXFXSLOT_LOCKED
&&
372 prim
->deferred
.fxslot
[idx
].effect_type
!= effect_type
)
374 ERR("Attempting to change effect type for locked FXSlot\n");
375 return DSERR_INVALIDCALL
;
378 if(prim
->deferred
.fxslot
[idx
].effect_type
!= effect_type
)
381 alEffecti(prim
->effect
[idx
], AL_EFFECT_TYPE
,
382 (effect_type
== FXSLOT_EFFECT_REVERB
) ? AL_EFFECT_EAXREVERB
:
383 (effect_type
== FXSLOT_EFFECT_CHORUS
) ? AL_EFFECT_CHORUS
:
386 if(alGetError() != AL_NO_ERROR
)
388 ERR("Failed to set effect type %lu\n", effect_type
);
389 return DSERR_INVALIDPARAM
;
392 prim
->deferred
.fxslot
[idx
].effect_type
= effect_type
;
393 memset(&prim
->deferred
.fxslot
[idx
].fx
, 0, sizeof(prim
->deferred
.fxslot
[idx
].fx
));
394 if(effect_type
== FXSLOT_EFFECT_REVERB
)
395 prim
->deferred
.fxslot
[idx
].fx
.reverb
= EnvironmentDefaults
[EAX_ENVIRONMENT_GENERIC
];
396 else if(effect_type
== FXSLOT_EFFECT_CHORUS
)
398 const EAXCHORUSPROPERTIES chorus_def
= CHORUS_PRESET_DEFAULT
;
399 prim
->deferred
.fxslot
[idx
].fx
.chorus
= chorus_def
;
402 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
404 prim
->deferred
.fxslot
[idx
].props
= *data
.props
;
406 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_VOL_BIT
);
407 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_LOCK_BIT
);
408 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_FLAGS_BIT
);
411 return DSERR_INVALIDPARAM
;
413 case EAXFXSLOT_LOADEFFECT
:
414 if(cbPropData
>= sizeof(GUID
))
416 union { const void *v
; const GUID
*guid
; } data
= { pPropData
};
418 TRACE("Load Effect: %s\n", debug_fxguid(data
.guid
));
420 effect_type
= FXSLOT_EFFECT_NULL
;
421 if(IsEqualGUID(data
.guid
, &EAX_REVERB_EFFECT
))
422 effect_type
= FXSLOT_EFFECT_REVERB
;
423 else if(IsEqualGUID(data
.guid
, &EAX_CHORUS_EFFECT
))
424 effect_type
= FXSLOT_EFFECT_CHORUS
;
425 else if(!IsEqualGUID(data
.guid
, &EAX_NULL_GUID
))
427 ERR("Unhandled effect: %s\n", debug_fxguid(data
.guid
));
428 return DSERR_INVALIDPARAM
;
431 if(prim
->deferred
.fxslot
[idx
].props
.lLock
== EAXFXSLOT_LOCKED
)
433 ERR("Attempting to change effect type for locked FXSlot\n");
434 return DSERR_INVALIDCALL
;
438 alEffecti(prim
->effect
[idx
], AL_EFFECT_TYPE
,
439 (effect_type
== FXSLOT_EFFECT_REVERB
) ? AL_EFFECT_EAXREVERB
:
440 (effect_type
== FXSLOT_EFFECT_CHORUS
) ? AL_EFFECT_CHORUS
:
443 if(alGetError() != AL_NO_ERROR
)
445 ERR("Failed to set effect type %lu\n", effect_type
);
446 return DSERR_INVALIDPARAM
;
449 prim
->deferred
.fxslot
[idx
].effect_type
= effect_type
;
450 memset(&prim
->deferred
.fxslot
[idx
].fx
, 0, sizeof(prim
->deferred
.fxslot
[idx
].fx
));
451 if(effect_type
== FXSLOT_EFFECT_REVERB
)
452 prim
->deferred
.fxslot
[idx
].fx
.reverb
= EnvironmentDefaults
[EAX_ENVIRONMENT_GENERIC
];
453 else if(effect_type
== FXSLOT_EFFECT_CHORUS
)
455 const EAXCHORUSPROPERTIES chorus_def
= CHORUS_PRESET_DEFAULT
;
456 prim
->deferred
.fxslot
[idx
].fx
.chorus
= chorus_def
;
458 prim
->deferred
.fxslot
[idx
].props
.guidLoadEffect
= *data
.guid
;
460 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_EFFECT_BIT
);
463 return DSERR_INVALIDPARAM
;
465 case EAXFXSLOT_VOLUME
:
466 if(cbPropData
>= sizeof(long))
468 union { const void *v
; const long *l
; } data
= { pPropData
};
469 TRACE("Volume: %ld\n", *data
.l
);
471 prim
->deferred
.fxslot
[idx
].props
.lVolume
= *data
.l
;
473 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_VOL_BIT
);
476 return DSERR_INVALIDPARAM
;
479 if(cbPropData
>= sizeof(long))
481 union { const void *v
; const long *l
; } data
= { pPropData
};
482 TRACE("Lock: %ld\n", *data
.l
);
484 prim
->deferred
.fxslot
[idx
].props
.lLock
= *data
.l
;
486 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_LOCK_BIT
);
489 return DSERR_INVALIDPARAM
;
491 case EAXFXSLOT_FLAGS
:
492 if(cbPropData
>= sizeof(DWORD
))
494 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
495 TRACE("Flags: 0x%lx\n", *data
.dw
);
497 prim
->deferred
.fxslot
[idx
].props
.dwFlags
= *data
.dw
;
499 FXSLOT_SET_DIRTY(prim
->dirty
.bit
, idx
, FXSLOT_FLAGS_BIT
);
502 return DSERR_INVALIDPARAM
;
504 FIXME("Unhandled propid: 0x%08lx\n", propid
);
505 return E_PROP_ID_UNSUPPORTED
;
508 HRESULT
EAX4Slot_Get(DSPrimary
*prim
, LONG idx
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
510 if(prim
->auxslot
[idx
] == 0)
511 return E_PROP_ID_UNSUPPORTED
;
513 if(propid
< EAXFXSLOT_NONE
)
515 if(prim
->deferred
.fxslot
[idx
].effect_type
== FXSLOT_EFFECT_REVERB
)
516 return EAXReverb_Get(prim
, idx
, propid
, pPropData
, cbPropData
, pcbReturned
);
517 if(prim
->deferred
.fxslot
[idx
].effect_type
== FXSLOT_EFFECT_CHORUS
)
518 return EAXChorus_Get(prim
, idx
, propid
, pPropData
, cbPropData
, pcbReturned
);
520 ERR("Unexpected null effect propid 0x%08lx\n", propid
);
521 return E_PROP_ID_UNSUPPORTED
;
529 case EAXFXSLOT_ALLPARAMETERS
:
530 GET_PROP(prim
->current
.fxslot
[idx
].props
, EAXFXSLOTPROPERTIES
);
531 case EAXFXSLOT_LOADEFFECT
:
532 GET_PROP(prim
->current
.fxslot
[idx
].props
.guidLoadEffect
, GUID
);
533 case EAXFXSLOT_VOLUME
:
534 GET_PROP(prim
->current
.fxslot
[idx
].props
.lVolume
, long);
536 GET_PROP(prim
->current
.fxslot
[idx
].props
.lLock
, long);
537 case EAXFXSLOT_FLAGS
:
538 GET_PROP(prim
->current
.fxslot
[idx
].props
.dwFlags
, DWORD
);
540 FIXME("Unhandled propid: 0x%08lx\n", propid
);
541 return E_PROP_ID_UNSUPPORTED
;
545 #define APPLY_WET0_PARAMS 1
546 #define APPLY_WET1_PARAMS 2
547 #define APPLY_DRY_PARAMS 4
548 #define APPLY_ALL_PARAMS (APPLY_WET0_PARAMS | APPLY_WET1_PARAMS | APPLY_DRY_PARAMS)
549 #define APPLY_ALLWET_PARAMS (APPLY_WET0_PARAMS | APPLY_WET1_PARAMS)
550 static void ApplyFilterParams(DSBuffer
*buf
, const EAXSOURCEPROPERTIES
*props
, int apply
)
552 /* The LFRatio properties determine how much the given level applies to low
553 * frequencies as well as high frequencies. Technically, given that the
554 * obstruction/occlusion/exclusion levels are the absolute level applied to
555 * high frequencies (relative to full-scale, according to the EAX 2.0 spec)
556 * while the HF filter gains are relative to the low, the HF gains should
557 * increase as LFRatio increases.
559 * However it seems Creative was either wrong when writing out the spec,
560 * or implemented it incorrectly, as the HF filter still applies in full
561 * regardless of the LFRatio. So to replicate the hardware behavior, we do
564 /* The interaction of ratios is pretty wierd. The typical combination of
565 * the two act as a minimal baseline, while the sum minus one is used when
566 * larger. This creates a more linear change with the individual ratios as
567 * DirectRatio goes beyond 1, but eases down as the two ratios go toward 0.
569 float room_mb
= props
->lRoom
+ props
->lExclusion
*props
->flExclusionLFRatio
+
570 maxF(props
->flOcclusionLFRatio
+props
->flOcclusionRoomRatio
-1.0f
,
571 props
->flOcclusionLFRatio
*props
->flOcclusionRoomRatio
) * props
->lOcclusion
;
572 float room_mbhf
= props
->lRoomHF
+ props
->lExclusion
+
573 props
->lOcclusion
*props
->flOcclusionRoomRatio
;
575 float direct_mbhf
= 0;
578 for(i
= 0;i
< EAX_MAX_ACTIVE_FXSLOTS
;i
++)
580 const struct Send
*send
= &buf
->deferred
.send
[i
];
581 if((apply
&(1<<i
)) && buf
->filter
[1+i
])
583 float mb
= room_mb
+ send
->lExclusion
*send
->flExclusionLFRatio
+
584 maxF(send
->flOcclusionLFRatio
+send
->flOcclusionRoomRatio
-1.0f
,
585 send
->flOcclusionLFRatio
*send
->flOcclusionRoomRatio
)*send
->lOcclusion
;
586 float mbhf
= room_mbhf
+ send
->lExclusion
+
587 send
->lOcclusion
*send
->flOcclusionRoomRatio
;
589 alFilterf(buf
->filter
[1+i
], AL_LOWPASS_GAIN
, mB_to_gain(minF(mb
, buf
->filter_mBLimit
)));
590 alFilterf(buf
->filter
[1+i
], AL_LOWPASS_GAINHF
, mB_to_gain(mbhf
));
592 /* FIXME: This should either be added like this, or take the minimum
593 * volume level from the separate occlusion properties.
595 direct_mb
+= maxF(send
->flOcclusionLFRatio
+send
->flOcclusionDirectRatio
-1.0f
,
596 send
->flOcclusionLFRatio
*send
->flOcclusionDirectRatio
) *
598 direct_mbhf
+= send
->lOcclusion
*send
->flOcclusionDirectRatio
;
600 if((apply
&APPLY_DRY_PARAMS
) && buf
->filter
[0])
602 float mb
= direct_mb
+ props
->lDirect
+ props
->lObstruction
*props
->flObstructionLFRatio
+
603 maxF(props
->flOcclusionLFRatio
+props
->flOcclusionDirectRatio
-1.0f
,
604 props
->flOcclusionLFRatio
*props
->flOcclusionDirectRatio
)*props
->lOcclusion
;
605 float mbhf
= direct_mbhf
+ props
->lDirectHF
+ props
->lObstruction
+
606 props
->lOcclusion
*props
->flOcclusionDirectRatio
;
608 alFilterf(buf
->filter
[0], AL_LOWPASS_GAIN
, mB_to_gain(minF(mb
, buf
->filter_mBLimit
)));
609 alFilterf(buf
->filter
[0], AL_LOWPASS_GAINHF
, mB_to_gain(mbhf
));
614 static EAXOBSTRUCTIONPROPERTIES
EAXSourceObstruction(const EAXSOURCEPROPERTIES
*props
)
616 EAXOBSTRUCTIONPROPERTIES ret
;
617 ret
.lObstruction
= props
->lObstruction
;
618 ret
.flObstructionLFRatio
= props
->flObstructionLFRatio
;
622 static EAXOCCLUSIONPROPERTIES
EAXSourceOcclusion(const EAXSOURCEPROPERTIES
*props
)
624 EAXOCCLUSIONPROPERTIES ret
;
625 ret
.lOcclusion
= props
->lOcclusion
;
626 ret
.flOcclusionLFRatio
= props
->flOcclusionLFRatio
;
627 ret
.flOcclusionRoomRatio
= props
->flOcclusionRoomRatio
;
628 ret
.flOcclusionDirectRatio
= props
->flOcclusionDirectRatio
;
632 static EAXEXCLUSIONPROPERTIES
EAXSourceExclusion(const EAXSOURCEPROPERTIES
*props
)
634 EAXEXCLUSIONPROPERTIES ret
;
635 ret
.lExclusion
= props
->lExclusion
;
636 ret
.flExclusionLFRatio
= props
->flExclusionLFRatio
;
640 static struct Send
*FindCurrentSend(DSBuffer
*buf
, const GUID
*guid
)
643 for(i
= 0;i
< EAX_MAX_ACTIVE_FXSLOTS
;i
++)
645 DWORD target
= buf
->current
.fxslot_targets
[i
];
646 if((target
== FXSLOT_TARGET_0
&& IsEqualGUID(guid
, &EAXPROPERTYID_EAX40_FXSlot0
)) ||
647 (target
== FXSLOT_TARGET_1
&& IsEqualGUID(guid
, &EAXPROPERTYID_EAX40_FXSlot1
)) ||
648 (target
== FXSLOT_TARGET_2
&& IsEqualGUID(guid
, &EAXPROPERTYID_EAX40_FXSlot2
)) ||
649 (target
== FXSLOT_TARGET_3
&& IsEqualGUID(guid
, &EAXPROPERTYID_EAX40_FXSlot3
)) ||
650 (target
== FXSLOT_TARGET_PRIMARY
&& IsEqualGUID(guid
, &EAX_PrimaryFXSlotID
)) ||
651 (target
== FXSLOT_TARGET_NULL
&& IsEqualGUID(guid
, &EAX_NULL_GUID
)))
652 return &buf
->current
.send
[i
];
657 static struct Send
*FindDeferredSend(DSBuffer
*buf
, const GUID
*guid
)
660 for(i
= 0;i
< EAX_MAX_ACTIVE_FXSLOTS
;i
++)
662 DWORD target
= buf
->deferred
.fxslot_targets
[i
];
663 if((target
== FXSLOT_TARGET_0
&& IsEqualGUID(guid
, &EAXPROPERTYID_EAX40_FXSlot0
)) ||
664 (target
== FXSLOT_TARGET_1
&& IsEqualGUID(guid
, &EAXPROPERTYID_EAX40_FXSlot1
)) ||
665 (target
== FXSLOT_TARGET_2
&& IsEqualGUID(guid
, &EAXPROPERTYID_EAX40_FXSlot2
)) ||
666 (target
== FXSLOT_TARGET_3
&& IsEqualGUID(guid
, &EAXPROPERTYID_EAX40_FXSlot3
)) ||
667 (target
== FXSLOT_TARGET_PRIMARY
&& IsEqualGUID(guid
, &EAX_PrimaryFXSlotID
)) ||
668 (target
== FXSLOT_TARGET_NULL
&& IsEqualGUID(guid
, &EAX_NULL_GUID
)))
669 return &buf
->deferred
.send
[i
];
674 HRESULT
EAX4Source_Query(DSBuffer
*buf
, DWORD propid
, ULONG
*pTypeSupport
)
676 if(!HAS_EXTENSION(buf
->share
, EXT_EFX
))
677 return E_PROP_ID_UNSUPPORTED
;
679 switch((propid
&~EAXSOURCE_PARAMETER_DEFERRED
))
682 case EAXSOURCE_ALLPARAMETERS
:
683 case EAXSOURCE_OBSTRUCTIONPARAMETERS
:
684 case EAXSOURCE_OCCLUSIONPARAMETERS
:
685 case EAXSOURCE_EXCLUSIONPARAMETERS
:
686 case EAXSOURCE_DIRECT
:
687 case EAXSOURCE_DIRECTHF
:
689 case EAXSOURCE_ROOMHF
:
690 case EAXSOURCE_OBSTRUCTION
:
691 case EAXSOURCE_OBSTRUCTIONLFRATIO
:
692 case EAXSOURCE_OCCLUSION
:
693 case EAXSOURCE_OCCLUSIONLFRATIO
:
694 case EAXSOURCE_OCCLUSIONROOMRATIO
:
695 case EAXSOURCE_OCCLUSIONDIRECTRATIO
:
696 case EAXSOURCE_EXCLUSION
:
697 case EAXSOURCE_EXCLUSIONLFRATIO
:
698 case EAXSOURCE_OUTSIDEVOLUMEHF
:
699 case EAXSOURCE_DOPPLERFACTOR
:
700 case EAXSOURCE_ROLLOFFFACTOR
:
701 case EAXSOURCE_ROOMROLLOFFFACTOR
:
702 case EAXSOURCE_AIRABSORPTIONFACTOR
:
703 case EAXSOURCE_FLAGS
:
704 case EAXSOURCE_SENDPARAMETERS
:
705 case EAXSOURCE_ALLSENDPARAMETERS
:
706 case EAXSOURCE_OCCLUSIONSENDPARAMETERS
:
707 case EAXSOURCE_EXCLUSIONSENDPARAMETERS
:
708 case EAXSOURCE_ACTIVEFXSLOTID
:
709 *pTypeSupport
= KSPROPERTY_SUPPORT_GET
| KSPROPERTY_SUPPORT_SET
;
712 FIXME("Unhandled propid: 0x%08lx\n", propid
);
713 return E_PROP_ID_UNSUPPORTED
;
716 HRESULT
EAX4Source_Set(DSBuffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
)
718 if(!HAS_EXTENSION(buf
->share
, EXT_EFX
))
719 return E_PROP_ID_UNSUPPORTED
;
726 case EAXSOURCE_ALLPARAMETERS
:
727 if(cbPropData
>= sizeof(EAXSOURCEPROPERTIES
))
731 const EAXSOURCEPROPERTIES
*props
;
732 } data
= { pPropData
};
733 TRACE("Parameters:\n\tDirect: %ld\n\tDirect HF: %ld\n\tRoom: %ld\n\tRoom HF: %ld\n\t"
734 "Obstruction: %ld\n\tObstruction LF Ratio: %f\n\tOcclusion: %ld\n\t"
735 "Occlusion LF Ratio: %f\n\tOcclusion Room Ratio: %f\n\t"
736 "Occlusion Direct Ratio: %f\n\tExclusion: %ld\n\tExclusion LF Ratio: %f\n\t"
737 "Outside Volume HF: %ld\n\tDoppler Factor: %f\n\tRolloff Factor: %f\n\t"
738 "Room Rolloff Factor: %f\n\tAir Absorb Factor: %f\n\tFlags: 0x%02lx\n",
739 data
.props
->lDirect
, data
.props
->lDirectHF
, data
.props
->lRoom
, data
.props
->lRoomHF
,
740 data
.props
->lObstruction
, data
.props
->flObstructionLFRatio
, data
.props
->lOcclusion
,
741 data
.props
->flOcclusionLFRatio
, data
.props
->flOcclusionRoomRatio
,
742 data
.props
->flOcclusionDirectRatio
, data
.props
->lExclusion
,
743 data
.props
->flExclusionLFRatio
, data
.props
->lOutsideVolumeHF
,
744 data
.props
->flDopplerFactor
, data
.props
->flRolloffFactor
,
745 data
.props
->flRoomRolloffFactor
, data
.props
->flAirAbsorptionFactor
,
749 buf
->deferred
.eax
= *data
.props
;
750 ApplyFilterParams(buf
, data
.props
, APPLY_ALL_PARAMS
);
752 buf
->dirty
.bit
.dry_filter
= 1;
753 buf
->dirty
.bit
.send_filter
= (1<<buf
->share
->num_sends
) - 1;
754 buf
->dirty
.bit
.doppler
= 1;
755 buf
->dirty
.bit
.rolloff
= 1;
756 buf
->dirty
.bit
.room_rolloff
= 1;
757 buf
->dirty
.bit
.cone_outsidevolumehf
= 1;
758 buf
->dirty
.bit
.air_absorb
= 1;
759 buf
->dirty
.bit
.flags
= 1;
762 return DSERR_INVALIDPARAM
;
763 case EAXSOURCE_OBSTRUCTIONPARAMETERS
:
764 if(cbPropData
>= sizeof(EAXOBSTRUCTIONPROPERTIES
))
768 const EAXOBSTRUCTIONPROPERTIES
*props
;
769 } data
= { pPropData
};
770 TRACE("Parameters:\n\tObstruction: %ld\n\tObstruction LF Ratio: %f\n",
771 data
.props
->lObstruction
, data
.props
->flObstructionLFRatio
);
773 buf
->deferred
.eax
.lObstruction
= data
.props
->lObstruction
;
774 buf
->deferred
.eax
.flObstructionLFRatio
= data
.props
->flObstructionLFRatio
;
775 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
777 buf
->dirty
.bit
.dry_filter
= 1;
780 return DSERR_INVALIDPARAM
;
781 case EAXSOURCE_OCCLUSIONPARAMETERS
:
782 if(cbPropData
>= sizeof(EAXOCCLUSIONPROPERTIES
))
786 const EAXOCCLUSIONPROPERTIES
*props
;
787 } data
= { pPropData
};
788 TRACE("Parameters:\n\tOcclusion: %ld\n\tOcclusion LF Ratio: %f\n\t"
789 "Occlusion Room Ratio: %f\n\tOcclusion Direct Ratio: %f\n",
790 data
.props
->lOcclusion
, data
.props
->flOcclusionLFRatio
,
791 data
.props
->flOcclusionRoomRatio
, data
.props
->flOcclusionDirectRatio
794 buf
->deferred
.eax
.lOcclusion
= data
.props
->lOcclusion
;
795 buf
->deferred
.eax
.flOcclusionLFRatio
= data
.props
->flOcclusionLFRatio
;
796 buf
->deferred
.eax
.flOcclusionRoomRatio
= data
.props
->flOcclusionRoomRatio
;
797 buf
->deferred
.eax
.flOcclusionDirectRatio
= data
.props
->flOcclusionDirectRatio
;
798 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_ALL_PARAMS
);
800 buf
->dirty
.bit
.dry_filter
= 1;
801 buf
->dirty
.bit
.send_filter
= (1<<buf
->share
->num_sends
) - 1;
804 return DSERR_INVALIDPARAM
;
805 case EAXSOURCE_EXCLUSIONPARAMETERS
:
806 if(cbPropData
>= sizeof(EAXEXCLUSIONPROPERTIES
))
810 const EAXEXCLUSIONPROPERTIES
*props
;
811 } data
= { pPropData
};
812 TRACE("Parameters:\n\tExclusion: %ld\n\tExclusion LF Ratio: %f\n",
813 data
.props
->lExclusion
, data
.props
->flExclusionLFRatio
);
815 buf
->deferred
.eax
.lExclusion
= data
.props
->lExclusion
;
816 buf
->deferred
.eax
.flExclusionLFRatio
= data
.props
->flExclusionLFRatio
;
817 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_ALLWET_PARAMS
);
819 buf
->dirty
.bit
.send_filter
= (1<<buf
->share
->num_sends
) - 1;
822 return DSERR_INVALIDPARAM
;
824 case EAXSOURCE_DIRECT
:
825 if(cbPropData
>= sizeof(long))
827 union { const void *v
; const long *l
; } data
= { pPropData
};
828 TRACE("Direct: %ld\n", *data
.l
);
830 buf
->deferred
.eax
.lDirect
= *data
.l
;
831 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
833 buf
->dirty
.bit
.dry_filter
= 1;
836 return DSERR_INVALIDPARAM
;
837 case EAXSOURCE_DIRECTHF
:
838 if(cbPropData
>= sizeof(long))
840 union { const void *v
; const long *l
; } data
= { pPropData
};
841 TRACE("Direct HF: %ld\n", *data
.l
);
843 buf
->deferred
.eax
.lDirectHF
= *data
.l
;
844 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
846 buf
->dirty
.bit
.dry_filter
= 1;
849 return DSERR_INVALIDPARAM
;
852 if(cbPropData
>= sizeof(long))
854 union { const void *v
; const long *l
; } data
= { pPropData
};
855 TRACE("Room: %ld\n", *data
.l
);
857 buf
->deferred
.eax
.lRoom
= *data
.l
;
858 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_ALLWET_PARAMS
);
860 buf
->dirty
.bit
.send_filter
= (1<<buf
->share
->num_sends
) - 1;
863 return DSERR_INVALIDPARAM
;
864 case EAXSOURCE_ROOMHF
:
865 if(cbPropData
>= sizeof(long))
867 union { const void *v
; const long *l
; } data
= { pPropData
};
868 TRACE("Room HF: %ld\n", *data
.l
);
870 buf
->deferred
.eax
.lRoomHF
= *data
.l
;
871 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_ALLWET_PARAMS
);
873 buf
->dirty
.bit
.send_filter
= (1<<buf
->share
->num_sends
) - 1;
876 return DSERR_INVALIDPARAM
;
878 case EAXSOURCE_OBSTRUCTION
:
879 if(cbPropData
>= sizeof(long))
881 union { const void *v
; const long *l
; } data
= { pPropData
};
882 TRACE("Obstruction: %ld\n", *data
.l
);
884 buf
->deferred
.eax
.lObstruction
= *data
.l
;
885 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
887 buf
->dirty
.bit
.dry_filter
= 1;
890 return DSERR_INVALIDPARAM
;
891 case EAXSOURCE_OBSTRUCTIONLFRATIO
:
892 if(cbPropData
>= sizeof(float))
894 union { const void *v
; const float *fl
; } data
= { pPropData
};
895 TRACE("Obstruction LF Ratio: %f\n", *data
.fl
);
897 buf
->deferred
.eax
.flObstructionLFRatio
= *data
.fl
;
898 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
900 buf
->dirty
.bit
.dry_filter
= 1;
903 return DSERR_INVALIDPARAM
;
905 case EAXSOURCE_OCCLUSION
:
906 if(cbPropData
>= sizeof(long))
908 union { const void *v
; const long *l
; } data
= { pPropData
};
909 TRACE("Occlusion: %ld\n", *data
.l
);
911 buf
->deferred
.eax
.lOcclusion
= *data
.l
;
912 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_ALL_PARAMS
);
914 buf
->dirty
.bit
.dry_filter
= 1;
915 buf
->dirty
.bit
.send_filter
= (1<<buf
->share
->num_sends
) - 1;
918 return DSERR_INVALIDPARAM
;
919 case EAXSOURCE_OCCLUSIONLFRATIO
:
920 if(cbPropData
>= sizeof(float))
922 union { const void *v
; const float *fl
; } data
= { pPropData
};
923 TRACE("Occlusion LF Ratio: %f\n", *data
.fl
);
925 buf
->deferred
.eax
.flOcclusionLFRatio
= *data
.fl
;
926 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_ALL_PARAMS
);
928 buf
->dirty
.bit
.dry_filter
= 1;
929 buf
->dirty
.bit
.send_filter
= (1<<buf
->share
->num_sends
) - 1;
932 return DSERR_INVALIDPARAM
;
933 case EAXSOURCE_OCCLUSIONROOMRATIO
:
934 if(cbPropData
>= sizeof(float))
936 union { const void *v
; const float *fl
; } data
= { pPropData
};
937 TRACE("Occlusion Room Ratio: %f\n", *data
.fl
);
939 buf
->deferred
.eax
.flOcclusionRoomRatio
= *data
.fl
;
940 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_ALLWET_PARAMS
);
942 buf
->dirty
.bit
.send_filter
= (1<<buf
->share
->num_sends
) - 1;
945 return DSERR_INVALIDPARAM
;
946 case EAXSOURCE_OCCLUSIONDIRECTRATIO
:
947 if(cbPropData
>= sizeof(float))
949 union { const void *v
; const float *fl
; } data
= { pPropData
};
950 TRACE("Occlusion Direct Ratio: %f\n", *data
.fl
);
952 buf
->deferred
.eax
.flOcclusionDirectRatio
= *data
.fl
;
953 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_DRY_PARAMS
);
955 buf
->dirty
.bit
.dry_filter
= 1;
958 return DSERR_INVALIDPARAM
;
960 case EAXSOURCE_EXCLUSION
:
961 if(cbPropData
>= sizeof(long))
963 union { const void *v
; const long *l
; } data
= { pPropData
};
964 TRACE("Exclusion: %ld\n", *data
.l
);
966 buf
->deferred
.eax
.lExclusion
= *data
.l
;
967 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_ALLWET_PARAMS
);
969 buf
->dirty
.bit
.send_filter
= (1<<buf
->share
->num_sends
) - 1;
972 return DSERR_INVALIDPARAM
;
973 case EAXSOURCE_EXCLUSIONLFRATIO
:
974 if(cbPropData
>= sizeof(float))
976 union { const void *v
; const float *fl
; } data
= { pPropData
};
977 TRACE("Exclusion LF Ratio: %f\n", *data
.fl
);
979 buf
->deferred
.eax
.flExclusionLFRatio
= *data
.fl
;
980 ApplyFilterParams(buf
, &buf
->deferred
.eax
, APPLY_ALLWET_PARAMS
);
982 buf
->dirty
.bit
.send_filter
= (1<<buf
->share
->num_sends
) - 1;
985 return DSERR_INVALIDPARAM
;
987 case EAXSOURCE_OUTSIDEVOLUMEHF
:
988 if(cbPropData
>= sizeof(long))
990 union { const void *v
; const long *l
; } data
= { pPropData
};
991 TRACE("Outisde Volume HF: %ld\n", *data
.l
);
993 buf
->deferred
.eax
.lOutsideVolumeHF
= *data
.l
;
995 buf
->dirty
.bit
.cone_outsidevolumehf
= 1;
998 return DSERR_INVALIDPARAM
;
1000 case EAXSOURCE_DOPPLERFACTOR
:
1001 if(cbPropData
>= sizeof(float))
1003 union { const void *v
; const float *fl
; } data
= { pPropData
};
1004 TRACE("Doppler Factor: %f\n", *data
.fl
);
1006 buf
->deferred
.eax
.flDopplerFactor
= *data
.fl
;
1008 buf
->dirty
.bit
.doppler
= 1;
1011 return DSERR_INVALIDPARAM
;
1013 case EAXSOURCE_ROLLOFFFACTOR
:
1014 if(cbPropData
>= sizeof(float))
1016 union { const void *v
; const float *fl
; } data
= { pPropData
};
1017 TRACE("Rolloff Factor: %f\n", *data
.fl
);
1019 buf
->deferred
.eax
.flRolloffFactor
= *data
.fl
;
1021 buf
->dirty
.bit
.rolloff
= 1;
1024 return DSERR_INVALIDPARAM
;
1026 case EAXSOURCE_ROOMROLLOFFFACTOR
:
1027 if(cbPropData
>= sizeof(float))
1029 union { const void *v
; const float *fl
; } data
= { pPropData
};
1030 TRACE("Room Rolloff Factor: %f\n", *data
.fl
);
1032 buf
->deferred
.eax
.flRoomRolloffFactor
= *data
.fl
;
1034 buf
->dirty
.bit
.room_rolloff
= 1;
1037 return DSERR_INVALIDPARAM
;
1039 case EAXSOURCE_AIRABSORPTIONFACTOR
:
1040 if(cbPropData
>= sizeof(float))
1042 union { const void *v
; const float *fl
; } data
= { pPropData
};
1043 TRACE("Air Absorb Factor: %f\n", *data
.fl
);
1045 buf
->deferred
.eax
.flAirAbsorptionFactor
= *data
.fl
;
1047 buf
->dirty
.bit
.air_absorb
= 1;
1050 return DSERR_INVALIDPARAM
;
1052 case EAXSOURCE_FLAGS
:
1053 if(cbPropData
>= sizeof(DWORD
))
1055 union { const void *v
; const DWORD
*dw
; } data
= { pPropData
};
1056 TRACE("Flags: 0x%lx\n", *data
.dw
);
1058 buf
->deferred
.eax
.dwFlags
= *data
.dw
;
1060 buf
->dirty
.bit
.flags
= 1;
1063 return DSERR_INVALIDPARAM
;
1065 case EAXSOURCE_SENDPARAMETERS
:
1066 if(cbPropData
>= sizeof(EAXSOURCESENDPROPERTIES
))
1068 union { const void *v
; const EAXSOURCESENDPROPERTIES
*send
; } data
= { pPropData
};
1069 struct Send
*srcsend
[EAX_MAX_ACTIVE_FXSLOTS
];
1070 LONG count
= cbPropData
/ sizeof(EAXSOURCESENDPROPERTIES
);
1073 if(count
> buf
->share
->num_sends
)
1075 ERR("Setting %ld sends, only %d supported\n", count
, buf
->share
->num_sends
);
1076 return DSERR_INVALIDPARAM
;
1079 for(i
= 0;i
< count
;++i
)
1081 TRACE("Send parameters:\n\tReceiving: %s\n\tSend: %ld\n\tSend HF: %ld\n",
1082 debug_fxslot(&data
.send
[i
].guidReceivingFXSlotID
),
1083 data
.send
[i
].lSend
, data
.send
[i
].lSendHF
1085 srcsend
[i
] = FindDeferredSend(buf
, &data
.send
[i
].guidReceivingFXSlotID
);
1088 ERR("Failed to find active FXSlot target: %s\n",
1089 debug_fxslot(&data
.send
[i
].guidReceivingFXSlotID
));
1090 return DSERR_INVALIDPARAM
;
1092 wetmask
|= 1 << (srcsend
[i
]-buf
->deferred
.send
);
1095 for(i
= 0;i
< count
;++i
)
1097 srcsend
[i
]->lSend
= data
.send
[i
].lSend
;
1098 srcsend
[i
]->lSendHF
= data
.send
[i
].lSendHF
;
1100 ApplyFilterParams(buf
, &buf
->deferred
.eax
, wetmask
);
1102 buf
->dirty
.bit
.send_filter
|= wetmask
;
1105 return DSERR_INVALIDPARAM
;
1106 case EAXSOURCE_ALLSENDPARAMETERS
:
1107 if(cbPropData
>= sizeof(EAXSOURCEALLSENDPROPERTIES
))
1109 union { const void *v
; const EAXSOURCEALLSENDPROPERTIES
*send
; } data
= { pPropData
};
1110 struct Send
*srcsend
[EAX_MAX_ACTIVE_FXSLOTS
];
1111 LONG count
= cbPropData
/ sizeof(EAXSOURCEALLSENDPROPERTIES
);
1114 if(count
> buf
->share
->num_sends
)
1116 ERR("Setting %ld sends, only %d supported\n", count
, buf
->share
->num_sends
);
1117 return DSERR_INVALIDPARAM
;
1120 for(i
= 0;i
< count
;++i
)
1122 TRACE("All send parameters:\n\tReceiving: %s\n\tSend: %ld\n\tSend HF: %ld\n\t"
1123 "Occlusion: %ld\n\tOcclusion LF Ratio: %f\n\tOcclusion Room Ratio: %f\n\t"
1124 "Occlusion Direct Ratio: %f\n\tExclusion: %ld\n\tExclusion LF Ratio: %f\n",
1125 debug_fxslot(&data
.send
[i
].guidReceivingFXSlotID
),
1126 data
.send
[i
].lSend
, data
.send
[i
].lSendHF
, data
.send
[i
].lOcclusion
,
1127 data
.send
[i
].flOcclusionLFRatio
, data
.send
[i
].flOcclusionRoomRatio
,
1128 data
.send
[i
].flOcclusionDirectRatio
, data
.send
[i
].lExclusion
,
1129 data
.send
[i
].flExclusionLFRatio
1131 srcsend
[i
] = FindDeferredSend(buf
, &data
.send
[i
].guidReceivingFXSlotID
);
1134 ERR("Failed to find active FXSlot target: %s\n",
1135 debug_fxslot(&data
.send
[i
].guidReceivingFXSlotID
));
1136 return DSERR_INVALIDPARAM
;
1138 wetmask
|= 1 << (srcsend
[i
]-buf
->deferred
.send
);
1141 for(i
= 0;i
< count
;++i
)
1143 srcsend
[i
]->lSend
= data
.send
[i
].lSend
;
1144 srcsend
[i
]->lSendHF
= data
.send
[i
].lSendHF
;
1145 srcsend
[i
]->lOcclusion
= data
.send
[i
].lOcclusion
;
1146 srcsend
[i
]->flOcclusionLFRatio
= data
.send
[i
].flOcclusionLFRatio
;
1147 srcsend
[i
]->flOcclusionRoomRatio
= data
.send
[i
].flOcclusionRoomRatio
;
1148 srcsend
[i
]->flOcclusionDirectRatio
= data
.send
[i
].flOcclusionDirectRatio
;
1149 srcsend
[i
]->lExclusion
= data
.send
[i
].lExclusion
;
1150 srcsend
[i
]->flExclusionLFRatio
= data
.send
[i
].flExclusionLFRatio
;
1152 ApplyFilterParams(buf
, &buf
->deferred
.eax
, wetmask
|APPLY_DRY_PARAMS
);
1154 buf
->dirty
.bit
.dry_filter
= 1;
1155 buf
->dirty
.bit
.send_filter
|= wetmask
;
1158 return DSERR_INVALIDPARAM
;
1159 case EAXSOURCE_OCCLUSIONSENDPARAMETERS
:
1160 if(cbPropData
>= sizeof(EAXSOURCEOCCLUSIONSENDPROPERTIES
))
1162 union { const void *v
; const EAXSOURCEOCCLUSIONSENDPROPERTIES
*send
; } data
= { pPropData
};
1163 struct Send
*srcsend
[EAX_MAX_ACTIVE_FXSLOTS
];
1164 LONG count
= cbPropData
/ sizeof(EAXSOURCEOCCLUSIONSENDPROPERTIES
);
1167 if(count
> buf
->share
->num_sends
)
1169 ERR("Setting %ld sends, only %d supported\n", count
, buf
->share
->num_sends
);
1170 return DSERR_INVALIDPARAM
;
1173 for(i
= 0;i
< count
;++i
)
1175 TRACE("Occlusion send parameters:\n\tReceiving: %s\n\tOcclusion: %ld\n\t"
1176 "Occlusion LF Ratio: %f\n\tOcclusion Room Ratio: %f\n\t"
1177 "Occlusion Direct Ratio: %f\n",
1178 debug_fxslot(&data
.send
[i
].guidReceivingFXSlotID
), data
.send
[i
].lOcclusion
,
1179 data
.send
[i
].flOcclusionLFRatio
, data
.send
[i
].flOcclusionRoomRatio
,
1180 data
.send
[i
].flOcclusionDirectRatio
1182 srcsend
[i
] = FindDeferredSend(buf
, &data
.send
[i
].guidReceivingFXSlotID
);
1185 ERR("Failed to find active FXSlot target: %s\n",
1186 debug_fxslot(&data
.send
[i
].guidReceivingFXSlotID
));
1187 return DSERR_INVALIDPARAM
;
1189 wetmask
|= 1 << (srcsend
[i
]-buf
->deferred
.send
);
1192 for(i
= 0;i
< count
;++i
)
1194 srcsend
[i
]->lOcclusion
= data
.send
[i
].lOcclusion
;
1195 srcsend
[i
]->flOcclusionLFRatio
= data
.send
[i
].flOcclusionLFRatio
;
1196 srcsend
[i
]->flOcclusionRoomRatio
= data
.send
[i
].flOcclusionRoomRatio
;
1197 srcsend
[i
]->flOcclusionDirectRatio
= data
.send
[i
].flOcclusionDirectRatio
;
1199 ApplyFilterParams(buf
, &buf
->deferred
.eax
, wetmask
|APPLY_DRY_PARAMS
);
1201 buf
->dirty
.bit
.dry_filter
= 1;
1202 buf
->dirty
.bit
.send_filter
|= wetmask
;
1205 return DSERR_INVALIDPARAM
;
1206 case EAXSOURCE_EXCLUSIONSENDPARAMETERS
:
1207 if(cbPropData
>= sizeof(EAXSOURCEEXCLUSIONSENDPROPERTIES
))
1209 union { const void *v
; const EAXSOURCEEXCLUSIONSENDPROPERTIES
*send
; } data
= { pPropData
};
1210 struct Send
*srcsend
[EAX_MAX_ACTIVE_FXSLOTS
];
1211 LONG count
= cbPropData
/ sizeof(EAXSOURCEEXCLUSIONSENDPROPERTIES
);
1214 if(count
> buf
->share
->num_sends
)
1216 ERR("Setting %ld sends, only %d supported\n", count
, buf
->share
->num_sends
);
1217 return DSERR_INVALIDPARAM
;
1220 for(i
= 0;i
< count
;++i
)
1222 TRACE("Exclusion send parameters:\n\tReceiving: %s\n\tExclusion: %ld\n\t"
1223 "Exclusion LF Ratio: %f\n",
1224 debug_fxslot(&data
.send
[i
].guidReceivingFXSlotID
),
1225 data
.send
[i
].lExclusion
, data
.send
[i
].flExclusionLFRatio
1227 srcsend
[i
] = FindDeferredSend(buf
, &data
.send
[i
].guidReceivingFXSlotID
);
1230 ERR("Failed to find active FXSlot target: %s\n",
1231 debug_fxslot(&data
.send
[i
].guidReceivingFXSlotID
));
1232 return DSERR_INVALIDPARAM
;
1234 wetmask
|= 1 << (srcsend
[i
]-buf
->deferred
.send
);
1237 for(i
= 0;i
< count
;++i
)
1239 srcsend
[i
]->lExclusion
= data
.send
[i
].lExclusion
;
1240 srcsend
[i
]->flExclusionLFRatio
= data
.send
[i
].flExclusionLFRatio
;
1242 ApplyFilterParams(buf
, &buf
->deferred
.eax
, wetmask
);
1244 buf
->dirty
.bit
.send_filter
|= wetmask
;
1247 return DSERR_INVALIDPARAM
;
1249 case EAXSOURCE_ACTIVEFXSLOTID
:
1250 if(cbPropData
&& (cbPropData
%sizeof(GUID
)) == 0)
1252 union { const void *v
; const GUID
*guid
; } data
= { pPropData
};
1253 DWORD targets
[EAX_MAX_ACTIVE_FXSLOTS
];
1254 LONG count
= cbPropData
/ sizeof(GUID
);
1257 if(count
> buf
->share
->num_sends
)
1259 ERR("Setting %ld sends, only %d supported\n", count
, buf
->share
->num_sends
);
1260 return DSERR_INVALIDPARAM
;
1263 for(i
= 0;i
< count
;i
++)
1265 TRACE("Active FXSlot %ld: %s\n", i
, debug_fxslot(&data
.guid
[i
]));
1267 targets
[i
] = FXSLOT_TARGET_NULL
;
1268 if(IsEqualGUID(&data
.guid
[i
], &EAXPROPERTYID_EAX40_FXSlot0
))
1269 targets
[i
] = FXSLOT_TARGET_0
;
1270 else if(IsEqualGUID(&data
.guid
[i
], &EAXPROPERTYID_EAX40_FXSlot1
))
1271 targets
[i
] = FXSLOT_TARGET_1
;
1272 else if(IsEqualGUID(&data
.guid
[i
], &EAXPROPERTYID_EAX40_FXSlot2
))
1273 targets
[i
] = FXSLOT_TARGET_2
;
1274 else if(IsEqualGUID(&data
.guid
[i
], &EAXPROPERTYID_EAX40_FXSlot3
))
1275 targets
[i
] = FXSLOT_TARGET_3
;
1276 else if(IsEqualGUID(&data
.guid
[i
], &EAX_PrimaryFXSlotID
))
1277 targets
[i
] = FXSLOT_TARGET_PRIMARY
;
1278 if(targets
[i
] == FXSLOT_TARGET_NULL
&& !IsEqualGUID(&data
.guid
[i
], &EAX_NULL_GUID
))
1280 ERR("Invalid FXSlot: %s\n", debug_fxslot(&data
.guid
[i
]));
1281 return DSERR_INVALIDPARAM
;
1285 for(i
= 0;i
< count
;++i
)
1286 buf
->deferred
.fxslot_targets
[i
] = targets
[i
];
1287 buf
->dirty
.bit
.send_filter
|= (1<<count
) - 1;
1290 return DSERR_INVALIDPARAM
;
1292 FIXME("Unhandled propid: 0x%08lx\n", propid
);
1293 return E_PROP_ID_UNSUPPORTED
;
1296 HRESULT
EAX4Source_Get(DSBuffer
*buf
, DWORD propid
, void *pPropData
, ULONG cbPropData
, ULONG
*pcbReturned
)
1298 if(!HAS_EXTENSION(buf
->share
, EXT_EFX
))
1299 return E_PROP_ID_UNSUPPORTED
;
1303 case EAXSOURCE_NONE
:
1307 case EAXSOURCE_ALLPARAMETERS
:
1308 GET_PROP(buf
->current
.eax
, EAXSOURCEPROPERTIES
);
1310 case EAXSOURCE_OBSTRUCTIONPARAMETERS
:
1311 GET_PROP(EAXSourceObstruction(&buf
->current
.eax
), EAXOBSTRUCTIONPROPERTIES
);
1312 case EAXSOURCE_OCCLUSIONPARAMETERS
:
1313 GET_PROP(EAXSourceOcclusion(&buf
->current
.eax
), EAXOCCLUSIONPROPERTIES
);
1314 case EAXSOURCE_EXCLUSIONPARAMETERS
:
1315 GET_PROP(EAXSourceExclusion(&buf
->current
.eax
), EAXEXCLUSIONPROPERTIES
);
1317 case EAXSOURCE_DIRECT
:
1318 GET_PROP(buf
->current
.eax
.lDirect
, long);
1319 case EAXSOURCE_DIRECTHF
:
1320 GET_PROP(buf
->current
.eax
.lDirectHF
, long);
1322 case EAXSOURCE_ROOM
:
1323 GET_PROP(buf
->current
.eax
.lRoom
, long);
1324 case EAXSOURCE_ROOMHF
:
1325 GET_PROP(buf
->current
.eax
.lRoomHF
, long);
1327 case EAXSOURCE_OBSTRUCTION
:
1328 GET_PROP(buf
->current
.eax
.lObstruction
, long);
1329 case EAXSOURCE_OBSTRUCTIONLFRATIO
:
1330 GET_PROP(buf
->current
.eax
.flObstructionLFRatio
, float);
1332 case EAXSOURCE_OCCLUSION
:
1333 GET_PROP(buf
->current
.eax
.lOcclusion
, long);
1334 case EAXSOURCE_OCCLUSIONLFRATIO
:
1335 GET_PROP(buf
->current
.eax
.flOcclusionLFRatio
, float);
1336 case EAXSOURCE_OCCLUSIONROOMRATIO
:
1337 GET_PROP(buf
->current
.eax
.flOcclusionRoomRatio
, float);
1338 case EAXSOURCE_OCCLUSIONDIRECTRATIO
:
1339 GET_PROP(buf
->current
.eax
.flOcclusionDirectRatio
, float);
1341 case EAXSOURCE_EXCLUSION
:
1342 GET_PROP(buf
->current
.eax
.lExclusion
, long);
1343 case EAXSOURCE_EXCLUSIONLFRATIO
:
1344 GET_PROP(buf
->current
.eax
.flExclusionLFRatio
, float);
1346 case EAXSOURCE_OUTSIDEVOLUMEHF
:
1347 GET_PROP(buf
->current
.eax
.lOutsideVolumeHF
, long);
1349 case EAXSOURCE_DOPPLERFACTOR
:
1350 GET_PROP(buf
->current
.eax
.flDopplerFactor
, float);
1352 case EAXSOURCE_ROLLOFFFACTOR
:
1353 GET_PROP(buf
->current
.eax
.flRolloffFactor
, float);
1354 case EAXSOURCE_ROOMROLLOFFFACTOR
:
1355 GET_PROP(buf
->current
.eax
.flRoomRolloffFactor
, float);
1357 case EAXSOURCE_AIRABSORPTIONFACTOR
:
1358 GET_PROP(buf
->current
.eax
.flAirAbsorptionFactor
, float);
1360 case EAXSOURCE_FLAGS
:
1361 GET_PROP(buf
->current
.eax
.dwFlags
, DWORD
);
1363 case EAXSOURCE_SENDPARAMETERS
:
1364 if(cbPropData
>= sizeof(EAXSOURCESENDPROPERTIES
))
1366 union { void *v
; EAXSOURCESENDPROPERTIES
*send
; } data
= { pPropData
};
1367 const struct Send
*srcsend
[EAX_MAX_ACTIVE_FXSLOTS
];
1368 LONG count
= minI(cbPropData
/ sizeof(EAXSOURCESENDPROPERTIES
),
1369 EAX_MAX_ACTIVE_FXSLOTS
);
1372 for(i
= 0;i
< count
;++i
)
1374 srcsend
[i
] = FindCurrentSend(buf
, &data
.send
[i
].guidReceivingFXSlotID
);
1377 ERR("Failed to find active FXSlot target: %s\n",
1378 debug_fxslot(&data
.send
[i
].guidReceivingFXSlotID
));
1379 return DSERR_INVALIDPARAM
;
1383 for(i
= 0;i
< count
;++i
)
1385 data
.send
[i
].lSend
= srcsend
[i
]->lSend
;
1386 data
.send
[i
].lSendHF
= srcsend
[i
]->lSendHF
;
1388 *pcbReturned
= sizeof(EAXSOURCESENDPROPERTIES
)*count
;
1391 return DSERR_INVALIDPARAM
;
1393 case EAXSOURCE_ALLSENDPARAMETERS
:
1394 if(cbPropData
>= sizeof(EAXSOURCEALLSENDPROPERTIES
))
1396 union { void *v
; EAXSOURCEALLSENDPROPERTIES
*send
; } data
= { pPropData
};
1397 const struct Send
*srcsend
[EAX_MAX_ACTIVE_FXSLOTS
];
1398 LONG count
= minI(cbPropData
/ sizeof(EAXSOURCEALLSENDPROPERTIES
),
1399 EAX_MAX_ACTIVE_FXSLOTS
);
1402 for(i
= 0;i
< count
;++i
)
1404 srcsend
[i
] = FindCurrentSend(buf
, &data
.send
[i
].guidReceivingFXSlotID
);
1407 ERR("Failed to find active FXSlot target: %s\n",
1408 debug_fxslot(&data
.send
[i
].guidReceivingFXSlotID
));
1409 return DSERR_INVALIDPARAM
;
1413 for(i
= 0;i
< count
;++i
)
1415 data
.send
[i
].lSend
= srcsend
[i
]->lSend
;
1416 data
.send
[i
].lSendHF
= srcsend
[i
]->lSendHF
;
1417 data
.send
[i
].lOcclusion
= srcsend
[i
]->lOcclusion
;
1418 data
.send
[i
].flOcclusionLFRatio
= srcsend
[i
]->flOcclusionLFRatio
;
1419 data
.send
[i
].flOcclusionRoomRatio
= srcsend
[i
]->flOcclusionRoomRatio
;
1420 data
.send
[i
].flOcclusionDirectRatio
= srcsend
[i
]->flOcclusionDirectRatio
;
1421 data
.send
[i
].lExclusion
= srcsend
[i
]->lExclusion
;
1422 data
.send
[i
].flExclusionLFRatio
= srcsend
[i
]->flExclusionLFRatio
;
1424 *pcbReturned
= sizeof(EAXSOURCEALLSENDPROPERTIES
)*count
;
1427 return DSERR_INVALIDPARAM
;
1428 case EAXSOURCE_OCCLUSIONSENDPARAMETERS
:
1429 if(cbPropData
>= sizeof(EAXSOURCEOCCLUSIONSENDPROPERTIES
))
1431 union { void *v
; EAXSOURCEOCCLUSIONSENDPROPERTIES
*send
; } data
= { pPropData
};
1432 const struct Send
*srcsend
[EAX_MAX_ACTIVE_FXSLOTS
];
1433 LONG count
= minI(cbPropData
/ sizeof(EAXSOURCEOCCLUSIONSENDPROPERTIES
),
1434 EAX_MAX_ACTIVE_FXSLOTS
);
1437 for(i
= 0;i
< count
;++i
)
1439 srcsend
[i
] = FindCurrentSend(buf
, &data
.send
[i
].guidReceivingFXSlotID
);
1442 ERR("Failed to find active FXSlot target: %s\n",
1443 debug_fxslot(&data
.send
[i
].guidReceivingFXSlotID
));
1444 return DSERR_INVALIDPARAM
;
1448 for(i
= 0;i
< count
;++i
)
1450 data
.send
[i
].lOcclusion
= srcsend
[i
]->lOcclusion
;
1451 data
.send
[i
].flOcclusionLFRatio
= srcsend
[i
]->flOcclusionLFRatio
;
1452 data
.send
[i
].flOcclusionRoomRatio
= srcsend
[i
]->flOcclusionRoomRatio
;
1453 data
.send
[i
].flOcclusionDirectRatio
= srcsend
[i
]->flOcclusionDirectRatio
;
1455 *pcbReturned
= sizeof(EAXSOURCEOCCLUSIONSENDPROPERTIES
)*count
;
1458 return DSERR_INVALIDPARAM
;
1459 case EAXSOURCE_EXCLUSIONSENDPARAMETERS
:
1460 if(cbPropData
>= sizeof(EAXSOURCEEXCLUSIONSENDPROPERTIES
))
1462 union { void *v
; EAXSOURCEEXCLUSIONSENDPROPERTIES
*send
; } data
= { pPropData
};
1463 const struct Send
*srcsend
[EAX_MAX_ACTIVE_FXSLOTS
];
1464 LONG count
= minI(cbPropData
/ sizeof(EAXSOURCEEXCLUSIONSENDPROPERTIES
),
1465 EAX_MAX_ACTIVE_FXSLOTS
);
1468 for(i
= 0;i
< count
;++i
)
1470 srcsend
[i
] = FindCurrentSend(buf
, &data
.send
[i
].guidReceivingFXSlotID
);
1473 ERR("Failed to find active FXSlot target: %s\n",
1474 debug_fxslot(&data
.send
[i
].guidReceivingFXSlotID
));
1475 return DSERR_INVALIDPARAM
;
1479 for(i
= 0;i
< count
;++i
)
1481 data
.send
[i
].lExclusion
= srcsend
[i
]->lExclusion
;
1482 data
.send
[i
].flExclusionLFRatio
= srcsend
[i
]->flExclusionLFRatio
;
1484 *pcbReturned
= sizeof(EAXSOURCEEXCLUSIONSENDPROPERTIES
)*count
;
1487 return DSERR_INVALIDPARAM
;
1489 case EAXSOURCE_ACTIVEFXSLOTID
:
1490 if(cbPropData
>= sizeof(GUID
))
1492 union { void *v
; GUID
*guid
; } data
= { pPropData
};
1493 LONG count
= minI(cbPropData
/ sizeof(GUID
), EAX_MAX_ACTIVE_FXSLOTS
);
1496 for(i
= 0;i
< count
;++i
)
1498 if(buf
->current
.fxslot_targets
[i
] == FXSLOT_TARGET_0
)
1499 data
.guid
[i
] = EAXPROPERTYID_EAX40_FXSlot0
;
1500 else if(buf
->current
.fxslot_targets
[i
] == FXSLOT_TARGET_1
)
1501 data
.guid
[i
] = EAXPROPERTYID_EAX40_FXSlot1
;
1502 else if(buf
->current
.fxslot_targets
[i
] == FXSLOT_TARGET_2
)
1503 data
.guid
[i
] = EAXPROPERTYID_EAX40_FXSlot2
;
1504 else if(buf
->current
.fxslot_targets
[i
] == FXSLOT_TARGET_3
)
1505 data
.guid
[i
] = EAXPROPERTYID_EAX40_FXSlot3
;
1506 else if(buf
->current
.fxslot_targets
[i
] == FXSLOT_TARGET_PRIMARY
)
1507 data
.guid
[i
] = EAX_PrimaryFXSlotID
;
1508 else /*if(buf->current.fxslot_targets[i] >= FXSLOT_TARGET_NULL)*/
1509 data
.guid
[i
] = EAX_NULL_GUID
;
1512 *pcbReturned
= sizeof(GUID
)*count
;
1515 return DSERR_INVALIDPARAM
;
1517 FIXME("Unhandled propid: 0x%08lx\n", propid
);
1518 return E_PROP_ID_UNSUPPORTED
;