1 // SDL digital audio support
14 #include "gr.h" // needed for piggy.h
22 int digi_sample_rate=11025;
23 int digi_timer_rate = 9943; // rate for the timer to go off to handle the driver system (120 Hz)
25 //edited 05/17/99 Matt Mueller - added ifndef NO_ASM
26 //added on 980905 by adb to add inline fixmul for mixer on i386
29 #define do_fixmul(x,y) \
32 asm("imull %2\n\tshrdl %3,%1,%0" \
33 : "=a"(_ax), "=d"(_dx) \
34 : "rm"(y), "i"(16), "0"(x)); \
37 extern inline fix fixmul(fix x, fix y) { return do_fixmul(x,y); }
43 //changed on 980905 by adb to increase number of concurrent sounds
44 #define MAX_SOUND_SLOTS 32
46 #define SOUND_BUFFER_SIZE 512
50 /* This table is used to add two sound values together and pin
51 * the value to avoid overflow. (used with permission from ARDI)
52 * DPH: Taken from SDL/src/SDL_mixer.c.
54 static const unsigned char mix8[] =
56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
68 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
69 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
70 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
71 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
72 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
73 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
74 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
75 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B,
76 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
77 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
78 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
79 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
80 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92,
81 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D,
82 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
83 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3,
84 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
85 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
86 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4,
87 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
88 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
89 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
90 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF,
91 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
92 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
93 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
94 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
95 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
96 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
97 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
98 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
99 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
100 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
101 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
102 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
105 #define SOF_USED 1 // Set if this sample is used
106 #define SOF_PLAYING 2 // Set if this sample is playing on a channel
107 #define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits.
108 #define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos
109 #define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once
111 typedef struct sound_object {
112 short signature; // A unique signature to this sound
113 ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long.
114 fix max_volume; // Max volume that this sound is playing at
115 fix max_distance; // The max distance that this sound can be heard at...
116 int volume; // Volume that this sound is playing at
117 int pan; // Pan value that this sound is playing at
118 int handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set.
119 short soundnum; // The sound number that is playing
122 short segnum; // Used if SOF_LINK_TO_POS field is used
127 short objnum; // Used if SOF_LINK_TO_OBJ field is used
132 #define lp_segnum link.pos.segnum
133 #define lp_sidenum link.pos.sidenum
134 #define lp_position link.pos.position
136 #define lo_objnum link.obj.objnum
137 #define lo_objsignature link.obj.objsignature
139 #define MAX_SOUND_OBJECTS 16
140 sound_object SoundObjects[MAX_SOUND_OBJECTS];
141 short next_signature=0;
143 //added/changed on 980905 by adb to make sfx volume work, on 990221 by adb changed F1_0 to F1_0 / 2
144 #define SOUND_MAX_VOLUME (F1_0 / 2)
146 int digi_volume = SOUND_MAX_VOLUME;
151 static int digi_initialised = 0;
155 int playing; // Is there a sample playing on this channel?
156 int looped; // Play this sample looped?
157 fix pan; // 0 = far left, 1 = far right
158 fix volume; // 0 = nothing, 1 = fully on
159 //changed on 980905 by adb from char * to unsigned char *
160 unsigned char *samples;
162 unsigned int length; // Length of the sample
163 unsigned int position; // Position we are at at the moment.
164 } SoundSlots[MAX_SOUND_SLOTS];
166 static int digi_sounds_initialized = 0;
168 //added on 980905 by adb to add rotating/volume based sound kill system
169 static int digi_max_channels = 16;
170 static int next_handle = 0;
171 int SampleHandles[32];
172 void reset_sounds_on_channel(int channel);
175 void digi_reset_digi_sounds(void);
177 /* Audio mixing callback */
178 //changed on 980905 by adb to cleanup, add pan support and optimize mixer
179 static void audio_mixcallback(void *userdata, unsigned char *stream, int len)
181 unsigned char *streamend = stream + len;
182 struct sound_slot *sl;
184 for (sl = SoundSlots; sl < SoundSlots + MAX_SOUND_SLOTS; sl++)
188 unsigned char *sldata = sl->samples + sl->position, *slend = sl->samples + sl->length;
189 unsigned char *sp = stream;
194 if ((x = sl->pan) & 0x8000)
196 vl = 0x20000 - x * 2;
204 vl = fixmul(vl, (x = sl->volume));
206 while (sp < streamend)
215 sldata = sl->samples;
217 v = *(sldata++) - 0x80;
218 *(sp++) = mix8[ *sp + fixmul(v, vl) + 0x80 ];
219 *(sp++) = mix8[ *sp + fixmul(v, vr) + 0x80 ];
221 sl->position = sldata - sl->samples;
227 /* Initialise audio devices. */
235 void digi_reset() { }
237 /* Shut down audio */
240 if (!digi_initialised) return;
241 digi_initialised = 0;
244 /* Find the sound which actually equates to a sound number */
245 int digi_xlat_sound(int soundno)
247 if ( soundno < 0 ) return -1;
250 soundno = AltSounds[soundno];
251 if ( soundno == 255 ) return -1;
253 return Sounds[soundno];
256 static int get_free_slot()
259 for (i=0; i<MAX_SOUND_SLOTS; i++)
261 if (!SoundSlots[i].playing) return i;
266 int digi_start_sound(int soundnum, fix volume, fix pan, int unknown1, int unknown2, int unknown3, int unknown4)
271 if (!digi_initialised) return -1;
273 //added on 980905 by adb from original source to add sound kill system
274 // play at most digi_max_channel samples, if possible kill sample with low volume
278 if ( (SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing) )
280 if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries<digi_max_channels) )
282 //mprintf(( 0, "Not stopping loud sound %d.\n", next_handle ));
284 if ( next_handle >= digi_max_channels )
289 //mprintf(( 0, "[SS:%d]", next_handle ));
290 SoundSlots[SampleHandles[next_handle]].playing = 0;
291 SampleHandles[next_handle] = -1;
295 slot = get_free_slot();
296 if (slot<0) return -1;
298 SoundSlots[slot].soundno = soundnum;
299 SoundSlots[slot].samples = GameSounds[soundnum].data;
300 SoundSlots[slot].length = GameSounds[soundnum].length;
301 SoundSlots[slot].volume = fixmul(digi_volume, volume);
302 SoundSlots[slot].pan = pan;
303 SoundSlots[slot].position = 0;
304 SoundSlots[slot].looped = 0;
305 SoundSlots[slot].playing = 1;
307 //added on 980905 by adb to add sound kill system from original sos digi.c
308 reset_sounds_on_channel(slot);
309 SampleHandles[next_handle] = slot;
311 if ( next_handle >= digi_max_channels )
318 //added on 980905 by adb to add sound kill system from original sos digi.c
319 void reset_sounds_on_channel( int channel )
323 for (i=0; i<digi_max_channels; i++)
324 if (SampleHandles[i] == channel)
325 SampleHandles[i] = -1;
329 int digi_start_sound_object(int obj)
333 if (!digi_initialised) return -1;
334 slot = get_free_slot();
336 if (slot<0) return -1;
339 SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
340 SoundSlots[slot].samples = GameSounds[SoundObjects[obj].soundnum].data;
341 SoundSlots[slot].length = GameSounds[SoundObjects[obj].soundnum].length;
342 SoundSlots[slot].volume = fixmul(digi_volume, SoundObjects[obj].volume);
343 SoundSlots[slot].pan = SoundObjects[obj].pan;
344 SoundSlots[slot].position = 0;
345 SoundSlots[slot].looped = (SoundObjects[obj].flags & SOF_PLAY_FOREVER);
346 SoundSlots[slot].playing = 1;
348 SoundObjects[obj].signature = next_signature++;
349 SoundObjects[obj].handle = slot;
351 SoundObjects[obj].flags |= SOF_PLAYING;
352 //added on 980905 by adb to add sound kill system from original sos digi.c
353 reset_sounds_on_channel(slot);
360 // Play the given sound number.
361 // Volume is max at F1_0.
362 void digi_play_sample( int soundno, fix max_volume )
365 if ( Newdemo_state == ND_STATE_RECORDING )
366 newdemo_record_sound( soundno );
368 soundno = digi_xlat_sound(soundno);
370 if (!digi_initialised) return;
372 if (soundno < 0 ) return;
374 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
377 // Play the given sound number. If the sound is already playing,
379 void digi_play_sample_once( int soundno, fix max_volume )
384 if ( Newdemo_state == ND_STATE_RECORDING )
385 newdemo_record_sound( soundno );
387 soundno = digi_xlat_sound(soundno);
389 if (!digi_initialised) return;
391 if (soundno < 0 ) return;
393 for (i=0; i < MAX_SOUND_SLOTS; i++)
394 if (SoundSlots[i].soundno == soundno)
395 SoundSlots[i].playing = 0;
396 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
400 void digi_play_sample_3d( int soundno, int angle, int volume, int no_dups ) // Volume from 0-0x7fff
405 if ( Newdemo_state == ND_STATE_RECORDING ) {
407 newdemo_record_sound_3d_once( soundno, angle, volume );
409 newdemo_record_sound_3d( soundno, angle, volume );
412 soundno = digi_xlat_sound(soundno);
414 if (!digi_initialised) return;
415 if (soundno < 0 ) return;
417 if (volume < MIN_VOLUME ) return;
418 digi_start_sound(soundno, volume, angle, 0, 0, 0, 0);
421 void digi_get_sound_loc( vms_matrix * listener, vms_vector * listener_pos, int listener_seg, vms_vector * sound_pos, int sound_seg, fix max_volume, int *volume, int *pan, fix max_distance )
423 vms_vector vector_to_sound;
424 fix angle_from_ear, cosang,sinang;
431 max_distance = (max_distance*5)/4; // Make all sounds travel 1.25 times as far.
433 // Warning: Made the vm_vec_normalized_dir be vm_vec_normalized_dir_quick and got illegal values to acos in the fang computation.
434 distance = vm_vec_normalized_dir_quick( &vector_to_sound, sound_pos, listener_pos );
436 if (distance < max_distance ) {
437 int num_search_segs = f2i(max_distance/20);
438 if ( num_search_segs < 1 ) num_search_segs = 1;
440 path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG );
441 if ( path_distance > -1 ) {
442 *volume = max_volume - fixdiv(path_distance,max_distance);
443 //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume ));
445 angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec);
446 fix_sincos(angle_from_ear,&sinang,&cosang);
447 //mprintf( (0, "volume is %.2f\n", f2fl(*volume) ));
448 if (Config_channels_reversed) cosang *= -1;
449 *pan = (cosang + F1_0)/2;
457 int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance )
463 soundnum = digi_xlat_sound(org_soundnum);
465 if ( max_volume < 0 ) return -1;
466 // if ( max_volume > F1_0 ) max_volume = F1_0;
468 if (!digi_initialised) return -1;
469 if (soundnum < 0 ) return -1;
470 if (GameSounds[soundnum].data==NULL) {
474 if ((objnum<0)||(objnum>Highest_object_index))
478 // Hack to keep sounds from building up...
479 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance );
480 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
484 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
485 if (SoundObjects[i].flags==0)
488 if (i==MAX_SOUND_OBJECTS) {
489 mprintf((1, "Too many sound objects!\n" ));
493 SoundObjects[i].signature=next_signature++;
494 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_OBJ;
496 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
497 SoundObjects[i].lo_objnum = objnum;
498 SoundObjects[i].lo_objsignature = Objects[objnum].signature;
499 SoundObjects[i].max_volume = max_volume;
500 SoundObjects[i].max_distance = max_distance;
501 SoundObjects[i].volume = 0;
502 SoundObjects[i].pan = 0;
503 SoundObjects[i].soundnum = soundnum;
505 objp = &Objects[SoundObjects[i].lo_objnum];
506 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
507 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
508 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
510 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
511 digi_start_sound_object(i);
513 return SoundObjects[i].signature;
516 int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume )
517 { return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0); }
519 int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance )
524 soundnum = digi_xlat_sound(org_soundnum);
526 if ( max_volume < 0 ) return -1;
527 // if ( max_volume > F1_0 ) max_volume = F1_0;
529 if (!digi_initialised) return -1;
530 if (soundnum < 0 ) return -1;
531 if (GameSounds[soundnum].data==NULL) {
536 if ((segnum<0)||(segnum>Highest_segment_index))
540 // Hack to keep sounds from building up...
541 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance );
542 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
546 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
547 if (SoundObjects[i].flags==0)
550 if (i==MAX_SOUND_OBJECTS) {
551 mprintf((1, "Too many sound objects!\n" ));
556 SoundObjects[i].signature=next_signature++;
557 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_POS;
559 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
560 SoundObjects[i].lp_segnum = segnum;
561 SoundObjects[i].lp_sidenum = sidenum;
562 SoundObjects[i].lp_position = *pos;
563 SoundObjects[i].soundnum = soundnum;
564 SoundObjects[i].max_volume = max_volume;
565 SoundObjects[i].max_distance = max_distance;
566 SoundObjects[i].volume = 0;
567 SoundObjects[i].pan = 0;
568 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
569 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
570 SoundObjects[i].max_volume,
571 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
573 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
574 digi_start_sound_object(i);
576 return SoundObjects[i].signature;
579 int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume )
581 return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 );
584 void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum )
588 soundnum = digi_xlat_sound(soundnum);
590 if (!digi_initialised) return;
594 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
595 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_POS) ) {
596 if ((SoundObjects[i].lp_segnum == segnum) && (SoundObjects[i].soundnum==soundnum ) && (SoundObjects[i].lp_sidenum==sidenum) ) {
597 if ( SoundObjects[i].flags & SOF_PLAYING ) {
598 SoundSlots[SoundObjects[i].handle].playing = 0;
600 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
605 // If this assert happens, it means that there were 2 sounds
606 // that got deleted. Weird, get John.
608 mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum ));
612 void digi_kill_sound_linked_to_object( int objnum )
616 if (!digi_initialised) return;
620 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
621 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
622 if (SoundObjects[i].lo_objnum == objnum) {
623 if ( SoundObjects[i].flags & SOF_PLAYING ) {
624 SoundSlots[SoundObjects[i].handle].playing = 0;
626 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
631 // If this assert happens, it means that there were 2 sounds
632 // that got deleted. Weird, get John.
634 mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum ));
638 void digi_sync_sounds()
641 int oldvolume, oldpan;
643 if (!digi_initialised) return;
645 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
646 if ( SoundObjects[i].flags & SOF_USED ) {
647 oldvolume = SoundObjects[i].volume;
648 oldpan = SoundObjects[i].pan;
650 if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) ) {
651 // Check if its done.
652 if (SoundObjects[i].flags & SOF_PLAYING) {
653 if (!SoundSlots[SoundObjects[i].handle].playing) {
654 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
655 continue; // Go on to next sound...
660 if ( SoundObjects[i].flags & SOF_LINK_TO_POS ) {
661 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
662 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
663 SoundObjects[i].max_volume,
664 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
666 } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) {
669 objp = &Objects[SoundObjects[i].lo_objnum];
671 if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) {
672 // The object that this is linked to is dead, so just end this sound if it is looping.
673 if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
674 SoundSlots[SoundObjects[i].handle].playing = 0;
676 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
677 continue; // Go on to next sound...
679 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
680 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
681 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
685 if (oldvolume != SoundObjects[i].volume) {
686 if ( SoundObjects[i].volume < MIN_VOLUME ) {
687 // Sound is too far away, so stop it from playing.
688 if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
689 SoundSlots[SoundObjects[i].handle].playing = 0;
690 SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing
693 if (!(SoundObjects[i].flags & SOF_PLAYING)) {
694 digi_start_sound_object(i);
696 SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0);
701 if (oldpan != SoundObjects[i].pan) {
702 if (SoundObjects[i].flags & SOF_PLAYING)
703 SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan;
709 void digi_init_sounds()
713 if (!digi_initialised) return;
715 digi_reset_digi_sounds();
717 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
718 if (digi_sounds_initialized) {
719 if ( SoundObjects[i].flags & SOF_PLAYING ) {
720 SoundSlots[SoundObjects[i].handle].playing=0;
723 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
725 digi_sounds_initialized = 1;
728 //added on 980905 by adb from original source to make sfx volume work
729 void digi_set_digi_volume( int dvolume )
731 dvolume = fixmuldiv( dvolume, SOUND_MAX_VOLUME, 0x7fff);
732 if ( dvolume > SOUND_MAX_VOLUME )
733 digi_volume = SOUND_MAX_VOLUME;
734 else if ( dvolume < 0 )
737 digi_volume = dvolume;
739 if ( !digi_initialised ) return;
745 void digi_set_volume( int dvolume, int mvolume ) { }
747 int digi_is_sound_playing(int soundno)
751 soundno = digi_xlat_sound(soundno);
753 for (i = 0; i < MAX_SOUND_SLOTS; i++)
754 //changed on 980905 by adb: added SoundSlots[i].playing &&
755 if (SoundSlots[i].playing && SoundSlots[i].soundno == soundno)
762 void digi_pause_all() { }
763 void digi_resume_all() { }
764 void digi_stop_all() { }
766 //added on 980905 by adb to make sound channel setting work
767 void digi_set_max_channels(int n) {
768 digi_max_channels = n;
770 if ( digi_max_channels < 1 )
771 digi_max_channels = 1;
772 if ( digi_max_channels > (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) )
773 digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS);
775 if ( !digi_initialised ) return;
777 digi_reset_digi_sounds();
780 int digi_get_max_channels() {
781 return digi_max_channels;
785 void digi_reset_digi_sounds() {
788 for (i=0; i< MAX_SOUND_SLOTS; i++)
789 SoundSlots[i].playing=0;
791 //added on 980905 by adb to reset sound kill system
792 memset(SampleHandles, 255, sizeof(SampleHandles));
798 // MIDI stuff follows.
799 //added/killed on 11/25/98 by Matthew Mueller
800 //void digi_set_midi_volume( int mvolume ) { }
801 //void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ) {}
802 //void digi_stop_current_song()
811 //end this section kill - MM
813 #endif // __ENV_DJGPP__