UFO: Alien Invasion
Loading...
Searching...
No Matches
s_sample.cpp
Go to the documentation of this file.
1
5
6/*
7All original material Copyright (C) 2002-2025 UFO: Alien Invasion.
8
9This program is free software; you can redistribute it and/or
10modify it under the terms of the GNU General Public License
11as published by the Free Software Foundation; either version 2
12of the License, or (at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18See the GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24*/
25
26#include "s_sample.h"
27#include "s_main.h" /* for MAX_SOUNDIDS */
28#include "../../common/filesys.h" /* for MAX_QPATH */
29#include "../../common/common.h" /* for many */
30
31#define SAMPLE_HASH_SIZE 64
33
34/* an index into the sampleHash to retrieve samples by an ID/number */
35#define SAMPLE_MAX_COUNT 1000
37static int sampleIndexLast = 0;
38
41
47static s_sample_t* S_FindByName (const char* name)
48{
49 const unsigned hash = Com_HashKey(name, SAMPLE_HASH_SIZE);
50
51 for (s_sample_t* sample = sampleHash[hash]; sample; sample = sample->hashNext)
52 if (Q_streq(name, sample->name))
53 return sample;
54
55 return nullptr;
56}
57
58static Mix_Chunk* S_LoadSampleChunk (const char* sound)
59{
60 byte* buf;
61 const char* soundExtensions[] = SAMPLE_TYPES;
62 const char** extension = soundExtensions;
63
64 if (!sound || sound[0] == '*')
65 return nullptr;
66
67 size_t len = strlen(sound);
68 if (len + 4 >= MAX_QPATH) {
69 Com_Printf("S_LoadSound: MAX_QPATH exceeded for: '%s'\n", sound);
70 return nullptr;
71 }
72
73 while (*extension) {
74 if ((len = FS_LoadFile(va("sound/%s.%s", sound, *extension++), &buf)) == -1)
75 continue;
76
77 SDL_RWops* rw = SDL_RWFromMem(buf, len);
78 if (!rw){
80 continue;
81 }
82
83 Mix_Chunk* chunk = Mix_LoadWAV_RW(rw, false);
84 if (!chunk)
85 Com_Printf("S_LoadSound: %s.\n", Mix_GetError());
86
88
89 SDL_FreeRW(rw);
90
91 if (chunk)
92 return chunk;
93 }
94
95 Com_Printf("S_LoadSound: Could not find sound file: '%s'\n", sound);
96 return nullptr;
97}
98
105int S_LoadSampleIdx (const char* soundFile)
106{
107 if (!s_env.initialized)
108 return 0;
109
110 char name[MAX_QPATH];
111 Com_StripExtension(soundFile, name, sizeof(name));
112
113 if (s_sample_t* const sample = S_FindByName(name))
114 return sample->index;
115
116 /* make sure the sound is loaded */
117 Mix_Chunk* chunk = S_LoadSampleChunk(name);
118 if (!chunk)
119 return 0; /* couldn't load the sound's data */
120
121 const unsigned hash = Com_HashKey(name, SAMPLE_HASH_SIZE);
124 sample->chunk = chunk;
125 sample->hashNext = sampleHash[hash];
126 sampleHash[hash] = sample;
127 sampleIndex[++sampleIndexLast] = sample;
128 sample->index = sampleIndexLast;
129 return sample->index;
130}
131
132s_sample_t* S_GetSample (const int soundIdx)
133{
134 if (soundIdx > 0 && soundIdx <= sampleIndexLast)
135 return sampleIndex[soundIdx];
136 return nullptr;
137}
138
139void S_FreeSamples (void)
140{
141 for (int i = 0; i < SAMPLE_HASH_SIZE; i++)
142 for (s_sample_t* sample = sampleHash[i]; sample; sample = sample->hashNext) {
143 Mix_FreeChunk(sample->chunk);
144 Mem_Free(sample->name);
145 }
146
147 for (int i = 0; i < SAMPLE_HASH_SIZE; i++) {
148 s_sample_t* next;
149 for (s_sample_t* sample = sampleHash[i]; sample; sample = next) {
150 next = sample->hashNext;
151 Mem_Free(sample);
152 }
153 }
154
157}
158
164{
165 if (!s_env.initialized)
166 return;
167
168 /* load weapon sounds */
169 for (int i = 0; i < csi.numODs; i++) { /* i = obj */
170 const objDef_t* od = INVSH_GetItemByIDX(i);
171 for (int j = 0; j < od->numWeapons; j++) { /* j = weapon-entry per obj */
172 for (int k = 0; k < od->numFiredefs[j]; k++) { /* k = firedef per weapon */
173 const fireDef_t* fd = &od->fd[j][k];
174 if (fd->fireSound != nullptr)
176 if (fd->impactSound != nullptr)
178 if (fd->hitBodySound != nullptr)
180 if (fd->bounceSound != nullptr)
182 }
183 }
184 }
185
186 /* precache the sound pool */
187 stdSoundPool[SOUND_WATER_IN] = S_LoadSample("footsteps/water_in");
188 stdSoundPool[SOUND_WATER_OUT] = S_LoadSample("footsteps/water_out");
189 stdSoundPool[SOUND_WATER_MOVE] = S_LoadSample("footsteps/water_under");
190}
csi_t csi
Definition common.cpp:39
void Com_Printf(const char *const fmt,...)
Definition common.cpp:428
definitions common between client and server, but not game lib
int FS_LoadFile(const char *path, byte **buffer)
Filenames are relative to the quake search path.
Definition files.cpp:384
void FS_FreeFile(void *buffer)
Definition files.cpp:411
Filesystem header file.
#define MAX_QPATH
Definition filesys.h:40
const objDef_t * INVSH_GetItemByIDX(int index)
Returns the item that belongs to the given index or nullptr if the index is invalid.
voidpf void * buf
Definition ioapi.h:42
#define Mem_Free(ptr)
Definition mem.h:35
#define Mem_PoolStrDup(in, pool, tagNum)
Definition mem.h:50
#define Mem_PoolAllocType(type, pool)
Definition mem.h:43
static wrapCache_t * hash[MAX_WRAP_HASH]
Definition r_font.cpp:86
QGL_EXTERN GLuint GLchar GLuint * len
Definition r_gl.h:99
QGL_EXTERN GLint i
Definition r_gl.h:113
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition r_gl.h:110
memPool_t * cl_soundSysPool
Definition s_main.cpp:48
#define SAMPLE_TYPES
Supported sound file extensions.
Definition s_local.h:39
s_env_t s_env
Definition s_main.cpp:40
s_sample_t * stdSoundPool[MAX_SOUNDIDS]
Definition s_sample.cpp:40
s_sample_t * S_LoadSample(const char *soundFile)
Loads and registers a sound file for later use.
Definition s_main.cpp:335
Specifies sound API?
@ SOUND_WATER_IN
Definition s_main.h:35
@ MAX_SOUNDIDS
Definition s_main.h:39
@ SOUND_WATER_OUT
Definition s_main.h:36
@ SOUND_WATER_MOVE
Definition s_main.h:37
void S_PrecacheSamples(void)
Definition s_sample.cpp:163
s_sample_t * S_GetSample(const int soundIdx)
Definition s_sample.cpp:132
int S_LoadSampleIdx(const char *soundFile)
Loads and registers a sound file for later use.
Definition s_sample.cpp:105
static int sampleIndexLast
Definition s_sample.cpp:37
static s_sample_t * sampleHash[SAMPLE_HASH_SIZE]
Definition s_sample.cpp:32
void S_FreeSamples(void)
Definition s_sample.cpp:139
#define SAMPLE_MAX_COUNT
Definition s_sample.cpp:35
static s_sample_t * sampleIndex[SAMPLE_MAX_COUNT]
Definition s_sample.cpp:36
static s_sample_t * S_FindByName(const char *name)
Searches the hash for a given sound file.
Definition s_sample.cpp:47
#define SAMPLE_HASH_SIZE
Definition s_sample.cpp:31
static Mix_Chunk * S_LoadSampleChunk(const char *sound)
Definition s_sample.cpp:58
#define Q_streq(a, b)
Definition shared.h:136
#define OBJZERO(obj)
Definition shared.h:178
void Com_StripExtension(const char *in, char *out, const size_t size)
Removes the file extension from a filename.
Definition shared.cpp:259
unsigned int Com_HashKey(const char *name, int hashsize)
returns hash key for a string
Definition shared.cpp:336
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functi...
Definition shared.cpp:410
this is a fire definition for our weapons/ammo
Definition inv_shared.h:110
const char * fireSound
Definition inv_shared.h:117
const char * hitBodySound
Definition inv_shared.h:116
const char * bounceSound
Definition inv_shared.h:118
const char * impactSound
Definition inv_shared.h:114
Defines all attributes of objects used in the inventory.
Definition inv_shared.h:264
fireDef_t fd[MAX_WEAPONS_PER_OBJDEF][MAX_FIREDEFS_PER_WEAPON]
Definition inv_shared.h:314
fireDefIndex_t numFiredefs[MAX_WEAPONS_PER_OBJDEF]
Definition inv_shared.h:315
int numWeapons
Definition inv_shared.h:317
int index
Definition s_local.h:47
char * name
Definition s_local.h:42
struct s_sample_s * hashNext
Definition s_local.h:46
Mix_Chunk * chunk
Definition s_local.h:45