4b825dc642cb6eb9a060e54bf8d69288fbee4904ebd360ec63ec976c05699f3180e866b3f69e5472
 
 
1
#include "system.h"
 
 
2
#include "stratdef.h"
 
 
3
#include "psndplat.h"
 
 
4
#include "userprofile.h"
 
 
5
#include <assert.h>
 
 
6
 
 
 
7
int MasterVolumeFadeLevel = ONE_FIXED;
 
 
8
static enum {FADE_STATUS_READY, FADE_STATUS_UP, FADE_STATUS_DOWN, FADE_STATUS_DOWN_FAST} MasterVolumeFadeStatus = FADE_STATUS_READY;
 
 
9
static unsigned int Sound_MaxActive_HW = SOUND_MAXACTIVE_SW + 32;
 
 
10
 
 
 
11
void Sound_Stop(int activeSoundNumber)
 
 
12
{
 
 
13
    if((activeSoundNumber < 0) || (activeSoundNumber >= SOUND_MAXACTIVE))
 
 
14
        return;
 
 
15
 
 
 
16
    if(SID_NOSOUND != ActiveSounds[activeSoundNumber].soundIndex)
 
 
17
    {
 
 
18
        /* update game sound instances, and external reference */
 
 
19
        SOUNDINDEX soundNo = ActiveSounds[activeSoundNumber].soundIndex;
 
 
20
        GameSounds[soundNo].activeInstances--;
 
 
21
 
 
 
22
        assert((GameSounds[soundNo].activeInstances >= 0) && (GameSounds[soundNo].activeInstances < SOUND_MAXINSTANCES));
 
 
23
 
 
 
24
        if(ActiveSounds[activeSoundNumber].externalRef)
 
 
25
            *(ActiveSounds[activeSoundNumber].externalRef) = SOUND_NOACTIVEINDEX;
 
 
26
 
 
 
27
        /* stop the sound: it may have already stopped, of course, but never mind */
 
 
28
 
 
 
29
        PlatStopSound(activeSoundNumber);
 
 
30
 
 
 
31
        //fprintf(stderr, "PSND: Stop: %d %d %s\n", activeSoundNumber, soundNo, GameSounds[soundNo].wavName);
 
 
32
        ActiveSounds[activeSoundNumber].soundIndex = SID_NOSOUND;
 
 
33
    }
 
 
34
}
 
 
35
 
 
 
36
void SoundSys_StopAll()
 
 
37
{
 
 
38
    int i;
 
 
39
    for(i=0; i < SOUND_MAXACTIVE; i++)
 
 
40
        Sound_Stop(i);
 
 
41
}
 
 
42
 
 
 
43
void SoundSys_ChangeVolume(int volume)
 
 
44
{
 
 
45
    static int GlobalVolume = VOLUME_DEFAULT;
 
 
46
 
 
 
47
    if (GlobalVolume != volume)
 
 
48
    {
 
 
49
        int newVolume = (volume > VOLUME_MAX) ? VOLUME_MAX : (volume < VOLUME_MIN) ? VOLUME_MIN : volume;
 
 
50
 
 
 
51
        if (newVolume != GlobalVolume)
 
 
52
        {
 
 
53
            GlobalVolume = newVolume;
 
 
54
 
 
 
55
            /* call the platform function: if we get back an error, ignore it */
 
 
56
            PlatChangeGlobalVolume(newVolume);
 
 
57
        }
 
 
58
    }
 
 
59
}
 
 
60
 
 
 
61
static void HandleFadingLevel()
 
 
62
{
 
 
63
    switch(MasterVolumeFadeStatus)
 
 
64
    {
 
 
65
        default:
 
 
66
        case FADE_STATUS_READY:
 
 
67
        break;
 
 
68
        case FADE_STATUS_UP:
 
 
69
        {
 
 
70
            MasterVolumeFadeLevel += NormalFrameTime/2;
 
 
71
 
 
 
72
            if (MasterVolumeFadeLevel > ONE_FIXED)
 
 
73
            {
 
 
74
                MasterVolumeFadeLevel = ONE_FIXED;
 
 
75
                MasterVolumeFadeStatus = FADE_STATUS_READY;
 
 
76
            }
 
 
77
        }
 
 
78
        break;
 
 
79
        case FADE_STATUS_DOWN:
 
 
80
        {
 
 
81
            MasterVolumeFadeLevel -= NormalFrameTime/8;
 
 
82
 
 
 
83
            if (MasterVolumeFadeLevel < 0)
 
 
84
            {
 
 
85
                MasterVolumeFadeLevel = 0;
 
 
86
                MasterVolumeFadeStatus = FADE_STATUS_READY;
 
 
87
            }
 
 
88
        }
 
 
89
        break;
 
 
90
        case FADE_STATUS_DOWN_FAST:
 
 
91
        {
 
 
92
            MasterVolumeFadeLevel -= NormalFrameTime;
 
 
93
 
 
 
94
            if (MasterVolumeFadeLevel < 0)
 
 
95
            {
 
 
96
                MasterVolumeFadeLevel = 0;
 
 
97
                MasterVolumeFadeStatus = FADE_STATUS_READY;
 
 
98
            }
 
 
99
        }
 
 
100
    }
 
 
101
}
 
 
102
 
 
 
103
void SoundSys_Management()
 
 
104
{
 
 
105
    int i;
 
 
106
 
 
 
107
    for(i=0; i < SOUND_MAXACTIVE; i++)
 
 
108
    {
 
 
109
        if(SID_NOSOUND != ActiveSounds[i].soundIndex)
 
 
110
        {
 
 
111
            if(SoundHasStopped(i))
 
 
112
            {
 
 
113
                Sound_Stop(i);
 
 
114
            }
 
 
115
            else if(ActiveSounds[i].threedee) 
 
 
116
            {
 
 
117
                PlatDo3dSound(i);
 
 
118
            }        
 
 
119
        }
 
 
120
    }
 
 
121
 
 
 
122
    HandleFadingLevel();
 
 
123
    PlatUpdatePlayer();
 
 
124
 
 
 
125
#if DEBUG_SOUNDS
 
 
126
    {
 
 
127
        int i = Sound_MaxActive_HW;
 
 
128
        int num_active = 0;
 
 
129
 
 
 
130
        while(i-- > 0)
 
 
131
        {
 
 
132
            if(ActiveSounds[i].soundIndex != SID_NOSOUND)
 
 
133
                num_active++;
 
 
134
        }
 
 
135
 
 
 
136
        printf("Number of Active Sounds %u \n", num_active);
 
 
137
 
 
 
138
        i = Sound_MaxActive_HW;
 
 
139
 
 
 
140
        while(i-- > 0)
 
 
141
        {
 
 
142
            if(ActiveSounds[i].soundIndex != SID_NOSOUND)
 
 
143
                printf("%s\n", GameSounds[ActiveSounds[i].soundIndex].wavName);
 
 
144
        }
 
 
145
    }
 
 
146
#endif
 
 
147
 
 
 
148
    switch(UserProfile.active_bonus)
 
 
149
    {
 
 
150
        case CHEATMODE_WARPSPEED:
 
 
151
        case CHEATMODE_JOHNWOO:
 
 
152
            UpdateSoundFrequencies();
 
 
153
        default:
 
 
154
        break;
 
 
155
    }
 
 
156
}
 
 
157
 
 
 
158
void SoundSys_ResetFadeLevel()
 
 
159
{
 
 
160
    MasterVolumeFadeLevel = ONE_FIXED;
 
 
161
    MasterVolumeFadeStatus = FADE_STATUS_READY;    
 
 
162
}
 
 
163
 
 
 
164
void SoundSys_FadeIn()
 
 
165
{
 
 
166
    /* always fade in from silence ? */
 
 
167
    MasterVolumeFadeLevel = ONE_FIXED/2;
 
 
168
    MasterVolumeFadeStatus = FADE_STATUS_UP;    
 
 
169
}
 
 
170
 
 
 
171
void SoundSys_FadeOut()
 
 
172
{
 
 
173
    MasterVolumeFadeLevel = ONE_FIXED;
 
 
174
    MasterVolumeFadeStatus = FADE_STATUS_DOWN;    
 
 
175
}
 
 
176
 
 
 
177
void SoundSys_FadeOutFast()
 
 
178
{
 
 
179
    MasterVolumeFadeLevel = ONE_FIXED;
 
 
180
    MasterVolumeFadeStatus = FADE_STATUS_DOWN_FAST;    
 
 
181
}
 
 
182
 
 
 
183
static int FindFreeActiveSound(unsigned int min, unsigned int max)
 
 
184
{
 
 
185
    unsigned int i = min;
 
 
186
 
 
 
187
    for(; i < max; i++) 
 
 
188
    {
 
 
189
        if(ActiveSounds[i].soundIndex == SID_NOSOUND)
 
 
190
                return i;
 
 
191
    }
 
 
192
 
 
 
193
return SOUND_NOACTIVEINDEX;
 
 
194
}
 
 
195
 
 
 
196
static int FindLowerPriorityActiveSound(ACTIVESOUNDPRIORITY testPriority, unsigned int min, unsigned int max)
 
 
197
{
 
 
198
    unsigned int i = min;
 
 
199
 
 
 
200
    for(; i < max; i++) 
 
 
201
    {
 
 
202
        if((ActiveSounds[i].soundIndex != SID_NOSOUND) && (ActiveSounds[i].priority < testPriority))
 
 
203
                return i;
 
 
204
    }
 
 
205
 
 
 
206
return SOUND_NOACTIVEINDEX;
 
 
207
}
 
 
208
 
 
 
209
/* Patrick 5/6/97 -------------------------------------------------------------
 
 
210
  Functions for playing and controlling individual sounds
 
 
211
  ----------------------------------------------------------------------------*/
 
 
212
void Sound_Play(SOUNDINDEX soundNumber, const char *format, ...)
 
 
213
{
 
 
214
    /* check soundIndex for bounds, whether it has been loaded, and number of instances */
 
 
215
    if((soundNumber < 0) || (soundNumber >= SID_MAXIMUM) || !GameSounds[soundNumber].loaded || !(GameSounds[soundNumber].activeInstances <
SOUND_MAXINSTANCES))
 
 
216
        return;
 
 
217
 
 
 
218
    int loop = 0;
 
 
219
    int *externalRef = NULL;
 
 
220
    ACTIVESOUNDPRIORITY priority = ASP_Minimum;
 
 
221
    SOUND3DDATA * p_3ddata = NULL;
 
 
222
    VECTORCH * worldPosn = NULL;
 
 
223
    int reverb_off = 0;
 
 
224
    int soundStartPosition = 0;
 
 
225
    int species = -1;
 
 
226
    int species_category = -1;
 
 
227
 
 
 
228
    //printf("About to play sound %i %s\n", soundNumber, GameSounds[soundNumber].wavName);
 
 
229
 
 
 
230
    int volume = GameSounds[soundNumber].volume;
 
 
231
    int pitch = GameSounds[soundNumber].pitch;
 
 
232
    int marine_ignore = 0;
 
 
233
 
 
 
234
    /* examine the format string: if it is null, ignore it */
 
 
235
    if(format)
 
 
236
    {
 
 
237
        const char *nextChar = format;
 
 
238
        va_list argPtr;
 
 
239
 
 
 
240
        va_start(argPtr, format);
 
 
241
 
 
 
242
        while(*nextChar != '\0')
 
 
243
        {
 
 
244
            switch(*nextChar)
 
 
245
            {
 
 
246
                case 'd':
 
 
247
                    worldPosn = va_arg(argPtr, VECTORCH*);
 
 
248
                break;
 
 
249
                case 'n':
 
 
250
                    p_3ddata = va_arg(argPtr, SOUND3DDATA*);
 
 
251
                break;
 
 
252
                case 'e':
 
 
253
                    externalRef = va_arg(argPtr, int*);
 
 
254
                break;
 
 
255
                case 'l':
 
 
256
                    loop = 1;
 
 
257
                //no break;
 
 
258
                case 'h':
 
 
259
                    priority = ASP_Maximum;
 
 
260
                break;
 
 
261
                case 'v':
 
 
262
                {
 
 
263
                    volume = va_arg(argPtr, int);
 
 
264
 
 
 
265
                    if(volume > VOLUME_MAX)
 
 
266
                        volume = VOLUME_MAX;
 
 
267
                    else if(volume < VOLUME_MIN)
 
 
268
                        volume = VOLUME_MIN;
 
 
269
                }        
 
 
270
                break;
 
 
271
                case 'p':
 
 
272
                {                    
 
 
273
                    pitch = va_arg(argPtr, int);
 
 
274
 
 
 
275
                    if(pitch > PITCH_MAX)
 
 
276
                        pitch = PITCH_MAX;
 
 
277
                    else if(pitch < PITCH_MIN)
 
 
278
                        pitch = PITCH_MIN;
 
 
279
                }
 
 
280
                break;
 
 
281
                case 'm':
 
 
282
                    marine_ignore = 1;
 
 
283
                break;
 
 
284
                case 'r':
 
 
285
                    reverb_off = 1;
 
 
286
                break;
 
 
287
                case 'P':
 
 
288
                    soundStartPosition = va_arg(argPtr,int);
 
 
289
                break;
 
 
290
                case 's':
 
 
291
                    species = va_arg(argPtr, int);
 
 
292
                break;
 
 
293
                case 'c':
 
 
294
                    species_category = va_arg(argPtr, int);
 
 
295
                default:
 
 
296
                break;
 
 
297
            }
 
 
298
            nextChar++;
 
 
299
        }
 
 
300
        va_end(argPtr);    
 
 
301
    }
 
 
302
 
 
 
303
    /* check for invalid parameter combinations */
 
 
304
    if(loop && (externalRef == NULL))
 
 
305
    {
 
 
306
        printf("SoundPlay bad params.\n");
 
 
307
        return;
 
 
308
    }
 
 
309
 
 
 
310
    /* Deal with resource allocation. */
 
 
311
    /* Range of active buffers to search. */
 
 
312
    unsigned int min, max;
 
 
313
    GameSounds[soundNumber].flags |= SAMPLE_IN_SW;
 
 
314
    if(GameSounds[soundNumber].flags & SAMPLE_IN_SW)
 
 
315
    {
 
 
316
        min = 0;
 
 
317
        max = SOUND_MAXACTIVE_SW;
 
 
318
    }
 
 
319
    else
 
 
320
    {
 
 
321
        min = SOUND_MAXACTIVE_SW + 1;
 
 
322
        max = Sound_MaxActive_HW;
 
 
323
    }
 
 
324
 
 
 
325
    int newIndex = FindFreeActiveSound(min, max);
 
 
326
 
 
 
327
    if((newIndex == SOUND_NOACTIVEINDEX) && !(GameSounds[soundNumber].flags & SAMPLE_IN_SW))
 
 
328
    {
 
 
329
        //failed to find a free hardware slot , so try software slot instead.
 
 
330
        //mainly to cope with cards that can load sounds into hardware , but can't play them there
 
 
331
        newIndex = FindFreeActiveSound(0, SOUND_MAXACTIVE_SW);
 
 
332
    }
 
 
333
 
 
 
334
    if(newIndex == SOUND_NOACTIVEINDEX)
 
 
335
    {
 
 
336
        printf("Having to stop another sound.\n");
 
 
337
        /* try to find an existing sound with a lower priority */
 
 
338
        newIndex = FindLowerPriorityActiveSound(priority, min, max);
 
 
339
 
 
 
340
        if(newIndex == SOUND_NOACTIVEINDEX && !(GameSounds[soundNumber].flags & SAMPLE_IN_SW))
 
 
341
        {
 
 
342
            //failed to find a free hardware slot , so try software slot instead.
 
 
343
            //mainly to cope with cards that can load sounds into hardware , but can't play them there
 
 
344
            newIndex = FindLowerPriorityActiveSound(priority, 0, SOUND_MAXACTIVE_SW);
 
 
345
        }
 
 
346
 
 
 
347
        if(newIndex == SOUND_NOACTIVEINDEX)
 
 
348
        {
 
 
349
            printf("Failed to find a lower priority sound.\n");
 
 
350
            return; /* give up */
 
 
351
        }
 
 
352
 
 
 
353
        /* remove it, and use it's slot */
 
 
354
        printf("Stopping a lower priority sound.\n");
 
 
355
        Sound_Stop(newIndex);
 
 
356
    }
 
 
357
    //else printf("Found a free slot.\n");
 
 
358
 
 
 
359
    if (GameSounds[soundNumber].loaded)
 
 
360
    {
 
 
361
        ActiveSounds[newIndex].soundIndex = soundNumber;
 
 
362
        ActiveSounds[newIndex].priority = priority;
 
 
363
        ActiveSounds[newIndex].volume = volume;
 
 
364
        ActiveSounds[newIndex].pitch = pitch;
 
 
365
        ActiveSounds[newIndex].externalRef = externalRef;
 
 
366
        ActiveSounds[newIndex].species = species;
 
 
367
        ActiveSounds[newIndex].species_category = species_category;
 
 
368
        ActiveSounds[newIndex].loop = loop;
 
 
369
        ActiveSounds[newIndex].threedee = 0;
 
 
370
        ActiveSounds[newIndex].paused = 0;
 
 
371
        ActiveSounds[newIndex].marine_ignore = marine_ignore;
 
 
372
        ActiveSounds[newIndex].reverb_off = reverb_off;
 
 
373
 
 
 
374
        if(worldPosn) 
 
 
375
        {
 
 
376
            ActiveSounds[newIndex].threedeedata.position = *worldPosn;
 
 
377
            ActiveSounds[newIndex].threedeedata.outer_range = 32000;
 
 
378
            ActiveSounds[newIndex].threedee = 1;
 
 
379
        }
 
 
380
        else if(p_3ddata)
 
 
381
        {
 
 
382
            ActiveSounds[newIndex].threedeedata = *p_3ddata;
 
 
383
            ActiveSounds[newIndex].threedee = 1;
 
 
384
        }
 
 
385
 
 
 
386
        if(PlatPlaySound(newIndex))
 
 
387
        {
 
 
388
            GameSounds[soundNumber].activeInstances++;
 
 
389
 
 
 
390
            if(externalRef)
 
 
391
                *externalRef = newIndex;
 
 
392
        }
 
 
393
        else
 
 
394
        {
 
 
395
            /* the sound failed to play: any platform cleanups should have been done, so just bank the sound slot */
 
 
396
            ActiveSounds[newIndex].soundIndex = SID_NOSOUND;
 
 
397
            printf("Error: PlatPlaySound failed for %d.\n", soundNumber);
 
 
398
        }
 
 
399
    }
 
 
400
    else
 
 
401
    {
 
 
402
        printf("GameSound %d not loaded \n", soundNumber);
 
 
403
    }
 
 
404
}
 
 
405
 
 
 
406
void Sound_ChangeVolume(int activeSoundNumber, int volume)
 
 
407
{
 
 
408
    if((activeSoundNumber < 0) || (activeSoundNumber >= SOUND_MAXACTIVE))
 
 
409
        return;
 
 
410
 
 
 
411
    if(SID_NOSOUND != ActiveSounds[activeSoundNumber].soundIndex)
 
 
412
    {
 
 
413
        /* check the new volume is different from the old one */
 
 
414
        if(volume != ActiveSounds[activeSoundNumber].volume)
 
 
415
        {
 
 
416
            ActiveSounds[activeSoundNumber].volume = (volume > VOLUME_MAX) ? VOLUME_MAX : (volume < VOLUME_MIN) ? VOLUME_MIN : volume;
 
 
417
 
 
 
418
            /* if we're a 2d sound, just change the volume, but if we're 3d then call 3d update instead */
 
 
419
 
 
 
420
            if(ActiveSounds[activeSoundNumber].threedee)
 
 
421
                PlatDo3dSound(activeSoundNumber);
 
 
422
            else
 
 
423
                PlatChangeSoundVolume(activeSoundNumber,ActiveSounds[activeSoundNumber].volume);    
 
 
424
        }
 
 
425
    }
 
 
426
}
 
 
427
 
 
 
428
void Sound_ChangePitch(int activeSoundNumber, int pitch)
 
 
429
{
 
 
430
    if((activeSoundNumber < 0) || (activeSoundNumber >= SOUND_MAXACTIVE))
 
 
431
        return;
 
 
432
 
 
 
433
    if(SID_NOSOUND != ActiveSounds[activeSoundNumber].soundIndex)
 
 
434
    {
 
 
435
        if(pitch != ActiveSounds[activeSoundNumber].pitch)
 
 
436
        {
 
 
437
            ActiveSounds[activeSoundNumber].pitch = (pitch > PITCH_MAX) ? PITCH_MAX : (pitch < PITCH_MIN) ? PITCH_MIN : pitch;
 
 
438
            PlatChangeSoundPitch(activeSoundNumber,ActiveSounds[activeSoundNumber].pitch);    
 
 
439
        }
 
 
440
    }
 
 
441
}
 
 
442
 
 
 
443
void Sound_Update3d(int activeSoundNumber, VECTORCH* posn)
 
 
444
{
 
 
445
    if((activeSoundNumber < 0) || (activeSoundNumber >= SOUND_MAXACTIVE))
 
 
446
        return;
 
 
447
 
 
 
448
    /* Check there's a sound in this slot */
 
 
449
    if(ActiveSounds[activeSoundNumber].soundIndex != SID_NOSOUND)
 
 
450
        ActiveSounds[activeSoundNumber].threedeedata.position = *posn;
 
 
451
}
 
 
452
 
 
 
453
void Sound_UpdateNew3d(int activeSoundNumber, SOUND3DDATA * s3d)
 
 
454
{
 
 
455
    if((activeSoundNumber < 0) || (activeSoundNumber >= SOUND_MAXACTIVE))
 
 
456
        return;
 
 
457
 
 
 
458
    /* Check there's a sound in this slot */
 
 
459
    if(ActiveSounds[activeSoundNumber].soundIndex != SID_NOSOUND)
 
 
460
        ActiveSounds[activeSoundNumber].threedeedata = *s3d;
 
 
461
}
 
 
462
 
 
 
463
static SOUNDINDEX GetSoundIndexFromNameAndIndex(const char* name, SOUNDINDEX index)
 
 
464
{
 
 
465
    int i = 0;
 
 
466
 
 
 
467
    if(index >= 0 && index < SID_MAXIMUM)
 
 
468
    {
 
 
469
        if(GameSounds[index].loaded)
 
 
470
        {
 
 
471
            if(!strcmp(GameSounds[index].wavName, name))
 
 
472
                return index;
 
 
473
        }
 
 
474
    }
 
 
475
 
 
 
476
    for(; i < SID_MAXIMUM; i++)
 
 
477
    {
 
 
478
        if(GameSounds[i].loaded)
 
 
479
        {
 
 
480
            if(!strcmp(GameSounds[i].wavName, name))
 
 
481
                return (SOUNDINDEX) i;
 
 
482
        }
 
 
483
    }
 
 
484
 
 
 
485
return SID_NOSOUND;
 
 
486
}
 
 
487
 
 
 
488
#include "savegame.h"
 
 
489
 
 
 
490
typedef struct sound_save_block
 
 
491
{
 
 
492
    SAVE_BLOCK_HEADER header;
 
 
493
 
 
 
494
    int fileNameLength;
 
 
495
 
 
 
496
    SOUNDINDEX soundIndex;
 
 
497
    ACTIVESOUNDPRIORITY priority;    
 
 
498
    int volume;
 
 
499
    int pitch;
 
 
500
    unsigned int loop :1;        
 
 
501
    unsigned int threedee :1;
 
 
502
    unsigned int marine_ignore :1;
 
 
503
    unsigned int reverb_off :1;
 
 
504
    unsigned int externalRef :1;
 
 
505
    SOUND3DDATA threedeedata;
 
 
506
    int position;
 
 
507
 
 
 
508
} SOUND_SAVE_BLOCK;
 
 
509
 
 
 
510
//defines for load/save macros
 
 
511
#define SAVELOAD_BLOCK block
 
 
512
#define SAVELOAD_BEHAV sound
 
 
513
 
 
 
514
void Load_SoundState(int* soundHandle)
 
 
515
{
 
 
516
    if(!soundHandle)
 
 
517
        return;
 
 
518
 
 
 
519
    SOUND_SAVE_BLOCK* block = (SOUND_SAVE_BLOCK*)GetNextBlockIfOfType(SaveBlock_SoundState);
 
 
520
 
 
 
521
    if(!block)
 
 
522
        return;
 
 
523
 
 
 
524
    const char* name = (const char*)(block+1);
 
 
525
    //stop the current sound
 
 
526
 
 
 
527
    if(*soundHandle == SOUND_NOACTIVEINDEX)
 
 
528
        Sound_Stop(*soundHandle);
 
 
529
 
 
 
530
    //check the size
 
 
531
    if(block->header.size != sizeof(*block) + block->fileNameLength)
 
 
532
        return;
 
 
533
 
 
 
534
    SOUNDINDEX soundIndex = GetSoundIndexFromNameAndIndex(name,block->soundIndex);
 
 
535
 
 
 
536
    if(soundIndex == SID_NOSOUND)
 
 
537
        return;
 
 
538
 
 
 
539
    char playOptions[20] = "evpP";
 
 
540
 
 
 
541
    if(block->loop)
 
 
542
        strcat(playOptions,"l");
 
 
543
 
 
 
544
    if(block->marine_ignore)
 
 
545
        strcat(playOptions,"m");
 
 
546
 
 
 
547
    if(block->reverb_off)
 
 
548
        strcat(playOptions,"r");
 
 
549
 
 
 
550
    if(block->priority == ASP_Maximum)
 
 
551
        strcat(playOptions,"h");
 
 
552
 
 
 
553
    if(block->threedee)
 
 
554
    {
 
 
555
        strcat(playOptions,"n");
 
 
556
        Sound_Play(soundIndex, playOptions, soundHandle, block->volume, block->pitch, block->position, &block->threedeedata);
 
 
557
    }
 
 
558
    else
 
 
559
    {
 
 
560
        Sound_Play(soundIndex, playOptions, soundHandle, block->volume, block->pitch, block->position);
 
 
561
    }
 
 
562
}
 
 
563
 
 
 
564
void Save_SoundState(int* soundHandle)
 
 
565
{
 
 
566
    if(!soundHandle)
 
 
567
        return;
 
 
568
 
 
 
569
    if(*soundHandle == SOUND_NOACTIVEINDEX)
 
 
570
    {
 
 
571
        SAVE_BLOCK_HEADER* header;
 
 
572
        GET_SAVE_BLOCK_POINTER(header);
 
 
573
 
 
 
574
        //fill in the header
 
 
575
        header->size = sizeof(*header);
 
 
576
        header->type = SaveBlock_SoundState;
 
 
577
    }
 
 
578
    else
 
 
579
    {
 
 
580
        ACTIVESOUNDSAMPLE* sound = &ActiveSounds[*soundHandle];
 
 
581
 
 
 
582
        const char* name = GameSounds[sound->soundIndex].wavName;
 
 
583
        int name_length = strlen(name) + 1;
 
 
584
 
 
 
585
        SOUND_SAVE_BLOCK* block = GetPointerForSaveBlock(sizeof(*block)+name_length);
 
 
586
 
 
 
587
        //fill in the header
 
 
588
        block->header.size = sizeof(*block) + name_length;
 
 
589
        block->header.type = SaveBlock_SoundState;
 
 
590
 
 
 
591
        COPYELEMENT_SAVE(soundIndex)
 
 
592
        COPYELEMENT_SAVE(priority)    
 
 
593
        COPYELEMENT_SAVE(volume)
 
 
594
        COPYELEMENT_SAVE(pitch)
 
 
595
        COPYELEMENT_SAVE(loop)        
 
 
596
        COPYELEMENT_SAVE(threedee)
 
 
597
        COPYELEMENT_SAVE(marine_ignore)
 
 
598
        COPYELEMENT_SAVE(reverb_off)
 
 
599
        COPYELEMENT_SAVE(threedeedata)
 
 
600
        block->externalRef = 1;
 
 
601
 
 
 
602
        block->position = 0;
 
 
603
           block->fileNameLength = name_length;
 
 
604
 
 
 
605
        //the volume in the active sound list is scaled differently from the volume used
 
 
606
        //by Sound_Play
 
 
607
        block->volume <<= 7;
 
 
608
        block->volume /= VOLUME_PLAT2DSCALE;
 
 
609
 
 
 
610
        block->position = 0;
 
 
611
 
 
 
612
        //fprintf(stderr, "Save_SoundState: GetCurrentPosition!\n");
 
 
613
        strcpy((char*)(block+1),name);
 
 
614
    }    
 
 
615
}
 
 
616
 
 
 
617
void Load_SoundState_NoRef(SAVE_BLOCK_HEADER* header)
 
 
618
{
 
 
619
    SOUND_SAVE_BLOCK* block = (SOUND_SAVE_BLOCK*) header;
 
 
620
    const char* name = (const char*)(block+1);
 
 
621
 
 
 
622
    //check the size
 
 
623
    if(block->header.size != sizeof(*block) + block->fileNameLength)
 
 
624
        return;
 
 
625
 
 
 
626
    //only load if the sound doesn't require an external reference
 
 
627
    if(block->externalRef)
 
 
628
        return;
 
 
629
 
 
 
630
    SOUNDINDEX soundIndex = GetSoundIndexFromNameAndIndex(name,block->soundIndex);
 
 
631
 
 
 
632
    if(soundIndex != SID_NOSOUND)
 
 
633
    {
 
 
634
        char playOptions[20] = "vpP";
 
 
635
 
 
 
636
        if(block->marine_ignore)
 
 
637
            strcat(playOptions, "m");
 
 
638
 
 
 
639
        if(block->reverb_off)
 
 
640
            strcat(playOptions, "r");
 
 
641
 
 
 
642
        if(block->priority == ASP_Maximum)
 
 
643
            strcat(playOptions, "h");
 
 
644
 
 
 
645
        if(block->threedee)
 
 
646
        {
 
 
647
            strcat(playOptions, "n");
 
 
648
            Sound_Play(soundIndex, playOptions, block->volume, block->pitch, block->position, &block->threedeedata);
 
 
649
        }
 
 
650
        else
 
 
651
        {
 
 
652
            Sound_Play(soundIndex, playOptions, block->volume, block->pitch, block->position);
 
 
653
        }
 
 
654
    }
 
 
655
}
 
 
656
 
 
 
657
void Save_SoundsWithNoReference()
 
 
658
{
 
 
659
    int i = 0;
 
 
660
 
 
 
661
    for(; i < SOUND_MAXACTIVE; i++)
 
 
662
    {
 
 
663
        if(ActiveSounds[i].soundIndex != SID_NOSOUND)
 
 
664
        {
 
 
665
            if(!ActiveSounds[i].externalRef)
 
 
666
            {
 
 
667
                ACTIVESOUNDSAMPLE* sound = &ActiveSounds[i];
 
 
668
                SOUND_SAVE_BLOCK* block;
 
 
669
 
 
 
670
                const char* name = GameSounds[sound->soundIndex].wavName;
 
 
671
                int name_length = strlen(name) + 1;
 
 
672
 
 
 
673
                block = GetPointerForSaveBlock(sizeof(*block)+name_length);
 
 
674
 
 
 
675
                //fill in the header
 
 
676
                block->header.size = sizeof(*block) + name_length;
 
 
677
                block->header.type = SaveBlock_SoundState;
 
 
678
 
 
 
679
                COPYELEMENT_SAVE(soundIndex)
 
 
680
                COPYELEMENT_SAVE(priority)    
 
 
681
                COPYELEMENT_SAVE(volume)
 
 
682
                COPYELEMENT_SAVE(pitch)
 
 
683
                COPYELEMENT_SAVE(loop)        
 
 
684
                COPYELEMENT_SAVE(threedee)
 
 
685
                COPYELEMENT_SAVE(marine_ignore)
 
 
686
                COPYELEMENT_SAVE(reverb_off)
 
 
687
                COPYELEMENT_SAVE(threedeedata)
 
 
688
                block->externalRef = 0;
 
 
689
                block->position = 0;
 
 
690
                block->fileNameLength = name_length;
 
 
691
 
 
 
692
                //the volume in the active sound list is scaled differently from the volume used by Sound_Play
 
 
693
                block->volume <<= 7;
 
 
694
                block->volume /= VOLUME_PLAT2DSCALE;
 
 
695
 
 
 
696
                block->position = 0;
 
 
697
 
 
 
698
                strcpy((char*)(block+1),name);
 
 
699
            }
 
 
700
        }
 
 
701
    }
 
 
702
}