Subversion Repositories Kolibri OS

Rev

Rev 298 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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