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

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

sdlport: make SDL_mixer mandatory. I'm not going to maintain legacy code
that cannot even play music.

File size: 5.7 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
[56]21#include "config.h"
22
[551]23#include <cstring>
[131]24
[2]25#include <SDL.h>
[479]26#include <SDL/SDL_mixer.h>
[2]27
[481]28#include "sound.h"
[551]29#include "hmi.h"
[481]30#include "readwav.h"
31#include "specs.h"
[2]32#include "setup.h"
33
34extern flags_struct flags;
35static int sound_enabled = 0;
36static SDL_AudioSpec audioObtained;
37
38//
39// sound_init()
40// Initialise audio
41//
42int sound_init( int argc, char **argv )
43{
[124]44    char *sfxdir, *datadir;
45    FILE *fd = NULL;
[2]46
[124]47    // Disable sound if requested.
48    if( flags.nosound )
49    {
50        // User requested that sound be disabled
[536]51        printf( "Sound: Disabled (-nosound)\n" );
[124]52        return 0;
53    }
[2]54
[124]55    // Check for the sfx directory, disable sound if we can't find it.
56    datadir = get_filename_prefix();
[129]57    sfxdir = (char *)malloc( strlen( datadir ) + 5 + 1 );
[124]58    sprintf( sfxdir, "%s/sfx/", datadir );
59    if( (fd = fopen( sfxdir,"r" )) == NULL )
60    {
61        // Didn't find the directory, so disable sound.
[536]62        printf( "Sound: Disabled (couldn't find the sfx directory)\n" );
[124]63        return 0;
64    }
[129]65    free( sfxdir );
[2]66
[479]67    if (Mix_OpenAudio(11025, AUDIO_U8, 2, 128) < 0)
68    {
[536]69        printf( "Sound: Unable to open audio - %s\nSound: Disabled (error)\n", SDL_GetError() );
[479]70        return 0;
71    }
72
73    Mix_AllocateChannels(50);
74
75    int tempChannels = 0;
76    Mix_QuerySpec(&audioObtained.freq, &audioObtained.format, &tempChannels);
77    audioObtained.channels = tempChannels & 0xFF;
78
79    sound_enabled = SFX_INITIALIZED | MUSIC_INITIALIZED;
[536]80
81    printf( "Sound: Enabled\n" );
[2]82
[124]83    // It's all good
84    return sound_enabled;
[2]85}
86
87//
88// sound_uninit
89//
90// Shutdown audio and release any memory left over.
91//
92void sound_uninit()
93{
[551]94    if (sound_enabled)
[124]95    {
[479]96        Mix_CloseAudio();
[124]97    }
[2]98}
99
100//
101// sound_effect constructor
102//
103// Read in the requested .wav file.
104//
105sound_effect::sound_effect( char * filename )
106{
[124]107    if( sound_enabled )
108    {
[534]109        int sample_speed;
[479]110
111        void* temp_data = (void *)read_wav( filename, sample_speed, size );
112
113        SDL_AudioCVT audiocvt;
[494]114
[479]115        SDL_BuildAudioCVT( &audiocvt, AUDIO_U8, 1, 11025, audioObtained.format, audioObtained.channels, audioObtained.freq );
116        data = malloc( size * audiocvt.len_mult );
117
118        memcpy( data, temp_data, size );
119        audiocvt.buf = (Uint8*)data;
120        audiocvt.len = size;
121        SDL_ConvertAudio( &audiocvt );
122        size = (Uint32)((double)size * audiocvt.len_ratio);
123
124        free(temp_data);
125
126        this->chunk = Mix_QuickLoad_RAW((Uint8*)data, size);
[124]127    }
[2]128}
129
130//
131// sound_effect destructor
132//
133// Release the audio data.
134//
135sound_effect::~sound_effect()
136{
[124]137    if( sound_enabled )
138    {
[479]139        // Sound effect deletion only happens on level load, so there
140        // is no problem in stopping everything. But the original playing
141        // code handles the sound effects and the "playlist" differently.
142        // Therefore with SDL_mixer, a sound that has not finished playing
143        // on a level load will cut off in the middle. This is most noticable
144        // for the button sound of the load savegame dialog.
145        Mix_FadeOutGroup(-1, 100);
146        while (Mix_Playing(-1))
147            SDL_Delay(10);
148        Mix_FreeChunk(this->chunk);
149
[124]150        if( data )
151        {
[129]152            free( data );
[124]153        }
154    }
[2]155}
156
157//
158// sound_effect::play
159//
[551]160// Add a new sample for playing.
[2]161// panpot defines the pan position for the sound effect.
162//   0   - Completely to the right.
163//   128 - Centered.
164//   255 - Completely to the left.
165//
166void sound_effect::play( int volume, int pitch, int panpot )
167{
[551]168    if (sound_enabled)
[124]169    {
[479]170        int channel = Mix_PlayChannel(-1, this->chunk, 0);
171        if (channel > -1)
172        {
173            Mix_Volume(channel, volume);
174            Mix_SetPanning(channel, panpot, 255 - panpot);
175        }
[124]176    }
[2]177}
178
179
[479]180// Play music using SDL_Mixer
[2]181
[536]182song::song(char const * filename)
[2]183{
[124]184    data = NULL;
[131]185    Name = strdup(filename);
[124]186    song_id = 0;
[494]187
[479]188    rw = NULL;
189    music = NULL;
190
191    char realname[255];
192    strcpy(realname, get_filename_prefix());
193    strcat(realname, filename);
194
195    unsigned int data_size;
196    data = load_hmi(realname, data_size);
197
[536]198    if (!data)
[479]199    {
[551]200        printf("Sound: ERROR - could not load %s\n", realname);
[536]201        return;
[479]202    }
[536]203
204    rw = SDL_RWFromMem(data, data_size);
205    music = Mix_LoadMUS_RW(rw);
206
207    if (!music)
208    {
[551]209        printf("Sound: ERROR - %s while loading %s\n",
[536]210               Mix_GetError(), realname);
211        return;
212    }
[2]213}
214
215song::~song()
216{
[536]217    if(playing())
[124]218        stop();
[536]219    free(data);
220    free(Name);
[479]221
[536]222    Mix_FreeMusic(music);
223    SDL_FreeRW(rw);
[2]224}
225
226void song::play( unsigned char volume )
227{
[124]228    song_id = 1;
[479]229
230    Mix_PlayMusic(this->music, 0);
231    Mix_VolumeMusic(volume);
[2]232}
233
234void song::stop( long fadeout_time )
235{
[124]236    song_id = 0;
[479]237
238    Mix_FadeOutMusic(100);
[2]239}
240
241int song::playing()
242{
[479]243    return Mix_PlayingMusic();
[2]244}
245
246void song::set_volume( int volume )
247{
[479]248    Mix_VolumeMusic(volume);
[2]249}
[551]250
Note: See TracBrowser for help on using the repository browser.