2 * Copyright (C) 2003 Robert Kooima
4 * NEVERBALL is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
16 #include <SDL_mixer.h>
22 /*---------------------------------------------------------------------------*/
24 static int audio_state
= 0;
26 static Mix_Music
*song
;
27 static Mix_Chunk
*buff
[AUD_COUNT
];
28 static int chan
[AUD_COUNT
];
38 /*---------------------------------------------------------------------------*/
40 static void chunk_load(int i
, const char *filename
, int channel
)
42 buff
[i
] = Mix_LoadWAV(config_data(filename
));
46 static void chunk_free(int i
)
50 Mix_FreeChunk(buff
[i
]);
55 /*---------------------------------------------------------------------------*/
59 int r
= config_get_d(CONFIG_AUDIO_RATE
);
60 int b
= config_get_d(CONFIG_AUDIO_BUFF
);
64 if (Mix_OpenAudio(r
, MIX_DEFAULT_FORMAT
, 1, b
) == 0)
66 chunk_load(AUD_MENU
, "snd/menu.wav", CH_MENU
);
67 chunk_load(AUD_START
, "snd/select.ogg", CH_VOICE
);
68 chunk_load(AUD_READY
, "snd/ready.ogg", CH_VOICE
);
69 chunk_load(AUD_SET
, "snd/set.ogg", CH_VOICE
);
70 chunk_load(AUD_GO
, "snd/go.ogg", CH_VOICE
);
71 chunk_load(AUD_BALL
, "snd/ball.ogg", CH_GRAB
);
72 chunk_load(AUD_BUMP
, "snd/bump.ogg", CH_BUMP
);
73 chunk_load(AUD_COIN
, "snd/coin.wav", CH_GRAB
);
74 chunk_load(AUD_TICK
, "snd/tick.ogg", CH_TICK
);
75 chunk_load(AUD_TOCK
, "snd/tock.ogg", CH_TICK
);
76 chunk_load(AUD_SWITCH
, "snd/switch.wav", CH_STATE
);
77 chunk_load(AUD_JUMP
, "snd/jump.ogg", CH_STATE
);
78 chunk_load(AUD_GOAL
, "snd/goal.wav", CH_STATE
);
79 chunk_load(AUD_SCORE
, "snd/record.ogg", CH_VOICE
);
80 chunk_load(AUD_FALL
, "snd/fall.ogg", CH_VOICE
);
81 chunk_load(AUD_TIME
, "snd/time.ogg", CH_VOICE
);
82 chunk_load(AUD_OVER
, "snd/over.ogg", CH_VOICE
);
86 audio_volume(config_get_d(CONFIG_SOUND_VOLUME
),
87 config_get_d(CONFIG_MUSIC_VOLUME
));
91 fprintf(stderr
, "Sound disabled\n");
97 void audio_play(int i
, float v
)
99 if (audio_state
== 1 && buff
[i
])
101 Mix_VolumeChunk(buff
[i
], (int) (v
* MIX_MAX_VOLUME
));
102 Mix_PlayChannel(chan
[i
], buff
[i
], 0);
106 void audio_free(void)
108 if (audio_state
== 1)
112 chunk_free(AUD_OVER
);
113 chunk_free(AUD_TIME
);
114 chunk_free(AUD_FALL
);
115 chunk_free(AUD_SCORE
);
116 chunk_free(AUD_GOAL
);
117 chunk_free(AUD_JUMP
);
118 chunk_free(AUD_SWITCH
);
119 chunk_free(AUD_TOCK
);
120 chunk_free(AUD_TICK
);
121 chunk_free(AUD_COIN
);
122 chunk_free(AUD_BUMP
);
123 chunk_free(AUD_BALL
);
126 chunk_free(AUD_READY
);
127 chunk_free(AUD_START
);
128 chunk_free(AUD_MENU
);
134 /*---------------------------------------------------------------------------*/
136 static const char *current
= NULL
;
137 static const char *next
= NULL
;
139 static float fade_volume
= 1.0f
;
140 static float fade_rate
= 0.0f
;
142 void audio_music_play(const char *filename
)
148 if ((config_get_d(CONFIG_MUSIC_VOLUME
) > 0) &&
149 (song
= Mix_LoadMUS(config_data(filename
))))
151 Mix_PlayMusic(song
, -1);
157 void audio_music_queue(const char *filename
)
161 if (!current
|| strcmp(filename
, current
) != 0)
166 audio_music_play(filename
);
174 void audio_music_stop(void)
178 if (Mix_PlayingMusic())
188 /*---------------------------------------------------------------------------*/
190 * SDL_mixer already provides music fading. Unfortunately, it halts playback
191 * at the end of a fade. We need to be able to fade music back in from the
192 * point where it stopped. So, we reinvent this wheel.
195 void audio_timer(float dt
)
199 if (fade_rate
> 0.0f
|| fade_rate
< 0.0f
)
200 fade_volume
+= dt
/ fade_rate
;
202 if (fade_volume
< 0.0f
)
209 if (Mix_PlayingMusic())
214 fade_rate
= -fade_rate
;
215 audio_music_queue(next
);
220 if (fade_volume
> 1.0f
)
226 if (Mix_PausedMusic() && fade_rate
> 0.0f
)
229 if (Mix_PlayingMusic())
230 Mix_VolumeMusic(config_get_d(CONFIG_MUSIC_VOLUME
) *
231 (int) (fade_volume
* MIX_MAX_VOLUME
) / 10);
235 void audio_music_fade_out(float t
)
241 void audio_music_fade_in(float t
)
247 void audio_music_fade_to(float t
, const char *filename
)
251 if (!current
|| strcmp(filename
, current
) != 0)
260 audio_music_queue(filename
);
261 audio_music_fade_in(t
);
265 void audio_volume(int s
, int m
)
269 Mix_Volume(-1, s
* MIX_MAX_VOLUME
/ 10);
270 Mix_VolumeMusic(m
* MIX_MAX_VOLUME
/ 10);
274 /*---------------------------------------------------------------------------*/