source: abuse/trunk/src/sdlport/sound.cpp @ 627

Last change on this file since 627 was 627, checked in by Sam Hocevar, 11 years ago

sdlport: make the SFX availability check more robust.

File size: 5.3 KB
RevLine 
[56]1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 2001 Anthony Kruize <trandor@labyrinth.net.au>
[494]4 *  Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
[56]5 *
6 *  This program is free software; you can redistribute it and/or modify
7 *  it under the terms of the GNU General Public License as published by
8 *  the Free Software Foundation; either version 2 of the License, or
9 *  (at your option) any later version.
10 *
11 *  This program is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *  GNU General Public License for more details.
15 *
16 *  You should have received a copy of the GNU General Public License
17 *  along with this program; if not, write to the Free Software Foundation,
18 *  Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 */
[2]20
[555]21#if defined HAVE_CONFIG_H
22#   include "config.h"
23#endif
[56]24
[551]25#include <cstring>
[131]26
[2]27#include <SDL.h>
[479]28#include <SDL/SDL_mixer.h>
[2]29
[481]30#include "sound.h"
[551]31#include "hmi.h"
[481]32#include "specs.h"
[2]33#include "setup.h"
34
35extern flags_struct flags;
36static int sound_enabled = 0;
37static SDL_AudioSpec audioObtained;
38
39//
40// sound_init()
41// Initialise audio
42//
43int sound_init( int argc, char **argv )
44{
[124]45    char *sfxdir, *datadir;
[627]46    FILE *f = NULL;
[2]47
[124]48    // Disable sound if requested.
49    if( flags.nosound )
50    {
51        // User requested that sound be disabled
[536]52        printf( "Sound: Disabled (-nosound)\n" );
[124]53        return 0;
54    }
[2]55
[124]56    // Check for the sfx directory, disable sound if we can't find it.
57    datadir = get_filename_prefix();
[627]58    sfxdir = (char *)malloc(strlen(datadir) + 5 + 1);
59    sprintf(sfxdir, "%s/sfx/ambcave1.wav", datadir);
60    FILE *f = fopen(sfxdir, "r");
61    if (!f)
[124]62    {
63        // Didn't find the directory, so disable sound.
[536]64        printf( "Sound: Disabled (couldn't find the sfx directory)\n" );
[124]65        return 0;
66    }
[627]67    fclose(f);
68    free(sfxdir);
[2]69
[617]70    if (Mix_OpenAudio(44100, AUDIO_S16SYS, 2, 128) < 0)
[479]71    {
[536]72        printf( "Sound: Unable to open audio - %s\nSound: Disabled (error)\n", SDL_GetError() );
[479]73        return 0;
74    }
75
76    Mix_AllocateChannels(50);
77
78    int tempChannels = 0;
79    Mix_QuerySpec(&audioObtained.freq, &audioObtained.format, &tempChannels);
80    audioObtained.channels = tempChannels & 0xFF;
81
82    sound_enabled = SFX_INITIALIZED | MUSIC_INITIALIZED;
[536]83
84    printf( "Sound: Enabled\n" );
[2]85
[124]86    // It's all good
87    return sound_enabled;
[2]88}
89
90//
91// sound_uninit
92//
93// Shutdown audio and release any memory left over.
94//
95void sound_uninit()
96{
[552]97    if (!sound_enabled)
98        return;
99
100    Mix_CloseAudio();
[2]101}
102
103//
104// sound_effect constructor
105//
106// Read in the requested .wav file.
107//
[552]108sound_effect::sound_effect(char const *filename)
[2]109{
[552]110    if (!sound_enabled)
111        return;
[479]112
[552]113    jFILE fp(filename, "rb");
114    if (fp.open_failure())
115        return;
[479]116
[552]117    void *temp_data = malloc(fp.file_size());
118    fp.read(temp_data, fp.file_size());
119    SDL_RWops *rw = SDL_RWFromMem(temp_data, fp.file_size());
120    m_chunk = Mix_LoadWAV_RW(rw, 1);
121    free(temp_data);
[2]122}
123
124//
125// sound_effect destructor
126//
127// Release the audio data.
128//
129sound_effect::~sound_effect()
130{
[552]131    if(!sound_enabled)
132        return;
[479]133
[552]134    // Sound effect deletion only happens on level load, so there
135    // is no problem in stopping everything. But the original playing
136    // code handles the sound effects and the "playlist" differently.
137    // Therefore with SDL_mixer, a sound that has not finished playing
138    // on a level load will cut off in the middle. This is most noticable
139    // for the button sound of the load savegame dialog.
140    Mix_FadeOutGroup(-1, 100);
141    while (Mix_Playing(-1))
142        SDL_Delay(10);
143    Mix_FreeChunk(m_chunk);
[2]144}
145
146//
147// sound_effect::play
148//
[551]149// Add a new sample for playing.
[2]150// panpot defines the pan position for the sound effect.
151//   0   - Completely to the right.
152//   128 - Centered.
153//   255 - Completely to the left.
154//
[552]155void sound_effect::play(int volume, int pitch, int panpot)
[2]156{
[552]157    if (!sound_enabled)
158        return;
159
160    int channel = Mix_PlayChannel(-1, m_chunk, 0);
161    if (channel > -1)
[124]162    {
[552]163        Mix_Volume(channel, volume);
164        Mix_SetPanning(channel, panpot, 255 - panpot);
[124]165    }
[2]166}
167
168
[479]169// Play music using SDL_Mixer
[2]170
[536]171song::song(char const * filename)
[2]172{
[124]173    data = NULL;
[131]174    Name = strdup(filename);
[124]175    song_id = 0;
[494]176
[479]177    rw = NULL;
178    music = NULL;
179
180    char realname[255];
181    strcpy(realname, get_filename_prefix());
182    strcat(realname, filename);
183
[616]184    uint32_t data_size;
[479]185    data = load_hmi(realname, data_size);
186
[536]187    if (!data)
[479]188    {
[551]189        printf("Sound: ERROR - could not load %s\n", realname);
[536]190        return;
[479]191    }
[536]192
193    rw = SDL_RWFromMem(data, data_size);
194    music = Mix_LoadMUS_RW(rw);
195
196    if (!music)
197    {
[551]198        printf("Sound: ERROR - %s while loading %s\n",
[536]199               Mix_GetError(), realname);
200        return;
201    }
[2]202}
203
204song::~song()
205{
[536]206    if(playing())
[124]207        stop();
[536]208    free(data);
209    free(Name);
[479]210
[536]211    Mix_FreeMusic(music);
212    SDL_FreeRW(rw);
[2]213}
214
215void song::play( unsigned char volume )
216{
[124]217    song_id = 1;
[479]218
219    Mix_PlayMusic(this->music, 0);
220    Mix_VolumeMusic(volume);
[2]221}
222
223void song::stop( long fadeout_time )
224{
[124]225    song_id = 0;
[479]226
227    Mix_FadeOutMusic(100);
[2]228}
229
230int song::playing()
231{
[479]232    return Mix_PlayingMusic();
[2]233}
234
235void song::set_volume( int volume )
236{
[479]237    Mix_VolumeMusic(volume);
[2]238}
[551]239
Note: See TracBrowser for help on using the repository browser.