]> icculus.org git repositories - crow/jumpnbump.git/blob - sdl/sound.c
Fixes for SDL and VisualC.
[crow/jumpnbump.git] / sdl / sound.c
1 #include "globals.h"
2
3 static Mix_Music *current_music = (Mix_Music *) NULL;
4 static struct {
5         int id;
6         Mix_Chunk *chunk;
7         int used;
8         int loop;
9 } soundsamples[128];
10
11 /* misc handling */
12
13 char dj_init(void)
14 {
15         int audio_rate = 22050;
16         Uint16 audio_format = AUDIO_U16;
17         int audio_channels = 2;
18         int audio_buffers = 4096;
19
20         if (Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) < 0) {
21                 fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
22                 return 0;
23         }
24
25         Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
26         printf("Opened audio at %dHz %dbit %s, %d bytes audio buffer\n", audio_rate, (audio_format & 0xFF), (audio_channels > 1) ? "stereo" : "mono", audio_buffers);
27
28         Mix_SetMusicCMD(getenv("MUSIC_CMD"));
29
30         memset(soundsamples, 0, sizeof(soundsamples));
31
32         return 0;
33 }
34
35 void dj_deinit(void)
36 {
37 //      int i;
38
39         Mix_FadeOutMusic(1500);
40         SDL_Delay(1500);
41         Mix_HaltMusic();
42         if (current_music)
43                 Mix_FreeMusic(current_music);
44         current_music = NULL;
45
46 /*      for(i = 0; i < 128; i++) {
47                 if(soundsamples[i].used && soundsamples[i].chunk)
48                         Mix_FreeChunk(soundsamples[i].chunk);
49         }*/
50
51         Mix_CloseAudio();
52
53         SDL_Quit();
54 }
55
56 void dj_start(void)
57 {
58 }
59
60 void dj_stop(void)
61 {
62 }
63
64 char dj_autodetect_sd(void)
65 {
66         return 0;
67 }
68
69 char dj_set_stereo(char flag)
70 {
71         return 0;
72 }
73
74 void dj_set_auto_mix(char flag)
75 {
76 }
77
78 unsigned short dj_set_mixing_freq(unsigned short freq)
79 {
80         return freq;
81 }
82
83 void dj_set_dma_time(unsigned short time)
84 {
85 }
86
87 void dj_set_nosound(char flag)
88 {
89 }
90
91 /* mix handling */
92
93 void dj_mix(void)
94 {
95 }
96
97 /* sfx handling */
98
99 char dj_set_num_sfx_channels(char num_channels)
100 {
101         return num_channels;
102 }
103
104 void dj_set_sfx_volume(char volume)
105 {
106 }
107
108 void dj_play_sfx(unsigned char sfx_num, unsigned short freq, char volume, char panning, unsigned short delay, char channel)
109 {
110         int i;
111         int used_channel;
112
113         for (i = 0; i < 128; i++) {
114                 if (soundsamples[i].id == sfx_num)
115                         break;
116         }
117         if (i == 128)
118                 return;
119         else if (!soundsamples[i].used)
120                 return;
121         else if (!soundsamples[i].chunk)
122                 return;
123
124         used_channel = Mix_PlayChannel(channel, soundsamples[i].chunk, soundsamples[i].loop);
125         Mix_Volume(used_channel, volume * 2);
126 }
127
128 char dj_get_sfx_settings(unsigned char sfx_num, sfx_data * data)
129 {
130         int i;
131
132         data->priority = 0;
133         data->default_freq = 0;
134         data->default_volume = 0;
135         data->length = 0;
136         data->loop = 0;
137         data->loop_start = 0;
138         data->loop_length = 0;
139         data->buf = 0;
140
141         for (i = 0; i < 128; i++) {
142                 if (soundsamples[i].id == sfx_num)
143                         break;
144         }
145         if (i == 128)
146                 return 1;
147         else if (!soundsamples[i].used)
148                 return 1;
149         else if (!soundsamples[i].chunk)
150                 return 1;
151
152         data->loop = soundsamples[i].loop;
153
154         return 0;
155 }
156
157 char dj_set_sfx_settings(unsigned char sfx_num, sfx_data * data)
158 {
159         int i;
160
161         for (i = 0; i < 128; i++) {
162                 if (soundsamples[i].id == sfx_num)
163                         break;
164         }
165         if (i == 128)
166                 return 1;
167         else if (!soundsamples[i].used)
168                 return 1;
169         else if (!soundsamples[i].chunk)
170                 return 1;
171
172         soundsamples[i].loop = (data->loop) ? (-1) : (0);
173
174         return 0;
175 }
176
177 void dj_set_sfx_channel_volume(char channel_num, char volume)
178 {
179         Mix_Volume(channel_num, volume * 2);
180 }
181
182 void dj_stop_sfx_channel(char channel_num)
183 {
184         Mix_HaltChannel(channel_num);
185 }
186
187 char dj_load_sfx(FILE * file_handle, char *filename, int file_length, char sfx_type, unsigned char sfx_num)
188 {
189         int i;
190         typedef struct {
191                 char RIFF_ID[4];
192                 long riff_size;
193                 char WAVE_ID[4];
194                 char FMT_ID[4];
195                 long fmt_size;
196                 short FormatTag;
197                 unsigned short Channels;
198                 unsigned long SamplesPerSec;
199                 unsigned long AvgBytesPerSec;
200                 unsigned short BlockAlign;
201                 unsigned short BitsPerSample;
202                 char DATA_ID[4];
203                 long data_size;
204                 unsigned char data[0];
205         } wave_file_t;
206
207         wave_file_t *wave_buffer;
208         SDL_RWops *rwop;
209
210         for (i = 0; (i < 128) && soundsamples[i].used; i++);
211         if (i == 128)
212                 return -1;
213
214         wave_buffer = (wave_file_t *) malloc(sizeof(wave_file_t) + file_length);
215         memset(wave_buffer, 0, sizeof(wave_file_t) + file_length);
216
217         strncpy(wave_buffer->RIFF_ID, "RIFF", 4);
218         wave_buffer->riff_size = sizeof(wave_file_t) + file_length - 8;
219         strncpy(wave_buffer->WAVE_ID, "WAVE", 4);
220         strncpy(wave_buffer->FMT_ID, "fmt ", 4);
221         wave_buffer->fmt_size = 16;
222         wave_buffer->FormatTag = 1;
223         wave_buffer->Channels = 1;
224         switch (sfx_num) {
225         case SFX_JUMP:
226                 wave_buffer->SamplesPerSec = SFX_JUMP_FREQ;
227                 break;
228         case SFX_LAND:
229                 wave_buffer->SamplesPerSec = SFX_LAND_FREQ;
230                 break;
231         case SFX_DEATH:
232                 wave_buffer->SamplesPerSec = SFX_DEATH_FREQ;
233                 break;
234         case SFX_SPRING:
235                 wave_buffer->SamplesPerSec = SFX_SPRING_FREQ;
236                 break;
237         case SFX_SPLASH:
238                 wave_buffer->SamplesPerSec = SFX_SPLASH_FREQ;
239                 break;
240         case SFX_FLY:
241                 wave_buffer->SamplesPerSec = SFX_FLY_FREQ;
242                 break;
243         default:
244                 wave_buffer->SamplesPerSec = 22050;
245                 break;
246         }
247         wave_buffer->BitsPerSample = 16;
248         wave_buffer->AvgBytesPerSec = wave_buffer->SamplesPerSec * wave_buffer->Channels * (wave_buffer->BitsPerSample / 8);
249         wave_buffer->BlockAlign = 1;
250         strncpy(wave_buffer->DATA_ID, "data", 4);
251         wave_buffer->data_size = file_length;
252         fread(wave_buffer->data, file_length, 1, file_handle);
253
254         rwop = SDL_RWFromMem(wave_buffer, sizeof(wave_file_t) + file_length);
255
256         soundsamples[i].chunk = Mix_LoadWAV_RW(rwop, 1);
257         soundsamples[i].chunk->allocated = 1;
258         soundsamples[i].used = 1;
259         soundsamples[i].id = sfx_num;
260         soundsamples[i].loop = 0;
261
262         return 0;
263 }
264
265 void dj_free_sfx(unsigned char sfx_num)
266 {
267         if (sfx_num >= 128 || !soundsamples[sfx_num].used)
268                 return;
269
270         Mix_FreeChunk(soundsamples[sfx_num].chunk);
271         soundsamples[sfx_num].chunk = (Mix_Chunk *) NULL;
272         soundsamples[sfx_num].used = 0;
273 }
274
275 /* mod handling */
276
277 char dj_ready_mod(char mod_num)
278 {
279         FILE *tmp;
280 #ifdef _MSC_VER
281         char filename[] = "jnb.tmpmusic.mod";
282 #else
283         char filename[] = "/tmp/jnb.tmpmusic.mod";
284 #endif
285         FILE *fp;
286         int len;
287         switch (mod_num) {
288         case MOD_MENU:
289                 fp = dat_open("jump.mod", datfile_name, "rb");
290                 len = dat_filelen("jump.mod", datfile_name);
291                 break;
292         case MOD_GAME:
293                 fp = dat_open("bump.mod", datfile_name, "rb");
294                 len = dat_filelen("bump.mod", datfile_name);
295                 break;
296         case MOD_SCORES:
297                 fp = dat_open("scores.mod", datfile_name, "rb");
298                 len = dat_filelen("scores.mod", datfile_name);
299                 break;
300         default:
301                 break;
302         }
303
304         if (Mix_PlayingMusic())
305                 Mix_FadeOutMusic(1500);
306
307         if (current_music) {
308                 Mix_FreeMusic(current_music);
309                 current_music = NULL;
310         }
311         tmp = fopen(filename, "wb");
312         for (; len > 0; len--)
313                 fputc(fgetc(fp), tmp);
314         fflush(tmp);
315         fclose(tmp);
316         fclose(fp);
317
318         current_music = Mix_LoadMUS(filename);
319         if (current_music == NULL) {
320                 fprintf(stderr, "Couldn't load music: %s\n", SDL_GetError());
321                 return 0;
322         }
323
324         return 0;
325 }
326
327 char dj_start_mod(void)
328 {
329         Mix_VolumeMusic(64);
330
331         Mix_FadeInMusic(current_music, -1, 2000);
332
333         return 0;
334 }
335
336 void dj_stop_mod(void)
337 {
338         Mix_HaltMusic();
339 }
340
341 void dj_set_mod_volume(char volume)
342 {
343         //Mix_VolumeMusic(volume*4);
344 }
345
346 char dj_load_mod(FILE * file_handle, char *filename, char mod_num)
347 {
348         return 0;
349 }
350
351 void dj_free_mod(char mod_num)
352 {
353 }