Subversion Repositories Kolibri OS

Rev

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