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