4b825dc642cb6eb9a060e54bf8d69288fbee490494a6641b73026d662261604d7d192beae70b11dc
 
 
1
#include "system.h"
 
 
2
#include "files.h"
 
 
3
#include "prototyp.h"
 
 
4
#include "psndplat.h"
 
 
5
#include "scream.h"
 
 
6
#include <string.h>
 
 
7
#include <ctype.h>
 
 
8
#include <stdlib.h>
 
 
9
 
 
 
10
struct ScreamSound
 
 
11
{
 
 
12
    SOUNDINDEX sound_number;
 
 
13
    int pitch;
 
 
14
    int volume;    
 
 
15
};
 
 
16
 
 
 
17
struct ScreamSoundCategory
 
 
18
{
 
 
19
    int num_sounds;
 
 
20
    struct ScreamSound* sounds;
 
 
21
    SOUNDINDEX last_sound;
 
 
22
};
 
 
23
 
 
 
24
struct ScreamVoiceType
 
 
25
{
 
 
26
    struct ScreamSoundCategory* category;
 
 
27
};
 
 
28
 
 
 
29
struct CharacterSoundEffects
 
 
30
{
 
 
31
    int num_voice_types;
 
 
32
    int num_voice_cats;
 
 
33
    struct ScreamVoiceType* voice_types;
 
 
34
    SOUNDINDEX global_last_sound;
 
 
35
};
 
 
36
 
 
 
37
static struct CharacterSoundEffects MarineSounds =    {5, 15, 0, SID_NOSOUND};
 
 
38
static struct CharacterSoundEffects AlienSounds =    {3,  9, 0, SID_NOSOUND};
 
 
39
static struct CharacterSoundEffects PredatorSounds =    {1,  9, 0, SID_NOSOUND};
 
 
40
static struct CharacterSoundEffects QueenSounds =    {1,  3, 0, SID_NOSOUND};
 
 
41
 
 
 
42
static int load_scream_sounds(const char *path, const char * file_name)
 
 
43
{
 
 
44
    int i = SID_STARTOF_SCREAMSLOTS;
 
 
45
 
 
 
46
    for (; i < SID_ENDOF_SCREAMSLOTS && GameSounds[i].loaded; i++)
 
 
47
            continue;
 
 
48
 
 
 
49
    int l = SID_STARTOF_SCREAMSLOTS;
 
 
50
 
 
 
51
    for (; l < i; l++)
 
 
52
    {
 
 
53
        if (!strcmp(GameSounds[l].wavName, file_name))
 
 
54
            return l;
 
 
55
    }
 
 
56
 
 
 
57
    if ( i < SID_ENDOF_SCREAMSLOTS)
 
 
58
    {
 
 
59
        if (!GameSounds[i].loaded && LoadWavFile(i, path, file_name))
 
 
60
            return i;
 
 
61
    }
 
 
62
 
 
 
63
return SID_NOSOUND;
 
 
64
}
 
 
65
 
 
 
66
static void LoadSounds(struct CharacterSoundEffects *testus, const char *data_file, const char *directory)
 
 
67
{
 
 
68
    if(testus->voice_types)
 
 
69
        return;
 
 
70
 
 
 
71
    FILE *file = OpenGameFile(data_file, 1, FILETYPE_GAMEDATA);
 
 
72
 
 
 
73
    if(file == NULL)
 
 
74
    {
 
 
75
        printf("Failed to open %s\n", data_file);
 
 
76
        return;
 
 
77
    }
 
 
78
 
 
 
79
    fseek(file, 0, SEEK_END);
 
 
80
    int file_size = ftell(file);
 
 
81
    rewind(file);
 
 
82
 
 
 
83
    char* buffer = malloc(file_size + 1);
 
 
84
 
 
 
85
    fread(buffer, file_size, 1, file);
 
 
86
    fclose(file);
 
 
87
 
 
 
88
    if(!strncmp("MARSOUND", buffer, 8))
 
 
89
    {
 
 
90
        int i;
 
 
91
        char* bufpos = buffer + 8;
 
 
92
 
 
 
93
        //num_voice_types = *(int*)bufpos;
 
 
94
        bufpos += 4;
 
 
95
        //num_voice_cats = *(int*)bufpos;
 
 
96
        bufpos += 4;
 
 
97
 
 
 
98
        testus->voice_types = malloc(testus->num_voice_types * sizeof(struct ScreamVoiceType));
 
 
99
 
 
 
100
        for(i=0; i < testus->num_voice_types; i++)    
 
 
101
        {
 
 
102
            testus->voice_types[i].category = malloc(testus->num_voice_cats * sizeof(struct ScreamSoundCategory));
 
 
103
 
 
 
104
            int j=0;
 
 
105
            for(; j < testus->num_voice_cats; j++)
 
 
106
            {
 
 
107
                struct ScreamSoundCategory* cat = &testus->voice_types[i].category[j];
 
 
108
                cat->last_sound = SID_NOSOUND;
 
 
109
                cat->num_sounds = *(int*)bufpos;
 
 
110
                bufpos += 4;
 
 
111
                cat->sounds = NULL;
 
 
112
 
 
 
113
                if(cat->num_sounds)
 
 
114
                    cat->sounds = malloc(cat->num_sounds * sizeof(struct ScreamSound));
 
 
115
 
 
 
116
                int k = 0;
 
 
117
                for(; k < cat->num_sounds;)
 
 
118
                {
 
 
119
                    struct ScreamSound * sound = &cat->sounds[k];
 
 
120
 
 
 
121
                    char  * file_name = bufpos;
 
 
122
                    size_t i = 0;
 
 
123
                    for (; i < strlen(file_name); i++)
 
 
124
                        file_name[i] = tolower(file_name[i]);
 
 
125
 
 
 
126
                    bufpos += i+1;
 
 
127
 
 
 
128
                    sound->pitch = 0; //*(int*)bufpos; is always 0 
 
 
129
                    //bufpos += 4;
 
 
130
                    sound->volume = 127; // *(int*)bufpos; is always 127
 
 
131
                    //bufpos += 4;
 
 
132
                    bufpos += 8;
 
 
133
 
 
 
134
                    sound->sound_number = (SOUNDINDEX) load_scream_sounds(directory, file_name);
 
 
135
 
 
 
136
                    if(SID_NOSOUND != sound->sound_number)
 
 
137
                        k++;
 
 
138
                    else
 
 
139
                        cat->num_sounds--;
 
 
140
                }
 
 
141
            }
 
 
142
        }
 
 
143
    }
 
 
144
 
 
 
145
    free(buffer);
 
 
146
}
 
 
147
 
 
 
148
void UnloadSounds(struct CharacterSoundEffects * testus)
 
 
149
{
 
 
150
    if(testus->voice_types)
 
 
151
    {
 
 
152
        int i,j;
 
 
153
        for (i=0; i < testus->num_voice_types; i++)
 
 
154
        {
 
 
155
            for (j=0; j < testus->num_voice_cats; j++)
 
 
156
            {
 
 
157
                struct ScreamSoundCategory* cat = &testus->voice_types[i].category[j];
 
 
158
 
 
 
159
                if (cat->sounds)
 
 
160
                    free(cat->sounds);
 
 
161
            }
 
 
162
 
 
 
163
            free(testus->voice_types[i].category);
 
 
164
        }
 
 
165
 
 
 
166
        free(testus->voice_types);
 
 
167
 
 
 
168
        testus->voice_types = NULL;
 
 
169
        testus->num_voice_types = 0;
 
 
170
        testus->num_voice_cats = 0;
 
 
171
    }
 
 
172
}
 
 
173
 
 
 
174
static void PlaySound(struct CharacterSoundEffects * testus, int VoiceType, int SoundCategory, int PitchShift, int* ExternalRef, VECTORCH* Location)
 
 
175
{
 
 
176
//    assert(Location);
 
 
177
 
 
 
178
    if(!testus->voice_types || VoiceType < 0 || VoiceType >= testus->num_voice_types)
 
 
179
        return;
 
 
180
 
 
 
181
    if(SoundCategory < 0 || SoundCategory >= testus->num_voice_cats)
 
 
182
        return;
 
 
183
 
 
 
184
    if(ExternalRef && (*ExternalRef != SOUND_NOACTIVEINDEX))
 
 
185
        return; //already playing a sound
 
 
186
 
 
 
187
    struct ScreamSoundCategory* cat = &testus->voice_types[VoiceType].category[SoundCategory];
 
 
188
    //make sure there are some sound for this category
 
 
189
 
 
 
190
    if(!cat->num_sounds)
 
 
191
        return;
 
 
192
 
 
 
193
    int index = FastRandom() % cat->num_sounds;
 
 
194
    int num_checked = 0;
 
 
195
 
 
 
196
    //pick a sound , trying to avoid the last one picked
 
 
197
    if(cat->num_sounds > 2)
 
 
198
    {
 
 
199
        while(num_checked < cat->num_sounds)
 
 
200
        {
 
 
201
            SOUNDINDEX sound_ind = (SOUNDINDEX)cat->sounds[index].sound_number;
 
 
202
 
 
 
203
            if(sound_ind != cat->last_sound && sound_ind != testus->global_last_sound)
 
 
204
                    break;
 
 
205
 
 
 
206
            index++;
 
 
207
            num_checked++;
 
 
208
 
 
 
209
            if(index == cat->num_sounds)
 
 
210
                index=0;    
 
 
211
        }
 
 
212
    }
 
 
213
 
 
 
214
    struct ScreamSound* sound = &cat->sounds[index];
 
 
215
 
 
 
216
    int pitch = sound->pitch+PitchShift;
 
 
217
 
 
 
218
    if(Location)
 
 
219
        Sound_Play((SOUNDINDEX)sound->sound_number, "dvpe", Location, sound->volume, pitch, ExternalRef);
 
 
220
    else
 
 
221
        Sound_Play((SOUNDINDEX)sound->sound_number, "vpe", sound->volume, pitch, ExternalRef);
 
 
222
 
 
 
223
    //take note of the last sound played
 
 
224
    testus->global_last_sound = cat->last_sound = (SOUNDINDEX)sound->sound_number;
 
 
225
}
 
 
226
 
 
 
227
void UnloadScreamSounds()
 
 
228
{
 
 
229
    UnloadSounds(&MarineSounds);
 
 
230
    UnloadSounds(&AlienSounds);
 
 
231
    UnloadSounds(&PredatorSounds);
 
 
232
    UnloadSounds(&QueenSounds);
 
 
233
}
 
 
234
 
 
 
235
void LoadMarineScreamSounds()
 
 
236
{
 
 
237
    LoadSounds(&MarineSounds, "fastfile/marsound.dat", "npc/marinevoice");
 
 
238
}
 
 
239
 
 
 
240
void LoadAlienScreamSounds()
 
 
241
{
 
 
242
    LoadSounds(&AlienSounds, "fastfile/aliensound.dat", "npc/alienvoice");
 
 
243
}
 
 
244
 
 
 
245
void LoadPredatorScreamSounds()
 
 
246
{
 
 
247
    LoadSounds(&PredatorSounds, "fastfile/predsound.dat", "npc/predatorvoice");
 
 
248
}
 
 
249
 
 
 
250
void LoadQueenScreamSounds()
 
 
251
{
 
 
252
    LoadSounds(&QueenSounds, "fastfile/queensound.dat", "npc/queenvoice");
 
 
253
}
 
 
254
 
 
 
255
void PlayMarineScream(int VoiceType, int SoundCategory, int PitchShift, int* ExternalRef, VECTORCH* Location)
 
 
256
{
 
 
257
    PlaySound(&MarineSounds, VoiceType, SoundCategory, PitchShift, ExternalRef, Location);
 
 
258
}
 
 
259
 
 
 
260
void PlayAlienSound(int VoiceType, int SoundCategory, int PitchShift, int* ExternalRef, VECTORCH* Location)
 
 
261
{
 
 
262
    PlaySound(&AlienSounds, VoiceType, SoundCategory, PitchShift, ExternalRef, Location);
 
 
263
}
 
 
264
 
 
 
265
void PlayPredatorSound(int VoiceType, int SoundCategory, int PitchShift, int* ExternalRef, VECTORCH* Location)
 
 
266
{
 
 
267
    PlaySound(&PredatorSounds, VoiceType, SoundCategory, PitchShift, ExternalRef, Location);
 
 
268
}
 
 
269
 
 
 
270
void PlayQueenSound(int VoiceType, int SoundCategory, int PitchShift, int* ExternalRef, VECTORCH* Location)
 
 
271
{
 
 
272
    PlaySound(&QueenSounds, VoiceType, SoundCategory, PitchShift, ExternalRef, Location);
 
 
273
}