Subversion Repositories Kolibri OS

Rev

Rev 333 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
298 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:  none
20
//
21
//-----------------------------------------------------------------------------
22
 
23
 
24
static const char
25
rcsid[] = "$Id: s_sound.c,v 1.6 1997/02/03 22:45:12 b1 Exp $";
26
 
27
 
28
#include 
29
#include 
30
 
31
#include "i_system.h"
32
#include "i_sound.h"
33
#include "sounds.h"
34
#include "s_sound.h"
35
 
36
#include "z_zone.h"
37
#include "m_random.h"
38
#include "w_wad.h"
39
 
40
#include "doomdef.h"
41
#include "p_local.h"
42
//#include "m_music.h"
43
 
44
#include "doomstat.h"
45
 
46
//#include "qmus2mid.h"
47
 
342 serge 48
 
49
#include "kolibri.h"
50
 
298 serge 51
void WriteDebug(char *);
52
 
53
// Purpose?
54
const char snd_prefixen[]
55
= { 'P', 'P', 'A', 'S', 'S', 'S', 'M', 'M', 'M', 'S', 'S', 'S' };
56
 
333 serge 57
#define S_MAX_VOLUME            127
298 serge 58
 
59
// when to clip out sounds
60
// Does not fit the large outdoor areas.
333 serge 61
#define S_CLIPPING_DIST         (1200*0x10000)
298 serge 62
 
63
// Distance tp origin when sounds should be maxed out.
64
// This should relate to movement clipping resolution
65
// (see BLOCKMAP handling).
66
// Originally: (200*0x10000).
333 serge 67
#define S_CLOSE_DIST            (160*0x10000)
298 serge 68
 
69
 
333 serge 70
#define S_ATTENUATOR            ((S_CLIPPING_DIST-S_CLOSE_DIST)>>FRACBITS)
298 serge 71
 
72
// Adjustable by menu.
333 serge 73
#define NORM_VOLUME             snd_MaxVolume
298 serge 74
 
333 serge 75
#define NORM_PITCH              128
76
#define NORM_PRIORITY           64
77
#define NORM_SEP                128
298 serge 78
 
333 serge 79
#define S_PITCH_PERTURB         1
80
#define S_STEREO_SWING          (96*0x10000)
298 serge 81
 
82
// percent attenuation from front to back
333 serge 83
#define S_IFRACVOL              30
298 serge 84
 
333 serge 85
#define NA                      0
86
//#define S_NUMCHANNELS         2
87
#define NUM_CHANNELS    16
298 serge 88
 
89
// Current music/sfx card - index useless
90
//  w/o a reference LUT in a sound module.
91
extern int snd_MusicDevice;
92
extern int snd_SfxDevice;
93
// Config file? Same disclaimer as above.
94
extern int snd_DesiredMusicDevice;
95
extern int snd_DesiredSfxDevice;
96
 
97
 
98
typedef struct
99
{
100
    // sound information (if null, channel avail.)
333 serge 101
    sfxinfo_t*  sfxinfo;
298 serge 102
 
103
    // origin of sound
333 serge 104
    void*       origin;
298 serge 105
 
106
    // handle of the sound being played
333 serge 107
    int         handle;
298 serge 108
 
109
} channel_t;
110
 
111
 
112
// the set of channels available
333 serge 113
static channel_t*       channels;
298 serge 114
 
115
// These are not used, but should be (menu).
116
// Maximum volume of a sound effect.
117
// Internal default is max out of 0-15.
342 serge 118
int             snd_SfxVolume = 15;
298 serge 119
 
120
// Maximum volume of music. Useless so far.
342 serge 121
int             snd_MusicVolume = 15;
298 serge 122
 
123
 
124
 
125
// whether songs are mus_paused
333 serge 126
static boolean          mus_paused;
298 serge 127
 
128
// music currently being played
333 serge 129
static musicinfo_t*     mus_playing=0;
298 serge 130
 
131
// following is set
132
//  by the defaults code in M_misc:
133
// number of channels available
333 serge 134
int                     numChannels;
298 serge 135
 
333 serge 136
static int              nextcleanup;
298 serge 137
 
138
 
139
 
140
//
141
// Internals.
142
//
143
int
144
S_getChannel
333 serge 145
( void*         origin,
146
  sfxinfo_t*    sfxinfo,
298 serge 147
  int       sfxid );
148
 
149
 
150
int
151
S_AdjustSoundParams
333 serge 152
( mobj_t*       listener,
153
  mobj_t*       source,
154
  int*          vol,
155
  int*          sep,
156
  int*          pitch );
298 serge 157
 
158
void S_StopChannel(int cnum);
159
 
160
 
161
 
162
//
163
// Initializes sound stuff, including volume
164
// Sets channels, SFX and music volume,
165
//  allocates channel buffer, sets S_sfx lookup.
166
//
342 serge 167
 
168
DWORD hMixBuff[4];
169
int mix_ptr;
170
 
298 serge 171
void S_Init
333 serge 172
( int           sfxVolume,
173
  int           musicVolume )
298 serge 174
{
333 serge 175
  int           i;
298 serge 176
 
177
  printf("S_Init: default sfx volume %d\n", sfxVolume);
178
 
342 serge 179
  InitSound();
180
 
181
  hMixBuff[0]= CreateBuffer(15);
182
  hMixBuff[1]= CreateBuffer(15);
183
  hMixBuff[2]= CreateBuffer(15);
184
  hMixBuff[3]= CreateBuffer(15);
185
 
298 serge 186
  numChannels = NUM_CHANNELS;
187
 
188
  // Whatever these did with DMX, these are rather dummies now.
189
  I_SetChannels();
190
 
191
  S_SetSfxVolume(sfxVolume);
192
  // No music with Linux - another dummy.
193
  S_SetMusicVolume(musicVolume);
194
 
195
  // Allocating the internal channels for mixing
196
  // (the maximum numer of sounds rendered
197
  // simultaneously) within zone memory.
198
  channels =
199
    (channel_t *) Z_Malloc(numChannels*sizeof(channel_t), PU_STATIC, 0);
200
 
201
  // Free all channels for use
202
  for (i=0 ; i
203
    channels[i].sfxinfo = 0;
204
 
205
  // no sounds are playing, and they are not mus_paused
206
  mus_paused = 0;
207
 
208
  // Note that sounds have not been cached (yet).
209
  for (i=1 ; i
210
    S_sfx[i].lumpnum = S_sfx[i].usefulness = -1;
211
}
212
 
213
//
214
// Per level startup code.
215
// Kills playing sounds at start of level,
216
//  determines music if any, changes music.
217
//
218
void S_Start(void)
219
{
220
  int cnum;
221
  int mnum;
222
 
223
  // kill all playing sounds at start of level
224
  //  (trust me - a good idea)
225
  for (cnum=0 ; cnum
226
    if (channels[cnum].sfxinfo)
227
      S_StopChannel(cnum);
228
 
229
  // start new music for the level
230
  mus_paused = 0;
231
 
232
  if (gamemode == commercial)
333 serge 233
          mnum = mus_runnin + gamemap - 1;
298 serge 234
  else
235
  {
333 serge 236
          int spmus[]=
237
          {
238
                  // Song - Who? - Where?
239
                mus_e3m4,       // American     e4m1
240
                mus_e3m2,       // Romero       e4m2
241
                mus_e3m3,       // Shawn        e4m3
242
                mus_e1m5,       // American     e4m4
243
                mus_e2m7,       // Tim  e4m5
244
                mus_e2m4,       // Romero       e4m6
245
                mus_e2m6,       // J.Anderson   e4m7 CHIRON.WAD
246
                mus_e2m5,       // Shawn        e4m8
247
                mus_e1m9        // Tim          e4m9
248
          };
249
 
250
          if (gameepisode < 4)
251
                  mnum = mus_e1m1 + (gameepisode-1)*9 + gamemap-1;
252
          else
253
                  mnum = spmus[gamemap-1];
254
  }
298 serge 255
 
256
  // HACK FOR COMMERCIAL
333 serge 257
  //  if (commercial && mnum > mus_e3m9)
298 serge 258
  //      mnum -= mus_e3m9;
259
 
260
  S_ChangeMusic(mnum, true);
261
 
262
  nextcleanup = 15;
333 serge 263
}
298 serge 264
 
265
void S_StartSoundAtVolume( void *origin_p, int sfx_id, int volume )
266
   {
267
    int        rc;
268
    int        sep;
269
    int        pitch;
270
    int        priority;
271
    sfxinfo_t *sfx;
272
    int        cnum;
273
    // int        chnum;  <-- 10.9.98 compiler warning
274
 
333 serge 275
    mobj_t*     origin = (mobj_t *)origin_p;
298 serge 276
 
277
    //WriteDebug("S_StartSoundAtVolume...\n");
278
 
279
    // Debug.
280
    /*fprintf( stderr,"S_StartSoundAtVolume: playing sound %d (%s)\n",sfx_id, S_sfx[sfx_id].name );*/
281
 
282
    // check for bogus sound #
283
    if (sfx_id < 1 || sfx_id > NUMSFX)
284
        I_Error("Bad sfx #: %d", sfx_id);
285
 
286
    sfx = &S_sfx[sfx_id];
287
 
288
    // Initialize sound parameters
289
    if (sfx->link)
290
       {
291
        pitch = sfx->pitch;
292
        priority = sfx->priority;
293
        volume += sfx->volume;
294
 
295
        if (volume < 1)
296
           {
297
            //WriteDebug("Volume off...\n");
298
            return;
299
           }
300
 
301
        if (volume > snd_SfxVolume)
302
            volume = snd_SfxVolume;
333 serge 303
       }
298 serge 304
    else
305
       {
306
        pitch = NORM_PITCH;
307
        priority = NORM_PRIORITY;
308
       }
309
 
310
 
311
    // Check to see if it is audible,
312
    //  and if not, modify the params
313
    if (origin && origin != players[consoleplayer].mo)
314
       {
315
        rc = S_AdjustSoundParams(players[consoleplayer].mo, origin, &volume, &sep, &pitch);
316
        if ( origin->x == players[consoleplayer].mo->x && origin->y == players[consoleplayer].mo->y)
333 serge 317
           {
298 serge 318
            sep = NORM_SEP;
319
           }
320
        if (!rc)
321
           {
322
            //WriteDebug("No rc from S_AdjustSoundParams...\n");
323
            return;
324
           }
333 serge 325
       }
298 serge 326
    else
327
       {
328
        sep = NORM_SEP;
329
       }
330
 
331
    // hacks to vary the sfx pitches
332
    if (sfx_id >= sfx_sawup && sfx_id <= sfx_sawhit)
333 serge 333
       {
298 serge 334
        pitch += 8 - (M_Random()&15);
335
        if (pitch < 0)
336
            pitch = 0;
337
        else
338
        if (pitch>255)
339
            pitch = 255;
340
       }
341
    else
342
    if (sfx_id != sfx_itemup && sfx_id != sfx_tink)
343
       {
344
        pitch += 16 - (M_Random()&31);
345
        if (pitch<0)
346
            pitch = 0;
347
        else
348
        if (pitch > 255)
349
            pitch = 255;
350
       }
351
 
352
  // kill old sound
353
  S_StopSound(origin);
354
 
355
  // try to find a channel
356
  cnum = S_getChannel(origin, sfx, sfx_id);
357
 
358
  if (cnum<0)
359
     {
360
        //WriteDebug("cnum < 0 -- no channel...\n");
361
    return;
362
     }
363
 
364
  //
365
  // This is supposed to handle the loading/caching.
366
  // For some odd reason, the caching is done nearly
367
  //  each time the sound is needed?
368
  //
369
 
370
  // get lumpnum if necessary
371
  if (sfx->lumpnum < 0)
372
    sfx->lumpnum = I_GetSfxLumpNum(sfx);
373
 
374
  // cache data if necessary
375
  if (!sfx->data)
376
  {
377
    sfx->data = (void *) W_CacheLumpNum(sfx->lumpnum, PU_MUSIC);
378
 
379
  }
380
 
381
  // increase the usefulness
382
  if (sfx->usefulness++ < 0)
383
      sfx->usefulness = 1;
384
 
385
  // Assigns the handle to one of the channels in the
386
  //  mix/output buffer.
387
  //WriteDebug("I_StartSound...\n");
333 serge 388
  channels[cnum].handle = I_StartSound(sfx_id,volume,sep,pitch,priority);
298 serge 389
  channels[cnum].handle = cnum;
390
  channels[cnum].sfxinfo = sfx;
391
  channels[cnum].origin = origin;
333 serge 392
}
298 serge 393
 
394
void S_StartSound( void *origin, int sfx_id )
395
   {
396
#ifdef SAWDEBUG
397
    // if (sfx_id == sfx_sawful)
398
    // sfx_id = sfx_itemup;
399
#endif
400
 
401
    S_StartSoundAtVolume(origin, sfx_id, snd_SfxVolume);
402
 
403
 
404
    // UNUSED. We had problems, had we not?
405
#ifdef SAWDEBUG
406
{
407
    int i;
408
    int n;
333 serge 409
 
298 serge 410
    static mobj_t*      last_saw_origins[10] = {1,1,1,1,1,1,1,1,1,1};
333 serge 411
    static int          first_saw=0;
412
    static int          next_saw=0;
413
 
298 serge 414
    if (sfx_id == sfx_sawidl
333 serge 415
        || sfx_id == sfx_sawful
416
        || sfx_id == sfx_sawhit)
298 serge 417
    {
333 serge 418
        for (i=first_saw;i!=next_saw;i=(i+1)%10)
419
            if (last_saw_origins[i] != origin)
420
                fprintf(stderr, "old origin 0x%lx != "
421
                        "origin 0x%lx for sfx %d\n",
422
                        last_saw_origins[i],
423
                        origin,
424
                        sfx_id);
425
 
426
        last_saw_origins[next_saw] = origin;
427
        next_saw = (next_saw + 1) % 10;
428
        if (next_saw == first_saw)
429
            first_saw = (first_saw + 1) % 10;
430
 
431
        for (n=i=0; i
432
        {
433
            if (channels[i].sfxinfo == &S_sfx[sfx_sawidl]
434
                || channels[i].sfxinfo == &S_sfx[sfx_sawful]
435
                || channels[i].sfxinfo == &S_sfx[sfx_sawhit]) n++;
436
        }
437
 
438
        if (n>1)
439
        {
440
            for (i=0; i
441
            {
442
                if (channels[i].sfxinfo == &S_sfx[sfx_sawidl]
443
                    || channels[i].sfxinfo == &S_sfx[sfx_sawful]
444
                    || channels[i].sfxinfo == &S_sfx[sfx_sawhit])
445
                {
446
                    fprintf(stderr,
447
                            "chn: sfxinfo=0x%lx, origin=0x%lx, "
448
                            "handle=%d\n",
449
                            channels[i].sfxinfo,
450
                            channels[i].origin,
451
                            channels[i].handle);
452
                }
453
            }
454
            fprintf(stderr, "\n");
455
        }
298 serge 456
    }
457
}
458
#endif
459
 
460
}
461
 
462
 
463
 
464
 
465
void S_StopSound(void *origin)
466
{
467
 
468
    int cnum;
469
 
470
    for (cnum=0 ; cnum
471
    {
333 serge 472
        if (channels[cnum].sfxinfo && channels[cnum].origin == origin)
473
        {
474
            S_StopChannel(cnum);
475
            break;
476
        }
298 serge 477
    }
478
}
479
 
480
 
481
 
482
 
483
 
484
 
485
 
486
 
487
 
488
//
489
// Stop and resume music, during game PAUSE.
490
//
491
void S_PauseSound(void)
492
{
493
    if (mus_playing && !mus_paused)
494
    {
333 serge 495
        I_PauseSong(mus_playing->handle);
496
        mus_paused = true;
298 serge 497
    }
498
}
499
 
500
void S_ResumeSound(void)
501
{
502
    if (mus_playing && mus_paused)
503
    {
333 serge 504
        I_ResumeSong(mus_playing->handle);
505
        mus_paused = false;
298 serge 506
    }
507
}
508
 
509
 
510
//
511
// Updates music & sounds
512
//
513
void S_UpdateSounds(void* listener_p)
514
{
333 serge 515
    int         audible;
516
    int         cnum;
517
    int         volume;
518
    int         sep;
519
    int         pitch;
520
    sfxinfo_t*  sfx;
521
    channel_t*  c;
298 serge 522
 
333 serge 523
    mobj_t*     listener = (mobj_t*)listener_p;
298 serge 524
 
525
 
526
 
527
    // Clean up unused data.
528
    // This is currently not done for 16bit (sounds cached static).
529
    // DOS 8bit remains.
530
    /*if (gametic > nextcleanup)
531
    {
333 serge 532
        for (i=1 ; i
533
        {
534
            if (S_sfx[i].usefulness < 1
535
                && S_sfx[i].usefulness > -1)
536
            {
537
                if (--S_sfx[i].usefulness == -1)
538
                {
539
                    Z_ChangeTag(S_sfx[i].data, PU_CACHE);
540
                    S_sfx[i].data = 0;
541
                }
542
            }
543
        }
544
        nextcleanup = gametic + 15;
298 serge 545
    }*/
546
 
547
    for (cnum=0 ; cnum
548
    {
333 serge 549
        c = &channels[cnum];
550
        sfx = c->sfxinfo;
298 serge 551
 
333 serge 552
        if (c->sfxinfo)
553
        {
554
            if (I_SoundIsPlaying(c->handle))
555
            {
556
                // initialize parameters
557
                volume = snd_SfxVolume;
558
                pitch = NORM_PITCH;
559
                sep = NORM_SEP;
298 serge 560
 
333 serge 561
                if (sfx->link)
562
                {
563
                    pitch = sfx->pitch;
564
                    volume += sfx->volume;
565
                    if (volume < 1)
566
                    {
567
                        S_StopChannel(cnum);
568
                        continue;
569
                    }
570
                    else if (volume > snd_SfxVolume)
571
                    {
572
                        volume = snd_SfxVolume;
573
                    }
574
                }
298 serge 575
 
333 serge 576
                // check non-local sounds for distance clipping
577
                //  or modify their params
578
                if (c->origin && listener_p != c->origin)
579
                {
580
                    audible = S_AdjustSoundParams(listener,
581
                                                  c->origin,
582
                                                  &volume,
583
                                                  &sep,
584
                                                  &pitch);
585
 
586
                    if (!audible)
587
                    {
588
                        S_StopChannel(cnum);
589
                    }
590
                    else
591
                        I_UpdateSoundParams(c->handle, volume, sep, pitch);
592
                }
593
            }
594
            else
595
            {
596
                // if channel is allocated but sound has stopped,
597
                //  free it
598
                S_StopChannel(cnum);
599
            }
600
        }
298 serge 601
    }
602
    // kill music if it is a single-play && finished
333 serge 603
    // if (     mus_playing
298 serge 604
    //      && !I_QrySongPlaying(mus_playing->handle)
605
    //      && !mus_paused )
606
    // S_StopMusic();
607
}
608
 
609
 
610
void S_SetMusicVolume(int volume)
611
{
612
    if (volume < 0 || volume > 127)
613
    {
333 serge 614
        I_Error("Attempt to set music volume at %d",
615
                volume);
298 serge 616
    }
617
 
618
    I_SetMusicVolume(127);
619
    I_SetMusicVolume(volume);
620
    snd_MusicVolume = volume;
621
}
622
 
623
 
624
 
625
void S_SetSfxVolume(int volume)
626
{
627
 
628
    if (volume < 0 || volume > 127)
333 serge 629
        I_Error("Attempt to set sfx volume at %d", volume);
298 serge 630
 
631
    snd_SfxVolume = volume;
632
 
633
}
634
 
635
//
636
// Starts some music with the music id found in sounds.h.
637
//
638
void S_StartMusic(int m_id)
639
{
640
//    S_ChangeMusic(m_id, false);
641
}
642
 
643
 
644
// clean-up&code for orig midi 10.9.98-dlw
645
void S_ChangeMusic(int musicnum, int looping)
646
{
647
 
648
    // I_PlaySong(music->handle, looping);
333 serge 649
//      mus_playing = music;
298 serge 650
}
651
 
652
 
653
void S_StopMusic(void)
654
{
655
    if (mus_playing)
656
    {
333 serge 657
                if (mus_paused) I_ResumeSong(mus_playing->handle);
658
                I_StopSong(mus_playing->handle);
659
                I_UnRegisterSong(mus_playing->handle);
660
                Z_ChangeTag(mus_playing->data, PU_CACHE);
661
                mus_playing->data = 0;
662
                mus_playing = 0;
298 serge 663
    }
664
}
665
 
666
void S_StopChannel(int cnum)
667
{
668
 
333 serge 669
    int         i;
670
    channel_t*  c = &channels[cnum];
298 serge 671
 
672
    if (c->sfxinfo)
673
    {
333 serge 674
        // stop the sound playing
675
        if (I_SoundIsPlaying(c->handle))
676
        {
298 serge 677
#ifdef SAWDEBUG
333 serge 678
            if (c->sfxinfo == &S_sfx[sfx_sawful])
679
                fprintf(stderr, "stopped\n");
298 serge 680
#endif
333 serge 681
            I_StopSound(c->handle);
682
        }
298 serge 683
 
333 serge 684
        // check to see
685
        //  if other channels are playing the sound
686
        for (i=0 ; i
687
        {
688
            if (cnum != i
689
                && c->sfxinfo == channels[i].sfxinfo)
690
            {
691
                break;
692
            }
693
        }
694
 
695
        // degrade usefulness of sound data
696
        c->sfxinfo->usefulness--;
298 serge 697
 
333 serge 698
        c->sfxinfo = 0;
298 serge 699
    }
700
}
701
 
702
 
703
//
704
// Changes volume, stereo-separation, and pitch variables
705
//  from the norm of a sound effect to be played.
706
// If the sound is not audible, returns a 0.
707
// Otherwise, modifies parameters and returns 1.
708
//
709
int
710
S_AdjustSoundParams (mobj_t* listener, mobj_t* source,
711
                     int* vol, int* sep, int* pitch)
712
{
333 serge 713
    fixed_t     approx_dist;
714
    fixed_t     adx;
715
    fixed_t     ady;
716
    angle_t     angle;
298 serge 717
 
718
    // calculate the distance to sound origin
719
    //  and clip it if necessary
720
    adx = abs(listener->x - source->x);
721
    ady = abs(listener->y - source->y);
722
 
723
    // From _GG1_ p.428. Appox. eucledian distance fast.
724
    approx_dist = adx + ady - ((adx < ady ? adx : ady)>>1);
725
 
726
    if (gamemap != 8
333 serge 727
        && approx_dist > S_CLIPPING_DIST)
298 serge 728
    {
333 serge 729
        return 0;
298 serge 730
    }
731
 
732
    // angle of source to listener
733
    angle = R_PointToAngle2(listener->x,
333 serge 734
                            listener->y,
735
                            source->x,
736
                            source->y);
298 serge 737
 
738
    if (angle > listener->angle)
333 serge 739
        angle = angle - listener->angle;
298 serge 740
    else
333 serge 741
        angle = angle + (0xffffffff - listener->angle);
298 serge 742
 
743
    angle >>= ANGLETOFINESHIFT;
744
 
745
    // stereo separation
746
    *sep = 128 - (FixedMul(S_STEREO_SWING,finesine[angle])>>FRACBITS);
747
 
748
    // volume calculation
749
    if (approx_dist < S_CLOSE_DIST)
750
    {
333 serge 751
        *vol = snd_SfxVolume;
298 serge 752
    }
753
    else if (gamemap == 8)
754
    {
333 serge 755
        if (approx_dist > S_CLIPPING_DIST)
756
            approx_dist = S_CLIPPING_DIST;
298 serge 757
 
333 serge 758
        *vol = 15+ ((snd_SfxVolume-15)
759
                    *((S_CLIPPING_DIST - approx_dist)>>FRACBITS))
760
            / S_ATTENUATOR;
298 serge 761
    }
762
    else
763
    {
333 serge 764
        // distance effect
765
        *vol = (snd_SfxVolume
766
                * ((S_CLIPPING_DIST - approx_dist)>>FRACBITS))
767
            / S_ATTENUATOR;
298 serge 768
    }
769
 
770
    return (*vol > 0);
771
}
772
 
773
//
774
// S_getChannel :
775
//   If none available, return -1.  Otherwise channel #.
776
//
777
int S_getChannel( void *origin, sfxinfo_t *sfxinfo, int sfxid )
778
   {
779
    // channel number to use
333 serge 780
    int         cnum;
298 serge 781
 
333 serge 782
    channel_t*  c;
298 serge 783
 
784
    // Find an open channel
785
    //for (cnum = 0; cnum < numChannels; cnum++)
786
    for (cnum = 0; cnum < NUM_CHANNELS; cnum++)
787
       {
788
        if (!channels[cnum].sfxinfo)
789
            break;
790
        else
791
        if (origin && channels[cnum].origin == origin)
792
           {
793
            S_StopChannel(cnum);
794
            break;
795
           }
796
       }
797
 
798
    // None available
799
    if (cnum == NUM_CHANNELS)
800
       {
801
        // Look for lower priority
802
        for (cnum = NUMSFX; cnum < NUM_CHANNELS; cnum++)
803
             if (channels[cnum].sfxinfo->priority >= sfxinfo->priority)
804
                 break;
805
 
806
        if (cnum == numChannels)
807
           {
808
            // FUCK!  No lower priority.  Sorry, Charlie.
809
            return -1;
810
           }
811
        else
812
           {
813
            // Otherwise, kick out lower priority.
814
            S_StopChannel(cnum);
815
           }
816
       }
817
 
818
    c = &channels[cnum];
819
 
820
    // channel is decided to be cnum.
821
    c->sfxinfo = sfxinfo;
822
    c->origin = origin;
823
 
824
    return cnum;
825
   }
826
 
827
 
828