s_sample.c

Go to the documentation of this file.
00001 
00006 /*
00007 All original material Copyright (C) 2002-2010 UFO: Alien Invasion.
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018 See the GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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     /* make sure the sound is loaded */
00122     chunk = S_LoadSampleChunk(name);
00123     if (!chunk)
00124         return NULL;        /* couldn't load the sound's data */
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     /* load weapon sounds */
00169     for (i = 0; i < csi.numODs; i++) { /* i = obj */
00170         const objDef_t *od = INVSH_GetItemByIDX(i);
00171         for (j = 0; j < od->numWeapons; j++) {  /* j = weapon-entry per obj */
00172             for (k = 0; k < od->numFiredefs[j]; k++) { /* k = firedef per weapon */
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     /* precache the sound pool */
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 }

Generated by  doxygen 1.6.2