2 * $Source: /cvs/cvsroot/d2x/sound/dos_digi.c,v $
5 * $Date: 2001-01-31 14:04:45 $
7 * DOS digital audio support
9 * $Log: not supported by cvs2svn $
10 * Revision 1.2 2001/01/29 13:53:28 bradleyb
11 * Fixed build, minor fixes
28 #include "gr.h" // needed for piggy.h
36 int digi_sample_rate=11025;
37 int digi_timer_rate = 9943; // rate for the timer to go off to handle the driver system (120 Hz)
39 //edited 05/17/99 Matt Mueller - added ifndef NO_ASM
40 //added on 980905 by adb to add inline fixmul for mixer on i386
43 #define do_fixmul(x,y) \
46 asm("imull %2\n\tshrdl %3,%1,%0" \
47 : "=a"(_ax), "=d"(_dx) \
48 : "rm"(y), "i"(16), "0"(x)); \
51 extern inline fix fixmul(fix x, fix y) { return do_fixmul(x,y); }
57 //changed on 980905 by adb to increase number of concurrent sounds
58 #define MAX_SOUND_SLOTS 32
60 #define SOUND_BUFFER_SIZE 512
64 /* This table is used to add two sound values together and pin
65 * the value to avoid overflow. (used with permission from ARDI)
66 * DPH: Taken from SDL/src/SDL_mixer.c.
68 static const unsigned char mix8[] =
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x01, 0x02, 0x03,
82 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
83 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
84 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
85 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
86 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
87 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
88 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
89 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B,
90 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
91 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
92 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
93 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
94 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92,
95 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D,
96 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
97 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3,
98 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
99 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
100 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4,
101 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
102 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
103 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
104 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF,
105 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
106 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
107 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 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,
119 #define SOF_USED 1 // Set if this sample is used
120 #define SOF_PLAYING 2 // Set if this sample is playing on a channel
121 #define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits.
122 #define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos
123 #define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once
125 typedef struct sound_object {
126 short signature; // A unique signature to this sound
127 ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long.
128 fix max_volume; // Max volume that this sound is playing at
129 fix max_distance; // The max distance that this sound can be heard at...
130 int volume; // Volume that this sound is playing at
131 int pan; // Pan value that this sound is playing at
132 int handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set.
133 short soundnum; // The sound number that is playing
136 short segnum; // Used if SOF_LINK_TO_POS field is used
141 short objnum; // Used if SOF_LINK_TO_OBJ field is used
146 #define lp_segnum link.pos.segnum
147 #define lp_sidenum link.pos.sidenum
148 #define lp_position link.pos.position
150 #define lo_objnum link.obj.objnum
151 #define lo_objsignature link.obj.objsignature
153 #define MAX_SOUND_OBJECTS 16
154 sound_object SoundObjects[MAX_SOUND_OBJECTS];
155 short next_signature=0;
157 //added/changed on 980905 by adb to make sfx volume work, on 990221 by adb changed F1_0 to F1_0 / 2
158 #define SOUND_MAX_VOLUME (F1_0 / 2)
160 int digi_volume = SOUND_MAX_VOLUME;
165 static int digi_initialised = 0;
169 int playing; // Is there a sample playing on this channel?
170 int looped; // Play this sample looped?
171 fix pan; // 0 = far left, 1 = far right
172 fix volume; // 0 = nothing, 1 = fully on
173 //changed on 980905 by adb from char * to unsigned char *
174 unsigned char *samples;
176 unsigned int length; // Length of the sample
177 unsigned int position; // Position we are at at the moment.
178 } SoundSlots[MAX_SOUND_SLOTS];
180 static int digi_sounds_initialized = 0;
182 //added on 980905 by adb to add rotating/volume based sound kill system
183 static int digi_max_channels = 16;
184 static int next_handle = 0;
185 int SampleHandles[32];
186 void reset_sounds_on_channel(int channel);
189 void digi_reset_digi_sounds(void);
191 /* Audio mixing callback */
192 //changed on 980905 by adb to cleanup, add pan support and optimize mixer
193 static void audio_mixcallback(void *userdata, unsigned char *stream, int len)
195 unsigned char *streamend = stream + len;
196 struct sound_slot *sl;
198 for (sl = SoundSlots; sl < SoundSlots + MAX_SOUND_SLOTS; sl++)
202 unsigned char *sldata = sl->samples + sl->position, *slend = sl->samples + sl->length;
203 unsigned char *sp = stream;
208 if ((x = sl->pan) & 0x8000)
210 vl = 0x20000 - x * 2;
218 vl = fixmul(vl, (x = sl->volume));
220 while (sp < streamend)
229 sldata = sl->samples;
231 v = *(sldata++) - 0x80;
232 *(sp++) = mix8[ *sp + fixmul(v, vl) + 0x80 ];
233 *(sp++) = mix8[ *sp + fixmul(v, vr) + 0x80 ];
235 sl->position = sldata - sl->samples;
241 /* Initialise audio devices. */
244 /* this is just here now to stop gcc from complaining about
245 * audio_mixcallback being declared static and not used...
247 if (0) audio_mixcallback(NULL,NULL,0);
253 void digi_reset() { }
255 /* Shut down audio */
258 if (!digi_initialised) return;
259 digi_initialised = 0;
262 /* Find the sound which actually equates to a sound number */
263 int digi_xlat_sound(int soundno)
265 if ( soundno < 0 ) return -1;
268 soundno = AltSounds[soundno];
269 if ( soundno == 255 ) return -1;
271 return Sounds[soundno];
274 static int get_free_slot()
277 for (i=0; i<MAX_SOUND_SLOTS; i++)
279 if (!SoundSlots[i].playing) return i;
284 int digi_start_sound(int soundnum, fix volume, fix pan, int unknown1, int unknown2, int unknown3, int unknown4)
289 if (!digi_initialised) return -1;
291 //added on 980905 by adb from original source to add sound kill system
292 // play at most digi_max_channel samples, if possible kill sample with low volume
296 if ( (SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing) )
298 if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries<digi_max_channels) )
300 //mprintf(( 0, "Not stopping loud sound %d.\n", next_handle ));
302 if ( next_handle >= digi_max_channels )
307 //mprintf(( 0, "[SS:%d]", next_handle ));
308 SoundSlots[SampleHandles[next_handle]].playing = 0;
309 SampleHandles[next_handle] = -1;
313 slot = get_free_slot();
314 if (slot<0) return -1;
316 SoundSlots[slot].soundno = soundnum;
317 SoundSlots[slot].samples = GameSounds[soundnum].data;
318 SoundSlots[slot].length = GameSounds[soundnum].length;
319 SoundSlots[slot].volume = fixmul(digi_volume, volume);
320 SoundSlots[slot].pan = pan;
321 SoundSlots[slot].position = 0;
322 SoundSlots[slot].looped = 0;
323 SoundSlots[slot].playing = 1;
325 //added on 980905 by adb to add sound kill system from original sos digi.c
326 reset_sounds_on_channel(slot);
327 SampleHandles[next_handle] = slot;
329 if ( next_handle >= digi_max_channels )
336 //added on 980905 by adb to add sound kill system from original sos digi.c
337 void reset_sounds_on_channel( int channel )
341 for (i=0; i<digi_max_channels; i++)
342 if (SampleHandles[i] == channel)
343 SampleHandles[i] = -1;
347 int digi_start_sound_object(int obj)
351 if (!digi_initialised) return -1;
352 slot = get_free_slot();
354 if (slot<0) return -1;
357 SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
358 SoundSlots[slot].samples = GameSounds[SoundObjects[obj].soundnum].data;
359 SoundSlots[slot].length = GameSounds[SoundObjects[obj].soundnum].length;
360 SoundSlots[slot].volume = fixmul(digi_volume, SoundObjects[obj].volume);
361 SoundSlots[slot].pan = SoundObjects[obj].pan;
362 SoundSlots[slot].position = 0;
363 SoundSlots[slot].looped = (SoundObjects[obj].flags & SOF_PLAY_FOREVER);
364 SoundSlots[slot].playing = 1;
366 SoundObjects[obj].signature = next_signature++;
367 SoundObjects[obj].handle = slot;
369 SoundObjects[obj].flags |= SOF_PLAYING;
370 //added on 980905 by adb to add sound kill system from original sos digi.c
371 reset_sounds_on_channel(slot);
378 // Play the given sound number.
379 // Volume is max at F1_0.
380 void digi_play_sample( int soundno, fix max_volume )
383 if ( Newdemo_state == ND_STATE_RECORDING )
384 newdemo_record_sound( soundno );
386 soundno = digi_xlat_sound(soundno);
388 if (!digi_initialised) return;
390 if (soundno < 0 ) return;
392 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
395 // Play the given sound number. If the sound is already playing,
397 void digi_play_sample_once( int soundno, fix max_volume )
402 if ( Newdemo_state == ND_STATE_RECORDING )
403 newdemo_record_sound( soundno );
405 soundno = digi_xlat_sound(soundno);
407 if (!digi_initialised) return;
409 if (soundno < 0 ) return;
411 for (i=0; i < MAX_SOUND_SLOTS; i++)
412 if (SoundSlots[i].soundno == soundno)
413 SoundSlots[i].playing = 0;
414 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
418 void digi_play_sample_3d( int soundno, int angle, int volume, int no_dups ) // Volume from 0-0x7fff
423 if ( Newdemo_state == ND_STATE_RECORDING ) {
425 newdemo_record_sound_3d_once( soundno, angle, volume );
427 newdemo_record_sound_3d( soundno, angle, volume );
430 soundno = digi_xlat_sound(soundno);
432 if (!digi_initialised) return;
433 if (soundno < 0 ) return;
435 if (volume < MIN_VOLUME ) return;
436 digi_start_sound(soundno, volume, angle, 0, 0, 0, 0);
439 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 )
441 vms_vector vector_to_sound;
442 fix angle_from_ear, cosang,sinang;
449 max_distance = (max_distance*5)/4; // Make all sounds travel 1.25 times as far.
451 // Warning: Made the vm_vec_normalized_dir be vm_vec_normalized_dir_quick and got illegal values to acos in the fang computation.
452 distance = vm_vec_normalized_dir_quick( &vector_to_sound, sound_pos, listener_pos );
454 if (distance < max_distance ) {
455 int num_search_segs = f2i(max_distance/20);
456 if ( num_search_segs < 1 ) num_search_segs = 1;
458 path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG );
459 if ( path_distance > -1 ) {
460 *volume = max_volume - fixdiv(path_distance,max_distance);
461 //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume ));
463 angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec);
464 fix_sincos(angle_from_ear,&sinang,&cosang);
465 //mprintf( (0, "volume is %.2f\n", f2fl(*volume) ));
466 if (Config_channels_reversed) cosang *= -1;
467 *pan = (cosang + F1_0)/2;
475 int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance )
481 soundnum = digi_xlat_sound(org_soundnum);
483 if ( max_volume < 0 ) return -1;
484 // if ( max_volume > F1_0 ) max_volume = F1_0;
486 if (!digi_initialised) return -1;
487 if (soundnum < 0 ) return -1;
488 if (GameSounds[soundnum].data==NULL) {
492 if ((objnum<0)||(objnum>Highest_object_index))
496 // Hack to keep sounds from building up...
497 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance );
498 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
502 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
503 if (SoundObjects[i].flags==0)
506 if (i==MAX_SOUND_OBJECTS) {
507 mprintf((1, "Too many sound objects!\n" ));
511 SoundObjects[i].signature=next_signature++;
512 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_OBJ;
514 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
515 SoundObjects[i].lo_objnum = objnum;
516 SoundObjects[i].lo_objsignature = Objects[objnum].signature;
517 SoundObjects[i].max_volume = max_volume;
518 SoundObjects[i].max_distance = max_distance;
519 SoundObjects[i].volume = 0;
520 SoundObjects[i].pan = 0;
521 SoundObjects[i].soundnum = soundnum;
523 objp = &Objects[SoundObjects[i].lo_objnum];
524 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
525 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
526 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
528 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
529 digi_start_sound_object(i);
531 return SoundObjects[i].signature;
534 int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume )
535 { return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0); }
537 int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance )
542 soundnum = digi_xlat_sound(org_soundnum);
544 if ( max_volume < 0 ) return -1;
545 // if ( max_volume > F1_0 ) max_volume = F1_0;
547 if (!digi_initialised) return -1;
548 if (soundnum < 0 ) return -1;
549 if (GameSounds[soundnum].data==NULL) {
554 if ((segnum<0)||(segnum>Highest_segment_index))
558 // Hack to keep sounds from building up...
559 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance );
560 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
564 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
565 if (SoundObjects[i].flags==0)
568 if (i==MAX_SOUND_OBJECTS) {
569 mprintf((1, "Too many sound objects!\n" ));
574 SoundObjects[i].signature=next_signature++;
575 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_POS;
577 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
578 SoundObjects[i].lp_segnum = segnum;
579 SoundObjects[i].lp_sidenum = sidenum;
580 SoundObjects[i].lp_position = *pos;
581 SoundObjects[i].soundnum = soundnum;
582 SoundObjects[i].max_volume = max_volume;
583 SoundObjects[i].max_distance = max_distance;
584 SoundObjects[i].volume = 0;
585 SoundObjects[i].pan = 0;
586 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
587 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
588 SoundObjects[i].max_volume,
589 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
591 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
592 digi_start_sound_object(i);
594 return SoundObjects[i].signature;
597 int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume )
599 return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 );
602 void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum )
606 soundnum = digi_xlat_sound(soundnum);
608 if (!digi_initialised) return;
612 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
613 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_POS) ) {
614 if ((SoundObjects[i].lp_segnum == segnum) && (SoundObjects[i].soundnum==soundnum ) && (SoundObjects[i].lp_sidenum==sidenum) ) {
615 if ( SoundObjects[i].flags & SOF_PLAYING ) {
616 SoundSlots[SoundObjects[i].handle].playing = 0;
618 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
623 // If this assert happens, it means that there were 2 sounds
624 // that got deleted. Weird, get John.
626 mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum ));
630 void digi_kill_sound_linked_to_object( int objnum )
634 if (!digi_initialised) return;
638 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
639 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
640 if (SoundObjects[i].lo_objnum == objnum) {
641 if ( SoundObjects[i].flags & SOF_PLAYING ) {
642 SoundSlots[SoundObjects[i].handle].playing = 0;
644 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
649 // If this assert happens, it means that there were 2 sounds
650 // that got deleted. Weird, get John.
652 mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum ));
656 void digi_sync_sounds()
659 int oldvolume, oldpan;
661 if (!digi_initialised) return;
663 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
664 if ( SoundObjects[i].flags & SOF_USED ) {
665 oldvolume = SoundObjects[i].volume;
666 oldpan = SoundObjects[i].pan;
668 if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) ) {
669 // Check if its done.
670 if (SoundObjects[i].flags & SOF_PLAYING) {
671 if (!SoundSlots[SoundObjects[i].handle].playing) {
672 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
673 continue; // Go on to next sound...
678 if ( SoundObjects[i].flags & SOF_LINK_TO_POS ) {
679 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
680 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
681 SoundObjects[i].max_volume,
682 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
684 } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) {
687 objp = &Objects[SoundObjects[i].lo_objnum];
689 if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) {
690 // The object that this is linked to is dead, so just end this sound if it is looping.
691 if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
692 SoundSlots[SoundObjects[i].handle].playing = 0;
694 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
695 continue; // Go on to next sound...
697 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
698 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
699 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
703 if (oldvolume != SoundObjects[i].volume) {
704 if ( SoundObjects[i].volume < MIN_VOLUME ) {
705 // Sound is too far away, so stop it from playing.
706 if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
707 SoundSlots[SoundObjects[i].handle].playing = 0;
708 SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing
711 if (!(SoundObjects[i].flags & SOF_PLAYING)) {
712 digi_start_sound_object(i);
714 SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0);
719 if (oldpan != SoundObjects[i].pan) {
720 if (SoundObjects[i].flags & SOF_PLAYING)
721 SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan;
727 void digi_init_sounds()
731 if (!digi_initialised) return;
733 digi_reset_digi_sounds();
735 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
736 if (digi_sounds_initialized) {
737 if ( SoundObjects[i].flags & SOF_PLAYING ) {
738 SoundSlots[SoundObjects[i].handle].playing=0;
741 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
743 digi_sounds_initialized = 1;
746 //added on 980905 by adb from original source to make sfx volume work
747 void digi_set_digi_volume( int dvolume )
749 dvolume = fixmuldiv( dvolume, SOUND_MAX_VOLUME, 0x7fff);
750 if ( dvolume > SOUND_MAX_VOLUME )
751 digi_volume = SOUND_MAX_VOLUME;
752 else if ( dvolume < 0 )
755 digi_volume = dvolume;
757 if ( !digi_initialised ) return;
763 void digi_set_volume( int dvolume, int mvolume ) { }
765 int digi_is_sound_playing(int soundno)
769 soundno = digi_xlat_sound(soundno);
771 for (i = 0; i < MAX_SOUND_SLOTS; i++)
772 //changed on 980905 by adb: added SoundSlots[i].playing &&
773 if (SoundSlots[i].playing && SoundSlots[i].soundno == soundno)
780 void digi_pause_all() { }
781 void digi_resume_all() { }
782 void digi_stop_all() { }
784 //added on 980905 by adb to make sound channel setting work
785 void digi_set_max_channels(int n) {
786 digi_max_channels = n;
788 if ( digi_max_channels < 1 )
789 digi_max_channels = 1;
790 if ( digi_max_channels > (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) )
791 digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS);
793 if ( !digi_initialised ) return;
795 digi_reset_digi_sounds();
798 int digi_get_max_channels() {
799 return digi_max_channels;
803 void digi_reset_digi_sounds() {
806 for (i=0; i< MAX_SOUND_SLOTS; i++)
807 SoundSlots[i].playing=0;
809 //added on 980905 by adb to reset sound kill system
810 memset(SampleHandles, 255, sizeof(SampleHandles));
816 // MIDI stuff follows.
817 //added/killed on 11/25/98 by Matthew Mueller
818 //void digi_set_midi_volume( int mvolume ) { }
819 //void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ) {}
820 //void digi_stop_current_song()
829 //end this section kill - MM