2 * $Source: /cvs/cvsroot/d2x/arch/dos/digi.c,v $
5 * $Date: 2001-10-25 08:25:33 $
7 * DOS digital audio support
9 * $Log: not supported by cvs2svn $
10 * Revision 1.3 2001/01/31 14:04:45 bradleyb
11 * Fix compiler warnings
13 * Revision 1.2 2001/01/29 13:53:28 bradleyb
14 * Fixed build, minor fixes
31 #include "gr.h" // needed for piggy.h
39 int digi_sample_rate=11025;
40 int digi_timer_rate = 9943; // rate for the timer to go off to handle the driver system (120 Hz)
42 //edited 05/17/99 Matt Mueller - added ifndef NO_ASM
43 //added on 980905 by adb to add inline fixmul for mixer on i386
46 #define do_fixmul(x,y) \
49 asm("imull %2\n\tshrdl %3,%1,%0" \
50 : "=a"(_ax), "=d"(_dx) \
51 : "rm"(y), "i"(16), "0"(x)); \
54 extern inline fix fixmul(fix x, fix y) { return do_fixmul(x,y); }
60 //changed on 980905 by adb to increase number of concurrent sounds
61 #define MAX_SOUND_SLOTS 32
63 #define SOUND_BUFFER_SIZE 512
67 /* This table is used to add two sound values together and pin
68 * the value to avoid overflow. (used with permission from ARDI)
69 * DPH: Taken from SDL/src/SDL_mixer.c.
71 static const unsigned char mix8[] =
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
85 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
86 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
87 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
88 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
89 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
90 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
91 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
92 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B,
93 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
94 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
95 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
96 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
97 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92,
98 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D,
99 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
100 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3,
101 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
102 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
103 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4,
104 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
105 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
106 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
107 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF,
108 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
109 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
110 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
111 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
112 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
113 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
114 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
115 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
116 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
117 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
118 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
119 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
122 #define SOF_USED 1 // Set if this sample is used
123 #define SOF_PLAYING 2 // Set if this sample is playing on a channel
124 #define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits.
125 #define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos
126 #define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once
128 typedef struct sound_object {
129 short signature; // A unique signature to this sound
130 ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long.
131 fix max_volume; // Max volume that this sound is playing at
132 fix max_distance; // The max distance that this sound can be heard at...
133 int volume; // Volume that this sound is playing at
134 int pan; // Pan value that this sound is playing at
135 int handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set.
136 short soundnum; // The sound number that is playing
139 short segnum; // Used if SOF_LINK_TO_POS field is used
144 short objnum; // Used if SOF_LINK_TO_OBJ field is used
149 #define lp_segnum link.pos.segnum
150 #define lp_sidenum link.pos.sidenum
151 #define lp_position link.pos.position
153 #define lo_objnum link.obj.objnum
154 #define lo_objsignature link.obj.objsignature
156 #define MAX_SOUND_OBJECTS 16
157 sound_object SoundObjects[MAX_SOUND_OBJECTS];
158 short next_signature=0;
160 //added/changed on 980905 by adb to make sfx volume work, on 990221 by adb changed F1_0 to F1_0 / 2
161 #define SOUND_MAX_VOLUME (F1_0 / 2)
163 int digi_volume = SOUND_MAX_VOLUME;
168 static int digi_initialised = 0;
172 int playing; // Is there a sample playing on this channel?
173 int looped; // Play this sample looped?
174 fix pan; // 0 = far left, 1 = far right
175 fix volume; // 0 = nothing, 1 = fully on
176 //changed on 980905 by adb from char * to unsigned char *
177 unsigned char *samples;
179 unsigned int length; // Length of the sample
180 unsigned int position; // Position we are at at the moment.
181 } SoundSlots[MAX_SOUND_SLOTS];
183 static int digi_sounds_initialized = 0;
185 //added on 980905 by adb to add rotating/volume based sound kill system
186 static int digi_max_channels = 16;
187 static int next_handle = 0;
188 int SampleHandles[32];
189 void reset_sounds_on_channel(int channel);
192 void digi_reset_digi_sounds(void);
194 /* Audio mixing callback */
195 //changed on 980905 by adb to cleanup, add pan support and optimize mixer
196 static void audio_mixcallback(void *userdata, unsigned char *stream, int len)
198 unsigned char *streamend = stream + len;
199 struct sound_slot *sl;
201 for (sl = SoundSlots; sl < SoundSlots + MAX_SOUND_SLOTS; sl++)
205 unsigned char *sldata = sl->samples + sl->position, *slend = sl->samples + sl->length;
206 unsigned char *sp = stream;
211 if ((x = sl->pan) & 0x8000)
213 vl = 0x20000 - x * 2;
221 vl = fixmul(vl, (x = sl->volume));
223 while (sp < streamend)
232 sldata = sl->samples;
234 v = *(sldata++) - 0x80;
235 *(sp++) = mix8[ *sp + fixmul(v, vl) + 0x80 ];
236 *(sp++) = mix8[ *sp + fixmul(v, vr) + 0x80 ];
238 sl->position = sldata - sl->samples;
244 /* Initialise audio devices. */
247 /* this is just here now to stop gcc from complaining about
248 * audio_mixcallback being declared static and not used...
250 if (0) audio_mixcallback(NULL,NULL,0);
256 void digi_reset() { }
258 /* Shut down audio */
261 if (!digi_initialised) return;
262 digi_initialised = 0;
265 /* Find the sound which actually equates to a sound number */
266 int digi_xlat_sound(int soundno)
268 if ( soundno < 0 ) return -1;
271 soundno = AltSounds[soundno];
272 if ( soundno == 255 ) return -1;
274 return Sounds[soundno];
277 static int get_free_slot()
280 for (i=0; i<MAX_SOUND_SLOTS; i++)
282 if (!SoundSlots[i].playing) return i;
287 int digi_start_sound(int soundnum, fix volume, fix pan, int unknown1, int unknown2, int unknown3, int unknown4)
292 if (!digi_initialised) return -1;
294 //added on 980905 by adb from original source to add sound kill system
295 // play at most digi_max_channel samples, if possible kill sample with low volume
299 if ( (SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing) )
301 if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries<digi_max_channels) )
303 //mprintf(( 0, "Not stopping loud sound %d.\n", next_handle ));
305 if ( next_handle >= digi_max_channels )
310 //mprintf(( 0, "[SS:%d]", next_handle ));
311 SoundSlots[SampleHandles[next_handle]].playing = 0;
312 SampleHandles[next_handle] = -1;
316 slot = get_free_slot();
317 if (slot<0) return -1;
319 SoundSlots[slot].soundno = soundnum;
320 SoundSlots[slot].samples = GameSounds[soundnum].data;
321 SoundSlots[slot].length = GameSounds[soundnum].length;
322 SoundSlots[slot].volume = fixmul(digi_volume, volume);
323 SoundSlots[slot].pan = pan;
324 SoundSlots[slot].position = 0;
325 SoundSlots[slot].looped = 0;
326 SoundSlots[slot].playing = 1;
328 //added on 980905 by adb to add sound kill system from original sos digi.c
329 reset_sounds_on_channel(slot);
330 SampleHandles[next_handle] = slot;
332 if ( next_handle >= digi_max_channels )
339 //added on 980905 by adb to add sound kill system from original sos digi.c
340 void reset_sounds_on_channel( int channel )
344 for (i=0; i<digi_max_channels; i++)
345 if (SampleHandles[i] == channel)
346 SampleHandles[i] = -1;
350 int digi_start_sound_object(int obj)
354 if (!digi_initialised) return -1;
355 slot = get_free_slot();
357 if (slot<0) return -1;
360 SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
361 SoundSlots[slot].samples = GameSounds[SoundObjects[obj].soundnum].data;
362 SoundSlots[slot].length = GameSounds[SoundObjects[obj].soundnum].length;
363 SoundSlots[slot].volume = fixmul(digi_volume, SoundObjects[obj].volume);
364 SoundSlots[slot].pan = SoundObjects[obj].pan;
365 SoundSlots[slot].position = 0;
366 SoundSlots[slot].looped = (SoundObjects[obj].flags & SOF_PLAY_FOREVER);
367 SoundSlots[slot].playing = 1;
369 SoundObjects[obj].signature = next_signature++;
370 SoundObjects[obj].handle = slot;
372 SoundObjects[obj].flags |= SOF_PLAYING;
373 //added on 980905 by adb to add sound kill system from original sos digi.c
374 reset_sounds_on_channel(slot);
381 // Play the given sound number.
382 // Volume is max at F1_0.
383 void digi_play_sample( int soundno, fix max_volume )
386 if ( Newdemo_state == ND_STATE_RECORDING )
387 newdemo_record_sound( soundno );
389 soundno = digi_xlat_sound(soundno);
391 if (!digi_initialised) return;
393 if (soundno < 0 ) return;
395 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
398 // Play the given sound number. If the sound is already playing,
400 void digi_play_sample_once( int soundno, fix max_volume )
405 if ( Newdemo_state == ND_STATE_RECORDING )
406 newdemo_record_sound( soundno );
408 soundno = digi_xlat_sound(soundno);
410 if (!digi_initialised) return;
412 if (soundno < 0 ) return;
414 for (i=0; i < MAX_SOUND_SLOTS; i++)
415 if (SoundSlots[i].soundno == soundno)
416 SoundSlots[i].playing = 0;
417 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
421 void digi_play_sample_3d( int soundno, int angle, int volume, int no_dups ) // Volume from 0-0x7fff
426 if ( Newdemo_state == ND_STATE_RECORDING ) {
428 newdemo_record_sound_3d_once( soundno, angle, volume );
430 newdemo_record_sound_3d( soundno, angle, volume );
433 soundno = digi_xlat_sound(soundno);
435 if (!digi_initialised) return;
436 if (soundno < 0 ) return;
438 if (volume < MIN_VOLUME ) return;
439 digi_start_sound(soundno, volume, angle, 0, 0, 0, 0);
442 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 )
444 vms_vector vector_to_sound;
445 fix angle_from_ear, cosang,sinang;
452 max_distance = (max_distance*5)/4; // Make all sounds travel 1.25 times as far.
454 // Warning: Made the vm_vec_normalized_dir be vm_vec_normalized_dir_quick and got illegal values to acos in the fang computation.
455 distance = vm_vec_normalized_dir_quick( &vector_to_sound, sound_pos, listener_pos );
457 if (distance < max_distance ) {
458 int num_search_segs = f2i(max_distance/20);
459 if ( num_search_segs < 1 ) num_search_segs = 1;
461 path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG );
462 if ( path_distance > -1 ) {
463 *volume = max_volume - fixdiv(path_distance,max_distance);
464 //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume ));
466 angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec);
467 fix_sincos(angle_from_ear,&sinang,&cosang);
468 //mprintf( (0, "volume is %.2f\n", f2fl(*volume) ));
469 if (Config_channels_reversed) cosang *= -1;
470 *pan = (cosang + F1_0)/2;
478 int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance )
484 soundnum = digi_xlat_sound(org_soundnum);
486 if ( max_volume < 0 ) return -1;
487 // if ( max_volume > F1_0 ) max_volume = F1_0;
489 if (!digi_initialised) return -1;
490 if (soundnum < 0 ) return -1;
491 if (GameSounds[soundnum].data==NULL) {
495 if ((objnum<0)||(objnum>Highest_object_index))
499 // Hack to keep sounds from building up...
500 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance );
501 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
505 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
506 if (SoundObjects[i].flags==0)
509 if (i==MAX_SOUND_OBJECTS) {
510 mprintf((1, "Too many sound objects!\n" ));
514 SoundObjects[i].signature=next_signature++;
515 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_OBJ;
517 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
518 SoundObjects[i].lo_objnum = objnum;
519 SoundObjects[i].lo_objsignature = Objects[objnum].signature;
520 SoundObjects[i].max_volume = max_volume;
521 SoundObjects[i].max_distance = max_distance;
522 SoundObjects[i].volume = 0;
523 SoundObjects[i].pan = 0;
524 SoundObjects[i].soundnum = soundnum;
526 objp = &Objects[SoundObjects[i].lo_objnum];
527 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
528 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
529 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
531 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
532 digi_start_sound_object(i);
534 return SoundObjects[i].signature;
537 int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume )
538 { return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0); }
540 int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance )
545 soundnum = digi_xlat_sound(org_soundnum);
547 if ( max_volume < 0 ) return -1;
548 // if ( max_volume > F1_0 ) max_volume = F1_0;
550 if (!digi_initialised) return -1;
551 if (soundnum < 0 ) return -1;
552 if (GameSounds[soundnum].data==NULL) {
557 if ((segnum<0)||(segnum>Highest_segment_index))
561 // Hack to keep sounds from building up...
562 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance );
563 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
567 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
568 if (SoundObjects[i].flags==0)
571 if (i==MAX_SOUND_OBJECTS) {
572 mprintf((1, "Too many sound objects!\n" ));
577 SoundObjects[i].signature=next_signature++;
578 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_POS;
580 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
581 SoundObjects[i].lp_segnum = segnum;
582 SoundObjects[i].lp_sidenum = sidenum;
583 SoundObjects[i].lp_position = *pos;
584 SoundObjects[i].soundnum = soundnum;
585 SoundObjects[i].max_volume = max_volume;
586 SoundObjects[i].max_distance = max_distance;
587 SoundObjects[i].volume = 0;
588 SoundObjects[i].pan = 0;
589 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
590 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
591 SoundObjects[i].max_volume,
592 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
594 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
595 digi_start_sound_object(i);
597 return SoundObjects[i].signature;
600 int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume )
602 return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 );
605 void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum )
609 soundnum = digi_xlat_sound(soundnum);
611 if (!digi_initialised) return;
615 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
616 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_POS) ) {
617 if ((SoundObjects[i].lp_segnum == segnum) && (SoundObjects[i].soundnum==soundnum ) && (SoundObjects[i].lp_sidenum==sidenum) ) {
618 if ( SoundObjects[i].flags & SOF_PLAYING ) {
619 SoundSlots[SoundObjects[i].handle].playing = 0;
621 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
626 // If this assert happens, it means that there were 2 sounds
627 // that got deleted. Weird, get John.
629 mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum ));
633 void digi_kill_sound_linked_to_object( int objnum )
637 if (!digi_initialised) return;
641 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
642 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
643 if (SoundObjects[i].lo_objnum == objnum) {
644 if ( SoundObjects[i].flags & SOF_PLAYING ) {
645 SoundSlots[SoundObjects[i].handle].playing = 0;
647 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
652 // If this assert happens, it means that there were 2 sounds
653 // that got deleted. Weird, get John.
655 mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum ));
659 void digi_sync_sounds()
662 int oldvolume, oldpan;
664 if (!digi_initialised) return;
666 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
667 if ( SoundObjects[i].flags & SOF_USED ) {
668 oldvolume = SoundObjects[i].volume;
669 oldpan = SoundObjects[i].pan;
671 if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) ) {
672 // Check if its done.
673 if (SoundObjects[i].flags & SOF_PLAYING) {
674 if (!SoundSlots[SoundObjects[i].handle].playing) {
675 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
676 continue; // Go on to next sound...
681 if ( SoundObjects[i].flags & SOF_LINK_TO_POS ) {
682 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
683 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
684 SoundObjects[i].max_volume,
685 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
687 } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) {
690 objp = &Objects[SoundObjects[i].lo_objnum];
692 if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) {
693 // The object that this is linked to is dead, so just end this sound if it is looping.
694 if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
695 SoundSlots[SoundObjects[i].handle].playing = 0;
697 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
698 continue; // Go on to next sound...
700 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
701 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
702 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
706 if (oldvolume != SoundObjects[i].volume) {
707 if ( SoundObjects[i].volume < MIN_VOLUME ) {
708 // Sound is too far away, so stop it from playing.
709 if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
710 SoundSlots[SoundObjects[i].handle].playing = 0;
711 SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing
714 if (!(SoundObjects[i].flags & SOF_PLAYING)) {
715 digi_start_sound_object(i);
717 SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0);
722 if (oldpan != SoundObjects[i].pan) {
723 if (SoundObjects[i].flags & SOF_PLAYING)
724 SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan;
730 void digi_init_sounds()
734 if (!digi_initialised) return;
736 digi_reset_digi_sounds();
738 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
739 if (digi_sounds_initialized) {
740 if ( SoundObjects[i].flags & SOF_PLAYING ) {
741 SoundSlots[SoundObjects[i].handle].playing=0;
744 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
746 digi_sounds_initialized = 1;
749 //added on 980905 by adb from original source to make sfx volume work
750 void digi_set_digi_volume( int dvolume )
752 dvolume = fixmuldiv( dvolume, SOUND_MAX_VOLUME, 0x7fff);
753 if ( dvolume > SOUND_MAX_VOLUME )
754 digi_volume = SOUND_MAX_VOLUME;
755 else if ( dvolume < 0 )
758 digi_volume = dvolume;
760 if ( !digi_initialised ) return;
766 void digi_set_volume( int dvolume, int mvolume ) { }
768 int digi_is_sound_playing(int soundno)
772 soundno = digi_xlat_sound(soundno);
774 for (i = 0; i < MAX_SOUND_SLOTS; i++)
775 //changed on 980905 by adb: added SoundSlots[i].playing &&
776 if (SoundSlots[i].playing && SoundSlots[i].soundno == soundno)
783 void digi_pause_all() { }
784 void digi_resume_all() { }
785 void digi_stop_all() { }
787 //added on 980905 by adb to make sound channel setting work
788 void digi_set_max_channels(int n) {
789 digi_max_channels = n;
791 if ( digi_max_channels < 1 )
792 digi_max_channels = 1;
793 if ( digi_max_channels > (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) )
794 digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS);
796 if ( !digi_initialised ) return;
798 digi_reset_digi_sounds();
801 int digi_get_max_channels() {
802 return digi_max_channels;
806 void digi_reset_digi_sounds() {
809 for (i=0; i< MAX_SOUND_SLOTS; i++)
810 SoundSlots[i].playing=0;
812 //added on 980905 by adb to reset sound kill system
813 memset(SampleHandles, 255, sizeof(SampleHandles));
819 // MIDI stuff follows.
820 //added/killed on 11/25/98 by Matthew Mueller
821 //void digi_set_midi_volume( int mvolume ) { }
822 //void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ) {}
823 //void digi_stop_current_song()
832 //end this section kill - MM