1 /*************************************************************************
2
3 "I Have No Tomatoes"
4 Copyright (c) 2004, Mika Halttunen
5
6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages
8 arising from the use of this software.
9
10 Permission is granted to anyone to use this software for any purpose,
11 including commercial applications, and to alter it and redistribute
12 it freely, subject to the following restrictions:
13
14 1. The origin of this software must not be misrepresented; you must
15 not claim that you wrote the original software. If you use this
16 software in a product, an acknowledgment in the product documentation
17 would be appreciated but is not required.
18
19 2. Altered source versions must be plainly marked as such, and must
20 not be misrepresented as being the original software.
21
22 3. This notice may not be removed or altered from any source
23 distribution.
24
25
26 Mika Halttunen <lsoft@mbnet.fi>
27
28 *************************************************************************/
29
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include "SDL.h"
33 #include "SDL_mixer.h"
34 #include "game.h"
35 #include <string.h>
36 #include <dirent.h>
37 #include <ctype.h>
38 #include "mymath.h"
39 #include "init.h"
40 #include "mpak.h"
41 #include "comments.h"
42 #include "timer.h"
43 #include "soundmusic.h"
44
45 // Current music module
46 Mix_Music *music_mod = NULL;
47
48 // Music files array
49 char music_files[MAX_MUSIC][256];
50 int num_music_files;
51 int cur_music;
52
53 // Sound array
54 Mix_Chunk *sounds[NUM_SOUNDS];
55
56
57 // Shuffle the playlist
shuffle_playlist()58 void shuffle_playlist() {
59 if(!num_music_files)
60 return;
61
62 cur_music = 0;
63
64 // Shuffle the list
65 for(int i = num_music_files - 1; i > 0; i--) {
66 int pos = RAND(0, i - 1);
67 char swap[256];
68 strcpy(swap, music_files[i]);
69 strcpy(music_files[i], music_files[pos]);
70 strcpy(music_files[pos], swap);
71 }
72 }
73
74
75 // Search for the music files
search_music()76 void search_music() {
77 DIR *dp;
78 dirent *ep;
79
80 // Search files from the music directory
81 dp = opendir(MUSIC_DIR);
82 if(!dp || !config.sound || !config.music_vol) {
83 // No files found, or the sound is turned off
84 num_music_files = 0;
85 return;
86 }
87
88 // Clear music file list
89 num_music_files = 0;
90 cur_music = 0;
91 for(int f=0; f<MAX_MUSIC; f++)
92 strcpy(music_files[f], "");
93
94 // Start searching
95 while((ep = readdir(dp)) ) {
96 if(num_music_files >= MAX_MUSIC-1) {
97 printf("Warning: Too many music files in '%s' directory!\n", MUSIC_DIR);
98 break;
99 }
100
101 // Check the extension
102 char ext[3];
103 char name[256] = "";
104 strcpy(name, ep->d_name);
105 int len = strlen(name);
106 if(len > 3) {
107 ext[0] = name[len-3];
108 ext[1] = name[len-2];
109 ext[2] = name[len-1];
110 if(toupper(ext[0]) == 'M' && toupper(ext[1]) == 'O' && toupper(ext[2]) == 'D') {
111 // Found MOD
112 strcpy(music_files[num_music_files], name);
113 num_music_files++;
114 }
115
116 if(toupper(ext[0]) == 'S' && toupper(ext[1]) == '3' && toupper(ext[2]) == 'M') {
117 // Found S3M
118 strcpy(music_files[num_music_files], name);
119 num_music_files++;
120 }
121
122 if(toupper(ext[1]) == 'X' && toupper(ext[2]) == 'M') {
123 // Found XM
124 strcpy(music_files[num_music_files], name);
125 num_music_files++;
126 }
127
128 if(toupper(ext[1]) == 'I' && toupper(ext[2]) == 'T') {
129 // Found IT
130 strcpy(music_files[num_music_files], name);
131 num_music_files++;
132 }
133
134 if(toupper(ext[0]) == 'O' && toupper(ext[1]) == 'G' && toupper(ext[2]) == 'G') {
135 // Found OGG
136 strcpy(music_files[num_music_files], name);
137 num_music_files++;
138 }
139 }
140 }
141
142 closedir(dp);
143 shuffle_playlist();
144 }
145
146
147 // If the current music has finished, start playing another
music_finished()148 void music_finished() {
149 static bool f1_key_down = false;
150
151 if(!config.sound || !num_music_files || !config.music_vol)
152 return;
153
154 if(f1_key_down == false) {
155 // Play the current song from the playlist
156 play_music(music_files[cur_music]);
157
158 cur_music++;
159 if(cur_music > num_music_files-1)
160 shuffle_playlist();
161 f1_key_down = true;
162 }
163 if(!key[SDLK_F1])
164 f1_key_down = false;
165
166 }
167
168
169 // This helper function loads a sound and stores it to the sound array
170 static int cur_sound = 0;
load_sound(char * file)171 void load_sound(char *file) {
172 if(cur_sound > NUM_SOUNDS-1)
173 error_msg("load_sounds():\nTrying to load too many sounds!\nNUM_SOUNDS is defined as %d.\n", NUM_SOUNDS);
174
175 // First try to load from the override directory
176 char soundfile[128] = "";
177 sprintf(soundfile, "%s%s", pakfile.override_dir, file);
178 FILE *check = fopen(soundfile, "rb");
179 if(check) {
180 // The file exists, load it
181 fclose(check);
182 sounds[cur_sound] = Mix_LoadWAV(soundfile);
183 }
184 else {
185 // The file doesn't exist in the override directory
186 // try to load it from the pakfile.
187 FILE *fp = pakfile.open_file(file);
188 SDL_RWops *rw = SDL_RWFromFP(fp,0);
189 sounds[cur_sound] = Mix_LoadWAV_RW(rw,0);
190 SDL_FreeRW(rw);
191 fclose(fp);
192 }
193
194 // Check for errors
195 if(!sounds[cur_sound])
196 error_msg("load_sound():\nUnable to load a sound from %s!\nError: %s\n",file,Mix_GetError());
197 cur_sound++;
198 }
199
200
201 // Initialize the SDL_Mixer
init_mixer()202 void init_mixer() {
203 if(!config.sound)
204 return;
205
206 // Initialize the Mixer
207 if(Mix_OpenAudio(config.sound_freq, AUDIO_S16, 2, 4096)) // Frequency, 16 bit sound, channels (stereo), buffer size
208 error_msg("Unable to open the audio device!\nError: %s\n", Mix_GetError());
209
210 // Load the sounds
211 load_sound("snd_appear.wav");
212 load_sound("snd_bomb.wav");
213 load_sound("snd_explo.wav");
214 load_sound("snd_bonus1.wav");
215 load_sound("snd_bonus2.wav");
216 load_sound("snd_bonus3.wav");
217 load_sound("snd_die1.wav");
218 load_sound("snd_die2.wav");
219 load_sound("snd_die3.wav");
220 load_sound("snd_die4.wav");
221 load_sound("snd_die5.wav");
222 load_sound("snd_die6.wav");
223 load_sound("snd_levelteleport.wav");
224 load_sound("snd_wildfire.wav");
225 load_sound("snd_teleport.wav");
226 load_sound("snd_trap.wav");
227 load_sound("snd_lightning.wav");
228 load_sound("snd_wisp.wav");
229 load_sound("snd_jump.wav");
230 load_sound("snd_potatoman.wav");
231 load_sound("snd_potatoman2.wav");
232 load_sound("snd_turn.wav");
233 load_sound("snd_flowerpower.wav");
234 load_sound("snd_kick.wav");
235 load_sound("snd_killed5.wav");
236 load_sound("snd_menu1.wav");
237 load_sound("snd_menu2.wav");
238 load_sound("snd_finish.wav");
239
240 // Search for music files
241 search_music();
242
243 // Set the volume
244 Mix_Volume(-1,config.sound_vol);
245
246 // Start playing the music
247 if(num_music_files) {
248 play_music(music_files[0]);
249 cur_music++;
250 if(cur_music > num_music_files-1)
251 cur_music = 0;
252 }
253
254 // Tell Mixer what to do when the music stops
255 Mix_HookMusicFinished(&music_finished);
256 }
257
258
259 // Play music
play_music(char * file)260 void play_music(char *file) {
261 if(!config.sound || !config.music_vol)
262 return;
263
264 game_paused = true;
265
266 char str[256] = "";
267 sprintf(str, "%s%s", MUSIC_DIR, file);
268 if(music_mod){
269 Mix_HaltMusic();
270 Mix_FreeMusic(music_mod);
271 }
272 music_mod = Mix_LoadMUS(str);
273 if(!music_mod)
274 error_msg("play_music():\nUnable to play music from '%s'!\nError: %s\n", file, Mix_GetError());
275
276 // Play
277 Mix_PlayMusic(music_mod, 0);
278
279 // Add the comment
280 add_comment(COL_DEFAULT, "Playing \"%s\"...", file);
281
282 // Set the volume
283 Mix_VolumeMusic(config.music_vol);
284
285 game_paused = false;
286 }
287
288
289 // Play a sound
play_sound(int sound,bool random_freq)290 void play_sound(int sound, bool random_freq) {
291 if(!config.sound)
292 return;
293
294 // Play the sound
295 Mix_PlayChannel(-1, sounds[sound], 0);
296 //int channel = Mix_PlayChannel(-1, sounds[sound], 0);
297
298 // Random the frequency
299 // This doesn't work in SDL!
300 /* if(random_freq) {
301 int freq;
302 int freq_change[2];
303 // freq = FSOUND_GetFrequency(channel);
304
305 freq_change[0] = (int)((float)freq * 0.3f);
306 freq_change[1] = (int)((float)freq * 0.1f);
307
308 // Upload the frequency to the sample
309 // FSOUND_SetFrequency(channel, freq+RAND(-freq_change[0], freq_change[1]));
310 }
311 */
312 }
313