s_sample.c
Go to the documentation of this file.00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "s_local.h"
00027 #include "s_sample.h"
00028
00029 #define SAMPLE_HASH_SIZE 64
00030 static s_sample_t *sampleHash[SAMPLE_HASH_SIZE];
00031
00036 void S_SetSampleRepeatRate (int sampleRepeatRate)
00037 {
00038 s_env.sampleRepeatRate = sampleRepeatRate;
00039 }
00040
00046 static s_sample_t *S_FindName (const char *name)
00047 {
00048 s_sample_t *sample;
00049 const unsigned hash = Com_HashKey(name, SAMPLE_HASH_SIZE);
00050
00051 for (sample = sampleHash[hash]; sample; sample = sample->hashNext)
00052 if (!strcmp(name, sample->name))
00053 return sample;
00054
00055 return NULL;
00056 }
00057
00058 static Mix_Chunk* S_LoadSampleChunk (const char *sound)
00059 {
00060 size_t len;
00061 byte *buf;
00062 const char *soundExtensions[] = SAMPLE_TYPES;
00063 const char **extension = soundExtensions;
00064 SDL_RWops *rw;
00065 Mix_Chunk *chunk;
00066
00067 if (!sound || sound[0] == '*')
00068 return NULL;
00069
00070 len = strlen(sound);
00071 if (len + 4 >= MAX_QPATH) {
00072 Com_Printf("S_LoadSound: MAX_QPATH exceeded for: '%s'\n", sound);
00073 return NULL;
00074 }
00075
00076 while (*extension) {
00077 if ((len = FS_LoadFile(va("sound/%s.%s", sound, *extension++), &buf)) == -1)
00078 continue;
00079
00080 if (!(rw = SDL_RWFromMem(buf, len))){
00081 FS_FreeFile(buf);
00082 continue;
00083 }
00084
00085 if (!(chunk = Mix_LoadWAV_RW(rw, qfalse)))
00086 Com_Printf("S_LoadSound: %s.\n", Mix_GetError());
00087
00088 FS_FreeFile(buf);
00089
00090 SDL_FreeRW(rw);
00091
00092 if (chunk)
00093 return chunk;
00094 }
00095
00096 Com_Printf("S_LoadSound: Could not find sound file: '%s'\n", sound);
00097 return NULL;
00098 }
00099
00105 s_sample_t *S_LoadSample (const char *soundFile)
00106 {
00107 Mix_Chunk *chunk;
00108 s_sample_t *sample;
00109 char name[MAX_QPATH];
00110 unsigned hash;
00111
00112 if (!s_env.initialized)
00113 return NULL;
00114
00115 Com_StripExtension(soundFile, name, sizeof(name));
00116
00117 sample = S_FindName(name);
00118 if (sample)
00119 return sample;
00120
00121
00122 chunk = S_LoadSampleChunk(name);
00123 if (!chunk)
00124 return NULL;
00125
00126 hash = Com_HashKey(name, SAMPLE_HASH_SIZE);
00127 sample = Mem_PoolAlloc(sizeof(*sample), cl_soundSysPool, 0);
00128 sample->name = Mem_PoolStrDup(name, cl_soundSysPool, 0);
00129 sample->chunk = chunk;
00130 sample->hashNext = sampleHash[hash];
00131 sampleHash[hash] = sample;
00132 return sample;
00133 }
00134
00135 void S_FreeSamples (void)
00136 {
00137 int i;
00138 s_sample_t* sample;
00139
00140 for (i = 0; i < SAMPLE_HASH_SIZE; i++)
00141 for (sample = sampleHash[i]; sample; sample = sample->hashNext) {
00142 Mix_FreeChunk(sample->chunk);
00143 Mem_Free(sample->name);
00144 }
00145
00146 for (i = 0; i < SAMPLE_HASH_SIZE; i++) {
00147 s_sample_t* next;
00148 for (sample = sampleHash[i]; sample; sample = next) {
00149 next = sample->hashNext;
00150 Mem_Free(sample);
00151 }
00152 }
00153
00154 memset(sampleHash, 0, sizeof(sampleHash));
00155 }
00156
00161 void S_LoadSamples (void)
00162 {
00163 int i, j, k;
00164
00165 if (!s_env.initialized)
00166 return;
00167
00168
00169 for (i = 0; i < csi.numODs; i++) {
00170 const objDef_t *od = INVSH_GetItemByIDX(i);
00171 for (j = 0; j < od->numWeapons; j++) {
00172 for (k = 0; k < od->numFiredefs[j]; k++) {
00173 const fireDef_t *fd = &od->fd[j][k];
00174 if (fd->fireSound[0] != '\0')
00175 S_LoadSample(fd->fireSound);
00176 if (fd->impactSound[0] != '\0')
00177 S_LoadSample(fd->impactSound);
00178 if (fd->hitBodySound[0] != '\0')
00179 S_LoadSample(fd->hitBodySound);
00180 if (fd->bounceSound[0] != '\0')
00181 S_LoadSample(fd->bounceSound);
00182 }
00183 }
00184 }
00185
00186
00187 cls.soundPool[SOUND_WATER_IN] = S_LoadSample("footsteps/water_in");
00188 cls.soundPool[SOUND_WATER_OUT] = S_LoadSample("footsteps/water_out");
00189 cls.soundPool[SOUND_WATER_MOVE] = S_LoadSample("footsteps/water_under");
00190 }