Allow specifying key and velocity ranges on fontsounds
[openal-soft.git] / OpenAL32 / alFontsound.c
blob8ad85c0e617f2de41a3407b7ea83c5df21b90e9f
2 #include "config.h"
4 #include <stdlib.h>
5 #include <string.h>
7 #include "alMain.h"
8 #include "alMidi.h"
9 #include "alError.h"
10 #include "alThunk.h"
12 #include "midi/base.h"
15 extern inline struct ALfontsound *LookupFontsound(ALCdevice *device, ALuint id);
16 extern inline struct ALfontsound *RemoveFontsound(ALCdevice *device, ALuint id);
19 AL_API void AL_APIENTRY alGenFontsoundsSOFT(ALsizei n, ALuint *ids)
21 ALCdevice *device;
22 ALCcontext *context;
23 ALsizei cur = 0;
24 ALenum err;
26 context = GetContextRef();
27 if(!context) return;
29 if(!(n >= 0))
30 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
32 device = context->Device;
33 for(cur = 0;cur < n;cur++)
35 ALfontsound *inst = calloc(1, sizeof(ALfontsound));
36 if(!inst)
38 alDeleteFontsoundsSOFT(cur, ids);
39 SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done);
41 ALfontsound_Construct(inst);
43 err = NewThunkEntry(&inst->id);
44 if(err == AL_NO_ERROR)
45 err = InsertUIntMapEntry(&device->FontsoundMap, inst->id, inst);
46 if(err != AL_NO_ERROR)
48 ALfontsound_Destruct(inst);
49 memset(inst, 0, sizeof(*inst));
50 free(inst);
52 alDeleteFontsoundsSOFT(cur, ids);
53 SET_ERROR_AND_GOTO(context, err, done);
56 ids[cur] = inst->id;
59 done:
60 ALCcontext_DecRef(context);
63 AL_API ALvoid AL_APIENTRY alDeleteFontsoundsSOFT(ALsizei n, const ALuint *ids)
65 ALCdevice *device;
66 ALCcontext *context;
67 ALfontsound *inst;
68 ALsizei i;
70 context = GetContextRef();
71 if(!context) return;
73 if(!(n >= 0))
74 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
76 device = context->Device;
77 for(i = 0;i < n;i++)
79 /* Check for valid ID */
80 if((inst=LookupFontsound(device, ids[i])) == NULL)
81 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
82 if(inst->ref != 0)
83 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
86 for(i = 0;i < n;i++)
88 if((inst=RemoveFontsound(device, ids[i])) == NULL)
89 continue;
91 ALfontsound_Destruct(inst);
93 memset(inst, 0, sizeof(*inst));
94 free(inst);
97 done:
98 ALCcontext_DecRef(context);
101 AL_API ALboolean AL_APIENTRY alIsFontsoundSOFT(ALuint id)
103 ALCcontext *context;
104 ALboolean ret;
106 context = GetContextRef();
107 if(!context) return AL_FALSE;
109 ret = LookupFontsound(context->Device, id) ? AL_TRUE : AL_FALSE;
111 ALCcontext_DecRef(context);
113 return ret;
116 AL_API void AL_APIENTRY alFontsoundiSOFT(ALuint id, ALenum param, ALint UNUSED(value))
118 ALCdevice *device;
119 ALCcontext *context;
120 ALfontsound *sound;
122 context = GetContextRef();
123 if(!context) return;
125 device = context->Device;
126 if(!(sound=LookupFontsound(device, id)))
127 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
128 if(sound->ref != 0)
129 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
130 switch(param)
132 default:
133 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
136 done:
137 ALCcontext_DecRef(context);
140 AL_API void AL_APIENTRY alFontsound2iSOFT(ALuint id, ALenum param, ALint value1, ALint value2)
142 ALCdevice *device;
143 ALCcontext *context;
144 ALfontsound *sound;
146 context = GetContextRef();
147 if(!context) return;
149 device = context->Device;
150 if(!(sound=LookupFontsound(device, id)))
151 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
152 if(sound->ref != 0)
153 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
154 switch(param)
156 case AL_KEY_RANGE_SOFT:
157 if(!(value1 >= 0 && value1 <= 127 && value2 >= 0 && value2 <= 127))
158 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
159 sound->MinKey = value1;
160 sound->MaxKey = value2;
161 break;
163 case AL_VELOCITY_RANGE_SOFT:
164 if(!(value1 >= 0 && value1 <= 127 && value2 >= 0 && value2 <= 127))
165 SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
166 sound->MinVelocity = value1;
167 sound->MaxVelocity = value2;
168 break;
170 default:
171 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
174 done:
175 ALCcontext_DecRef(context);
178 AL_API void AL_APIENTRY alFontsoundivSOFT(ALuint id, ALenum param, const ALint *values)
180 ALCdevice *device;
181 ALCcontext *context;
182 ALfontsound *sound;
184 switch(param)
186 case AL_KEY_RANGE_SOFT:
187 case AL_VELOCITY_RANGE_SOFT:
188 alFontsound2iSOFT(id, param, values[0], values[1]);
189 return;
192 context = GetContextRef();
193 if(!context) return;
195 device = context->Device;
196 if(!(sound=LookupFontsound(device, id)))
197 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
198 if(sound->ref != 0)
199 SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
200 switch(param)
202 default:
203 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
206 done:
207 ALCcontext_DecRef(context);
210 AL_API void AL_APIENTRY alGetFontsoundivSOFT(ALuint id, ALenum param, ALint *values)
212 ALCdevice *device;
213 ALCcontext *context;
214 const ALfontsound *sound;
216 context = GetContextRef();
217 if(!context) return;
219 device = context->Device;
220 if(!(sound=LookupFontsound(device, id)))
221 SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
222 switch(param)
224 case AL_KEY_RANGE_SOFT:
225 values[0] = sound->MinKey;
226 values[1] = sound->MaxKey;
227 break;
229 case AL_VELOCITY_RANGE_SOFT:
230 values[0] = sound->MinVelocity;
231 values[1] = sound->MaxVelocity;
232 break;
234 default:
235 SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
238 done:
239 ALCcontext_DecRef(context);
243 /* ReleaseALFontsounds
245 * Called to destroy any fontsounds that still exist on the device
247 void ReleaseALFontsounds(ALCdevice *device)
249 ALsizei i;
250 for(i = 0;i < device->FontsoundMap.size;i++)
252 ALfontsound *temp = device->FontsoundMap.array[i].value;
253 device->FontsoundMap.array[i].value = NULL;
255 ALfontsound_Destruct(temp);
257 memset(temp, 0, sizeof(*temp));
258 free(temp);