Rev 333 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
342 | serge | 1 | // Emacs style mode select -*- C++ -*- |
2 | //----------------------------------------------------------------------------- |
||
3 | // |
||
4 | // $Id:$ |
||
5 | // |
||
6 | // Copyright (C) 1993-1996 by id Software, Inc. |
||
7 | // |
||
8 | // This source is available for distribution and/or modification |
||
9 | // only under the terms of the DOOM Source Code License as |
||
10 | // published by id Software. All rights reserved. |
||
11 | // |
||
12 | // The source is distributed in the hope that it will be useful, |
||
13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License |
||
15 | // for more details. |
||
16 | // |
||
17 | // $Log:$ |
||
18 | // |
||
19 | // DESCRIPTION: |
||
20 | // System interface for sound. |
||
21 | // |
||
22 | //----------------------------------------------------------------------------- |
||
23 | |||
24 | static const char |
||
25 | rcsid[] = "$Id: i_unix.c,v 1.5 1997/02/03 22:45:10 b1 Exp $"; |
||
26 | |||
27 | #include |
||
28 | #include |
||
29 | #include |
||
30 | |||
31 | #include |
||
32 | |||
33 | #include |
||
34 | |||
35 | #include |
||
36 | |||
37 | // Timer stuff. Experimental. |
||
38 | #include |
||
39 | #include |
||
40 | |||
41 | #include "z_zone.h" |
||
42 | |||
43 | #include "i_system.h" |
||
44 | #include "i_sound.h" |
||
45 | #include "m_argv.h" |
||
46 | #include "m_misc.h" |
||
47 | #include "w_wad.h" |
||
48 | |||
49 | #include "doomdef.h" |
||
50 | |||
51 | #include "kolibri.h" |
||
52 | |||
53 | // The number of internal mixing channels, |
||
54 | // the samples calculated for each mixing step, |
||
55 | // the size of the 16bit, 2 hardware channel (stereo) |
||
56 | // mixing buffer, and the samplerate of the raw data. |
||
57 | |||
58 | |||
59 | // Needed for calling the actual sound output. |
||
60 | #define SAMPLECOUNT 8192 |
||
61 | #define NUM_CHANNELS 16 |
||
62 | // It is 2 for 16bit, and 2 for two channels. |
||
63 | #define BUFMUL 4 |
||
64 | #define MIXBUFFERSIZE (SAMPLECOUNT*BUFMUL) |
||
65 | |||
66 | #define SAMPLERATE 11025 // Hz |
||
67 | #define SAMPLESIZE 2 // 16bit |
||
68 | |||
69 | // The actual lengths of all sound effects. |
||
70 | int lengths[NUMSFX]; |
||
71 | |||
72 | // The actual output device. |
||
73 | int audio_fd; |
||
74 | |||
75 | // The global mixing buffer. |
||
76 | // Basically, samples from all active internal channels |
||
77 | // are modifed and added, and stored in the buffer |
||
78 | // that is submitted to the audio device. |
||
79 | signed short mixbuffer[MIXBUFFERSIZE]; |
||
80 | |||
81 | |||
82 | // The channel step amount... |
||
83 | unsigned int channelstep[NUM_CHANNELS]; |
||
84 | // ... and a 0.16 bit remainder of last step. |
||
85 | unsigned int channelstepremainder[NUM_CHANNELS]; |
||
86 | |||
87 | |||
88 | // The channel data pointers, start and end. |
||
89 | unsigned char* channels[NUM_CHANNELS]; |
||
90 | unsigned char* channelsend[NUM_CHANNELS]; |
||
91 | |||
92 | |||
93 | // Time/gametic that the channel started playing, |
||
94 | // used to determine oldest, which automatically |
||
95 | // has lowest priority. |
||
96 | // In case number of active sounds exceeds |
||
97 | // available channels. |
||
98 | int channelstart[NUM_CHANNELS]; |
||
99 | |||
100 | // The sound in channel handles, |
||
101 | // determined on registration, |
||
102 | // might be used to unregister/stop/modify, |
||
103 | // currently unused. |
||
104 | int channelhandles[NUM_CHANNELS]; |
||
105 | |||
106 | // SFX id of the playing sound effect. |
||
107 | // Used to catch duplicates (like chainsaw). |
||
108 | int channelids[NUM_CHANNELS]; |
||
109 | |||
110 | // Pitch to stepping lookup, unused. |
||
111 | int steptable[256]; |
||
112 | |||
113 | // Volume lookups. |
||
114 | int vol_lookup[128*256]; |
||
115 | |||
116 | // Hardware left and right channel volume lookup. |
||
117 | int* channelleftvol_lookup[NUM_CHANNELS]; |
||
118 | int* channelrightvol_lookup[NUM_CHANNELS]; |
||
119 | |||
120 | |||
121 | // |
||
122 | // This function loads the sound data from the WAD lump, |
||
123 | // for single sound. |
||
124 | // |
||
125 | void* getsfx (char* sfxname, int* len) |
||
126 | { |
||
127 | unsigned char* sfx; |
||
128 | unsigned char* paddedsfx; |
||
129 | int i; |
||
130 | int size; |
||
131 | int paddedsize; |
||
132 | char name[20]; |
||
133 | int sfxlump; |
||
134 | |||
135 | |||
136 | // Get the sound data from the WAD, allocate lump |
||
137 | // in zone memory. |
||
138 | sprintf(name, "ds%s", sfxname); |
||
139 | |||
140 | // Now, there is a severe problem with the |
||
141 | // sound handling, in it is not (yet/anymore) |
||
142 | // gamemode aware. That means, sounds from |
||
143 | // DOOM II will be requested even with DOOM |
||
144 | // shareware. |
||
145 | // The sound list is wired into sounds.c, |
||
146 | // which sets the external variable. |
||
147 | // I do not do runtime patches to that |
||
148 | // variable. Instead, we will use a |
||
149 | // default sound for replacement. |
||
150 | if ( W_CheckNumForName(name) == -1 ) |
||
151 | sfxlump = W_GetNumForName("dspistol"); |
||
152 | else |
||
153 | sfxlump = W_GetNumForName(name); |
||
154 | |||
155 | size = W_LumpLength( sfxlump ); |
||
156 | |||
157 | // Debug. |
||
158 | // fprintf( stderr, "." ); |
||
159 | //fprintf( stderr, " -loading %s (lump %d, %d bytes)\n", |
||
160 | // sfxname, sfxlump, size ); |
||
161 | //fflush( stderr ); |
||
162 | |||
163 | sfx = (unsigned char*)W_CacheLumpNum( sfxlump, PU_STATIC ); |
||
164 | |||
165 | // Pads the sound effect out to the mixing buffer size. |
||
166 | // The original realloc would interfere with zone memory. |
||
167 | paddedsize = ((size-8 + (SAMPLECOUNT-1)) / SAMPLECOUNT) * SAMPLECOUNT; |
||
168 | |||
169 | // Allocate from zone memory. |
||
170 | paddedsfx = (unsigned char*)Z_Malloc( paddedsize+8, PU_STATIC, 0 ); |
||
171 | // ddt: (unsigned char *) realloc(sfx, paddedsize+8); |
||
172 | // This should interfere with zone memory handling, |
||
173 | // which does not kick in in the soundserver. |
||
174 | |||
175 | // Now copy and pad. |
||
176 | memcpy( paddedsfx, sfx, size ); |
||
177 | for (i=size ; i |
||
178 | paddedsfx[i] = 128; |
||
179 | |||
180 | // Remove the cached lump. |
||
181 | Z_Free( sfx ); |
||
182 | |||
183 | // Preserve padded length. |
||
184 | *len = paddedsize; |
||
185 | |||
186 | // Return allocated padded data. |
||
187 | return (void *) (paddedsfx + 8); |
||
188 | } |
||
189 | |||
190 | // |
||
191 | // This function adds a sound to the |
||
192 | // list of currently active sounds, |
||
193 | // which is maintained as a given number |
||
194 | // (eight, usually) of internal channels. |
||
195 | // Returns a handle. |
||
196 | // |
||
197 | |||
198 | static unsigned short handlenums = 0; |
||
199 | |||
200 | int addsfx(int sfxid, int volume, int step, int seperation) |
||
201 | { |
||
202 | |||
203 | int i; |
||
204 | int rc = -1; |
||
205 | |||
206 | int oldest = gametic; |
||
207 | int oldestnum = 0; |
||
208 | int slot; |
||
209 | |||
210 | int rightvol; |
||
211 | int leftvol; |
||
212 | |||
213 | // Chainsaw troubles. |
||
214 | // Play these sound effects only one at a time. |
||
215 | if ( sfxid == sfx_sawup |
||
216 | || sfxid == sfx_sawidl |
||
217 | || sfxid == sfx_sawful |
||
218 | || sfxid == sfx_sawhit |
||
219 | || sfxid == sfx_stnmov |
||
220 | || sfxid == sfx_pistol ) |
||
221 | { |
||
222 | // Loop all channels, check. |
||
223 | for (i=0 ; i |
||
224 | { |
||
225 | // Active, and using the same SFX? |
||
226 | if ( (channels[i]) |
||
227 | && (channelids[i] == sfxid) ) |
||
228 | { |
||
229 | // Reset. |
||
230 | channels[i] = 0; |
||
231 | // We are sure that iff, |
||
232 | // there will only be one. |
||
233 | break; |
||
234 | } |
||
235 | } |
||
236 | } |
||
237 | |||
238 | // Loop all channels to find oldest SFX. |
||
239 | for (i=0; (i |
||
240 | { |
||
241 | if (channelstart[i] < oldest) |
||
242 | { |
||
243 | oldestnum = i; |
||
244 | oldest = channelstart[i]; |
||
245 | } |
||
246 | } |
||
247 | |||
248 | // Tales from the cryptic. |
||
249 | // If we found a channel, fine. |
||
250 | // If not, we simply overwrite the first one, 0. |
||
251 | // Probably only happens at startup. |
||
252 | if (i == NUM_CHANNELS) |
||
253 | slot = oldestnum; |
||
254 | else |
||
255 | slot = i; |
||
256 | |||
257 | // Okay, in the less recent channel, |
||
258 | // we will handle the new SFX. |
||
259 | // Set pointer to raw data. |
||
260 | channels[slot] = (unsigned char *) S_sfx[sfxid].data; |
||
261 | // Set pointer to end of raw data. |
||
262 | channelsend[slot] = channels[slot] + lengths[sfxid]; |
||
263 | |||
264 | // Reset current handle number, limited to 0..100. |
||
265 | if (!handlenums) |
||
266 | handlenums = 100; |
||
267 | |||
268 | // Assign current handle number. |
||
269 | // Preserved so sounds could be stopped (unused). |
||
270 | channelhandles[slot] = rc = handlenums++; |
||
271 | |||
272 | channelstep[slot] = step; |
||
273 | |||
274 | channelstepremainder[slot] = 0; |
||
275 | // Should be gametic, I presume. |
||
276 | channelstart[slot] = gametic; |
||
277 | |||
278 | // Separation, that is, orientation/stereo. |
||
279 | // range is: 1 - 256 |
||
280 | seperation += 1; |
||
281 | |||
282 | volume *=7; |
||
283 | // Per left/right channel. |
||
284 | // x^2 seperation, |
||
285 | // adjust volume properly. |
||
286 | leftvol = |
||
287 | volume - ((volume*seperation*seperation) >> 16); ///(256*256); |
||
288 | seperation = seperation - 257; |
||
289 | rightvol = |
||
290 | volume - ((volume*seperation*seperation) >> 16); |
||
291 | |||
292 | // Sanity check, clamp volume. |
||
293 | if (rightvol < 0 || rightvol > 127) |
||
294 | I_Error("rightvol out of bounds"); |
||
295 | |||
296 | if (leftvol < 0 || leftvol > 127) |
||
297 | I_Error("leftvol out of bounds"); |
||
298 | |||
299 | // Get the proper lookup table piece |
||
300 | // for this volume level??? |
||
301 | channelleftvol_lookup[slot] = &vol_lookup[leftvol*256]; |
||
302 | channelrightvol_lookup[slot] = &vol_lookup[rightvol*256]; |
||
303 | |||
304 | // Preserve sound SFX id, |
||
305 | // e.g. for avoiding duplicates of chainsaw. |
||
306 | channelids[slot] = sfxid; |
||
307 | |||
308 | // You tell me. |
||
309 | return rc; |
||
310 | } |
||
311 | |||
312 | // |
||
313 | // SFX API |
||
314 | // Note: this was called by S_Init. |
||
315 | // However, whatever they did in the |
||
316 | // old DPMS based DOS version, this |
||
317 | // were simply dummies in the Linux |
||
318 | // version. |
||
319 | // See soundserver initdata(). |
||
320 | // |
||
321 | void I_SetChannels() |
||
322 | { |
||
323 | // Init internal lookups (raw data, mixing buffer, channels). |
||
324 | // This function sets up internal lookups used during |
||
325 | // the mixing process. |
||
326 | int i; |
||
327 | int j; |
||
328 | |||
329 | int* steptablemid = steptable + 128; |
||
330 | |||
331 | // Okay, reset internal mixing channels to zero. |
||
332 | for (i=0; i |
||
333 | { |
||
334 | channels[i] = 0; |
||
335 | } |
||
336 | |||
337 | for (i=-128 ; i<128 ; i++) |
||
338 | steptablemid[i] = (int)(pow(2.0, (i/64.0))*65536.0); |
||
339 | |||
340 | // Generates volume lookup tables |
||
341 | // which also turn the unsigned samples |
||
342 | // into signed samples. |
||
343 | for (i=0 ; i<128 ; i++) |
||
344 | for (j=0 ; j<256 ; j++) |
||
345 | vol_lookup[i*256+j] = (i*(j-128)*256)/127; |
||
346 | } |
||
347 | |||
348 | |||
349 | void I_SetSfxVolume(int volume) |
||
350 | { |
||
351 | // Identical to DOS. |
||
352 | // Basically, this should propagate |
||
353 | // the menu/config file setting |
||
354 | // to the state variable used in |
||
355 | // the mixing. |
||
356 | snd_SfxVolume = volume; |
||
357 | } |
||
358 | |||
359 | // MUSIC API - dummy. Some code from DOS version. |
||
360 | void I_SetMusicVolume(int volume) |
||
361 | { |
||
362 | // Internal state variable. |
||
363 | snd_MusicVolume = volume; |
||
364 | } |
||
365 | |||
366 | |||
367 | // |
||
368 | // Retrieve the raw data lump index |
||
369 | // for a given SFX name. |
||
370 | // |
||
371 | int I_GetSfxLumpNum(sfxinfo_t* sfx) |
||
372 | { |
||
373 | char namebuf[9]; |
||
374 | sprintf(namebuf, "ds%s", sfx->name); |
||
375 | return W_GetNumForName(namebuf); |
||
376 | } |
||
377 | |||
378 | // |
||
379 | // Starting a sound means adding it |
||
380 | // to the current list of active sounds |
||
381 | // in the internal channels. |
||
382 | // As the SFX info struct contains |
||
383 | // e.g. a pointer to the raw data, |
||
384 | // it is ignored. |
||
385 | // As our sound handling does not handle |
||
386 | // priority, it is ignored. |
||
387 | // Pitching (that is, increased speed of playback) |
||
388 | // |
||
389 | int I_StartSound(int id, int vol, int sep, |
||
390 | int pitch, int priority ) |
||
391 | { |
||
392 | // Returns a handle (not used). |
||
393 | id = addsfx( id, vol, steptable[pitch], sep ); |
||
394 | return id; |
||
395 | } |
||
396 | |||
397 | void I_StopSound (int handle) |
||
398 | { |
||
399 | // You need the handle returned by StartSound. |
||
400 | // Would be looping all channels, |
||
401 | // tracking down the handle, |
||
402 | // an setting the channel to zero. |
||
403 | |||
404 | // UNUSED. |
||
405 | handle = 0; |
||
406 | } |
||
407 | |||
408 | |||
409 | int I_SoundIsPlaying(int handle) |
||
410 | { |
||
411 | // Ouch. |
||
412 | return gametic < handle; |
||
413 | } |
||
414 | |||
415 | // |
||
416 | // This function loops all active (internal) sound |
||
417 | // channels, retrieves a given number of samples |
||
418 | // from the raw sound data, modifies it according |
||
419 | // to the current (internal) channel parameters, |
||
420 | // mixes the per channel samples into the global |
||
421 | // mixbuffer, clamping it to the allowed range, |
||
422 | // and sets up everything for transferring the |
||
423 | // contents of the mixbuffer to the (two) |
||
424 | // hardware channels (left and right, that is). |
||
425 | // |
||
426 | // This function currently supports only 16bit. |
||
427 | // |
||
428 | |||
429 | extern DWORD hMixBuff[4]; |
||
430 | extern int mix_ptr; |
||
431 | |||
432 | void I_UpdateSound( void ) |
||
433 | { |
||
434 | |||
435 | // Mix current sound data. |
||
436 | // Data, from raw sound, for right and left. |
||
437 | register unsigned int sample; |
||
438 | register int dl; |
||
439 | register int dr; |
||
440 | |||
441 | // Pointers in global mixbuffer, left, right, end. |
||
442 | signed short* leftout; |
||
443 | signed short* rightout; |
||
444 | signed short* leftend; |
||
445 | // Step in mixbuffer, left and right, thus two. |
||
446 | int step; |
||
447 | |||
448 | // Mixing channel index. |
||
449 | int chan; |
||
450 | int i; |
||
451 | int flags; |
||
452 | flags = 0; |
||
453 | |||
454 | // Left and right channel |
||
455 | // are in global mixbuffer, alternating. |
||
456 | leftout = mixbuffer; |
||
457 | rightout = mixbuffer+1; |
||
458 | step = 2; |
||
459 | |||
460 | // Determine end, for left channel only |
||
461 | // (right channel is implicit). |
||
462 | leftend = mixbuffer + SAMPLECOUNT*step; |
||
463 | |||
464 | // Mix sounds into the mixing buffer. |
||
465 | // Loop over step*SAMPLECOUNT, |
||
466 | // that is 512 values for two channels. |
||
467 | for (i=0; i < 8192; i++) |
||
468 | { |
||
469 | // Reset left/right value. |
||
470 | dl = 0; |
||
471 | dr = 0; |
||
472 | |||
473 | // Love thy L2 chache - made this a loop. |
||
474 | // Now more channels could be set at compile time |
||
475 | // as well. Thus loop those channels. |
||
476 | for ( chan = 0; chan < NUM_CHANNELS; chan++ ) |
||
477 | { |
||
478 | // Check channel, if active. |
||
479 | if (channels[ chan ]) |
||
480 | { |
||
481 | flags=1; |
||
482 | |||
483 | // Get the raw data from the channel. |
||
484 | sample = *channels[ chan ]; |
||
485 | // Add left and right part |
||
486 | // for this channel (sound) |
||
487 | // to the current data. |
||
488 | // Adjust volume accordingly. |
||
489 | dl += channelleftvol_lookup[ chan ][sample]; |
||
490 | dr += channelrightvol_lookup[ chan ][sample]; |
||
491 | |||
492 | channelstepremainder[ chan ] += channelstep[ chan ]; |
||
493 | |||
494 | channels[ chan ] += channelstepremainder[ chan ] >> 16; |
||
495 | |||
496 | channelstepremainder[ chan ] &= 65536-1; |
||
497 | |||
498 | // Check whether we are done. |
||
499 | if (channels[ chan ] >= channelsend[ chan ]) |
||
500 | channels[ chan ] = 0; |
||
501 | } |
||
502 | } |
||
503 | |||
504 | // Clamp to range. Left hardware channel. |
||
505 | // Has been char instead of short. |
||
506 | // if (dl > 127) *leftout = 127; |
||
507 | // else if (dl < -128) *leftout = -128; |
||
508 | // else *leftout = dl; |
||
509 | |||
510 | if (dl > 0x7fff) |
||
511 | *leftout = 0x7fff; |
||
512 | else if (dl < -0x8000) |
||
513 | *leftout = -0x8000; |
||
514 | else |
||
515 | *leftout = dl; |
||
516 | |||
517 | // Same for right hardware channel. |
||
518 | if (dr > 0x7fff) |
||
519 | *rightout = 0x7fff; |
||
520 | else if (dr < -0x8000) |
||
521 | *rightout = -0x8000; |
||
522 | else |
||
523 | *rightout = dr; |
||
524 | |||
525 | // Increment current pointers in mixbuffer. |
||
526 | leftout += step; |
||
527 | rightout += step; |
||
528 | } |
||
529 | if(flags) |
||
530 | { WaveOut(hMixBuff[mix_ptr],(char*)&mixbuffer[0],32768); |
||
531 | mix_ptr= (mix_ptr+1)&3; |
||
532 | }; |
||
533 | } |
||
534 | |||
535 | |||
536 | // |
||
537 | // This would be used to write out the mixbuffer |
||
538 | // during each game loop update. |
||
539 | // Updates sound buffer and audio device at runtime. |
||
540 | // It is called during Timer interrupt with SNDINTR. |
||
541 | // Mixing now done synchronous, and |
||
542 | // only output be done asynchronous? |
||
543 | // |
||
544 | //void I_SubmitSound(void) |
||
545 | //{ |
||
546 | // Write it to DSP device. |
||
547 | // write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL); |
||
548 | //} |
||
549 | |||
550 | |||
551 | void I_UpdateSoundParams(int handle, int vol, int sep, int pitch) |
||
552 | { |
||
553 | // I fail too see that this is used. |
||
554 | // Would be using the handle to identify |
||
555 | // on which channel the sound might be active, |
||
556 | // and resetting the channel parameters. |
||
557 | |||
558 | // UNUSED. |
||
559 | handle = vol = sep = pitch = 0; |
||
560 | } |
||
561 | |||
562 | void I_ShutdownSound(void) |
||
563 | { |
||
564 | // Wait till all pending sounds are finished. |
||
565 | int done = 0; |
||
566 | int i; |
||
567 | |||
568 | // FIXME (below). |
||
569 | printf( "I_ShutdownSound: NOT finishing pending sounds\n"); |
||
570 | |||
571 | while ( !done ) |
||
572 | { |
||
573 | for( i=0 ; i<8 && !channels[i] ; i++); |
||
574 | |||
575 | // FIXME. No proper channel output. |
||
576 | //if (i==8) |
||
577 | done=1; |
||
578 | } |
||
579 | return; |
||
580 | } |
||
581 | |||
582 | void I_InitSound() |
||
583 | { int i; |
||
584 | |||
585 | printf("I_InitSound: "); |
||
586 | |||
587 | for (i=1 ; i |
||
588 | { |
||
589 | // Alias? Example is the chaingun sound linked to pistol. |
||
590 | if (!S_sfx[i].link) |
||
591 | { |
||
592 | // Load data from WAD file. |
||
593 | S_sfx[i].data = getsfx( S_sfx[i].name, &lengths[i] ); |
||
594 | } |
||
595 | else |
||
596 | { |
||
597 | // Previously loaded already? |
||
598 | S_sfx[i].data = S_sfx[i].link->data; |
||
599 | lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(sfxinfo_t)]; |
||
600 | } |
||
601 | } |
||
602 | |||
603 | printf( " pre-cached all sound data\n"); |
||
604 | |||
605 | // Now initialize mixbuffer with zero. |
||
606 | for ( i = 0; i< MIXBUFFERSIZE; i++ ) |
||
607 | mixbuffer[i] = 0; |
||
608 | |||
609 | // Finished initialization. |
||
610 | printf("I_InitSound: sound module ready\n"); |
||
611 | |||
612 | } |
||
613 | |||
614 | |||
615 | // |
||
616 | // MUSIC API. |
||
617 | // Still no music done. |
||
618 | // Remains. Dummies. |
||
619 | // |
||
620 | void I_InitMusic(void) { } |
||
621 | void I_ShutdownMusic(void) { } |
||
622 | |||
623 | static int looping=0; |
||
624 | static int musicdies=-1; |
||
625 | |||
626 | void I_PlaySong(int handle, int looping) |
||
627 | { |
||
628 | // UNUSED. |
||
629 | handle = looping = 0; |
||
630 | musicdies = gametic + TICRATE*30; |
||
631 | } |
||
632 | |||
633 | void I_PauseSong (int handle) |
||
634 | { |
||
635 | // UNUSED. |
||
636 | handle = 0; |
||
637 | } |
||
638 | |||
639 | void I_ResumeSong (int handle) |
||
640 | { |
||
641 | // UNUSED. |
||
642 | handle = 0; |
||
643 | } |
||
644 | |||
645 | void I_StopSong(int handle) |
||
646 | { |
||
647 | // UNUSED. |
||
648 | handle = 0; |
||
649 | |||
650 | looping = 0; |
||
651 | musicdies = 0; |
||
652 | } |
||
653 | |||
654 | void I_UnRegisterSong(int handle) |
||
655 | { |
||
656 | // UNUSED. |
||
657 | handle = 0; |
||
658 | } |
||
659 | |||
660 | int I_RegisterSong(void* data) |
||
661 | { |
||
662 | // UNUSED. |
||
663 | data = NULL; |
||
664 | |||
665 | return 1; |
||
666 | } |
||
667 | |||
668 | // Is the song playing? |
||
669 | int I_QrySongPlaying(int handle) |
||
670 | { |
||
671 | // UNUSED. |
||
672 | handle = 0; |
||
673 | return looping || musicdies > gametic; |
||
674 | } |
||
675 | |||
676 | |||
677 | // Interrupt handler. |
||
678 | void I_HandleSoundTimer( int ignore ) |
||
679 | { |
||
680 | |||
681 | // UNUSED, but required. |
||
682 | ignore = 0; |
||
683 | return; |
||
684 | }>8>>>>>>>256>128>128>>>> |
||
685 |