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

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

sdlport: use SDL_Mixer to read samples, and get rid of imlib's readwav.

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