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