Mercurial > ~darius > hgwebdir.cgi > mikmod
comparison playercode/mdriver.c @ 12:437e8455d862
General tidy up..
Rename makefile.gcc to Makefile
author | darius |
---|---|
date | Thu, 23 Apr 1998 07:20:13 +0000 |
parents | 42e11dc15457 |
children | 80fa6dd10e14 |
comparison
equal
deleted
inserted
replaced
11:d5cb2cfc8eca | 12:437e8455d862 |
---|---|
1 /* | 1 /* |
2 | 2 * Name: MDRIVER.C |
3 Name: MDRIVER.C | 3 * |
4 | 4 * Description: These routines are used to access the available soundcard |
5 Description: | 5 * drivers. |
6 These routines are used to access the available soundcard drivers. | 6 * |
7 | 7 * Portability: All systems - all compilers |
8 Portability: | 8 * |
9 All systems - all compilers | 9 */ |
10 | |
11 */ | |
12 | 10 |
13 #include "mikmod.h" | 11 #include "mikmod.h" |
14 | 12 |
15 MDRIVER *firstdriver = NULL, *md_driver = &drv_nos; | 13 MDRIVER *firstdriver = NULL, *md_driver = &drv_nos; |
16 | 14 |
17 UWORD md_device = 0; | 15 UWORD md_device = 0; |
18 UWORD md_mixfreq = 44100; | 16 UWORD md_mixfreq = 44100; |
19 UWORD md_mode = DMODE_STEREO | DMODE_16BITS | DMODE_SURROUND; | 17 UWORD md_mode = DMODE_STEREO | DMODE_16BITS | DMODE_SURROUND; |
20 UWORD md_dmabufsize = 50; | 18 UWORD md_dmabufsize = 50; |
21 UBYTE md_pansep = 128; // 128 == 100% (full left/right) | 19 UBYTE md_pansep = 128; /* 128 == 100% (full left/right) */ |
22 | 20 |
23 UBYTE md_reverb = 6; // Reverb | 21 UBYTE md_reverb = 6; /* Reverb */ |
24 | 22 |
25 UBYTE md_volume = 96; // Global sound volume (0-128) | 23 UBYTE md_volume = 96; /* Global sound volume (0-128) */ |
26 UBYTE md_musicvolume = 128; // volume of song | 24 UBYTE md_musicvolume = 128; /* volume of song */ |
27 UBYTE md_sndfxvolume = 128; // volume of sound effects | 25 UBYTE md_sndfxvolume = 128; /* volume of sound effects */ |
28 | 26 |
29 UBYTE md_bpm = 125; | 27 UBYTE md_bpm = 125; |
30 | 28 |
31 | 29 |
32 // Do not modify the numchn variables yourself! use MD_SetVoices() | 30 /* Do not modify the numchn variables yourself! use MD_SetVoices() */ |
33 | 31 |
34 UBYTE md_numchn = 0, md_sngchn = 0, md_sfxchn = 0; | 32 UBYTE md_numchn = 0, md_sngchn = 0, md_sfxchn = 0; |
35 UBYTE md_hardchn = 0, md_softchn = 0; | 33 UBYTE md_hardchn = 0, md_softchn = 0; |
36 | 34 |
37 | 35 |
38 void (*md_player)(void) = Player_HandleTick; | 36 void (*md_player) (void) = Player_HandleTick; |
39 static BOOL isplaying = 0, initialized = 0; | 37 static BOOL isplaying = 0, initialized = 0; |
40 static UBYTE *sfxinfo; | 38 static UBYTE *sfxinfo; |
41 static int sfxpool; | 39 static int sfxpool; |
42 | 40 |
43 static SAMPLE **md_sample = NULL; | 41 static SAMPLE **md_sample = NULL; |
44 | 42 |
45 // Backup variables. This way, the end programmer can fiddle with the | 43 /* |
46 // main globals without mikmod blowing up. | 44 * Backup variables. This way, the end programmer can fiddle with the main |
47 | 45 * globals without mikmod blowing up. |
48 static UWORD idevice, imixfreq, imode, idmabufsize; | 46 */ |
49 | 47 |
50 | 48 static UWORD idevice, imixfreq, imode, idmabufsize; |
51 static void LimitHardVoices(int limit) | 49 |
52 | 50 /* |
53 // Limits the number of hardware voices to the specified amount. | 51 * Limits the number of hardware voices to the specified amount. This |
54 // This function should only be used by the low-level drivers. | 52 * function should only be used by the low-level drivers. |
55 | 53 */ |
56 { | 54 static void |
57 int t = 0; | 55 LimitHardVoices(int limit) |
58 | 56 { |
59 if(!(md_mode & DMODE_SOFT_SNDFX) && (md_sfxchn > limit)) md_sfxchn = limit; | 57 int t = 0; |
60 if(!(md_mode & DMODE_SOFT_MUSIC) && (md_sngchn > limit)) md_sngchn = limit; | 58 |
61 | 59 if (!(md_mode & DMODE_SOFT_SNDFX) && (md_sfxchn > limit)) |
62 if(!(md_mode & DMODE_SOFT_SNDFX)) | 60 md_sfxchn = limit; |
63 md_hardchn = md_sfxchn; | 61 if (!(md_mode & DMODE_SOFT_MUSIC) && (md_sngchn > limit)) |
62 md_sngchn = limit; | |
63 | |
64 if (!(md_mode & DMODE_SOFT_SNDFX)) | |
65 md_hardchn = md_sfxchn; | |
64 else | 66 else |
65 md_hardchn = 0; | 67 md_hardchn = 0; |
66 | 68 |
67 if(!(md_mode & DMODE_SOFT_MUSIC)) | 69 if (!(md_mode & DMODE_SOFT_MUSIC)) |
68 md_hardchn += md_sngchn; | 70 md_hardchn += md_sngchn; |
69 | 71 |
70 while(md_hardchn > limit) | 72 while (md_hardchn > limit) { |
71 { | 73 if (++t & 1) |
72 if(++t & 1) | 74 if (!(md_mode & DMODE_SOFT_SNDFX) && (md_sfxchn > 4)) |
73 if(!(md_mode & DMODE_SOFT_SNDFX) && (md_sfxchn > 4)) md_sfxchn--; | 75 md_sfxchn--; |
74 else | 76 else if (!(md_mode & DMODE_SOFT_MUSIC) && (md_sngchn > 8)) |
75 if(!(md_mode & DMODE_SOFT_MUSIC) && (md_sngchn > 8)) md_sngchn--; | 77 md_sngchn--; |
76 | 78 |
77 if(!(md_mode & DMODE_SOFT_SNDFX)) | 79 if (!(md_mode & DMODE_SOFT_SNDFX)) |
78 md_hardchn = md_sfxchn; | 80 md_hardchn = md_sfxchn; |
79 else | 81 else |
80 md_hardchn = 0; | 82 md_hardchn = 0; |
81 | 83 |
82 if(!(md_mode & DMODE_SOFT_MUSIC)) | 84 if (!(md_mode & DMODE_SOFT_MUSIC)) |
83 md_hardchn += md_sngchn; | 85 md_hardchn += md_sngchn; |
84 } | 86 } |
85 | 87 |
86 md_numchn = md_hardchn + md_softchn; | 88 md_numchn = md_hardchn + md_softchn; |
87 } | 89 } |
88 | 90 |
89 | 91 /* |
90 static void LimitSoftVoices(int limit) | 92 * Limits the number of hardware voices to the specified amount. This |
91 | 93 * function should only be used by the low-level drivers. |
92 // Limits the number of hardware voices to the specified amount. | 94 */ |
93 // This function should only be used by the low-level drivers. | 95 static void |
94 | 96 LimitSoftVoices(int limit) |
95 { | 97 { |
96 int t = 0; | 98 int t = 0; |
97 | 99 |
98 if((md_mode & DMODE_SOFT_SNDFX) && (md_sfxchn > limit)) md_sfxchn = limit; | 100 if ((md_mode & DMODE_SOFT_SNDFX) && (md_sfxchn > limit)) |
99 if((md_mode & DMODE_SOFT_MUSIC) && (md_sngchn > limit)) md_sngchn = limit; | 101 md_sfxchn = limit; |
100 | 102 if ((md_mode & DMODE_SOFT_MUSIC) && (md_sngchn > limit)) |
101 if(md_mode & DMODE_SOFT_SNDFX) | 103 md_sngchn = limit; |
102 md_softchn = md_sfxchn; | 104 |
105 if (md_mode & DMODE_SOFT_SNDFX) | |
106 md_softchn = md_sfxchn; | |
103 else | 107 else |
104 md_softchn = 0; | 108 md_softchn = 0; |
105 | 109 |
106 if(md_mode & DMODE_SOFT_MUSIC) | 110 if (md_mode & DMODE_SOFT_MUSIC) |
107 md_softchn += md_sngchn; | 111 md_softchn += md_sngchn; |
108 | 112 |
109 while(md_softchn > limit) | 113 while (md_softchn > limit) { |
110 { | 114 if (++t & 1) |
111 if(++t & 1) | 115 if ((md_mode & DMODE_SOFT_SNDFX) && (md_sfxchn > 4)) |
112 if((md_mode & DMODE_SOFT_SNDFX) && (md_sfxchn > 4)) md_sfxchn--; | 116 md_sfxchn--; |
113 else | 117 else if ((md_mode & DMODE_SOFT_MUSIC) && (md_sngchn > 8)) |
114 if((md_mode & DMODE_SOFT_MUSIC) && (md_sngchn > 8)) md_sngchn--; | 118 md_sngchn--; |
115 | 119 |
116 if(!(md_mode & DMODE_SOFT_SNDFX)) | 120 if (!(md_mode & DMODE_SOFT_SNDFX)) |
117 md_softchn = md_sfxchn; | 121 md_softchn = md_sfxchn; |
118 else | 122 else |
119 md_softchn = 0; | 123 md_softchn = 0; |
120 | 124 |
121 if(!(md_mode & DMODE_SOFT_MUSIC)) | 125 if (!(md_mode & DMODE_SOFT_MUSIC)) |
122 md_softchn += md_sngchn; | 126 md_softchn += md_sngchn; |
123 } | 127 } |
124 | 128 |
125 md_numchn = md_hardchn + md_softchn; | 129 md_numchn = md_hardchn + md_softchn; |
126 } | 130 } |
127 | 131 |
128 | 132 |
129 // Note: 'type' indicates whether the returned value should be for music | 133 /* |
130 // or for sound effects. | 134 * Note: 'type' indicates whether the returned value should be for music or |
131 | 135 * for sound effects. |
132 ULONG MD_SampleSpace(int type) | 136 */ |
133 { | 137 ULONG |
134 if(type==MD_MUSIC) | 138 MD_SampleSpace(int type) |
135 type = (md_mode & DMODE_SOFT_MUSIC) ? MD_SOFTWARE : MD_HARDWARE; | 139 { |
136 else if(type==MD_SNDFX) | 140 if (type == MD_MUSIC) |
137 type = (md_mode & DMODE_SOFT_SNDFX) ? MD_SOFTWARE : MD_HARDWARE; | 141 type = (md_mode & DMODE_SOFT_MUSIC) ? MD_SOFTWARE : MD_HARDWARE; |
142 else if (type == MD_SNDFX) | |
143 type = (md_mode & DMODE_SOFT_SNDFX) ? MD_SOFTWARE : MD_HARDWARE; | |
138 | 144 |
139 return md_driver->FreeSampleSpace(type); | 145 return md_driver->FreeSampleSpace(type); |
140 } | 146 } |
141 | 147 |
142 | 148 |
143 ULONG MD_SampleLength(int type, SAMPLE *s) | 149 ULONG |
144 { | 150 MD_SampleLength(int type, SAMPLE * s) |
145 if(type==MD_MUSIC) | 151 { |
146 type = (md_mode & DMODE_SOFT_MUSIC) ? MD_SOFTWARE : MD_HARDWARE; | 152 if (type == MD_MUSIC) |
147 else if(type==MD_SNDFX) | 153 type = (md_mode & DMODE_SOFT_MUSIC) ? MD_SOFTWARE : MD_HARDWARE; |
148 type = (md_mode & DMODE_SOFT_SNDFX) ? MD_SOFTWARE : MD_HARDWARE; | 154 else if (type == MD_SNDFX) |
155 type = (md_mode & DMODE_SOFT_SNDFX) ? MD_SOFTWARE : MD_HARDWARE; | |
149 | 156 |
150 return md_driver->RealSampleLength(type, s); | 157 return md_driver->RealSampleLength(type, s); |
151 } | 158 } |
152 | 159 |
153 | 160 |
154 UWORD MD_SetDMA(int secs) | 161 /* |
155 | 162 * Converts the given number of 1/10th seconds into the number of bytes of |
156 // Converts the given number of 1/10th seconds into the number of bytes of | 163 * audio that a sample # 1/10th seconds long would require at the current md_* |
157 // audio that a sample # 1/10th seconds long would require at the current md_* | 164 * settings. |
158 // settings. | 165 */ |
159 | 166 UWORD |
160 { | 167 MD_SetDMA(int secs) |
161 ULONG result; | 168 { |
169 ULONG result; | |
162 | 170 |
163 result = (md_mixfreq * ((md_mode & DMODE_STEREO) ? 2 : 1) * | 171 result = (md_mixfreq * ((md_mode & DMODE_STEREO) ? 2 : 1) * |
164 ((md_mode & DMODE_16BITS) ? 2 : 1) * secs) * 10; | 172 ((md_mode & DMODE_16BITS) ? 2 : 1) * secs) * 10; |
165 | 173 |
166 if(result > 32000) result = 32000; | 174 if (result > 32000) |
167 return(md_dmabufsize = (result & ~3)); // round it off to an 8 byte boundry | 175 result = 32000; |
168 } | 176 return (md_dmabufsize = (result & ~3)); /* round it off to an 8 byte |
169 | 177 * boundry */ |
170 | 178 } |
171 void MD_InfoDriver(void) | 179 |
172 { | 180 |
173 int t; | 181 void |
174 MDRIVER *l; | 182 MD_InfoDriver(void) |
175 | 183 { |
176 // list all registered devicedrivers: | 184 int t; |
177 for(t=1,l=firstdriver; l!=NULL; l=l->next, t++) | 185 MDRIVER *l; |
178 printf("%d. %s\n",t,l->Version); | 186 |
179 } | 187 /* list all registered devicedrivers: */ |
180 | 188 for (t = 1, l = firstdriver; l != NULL; l = l->next, t++) |
181 | 189 printf("%d. %s\n", t, l->Version); |
182 void MD_RegisterDriver(MDRIVER *drv) | 190 } |
183 { | 191 |
184 MDRIVER *cruise = firstdriver; | 192 |
185 | 193 void |
186 if(cruise!=NULL) | 194 MD_RegisterDriver(MDRIVER * drv) |
187 { while(cruise->next!=NULL) cruise = cruise->next; | 195 { |
188 cruise->next = drv; | 196 MDRIVER *cruise = firstdriver; |
197 | |
198 if (cruise != NULL) { | |
199 while (cruise->next != NULL) | |
200 cruise = cruise->next; | |
201 cruise->next = drv; | |
189 } else | 202 } else |
190 firstdriver = drv; | 203 firstdriver = drv; |
191 } | 204 } |
192 | 205 |
193 | 206 |
194 SWORD MD_SampleLoad(SAMPLOAD *s, int type, FILE *fp) | 207 /* type - sample type .. MD_MUSIC or MD_SNDFX */ |
195 // type - sample type .. MD_MUSIC or MD_SNDFX | 208 SWORD |
196 { | 209 MD_SampleLoad(SAMPLOAD * s, int type, FILE * fp) |
197 SWORD result; | 210 { |
198 | 211 SWORD result; |
199 if(type==MD_MUSIC) | 212 |
200 type = (md_mode & DMODE_SOFT_MUSIC) ? MD_SOFTWARE : MD_HARDWARE; | 213 if (type == MD_MUSIC) |
201 else if(type==MD_SNDFX) | 214 type = (md_mode & DMODE_SOFT_MUSIC) ? MD_SOFTWARE : MD_HARDWARE; |
202 type = (md_mode & DMODE_SOFT_SNDFX) ? MD_SOFTWARE : MD_HARDWARE; | 215 else if (type == MD_SNDFX) |
216 type = (md_mode & DMODE_SOFT_SNDFX) ? MD_SOFTWARE : MD_HARDWARE; | |
203 | 217 |
204 SL_Init(s); | 218 SL_Init(s); |
205 result = md_driver->SampleLoad(s, type, fp); | 219 result = md_driver->SampleLoad(s, type, fp); |
206 SL_Exit(s); | 220 SL_Exit(s); |
207 | 221 |
208 return result; | 222 return result; |
209 } | 223 } |
210 | 224 |
211 | 225 |
212 void MD_SampleUnLoad(SWORD handle) | 226 void |
227 MD_SampleUnLoad(SWORD handle) | |
213 { | 228 { |
214 md_driver->SampleUnLoad(handle); | 229 md_driver->SampleUnLoad(handle); |
215 } | 230 } |
216 | 231 |
217 | 232 |
218 void MD_SetBPM(UBYTE bpm) | 233 void |
234 MD_SetBPM(UBYTE bpm) | |
219 { | 235 { |
220 md_bpm = bpm; | 236 md_bpm = bpm; |
221 } | 237 } |
222 | 238 |
223 | 239 |
224 void MikMod_RegisterPlayer(void (*player)(void)) | 240 void |
241 MikMod_RegisterPlayer(void (*player) (void)) | |
225 { | 242 { |
226 md_player = player; | 243 md_player = player; |
227 } | 244 } |
228 | 245 |
229 | 246 |
230 void MikMod_Update(void) | 247 void |
231 { | 248 MikMod_Update(void) |
232 if(isplaying) md_driver->Update(); | 249 { |
233 } | 250 if (isplaying) |
234 | 251 md_driver->Update(); |
235 | 252 } |
236 void Voice_SetVolume(int voice, UWORD vol) | 253 |
237 { | 254 |
238 ULONG tmp; | 255 void |
239 | 256 Voice_SetVolume(int voice, UWORD vol) |
240 if((voice<0) || (voice>=md_numchn)) return; | 257 { |
241 tmp = (ULONG)vol * (ULONG)md_volume * ((voice < md_sngchn) ? (ULONG)md_musicvolume : (ULONG)md_sndfxvolume); | 258 ULONG tmp; |
242 md_driver->VoiceSetVolume(voice,tmp/16384UL); | 259 |
243 } | 260 if ((voice < 0) || (voice >= md_numchn)) |
244 | 261 return; |
245 | 262 tmp = (ULONG) vol *(ULONG) md_volume * |
246 void Voice_SetFrequency(int voice, ULONG frq) | 263 ((voice < md_sngchn) ? (ULONG) md_musicvolume : (ULONG) md_sndfxvolume); |
247 { | 264 md_driver->VoiceSetVolume(voice, tmp / 16384 UL); |
248 if((voice < 0) || (voice >= md_numchn)) return; | 265 } |
249 if(md_sample[voice]!=NULL && md_sample[voice]->divfactor!=0) frq/=md_sample[voice]->divfactor; | 266 |
267 | |
268 void | |
269 Voice_SetFrequency(int voice, ULONG frq) | |
270 { | |
271 if ((voice < 0) || (voice >= md_numchn)) | |
272 return; | |
273 if (md_sample[voice] != NULL && md_sample[voice]->divfactor != 0) | |
274 frq /= md_sample[voice]->divfactor; | |
250 md_driver->VoiceSetFrequency(voice, frq); | 275 md_driver->VoiceSetFrequency(voice, frq); |
251 } | 276 } |
252 | 277 |
253 | 278 |
254 void Voice_SetPanning(int voice, ULONG pan) | 279 void |
255 { | 280 Voice_SetPanning(int voice, ULONG pan) |
256 if((voice < 0) || (voice >= md_numchn)) return; | 281 { |
257 if(pan!=PAN_SURROUND) | 282 if ((voice < 0) || (voice >= md_numchn)) |
258 { if(md_mode & DMODE_REVERSE) pan = 255-pan; | 283 return; |
259 pan = (((SWORD)(pan-128)*md_pansep) / 128)+128; | 284 if (pan != PAN_SURROUND) { |
285 if (md_mode & DMODE_REVERSE) | |
286 pan = 255 - pan; | |
287 pan = (((SWORD) (pan - 128) * md_pansep) / 128) + 128; | |
260 } | 288 } |
261 md_driver->VoiceSetPanning(voice, pan); | 289 md_driver->VoiceSetPanning(voice, pan); |
262 } | 290 } |
263 | 291 |
264 | 292 |
265 void Voice_Play(int voice, SAMPLE *s, ULONG start) | 293 void |
266 { | 294 Voice_Play(int voice, SAMPLE * s, ULONG start) |
267 ULONG repend; | 295 { |
268 | 296 ULONG repend; |
269 if((voice < 0) || (voice >= md_numchn) || (start >= s->length)) return; | 297 |
298 if ((voice < 0) || (voice >= md_numchn) || (start >= s->length)) | |
299 return; | |
270 | 300 |
271 md_sample[voice] = s; | 301 md_sample[voice] = s; |
272 repend = s->loopend; | 302 repend = s->loopend; |
273 | 303 |
274 if(s->flags&SF_LOOP) | 304 if (s->flags & SF_LOOP) |
275 if(repend > s->length) repend = s->length; // repend can't be bigger than size | 305 if (repend > s->length) |
276 | 306 repend = s->length; /* repend can't be bigger than size */ |
277 md_driver->VoicePlay(voice,s->handle,start,s->length,s->loopstart,repend,s->flags); | 307 |
278 } | 308 md_driver->VoicePlay(voice, s->handle, start, s->length, s->loopstart, repend, s->flags); |
279 | 309 } |
280 | 310 |
281 void Voice_Stop(int voice) | 311 |
282 { | 312 void |
283 if((voice < 0) || (voice >= md_numchn)) return; | 313 Voice_Stop(int voice) |
284 if(voice >= md_sngchn) | 314 { |
285 { // It is a sound effects channel, so flag the voice as non-critical! | 315 if ((voice < 0) || (voice >= md_numchn)) |
286 sfxinfo[voice-md_sngchn] = 0; | 316 return; |
287 } | 317 if (voice >= md_sngchn) { /* It is a sound effects channel, so flag the |
288 | 318 * voice as non-critical! */ |
319 sfxinfo[voice - md_sngchn] = 0; | |
320 } | |
289 md_driver->VoiceStop(voice); | 321 md_driver->VoiceStop(voice); |
290 } | 322 } |
291 | 323 |
292 | 324 |
293 BOOL Voice_Stopped(int voice) | 325 BOOL |
294 { | 326 Voice_Stopped(int voice) |
295 if((voice < 0) || (voice >= md_numchn)) return 0; | 327 { |
296 return(md_driver->VoiceStopped(voice)); | 328 if ((voice < 0) || (voice >= md_numchn)) |
297 } | 329 return 0; |
298 | 330 return (md_driver->VoiceStopped(voice)); |
299 | 331 } |
300 SLONG Voice_GetPosition(int voice) | 332 |
301 { | 333 |
302 if((voice < 0) || (voice >= md_numchn)) return 0; | 334 SLONG |
303 return(md_driver->VoiceGetPosition(voice)); | 335 Voice_GetPosition(int voice) |
304 } | 336 { |
305 | 337 if ((voice < 0) || (voice >= md_numchn)) |
306 | 338 return 0; |
307 ULONG Voice_RealVolume(int voice) | 339 return (md_driver->VoiceGetPosition(voice)); |
308 { | 340 } |
309 if((voice < 0) || (voice >= md_numchn)) return 0; | 341 |
310 return(md_driver->VoiceRealVolume(voice)); | 342 |
311 } | 343 ULONG |
312 | 344 Voice_RealVolume(int voice) |
313 | 345 { |
314 // ================================ | 346 if ((voice < 0) || (voice >= md_numchn)) |
315 // Functions prefixed with MikMod | 347 return 0; |
316 // ================================ | 348 return (md_driver->VoiceRealVolume(voice)); |
317 | 349 } |
318 BOOL MikMod_Init(void) | 350 |
319 { | 351 |
320 UWORD t; | 352 /* |
353 * Functions prefixed with MikMod | |
354 */ | |
355 BOOL | |
356 MikMod_Init(void) | |
357 { | |
358 UWORD t; | |
321 | 359 |
322 _mm_critical = 1; | 360 _mm_critical = 1; |
323 | 361 |
324 // if md_device==0, try to find a device number | 362 /* if md_device==0, try to find a device number */ |
325 | 363 |
326 if(md_device==0) | 364 if (md_device == 0) { |
327 { for(t=1,md_driver=firstdriver; md_driver!=NULL; md_driver=md_driver->next, t++) | 365 for (t = 1, md_driver = firstdriver; md_driver != NULL; md_driver = md_driver->next, t++) { |
328 { if(md_driver->IsPresent()) break; | 366 if (md_driver->IsPresent()) |
329 } | 367 break; |
330 | 368 } |
331 if(md_driver==NULL) | 369 |
332 { _mm_errno = MMERR_DETECTING_DEVICE; | 370 if (md_driver == NULL) { |
333 if(_mm_errorhandler!=NULL) _mm_errorhandler(); | 371 _mm_errno = MMERR_DETECTING_DEVICE; |
334 md_driver = &drv_nos; | 372 if (_mm_errorhandler != NULL) |
335 return 1; | 373 _mm_errorhandler(); |
336 } | 374 md_driver = &drv_nos; |
337 | 375 return 1; |
338 md_device = t; | 376 } |
339 } else | 377 md_device = t; |
340 { // if n>0 use that driver | 378 } else { /* if n>0 use that driver */ |
341 for(t=1,md_driver=firstdriver; (md_driver!=NULL) && (t!=md_device); md_driver=md_driver->next, t++); | 379 for (t = 1, md_driver = firstdriver; |
342 | 380 (md_driver != NULL) && (t != md_device); |
343 if(md_driver==NULL) | 381 md_driver = md_driver->next, t++) |
344 { _mm_errno = MMERR_INVALID_DEVICE; | 382 ; /* Nothing */ |
345 if(_mm_errorhandler!=NULL) _mm_errorhandler(); | 383 |
346 md_driver = &drv_nos; | 384 if (md_driver == NULL) { |
347 return 1; | 385 _mm_errno = MMERR_INVALID_DEVICE; |
348 } | 386 if (_mm_errorhandler != NULL) |
349 | 387 _mm_errorhandler(); |
350 if(!md_driver->IsPresent()) | 388 md_driver = &drv_nos; |
351 { _mm_errno = MMERR_DETECTING_DEVICE; | 389 return 1; |
352 if(_mm_errorhandler!=NULL) _mm_errorhandler(); | 390 } |
353 md_driver = &drv_nos; | 391 if (!md_driver->IsPresent()) { |
354 return 1; | 392 _mm_errno = MMERR_DETECTING_DEVICE; |
355 } | 393 if (_mm_errorhandler != NULL) |
356 } | 394 _mm_errorhandler(); |
357 | 395 md_driver = &drv_nos; |
358 if(md_driver->Init()) | 396 return 1; |
359 { MikMod_Exit(); | 397 } |
360 if(_mm_errorhandler!=NULL) _mm_errorhandler(); | 398 } |
361 return 1; | 399 |
362 } | 400 if (md_driver->Init()) { |
363 | 401 MikMod_Exit(); |
364 idevice = md_device; imode = md_mode; | 402 if (_mm_errorhandler != NULL) |
365 imixfreq = md_mixfreq; idmabufsize = md_dmabufsize; | 403 _mm_errorhandler(); |
404 return 1; | |
405 } | |
406 idevice = md_device; | |
407 imode = md_mode; | |
408 imixfreq = md_mixfreq; | |
409 idmabufsize = md_dmabufsize; | |
366 initialized = 1; | 410 initialized = 1; |
367 _mm_critical = 0; | 411 _mm_critical = 0; |
368 | 412 |
369 return 0; | 413 return 0; |
370 } | 414 } |
371 | 415 |
372 | 416 |
373 void MikMod_Exit(void) | 417 void |
418 MikMod_Exit(void) | |
374 { | 419 { |
375 MikMod_DisableOutput(); | 420 MikMod_DisableOutput(); |
376 md_driver->Exit(); | 421 md_driver->Exit(); |
377 md_numchn = md_sfxchn = md_sngchn = 0; | 422 md_numchn = md_sfxchn = md_sngchn = 0; |
378 md_driver = &drv_nos; | 423 md_driver = &drv_nos; |
379 initialized = 0; | 424 initialized = 0; |
380 } | 425 } |
381 | 426 |
382 | 427 |
383 BOOL MikMod_Reset(void) | 428 /* |
384 | 429 * Reset the driver using the new global variable settings. If the driver has |
385 // Reset the driver using the new global variable settings. | 430 * not been initialized, it will be now. |
386 // If the driver has not been initialized, it will be now. | 431 */ |
387 | 432 BOOL |
388 { | 433 MikMod_Reset(void) |
389 if(!initialized) return MikMod_Init(); | 434 { |
390 if((md_driver->Reset == NULL) || (md_device != idevice)) | 435 if (!initialized) |
391 { // md_driver->Reset was NULL, or md_device was changed, | 436 return MikMod_Init(); |
392 // so do a full reset of the driver. | 437 if ((md_driver->Reset == NULL) || |
393 | 438 (md_device != idevice)) { /* md_driver->Reset was |
394 if(isplaying) md_driver->PlayStop(); | 439 * NULL, or md_device |
395 md_driver->Exit(); | 440 * was changed, so do a |
396 if(MikMod_Init()) | 441 * full reset of the |
397 { MikMod_Exit(); | 442 * driver. */ |
398 if(_mm_errorhandler!=NULL) _mm_errorhandler(); | 443 if (isplaying) |
399 return 1; | 444 md_driver->PlayStop(); |
400 } | 445 md_driver->Exit(); |
401 if(isplaying) md_driver->PlayStart(); | 446 if (MikMod_Init()) { |
402 } else | 447 MikMod_Exit(); |
403 { if(md_driver->Reset()) | 448 if (_mm_errorhandler != NULL) |
404 { MikMod_Exit(); | 449 _mm_errorhandler(); |
405 if(_mm_errorhandler!=NULL) _mm_errorhandler(); | 450 return 1; |
406 return 1; | 451 } |
407 } | 452 if (isplaying) |
408 } | 453 md_driver->PlayStart(); |
409 | 454 } else { |
455 if (md_driver->Reset()) { | |
456 MikMod_Exit(); | |
457 if (_mm_errorhandler != NULL) | |
458 _mm_errorhandler(); | |
459 return 1; | |
460 } | |
461 } | |
462 | |
410 return 0; | 463 return 0; |
411 } | 464 } |
412 | 465 |
413 | 466 |
414 BOOL MikMod_SetNumVoices(int music, int sfx) | 467 /* If either parameter is -1, the current set value will be retained. */ |
415 | 468 BOOL |
416 // If either parameter is -1, the current set value will be retained. | 469 MikMod_SetNumVoices(int music, int sfx) |
417 | 470 { |
418 { | 471 BOOL resume = 0; |
419 BOOL resume = 0; | 472 int t, oldchn = 0; |
420 int t, oldchn = 0; | 473 |
421 | 474 if ((music == 0) && (sfx == 0)) |
422 if((music==0) && (sfx==0)) return 0; | 475 return 0; |
423 | 476 |
424 _mm_critical = 1; | 477 _mm_critical = 1; |
425 | 478 |
426 if(isplaying) | 479 if (isplaying) { |
427 { MikMod_DisableOutput(); | 480 MikMod_DisableOutput(); |
428 oldchn = md_numchn; | 481 oldchn = md_numchn; |
429 resume = 1; | 482 resume = 1; |
430 } | 483 } |
431 | 484 if (sfxinfo != NULL) |
432 if(sfxinfo!=NULL) free(sfxinfo); | 485 free(sfxinfo); |
433 if(md_sample!=NULL) free(md_sample); | 486 if (md_sample != NULL) |
434 md_sample = NULL; | 487 free(md_sample); |
435 sfxinfo = NULL; | 488 md_sample = NULL; |
436 | 489 sfxinfo = NULL; |
437 /*md_softchn = md_hardchn = 0; | 490 |
438 | 491 /* |
439 if(md_mode & DMODE_SOFT_SNDFX) | 492 * md_softchn = md_hardchn = 0; |
440 md_softchn = sfx; else md_hardchn = sfx; | 493 * |
441 | 494 * if(md_mode & DMODE_SOFT_SNDFX) md_softchn = sfx; else md_hardchn = sfx; |
442 if(md_mode & DMODE_SOFT_MUSIC) | 495 * |
443 md_softchn += music; else md_hardchn += music; | 496 * if(md_mode & DMODE_SOFT_MUSIC) md_softchn += music; else md_hardchn += |
444 */ | 497 * music; |
445 | 498 */ |
446 if(music != -1) md_sngchn = music; | 499 |
447 if(sfx != -1) md_sfxchn = sfx; | 500 if (music != -1) |
501 md_sngchn = music; | |
502 if (sfx != -1) | |
503 md_sfxchn = sfx; | |
448 | 504 |
449 md_numchn = md_sngchn + md_sfxchn; | 505 md_numchn = md_sngchn + md_sfxchn; |
450 | 506 |
451 LimitHardVoices(md_driver->HardVoiceLimit); | 507 LimitHardVoices(md_driver->HardVoiceLimit); |
452 LimitSoftVoices(md_driver->SoftVoiceLimit); | 508 LimitSoftVoices(md_driver->SoftVoiceLimit); |
453 | 509 |
454 if(md_driver->SetNumVoices()) | 510 if (md_driver->SetNumVoices()) { |
455 { MikMod_Exit(); | 511 MikMod_Exit(); |
456 md_numchn = md_softchn = md_hardchn = md_sfxchn = md_sngchn = 0; | 512 md_numchn = md_softchn = md_hardchn = md_sfxchn = md_sngchn = 0; |
457 if(_mm_errorhandler!=NULL) _mm_errorhandler(); | 513 if (_mm_errorhandler != NULL) |
458 return 1; | 514 _mm_errorhandler(); |
459 } | 515 return 1; |
460 | 516 } |
461 if(md_sngchn || md_sfxchn) | 517 if (md_sngchn || md_sfxchn) |
462 md_sample = (SAMPLE **)_mm_calloc(md_sngchn+md_sfxchn, sizeof(SAMPLE *)); | 518 md_sample = (SAMPLE **) _mm_calloc(md_sngchn + md_sfxchn, sizeof(SAMPLE *)); |
463 if(md_sfxchn) | 519 if (md_sfxchn) |
464 sfxinfo = (UBYTE *)_mm_calloc(md_sfxchn, sizeof(UBYTE)); | 520 sfxinfo = (UBYTE *) _mm_calloc(md_sfxchn, sizeof(UBYTE)); |
465 | 521 |
466 // make sure the player doesn't start with garbage | 522 /* make sure the player doesn't start with garbage */ |
467 for(t=oldchn; t<md_numchn; t++) Voice_Stop(t); | 523 for (t = oldchn; t < md_numchn; t++) |
524 Voice_Stop(t); | |
468 | 525 |
469 sfxpool = 0; | 526 sfxpool = 0; |
470 | 527 |
471 if(resume) MikMod_EnableOutput(); | 528 if (resume) |
529 MikMod_EnableOutput(); | |
472 _mm_critical = 0; | 530 _mm_critical = 0; |
473 | 531 |
474 return 0; | 532 return 0; |
475 } | 533 } |
476 | 534 |
477 | 535 |
478 BOOL MikMod_EnableOutput(void) | 536 BOOL |
479 { | 537 MikMod_EnableOutput(void) |
480 // safety valve, prevents entering | 538 { |
481 // playstart twice: | 539 /* |
482 | 540 * safety valve, prevents entering playstart twice: |
541 */ | |
483 _mm_critical = 1; | 542 _mm_critical = 1; |
484 if(!isplaying) | 543 if (!isplaying) { |
485 { if(md_driver->PlayStart()) return 1; | 544 if (md_driver->PlayStart()) |
486 isplaying = 1; | 545 return 1; |
546 isplaying = 1; | |
487 } | 547 } |
488 _mm_critical = 0; | 548 _mm_critical = 0; |
489 return 0; | 549 return 0; |
490 } | 550 } |
491 | 551 |
492 | 552 |
493 void MikMod_DisableOutput(void) | 553 void |
494 { | 554 MikMod_DisableOutput(void) |
495 // safety valve, prevents calling playStop when playstart | 555 { |
496 // hasn't been called: | 556 /* |
497 | 557 * safety valve, prevents calling playStop when playstart hasn't been |
498 if(isplaying && md_driver!=NULL) | 558 * called: |
499 { isplaying = 0; | 559 */ |
500 md_driver->PlayStop(); | 560 |
501 } | 561 if (isplaying && md_driver != NULL) { |
502 } | 562 isplaying = 0; |
503 | 563 md_driver->PlayStop(); |
504 | 564 } |
505 BOOL MikMod_Active(void) | 565 } |
566 | |
567 | |
568 BOOL | |
569 MikMod_Active(void) | |
506 { | 570 { |
507 return isplaying; | 571 return isplaying; |
508 } | 572 } |
509 | 573 |
510 | 574 |
511 int MikMod_PlaySample(SAMPLE *s, ULONG start, UBYTE flags) | 575 /* |
512 | 576 * Plays a sound effects sample. Picks a voice from the number of voices |
513 // Plays a sound effects sample. Picks a voice from the number of voices | 577 * allocated for use as sound effects (loops through voices, skipping all |
514 // allocated for use as sound effects (loops through voices, skipping all | 578 * active criticals). |
515 // active criticals). | 579 * |
516 // | 580 * Returns the voice that the sound is being played on. |
517 // Returns the voice that the sound is being played on. | 581 */ |
518 | 582 int |
519 { | 583 MikMod_PlaySample(SAMPLE * s, ULONG start, UBYTE flags) |
520 int orig = sfxpool; // for cases where all channels are critical | 584 { |
521 int c; | 585 int orig = sfxpool; /* for cases where all channels are |
522 | 586 * critical */ |
523 if(md_sfxchn==0) return -1; | 587 int c; |
524 if(s->volume > 64) s->volume = 64; | 588 |
525 | 589 if (md_sfxchn == 0) |
526 // check the first location after sfxpool | 590 return -1; |
527 do | 591 if (s->volume > 64) |
528 { if(sfxinfo[sfxpool] & SFX_CRITICAL) | 592 s->volume = 64; |
529 { if(md_driver->VoiceStopped(c=sfxpool+md_sngchn)) | 593 |
530 { sfxinfo[sfxpool] = flags; | 594 /* check the first location after sfxpool */ |
531 Voice_Play(c, s, start); | 595 do { |
532 md_driver->VoiceSetVolume(c,s->volume<<2); | 596 if (sfxinfo[sfxpool] & SFX_CRITICAL) { |
533 md_driver->VoiceSetPanning(c,s->panning); | 597 if (md_driver->VoiceStopped(c = sfxpool + md_sngchn)) { |
534 md_driver->VoiceSetFrequency(c,s->speed); | 598 sfxinfo[sfxpool] = flags; |
535 sfxpool++; | 599 Voice_Play(c, s, start); |
536 if(sfxpool >= md_sfxchn) sfxpool = 0; | 600 md_driver->VoiceSetVolume(c, s->volume << 2); |
537 return c; | 601 md_driver->VoiceSetPanning(c, s->panning); |
538 } | 602 md_driver->VoiceSetFrequency(c, s->speed); |
539 } else | 603 sfxpool++; |
540 { sfxinfo[sfxpool] = flags; | 604 if (sfxpool >= md_sfxchn) |
541 Voice_Play(c=sfxpool+md_sngchn, s, start); | 605 sfxpool = 0; |
542 md_driver->VoiceSetVolume(c,s->volume<<2); | 606 return c; |
543 md_driver->VoiceSetPanning(c,s->panning); | 607 } |
544 md_driver->VoiceSetFrequency(c,s->speed); | 608 } else { |
545 sfxpool++; | 609 sfxinfo[sfxpool] = flags; |
546 if(sfxpool >= md_sfxchn) sfxpool = 0; | 610 Voice_Play(c = sfxpool + md_sngchn, s, start); |
547 return c; | 611 md_driver->VoiceSetVolume(c, s->volume << 2); |
548 } | 612 md_driver->VoiceSetPanning(c, s->panning); |
549 | 613 md_driver->VoiceSetFrequency(c, s->speed); |
550 sfxpool++; | 614 sfxpool++; |
551 if(sfxpool >= md_sfxchn) sfxpool = 0; | 615 if (sfxpool >= md_sfxchn) |
552 } while(sfxpool!=orig); | 616 sfxpool = 0; |
617 return c; | |
618 } | |
619 | |
620 sfxpool++; | |
621 if (sfxpool >= md_sfxchn) | |
622 sfxpool = 0; | |
623 } while (sfxpool != orig); | |
553 | 624 |
554 return -1; | 625 return -1; |
555 } | 626 } |
556 |