Couple small error handling fixups
[openal-soft/openal-hmr.git] / OpenAL32 / alState.c
blob74da096995aa7d464192b35254703cac4ef29311
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2000 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include <stdlib.h>
24 #include "alMain.h"
25 #include "AL/alc.h"
26 #include "AL/alext.h"
27 #include "alError.h"
28 #include "alSource.h"
29 #include "alAuxEffectSlot.h"
30 #include "alState.h"
32 static const ALchar alVendor[] = "OpenAL Community";
33 static const ALchar alVersion[] = "1.1 ALSOFT "ALSOFT_VERSION;
34 static const ALchar alRenderer[] = "OpenAL Soft";
36 // Error Messages
37 static const ALchar alNoError[] = "No Error";
38 static const ALchar alErrInvalidName[] = "Invalid Name";
39 static const ALchar alErrInvalidEnum[] = "Invalid Enum";
40 static const ALchar alErrInvalidValue[] = "Invalid Value";
41 static const ALchar alErrInvalidOp[] = "Invalid Operation";
42 static const ALchar alErrOutOfMemory[] = "Out of Memory";
44 AL_API ALvoid AL_APIENTRY alEnable(ALenum capability)
46 ALCcontext *Context;
48 Context = GetContextRef();
49 if(!Context) return;
51 al_try
53 switch(capability)
55 case AL_SOURCE_DISTANCE_MODEL:
56 Context->SourceDistanceModel = AL_TRUE;
57 Context->UpdateSources = AL_TRUE;
58 break;
60 default:
61 al_throwerr(Context, AL_INVALID_ENUM);
64 al_endtry;
66 ALCcontext_DecRef(Context);
69 AL_API ALvoid AL_APIENTRY alDisable(ALenum capability)
71 ALCcontext *Context;
73 Context = GetContextRef();
74 if(!Context) return;
76 al_try
78 switch(capability)
80 case AL_SOURCE_DISTANCE_MODEL:
81 Context->SourceDistanceModel = AL_FALSE;
82 Context->UpdateSources = AL_TRUE;
83 break;
85 default:
86 al_throwerr(Context, AL_INVALID_ENUM);
89 al_endtry;
91 ALCcontext_DecRef(Context);
94 AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability)
96 ALCcontext *Context;
97 ALboolean value=AL_FALSE;
99 Context = GetContextRef();
100 if(!Context) return AL_FALSE;
102 al_try
104 switch(capability)
106 case AL_SOURCE_DISTANCE_MODEL:
107 value = Context->SourceDistanceModel;
108 break;
110 default:
111 al_throwerr(Context, AL_INVALID_ENUM);
114 al_endtry;
116 ALCcontext_DecRef(Context);
118 return value;
121 AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname)
123 ALCcontext *Context;
124 ALboolean value=AL_FALSE;
126 Context = GetContextRef();
127 if(!Context) return AL_FALSE;
129 al_try
131 switch(pname)
133 case AL_DOPPLER_FACTOR:
134 if(Context->DopplerFactor != 0.0f)
135 value = AL_TRUE;
136 break;
138 case AL_DOPPLER_VELOCITY:
139 if(Context->DopplerVelocity != 0.0f)
140 value = AL_TRUE;
141 break;
143 case AL_DISTANCE_MODEL:
144 if(Context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED)
145 value = AL_TRUE;
146 break;
148 case AL_SPEED_OF_SOUND:
149 if(Context->SpeedOfSound != 0.0f)
150 value = AL_TRUE;
151 break;
153 case AL_DEFERRED_UPDATES_SOFT:
154 value = Context->DeferUpdates;
155 break;
157 default:
158 al_throwerr(Context, AL_INVALID_ENUM);
161 al_endtry;
163 ALCcontext_DecRef(Context);
165 return value;
168 AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname)
170 ALCcontext *Context;
171 ALdouble value = 0.0;
173 Context = GetContextRef();
174 if(!Context) return 0.0;
176 al_try
178 switch(pname)
180 case AL_DOPPLER_FACTOR:
181 value = (ALdouble)Context->DopplerFactor;
182 break;
184 case AL_DOPPLER_VELOCITY:
185 value = (ALdouble)Context->DopplerVelocity;
186 break;
188 case AL_DISTANCE_MODEL:
189 value = (ALdouble)Context->DistanceModel;
190 break;
192 case AL_SPEED_OF_SOUND:
193 value = (ALdouble)Context->SpeedOfSound;
194 break;
196 case AL_DEFERRED_UPDATES_SOFT:
197 value = (ALdouble)Context->DeferUpdates;
198 break;
200 default:
201 al_throwerr(Context, AL_INVALID_ENUM);
204 al_endtry;
206 ALCcontext_DecRef(Context);
208 return value;
211 AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname)
213 ALCcontext *Context;
214 ALfloat value = 0.0f;
216 Context = GetContextRef();
217 if(!Context) return 0.0f;
219 al_try
221 switch(pname)
223 case AL_DOPPLER_FACTOR:
224 value = Context->DopplerFactor;
225 break;
227 case AL_DOPPLER_VELOCITY:
228 value = Context->DopplerVelocity;
229 break;
231 case AL_DISTANCE_MODEL:
232 value = (ALfloat)Context->DistanceModel;
233 break;
235 case AL_SPEED_OF_SOUND:
236 value = Context->SpeedOfSound;
237 break;
239 case AL_DEFERRED_UPDATES_SOFT:
240 value = (ALfloat)Context->DeferUpdates;
241 break;
243 default:
244 al_throwerr(Context, AL_INVALID_ENUM);
247 al_endtry;
249 ALCcontext_DecRef(Context);
251 return value;
254 AL_API ALint AL_APIENTRY alGetInteger(ALenum pname)
256 ALCcontext *Context;
257 ALint value = 0;
259 Context = GetContextRef();
260 if(!Context) return 0;
262 al_try
264 switch(pname)
266 case AL_DOPPLER_FACTOR:
267 value = (ALint)Context->DopplerFactor;
268 break;
270 case AL_DOPPLER_VELOCITY:
271 value = (ALint)Context->DopplerVelocity;
272 break;
274 case AL_DISTANCE_MODEL:
275 value = (ALint)Context->DistanceModel;
276 break;
278 case AL_SPEED_OF_SOUND:
279 value = (ALint)Context->SpeedOfSound;
280 break;
282 case AL_DEFERRED_UPDATES_SOFT:
283 value = (ALint)Context->DeferUpdates;
284 break;
286 default:
287 al_throwerr(Context, AL_INVALID_ENUM);
290 al_endtry;
292 ALCcontext_DecRef(Context);
294 return value;
297 AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname, ALboolean *values)
299 ALCcontext *Context;
301 if(values)
303 switch(pname)
305 case AL_DOPPLER_FACTOR:
306 case AL_DOPPLER_VELOCITY:
307 case AL_DISTANCE_MODEL:
308 case AL_SPEED_OF_SOUND:
309 case AL_DEFERRED_UPDATES_SOFT:
310 values[0] = alGetBoolean(pname);
311 return;
315 Context = GetContextRef();
316 if(!Context) return;
318 al_try
320 CHECK_VALUE(Context, values);
321 switch(pname)
323 default:
324 al_throwerr(Context, AL_INVALID_ENUM);
327 al_endtry;
329 ALCcontext_DecRef(Context);
332 AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname, ALdouble *values)
334 ALCcontext *Context;
336 if(values)
338 switch(pname)
340 case AL_DOPPLER_FACTOR:
341 case AL_DOPPLER_VELOCITY:
342 case AL_DISTANCE_MODEL:
343 case AL_SPEED_OF_SOUND:
344 case AL_DEFERRED_UPDATES_SOFT:
345 values[0] = alGetDouble(pname);
346 return;
350 Context = GetContextRef();
351 if(!Context) return;
353 al_try
355 CHECK_VALUE(Context, values);
356 switch(pname)
358 default:
359 al_throwerr(Context, AL_INVALID_ENUM);
362 al_endtry;
364 ALCcontext_DecRef(Context);
367 AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname, ALfloat *values)
369 ALCcontext *Context;
371 if(values)
373 switch(pname)
375 case AL_DOPPLER_FACTOR:
376 case AL_DOPPLER_VELOCITY:
377 case AL_DISTANCE_MODEL:
378 case AL_SPEED_OF_SOUND:
379 case AL_DEFERRED_UPDATES_SOFT:
380 values[0] = alGetFloat(pname);
381 return;
385 Context = GetContextRef();
386 if(!Context) return;
388 al_try
390 CHECK_VALUE(Context, values);
391 switch(pname)
393 default:
394 al_throwerr(Context, AL_INVALID_ENUM);
397 al_endtry;
399 ALCcontext_DecRef(Context);
402 AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values)
404 ALCcontext *Context;
406 if(values)
408 switch(pname)
410 case AL_DOPPLER_FACTOR:
411 case AL_DOPPLER_VELOCITY:
412 case AL_DISTANCE_MODEL:
413 case AL_SPEED_OF_SOUND:
414 case AL_DEFERRED_UPDATES_SOFT:
415 values[0] = alGetInteger(pname);
416 return;
420 Context = GetContextRef();
421 if(!Context) return;
423 al_try
425 CHECK_VALUE(Context, values);
426 switch(pname)
428 default:
429 al_throwerr(Context, AL_INVALID_ENUM);
432 al_endtry;
434 ALCcontext_DecRef(Context);
437 AL_API const ALchar* AL_APIENTRY alGetString(ALenum pname)
439 const ALchar *value;
440 ALCcontext *Context;
442 Context = GetContextRef();
443 if(!Context) return NULL;
445 al_try
447 switch(pname)
449 case AL_VENDOR:
450 value = alVendor;
451 break;
453 case AL_VERSION:
454 value = alVersion;
455 break;
457 case AL_RENDERER:
458 value = alRenderer;
459 break;
461 case AL_EXTENSIONS:
462 value = Context->ExtensionList;
463 break;
465 case AL_NO_ERROR:
466 value = alNoError;
467 break;
469 case AL_INVALID_NAME:
470 value = alErrInvalidName;
471 break;
473 case AL_INVALID_ENUM:
474 value = alErrInvalidEnum;
475 break;
477 case AL_INVALID_VALUE:
478 value = alErrInvalidValue;
479 break;
481 case AL_INVALID_OPERATION:
482 value = alErrInvalidOp;
483 break;
485 case AL_OUT_OF_MEMORY:
486 value = alErrOutOfMemory;
487 break;
489 default:
490 al_throwerr(Context, AL_INVALID_ENUM);
493 al_catchany()
495 value = NULL;
497 al_endtry;
499 ALCcontext_DecRef(Context);
501 return value;
504 AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value)
506 ALCcontext *Context;
508 Context = GetContextRef();
509 if(!Context) return;
511 al_try
513 CHECK_VALUE(Context, value >= 0.0f && isfinite(value));
515 Context->DopplerFactor = value;
516 Context->UpdateSources = AL_TRUE;
518 al_endtry;
520 ALCcontext_DecRef(Context);
523 AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value)
525 ALCcontext *Context;
527 Context = GetContextRef();
528 if(!Context) return;
530 al_try
532 CHECK_VALUE(Context, value >= 0.0f && isfinite(value));
534 Context->DopplerVelocity = value;
535 Context->UpdateSources = AL_TRUE;
537 al_endtry;
539 ALCcontext_DecRef(Context);
542 AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value)
544 ALCcontext *Context;
546 Context = GetContextRef();
547 if(!Context) return;
549 al_try
551 CHECK_VALUE(Context, value > 0.0f && isfinite(value));
553 Context->SpeedOfSound = value;
554 Context->UpdateSources = AL_TRUE;
556 al_endtry;
558 ALCcontext_DecRef(Context);
561 AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value)
563 ALCcontext *Context;
565 Context = GetContextRef();
566 if(!Context) return;
568 al_try
570 CHECK_VALUE(Context, value == AL_NONE ||
571 value == AL_INVERSE_DISTANCE ||
572 value == AL_INVERSE_DISTANCE_CLAMPED ||
573 value == AL_LINEAR_DISTANCE ||
574 value == AL_LINEAR_DISTANCE_CLAMPED ||
575 value == AL_EXPONENT_DISTANCE ||
576 value == AL_EXPONENT_DISTANCE_CLAMPED);
578 Context->DistanceModel = value;
579 if(!Context->SourceDistanceModel)
580 Context->UpdateSources = AL_TRUE;
582 al_endtry;
584 ALCcontext_DecRef(Context);
588 AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void)
590 ALCcontext *Context;
592 Context = GetContextRef();
593 if(!Context) return;
595 if(!Context->DeferUpdates)
597 ALboolean UpdateSources;
598 ALsource **src, **src_end;
599 ALeffectslot **slot, **slot_end;
600 int fpuState;
602 fpuState = SetMixerFPUMode();
604 LockContext(Context);
605 Context->DeferUpdates = AL_TRUE;
607 /* Make sure all pending updates are performed */
608 UpdateSources = ExchangeInt(&Context->UpdateSources, AL_FALSE);
610 src = Context->ActiveSources;
611 src_end = src + Context->ActiveSourceCount;
612 while(src != src_end)
614 if((*src)->state != AL_PLAYING)
616 Context->ActiveSourceCount--;
617 *src = *(--src_end);
618 continue;
621 if(ExchangeInt(&(*src)->NeedsUpdate, AL_FALSE) || UpdateSources)
622 ALsource_Update(*src, Context);
624 src++;
627 slot = Context->ActiveEffectSlots;
628 slot_end = slot + Context->ActiveEffectSlotCount;
629 while(slot != slot_end)
631 if(ExchangeInt(&(*slot)->NeedsUpdate, AL_FALSE))
632 ALeffectState_Update((*slot)->EffectState, Context->Device, *slot);
633 slot++;
636 UnlockContext(Context);
637 RestoreFPUMode(fpuState);
640 ALCcontext_DecRef(Context);
643 AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void)
645 ALCcontext *Context;
647 Context = GetContextRef();
648 if(!Context) return;
650 if(ExchangeInt(&Context->DeferUpdates, AL_FALSE))
652 ALsizei pos;
654 LockContext(Context);
655 LockUIntMapRead(&Context->SourceMap);
656 for(pos = 0;pos < Context->SourceMap.size;pos++)
658 ALsource *Source = Context->SourceMap.array[pos].value;
659 ALenum new_state;
661 if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
662 Source->Offset >= 0.0)
663 ApplyOffset(Source);
665 new_state = ExchangeInt(&Source->new_state, AL_NONE);
666 if(new_state)
667 SetSourceState(Source, Context, new_state);
669 UnlockUIntMapRead(&Context->SourceMap);
670 UnlockContext(Context);
673 ALCcontext_DecRef(Context);