Patch against current CVS (2005.04.12) to add music/sound support and clean up some autotool usage. Original Music/Sound patch from: http://www.miguev.net/misc/ Index: autogen.sh =================================================================== RCS file: /cvsroot/crack-attack/crack-attack/autogen.sh,v retrieving revision 1.1 diff -u -r1.1 autogen.sh --- autogen.sh 13 Oct 2004 16:16:26 -0000 1.1 +++ autogen.sh 13 Apr 2005 02:04:08 -0000 @@ -2,8 +2,7 @@ aclocal-1.8 $ACLOCAL_FLAGS || exit; autoheader-2.59 || exit; -automake-1.8 --add-missing --copy; autoconf-2.59 || exit; -automake-1.8 || exit; +automake-1.8 --add-missing --copy || exit; ./configure $@ Index: configure.ac =================================================================== RCS file: /cvsroot/crack-attack/crack-attack/configure.ac,v retrieving revision 1.10 diff -u -r1.10 configure.ac --- configure.ac 1 Apr 2005 23:46:32 -0000 1.10 +++ configure.ac 13 Apr 2005 02:04:08 -0000 @@ -55,23 +55,38 @@ AC_SUBST(PACKAGE_LIBS) AM_CONDITIONAL([WANT_GTK], [test "$enable_gtk" = yes]) -dnl Check for SDL_mixer +dnl Check for sound support AC_ARG_ENABLE(sound, AC_HELP_STRING([--enable-sound=[yes/no]], - [Play sounds and music during game[default=yes]]), + [Play sounds and music during game [default=yes]]), enable_sound="$enableval", - enable_sound=yes) -if test "$enable_sound" = "yes"; then - AM_PATH_SDL(1.2.0,, AC_MSG_ERROR([libSDL is needed])) - AC_CHECK_LIB([SDL_mixer], - [Mix_OpenAudio], - AC_MSG_RESULT("SDL_mixer found"); SOUND_LIBS="-lSDL_mixer"; enable_sound=no;, - AC_MSG_RESULT("SDL_mixer not found"); SOUND_LIBS=""; enable_sound=no;) -else - SOUND_LIBS="" + enable_sound=auto) +AUDIO_CFLAGS="" +AUDIO_LIBS="" +if test "$enable_sound" != "no"; then + found_sound="no" + AM_PATH_SDL(1.2.0, + [ + AC_CHECK_LIB([SDL_mixer], + [Mix_OpenAudio], + [found_sound=yes], + [found_sound=no] + ) + ],[found_sound=no] + ) + + if test "$enable_sound" == "yes" -a "$found_sound" == "no"; then + AC_MSG_ERROR(libSDL and SDL_mixer are required for sound) + fi + if test "$found_sound" == "yes"; then + AUDIO_CFLAGS="$SDL_CFLAGS" + AUDIO_LIBS="$SDL_LIBS -lSDL_mixer" + AC_DEFINE(AUDIO_ENABLED, 1, [Has audio support]) + fi fi -AC_SUBST(SOUND_LIBS) -AM_CONDITIONAL([AUDIO_ENABLED], [test "$enable_sound" = yes]) +AC_SUBST(AUDIO_CFLAGS) +AC_SUBST(AUDIO_LIBS) +AM_CONDITIONAL([AUDIO_ENABLED], [test "$found_sound" = "yes"]) dnl Check for debugging Index: src/Attack.cxx =================================================================== RCS file: /cvsroot/crack-attack/crack-attack/src/Attack.cxx,v retrieving revision 1.8 diff -u -r1.8 Attack.cxx --- src/Attack.cxx 26 Mar 2005 13:48:10 -0000 1.8 +++ src/Attack.cxx 13 Apr 2005 02:04:09 -0000 @@ -44,6 +44,11 @@ #include "MetaState.h" #include "Random.h" +#ifdef AUDIO_ENABLED +#include "Sound.h" +#include "Music.h" +#endif + #ifdef WANT_GTK #include "gtk-gui/gui_main.h" #endif @@ -63,6 +68,8 @@ * find and use correct GL_LIGHT_MODEL_COLOR_CONTROL defines */ +int nosound = 0; + int main ( int argc, char **argv ) { setupLocalDataDirectory(); @@ -86,14 +93,14 @@ cerr << "Usage: " GC_BINARY " --server [PORT] [--low] [--extreme] [--wait] " "[--name 'NAME']\n" " \n" - " " GC_BINARY " SERVER[:PORT] [[--really] --low] [--name 'NAME']\n" + " " GC_BINARY " SERVER[:PORT] [[--really] --low] [--nosound] [--name 'NAME']\n" " \n" - " " GC_BINARY " --solo [[--really] --low] [-X] [--name 'NAME']\n" + " " GC_BINARY " --solo [[--really] --low] [-X] [--nosound] [--name 'NAME']\n" " \n" " " GC_BINARY " -1 [[-r] -l] [-X] [-n 'NAME']\n" " \n" " " GC_BINARY " --solo [--hard] [--easy] [--medium] [[--really] --low]" - " [--name 'NAME']\n" + " [--nosound] [--name 'NAME']\n" " " << endl; exit(1); @@ -134,7 +141,21 @@ MetaState::programStart(mode, player_name, width, height); +#ifdef AUDIO_ENABLED + if (!nosound) { + Sound::initialize(); + Music::initialize(); + Music::play_prelude(); + } +#endif + glutMainLoop(); + +#ifdef AUDIO_ENABLED + Music::stop(); + Music::cleanup(); + Sound::cleanup(); +#endif } void parseCommandLine ( int argc, char **argv, int &mode, int &port, @@ -142,6 +163,9 @@ { for (int n = 1; argv[n]; n++) { + if (!strcmp(argv[n], "--nosound")) + nosound = 1; + else if (!strcmp(argv[n], "-s") || !strcmp(argv[n], "--server")) { if (mode & (CM_SERVER | CM_CLIENT | CM_SOLO)) usage(); Index: src/Block.cxx =================================================================== RCS file: /cvsroot/crack-attack/crack-attack/src/Block.cxx,v retrieving revision 1.1 diff -u -r1.1 Block.cxx --- src/Block.cxx 11 Oct 2004 01:09:57 -0000 1.1 +++ src/Block.cxx 13 Apr 2005 02:04:09 -0000 @@ -35,6 +35,7 @@ #include "Swapper.h" #include "SparkleManager.h" #include "X.h" +#include "Sound.h" using namespace std; @@ -98,8 +99,12 @@ } else if (state & BS_AWAKING) { // The alarm has been set to go off when we're done awaking. When the // pop alarm goes off, we only switch our appearence. - if (pop_alarm == Game::time_step) + if (pop_alarm == Game::time_step) { +#ifdef AUDIO_ENABLED + Sound::play( GC_SOUND_BLOCK_AWAKING, 5 ); +#endif pop_alarm = 0; + } if (alarm == Game::time_step) { @@ -159,6 +164,9 @@ // change our state state = BS_STATIC; +#ifdef AUDIO_ENABLED + Sound::play( GC_SOUND_BLOCK_FALLEN, 2 ); +#endif // update the grid Grid::changeState(x, y, this, GR_BLOCK); @@ -262,6 +270,9 @@ // change the game state Game::dying_count++; Game::dying_count_2++; +#ifdef AUDIO_ENABLED + Sound::play( GC_SOUND_BLOCK_DYING, spark_number / 3 ); +#endif // let the combo know we're in beginComboInvolvement(combo); Index: src/CelebrationManager.cxx =================================================================== RCS file: /cvsroot/crack-attack/crack-attack/src/CelebrationManager.cxx,v retrieving revision 1.2 diff -u -r1.2 CelebrationManager.cxx --- src/CelebrationManager.cxx 24 Mar 2005 19:35:35 -0000 1.2 +++ src/CelebrationManager.cxx 13 Apr 2005 02:04:09 -0000 @@ -34,6 +34,9 @@ #include "WinRecord.h" #include "Random.h" #include "Score.h" +#ifdef AUDIO_ENABLED +#include "Music.h" +#endif using namespace std; @@ -57,6 +60,10 @@ draw_game = true; light_level = 1.0f; +#ifdef AUDIO_ENABLED + Music::fadeout( 1000 ); +#endif + MessageManager::mode = MM_CELEBRATION; if (WinRecord::won) { @@ -133,6 +139,9 @@ spark_rate[n] = DC_CSPARK_STARTING_RATE; spark_color[n] = Random::number(DC_CSPARK_COLOR_NUMBER); } +#ifdef AUDIO_ENABLED + Music::play_youwin(); +#endif } else { @@ -200,6 +209,9 @@ loss_bounce_count--; loss_velocity = 0.0f; loss_height = 0.0f; +#ifdef AUDIO_ENABLED + Music::play_gameover(); +#endif // otherwise, bounce } else { Index: src/CountDownManager.cxx =================================================================== RCS file: /cvsroot/crack-attack/crack-attack/src/CountDownManager.cxx,v retrieving revision 1.1 diff -u -r1.1 CountDownManager.cxx --- src/CountDownManager.cxx 11 Oct 2004 01:09:57 -0000 1.1 +++ src/CountDownManager.cxx 13 Apr 2005 02:04:09 -0000 @@ -29,6 +29,10 @@ #include "CountDownManager.h" #include "MessageManager.h" #include "Displayer.h" +#ifdef AUDIO_ENABLED +#include "Sound.h" +#include "Music.h" +#endif using namespace std; @@ -43,6 +47,9 @@ state = 3; MessageManager::readyMessage(state); +#ifdef AUDIO_ENABLED + Music::fadeout( 3000 ); +#endif } void CountDownManager::cleanUp ( ) @@ -55,7 +62,12 @@ if (start_pause_alarm) start_pause_alarm--; - if (--message_switch_alarm == 0) + if (message_switch_alarm == 30) { +#ifdef AUDIO_ENABLED + Sound::play( GC_SOUND_COUNTDOWN, 1 + state * 3 ); +#endif + } + if (--message_switch_alarm == 0) { if (--state == -1) { MessageManager::freeMessage(); message_switch_alarm = 0; @@ -63,11 +75,16 @@ } else if (state == MS_COUNT_DOWN_GO) { MessageManager::freeMessage(); MessageManager::readyMessage(MS_COUNT_DOWN_GO); +#ifdef AUDIO_ENABLED + Music::stop(); + Music::play(); +#endif message_switch_alarm = GC_START_PAUSE_DELAY / 3; } else { MessageManager::nextMessage(state); message_switch_alarm = GC_START_PAUSE_DELAY / 3; } + } } Index: src/Game.cxx =================================================================== RCS file: /cvsroot/crack-attack/crack-attack/src/Game.cxx,v retrieving revision 1.12 diff -u -r1.12 Game.cxx --- src/Game.cxx 28 Mar 2005 10:04:53 -0000 1.12 +++ src/Game.cxx 13 Apr 2005 02:04:09 -0000 @@ -66,6 +66,9 @@ #include "WinRecord.h" #include "X.h" #include "ComputerPlayer.h" +#ifdef AUDIO_ENABLED +#include "Music.h" +#endif int Game::time_step; int Game::state; @@ -204,6 +207,9 @@ Communicator::unpauseSyncCheck(); Communicator::signalUnpaused(); } +#ifdef AUDIO_ENABLED + Music::resume(); +#endif // pause } else { @@ -218,6 +224,9 @@ if (!(MetaState::mode & CM_SOLO)) Communicator::signalPaused(); +#ifdef AUDIO_ENABLED + Music::pause(); +#endif } } Index: src/Garbage.cxx =================================================================== RCS file: /cvsroot/crack-attack/crack-attack/src/Garbage.cxx,v retrieving revision 1.4 diff -u -r1.4 Garbage.cxx --- src/Garbage.cxx 28 Mar 2005 10:04:53 -0000 1.4 +++ src/Garbage.cxx 13 Apr 2005 02:04:09 -0000 @@ -34,6 +34,9 @@ #include "Spring.h" #include "Random.h" #include "X.h" +#ifdef AUDIO_ENABLED +#include "Sound.h" +#endif #include @@ -98,6 +101,11 @@ width = GC_PLAY_WIDTH; flavor = GF_NORMAL; f_y = 0; +/* +#ifdef AUDIO_ENABLED + Sound::play( GC_SOUND_GARBAGE_SHATTERING, this-> width * this->height ); +#endif +*/ state = GS_AWAKING; alarm = Game::time_step + awake_delay; @@ -244,6 +252,9 @@ // change our state state = BS_STATIC; +#ifdef AUDIO_ENABLED + Sound::play( GC_SOUND_GARBAGE_FALLEN, this->width * this->height ); +#endif // if this is the end of our initial fall if (initial_fall) { @@ -332,6 +343,9 @@ for (int w = 0; w < width; w++) Grid::remove(s_x + w, s_y, this); #endif +#ifdef AUDIO_ENABLED + Sound::play( GC_SOUND_GARBAGE_SHATTERING, this-> width * this->height ); +#endif // if it's an even row, perhaps shatter into new garbage if ((width == GC_PLAY_WIDTH && ((s_y - y) & (1 << 0)) Index: src/Makefile.am =================================================================== RCS file: /cvsroot/crack-attack/crack-attack/src/Makefile.am,v retrieving revision 1.8 diff -u -r1.8 Makefile.am --- src/Makefile.am 1 Apr 2005 21:04:56 -0000 1.8 +++ src/Makefile.am 13 Apr 2005 02:04:09 -0000 @@ -1,6 +1,11 @@ bin_PROGRAMS = crack-attack -crack_attack_SOURCES = Attack.cxx Block.cxx BlockManager.cxx CelebrationManager.cxx Clock.cxx ComboManager.cxx ComboTabulator.cxx Communicator.cxx ComputerPlayer.cxx ComputerPlayerAI.cxx Controller.cxx CountDownManager.cxx Creep.cxx Displayer.cxx Game.cxx Garbage.cxx GarbageFlavorImage.cxx GarbageGenerator.cxx GarbageManager.cxx GarbageQueue.cxx Grid.cxx LevelLights.cxx LightManager.cxx LoseBar.cxx MessageManager.cxx MetaState.cxx Random.cxx Sine.cxx Score.cxx ScoreRecordManager.cxx Swapper.cxx SparkleManager.cxx Spring.cxx SignManager.cxx String.cxx TextureLoader.cxx WinRecord.cxx X.cxx DrawBlocks.cxx DrawGarbage.cxx DrawCandy.cxx DrawScoreRecord.cxx DrawSwapper.cxx DrawExternalCandy.cxx DrawLevelLights.cxx DrawCountDown.cxx DrawMessages.cxx DrawWinRecord.cxx obj_block.cxx obj_garbage.cxx obj_garbage_thin_middle.cxx obj_garbage_thin_cap.cxx obj_garbage_thick_corner.cxx obj_garbage_thick_edge.cxx obj_garbage_thick_middle.cxx obj_garbage_small.cxx obj_sparkle.cxx obj_sign.cxx obj_swapper.cxx obj_external_candy.cxx obj_level_lights.cxx obj_messages.cxx obj_clock.cxx obj_name.cxx obj_score_record.cxx Attack.h Block.h BlockManager.h CelebrationManager.h Clock.h ComboManager.h ComboTabulator.h Communicator.h ComputerPlayer.h ComputerPlayerAI.h Controller.h CountDownManager.h Creep.h Displayer.h Game.h Garbage.h GarbageFlavorImage.h GarbageGenerator.h GarbageManager.h GarbageQueue.h Grid.h LevelLights.h LightManager.h LoseBar.h MessageManager.h MetaState.h Random.h Sine.h Score.h ScoreRecordManager.h Swapper.h SparkleManager.h Spring.h SignManager.h String.h TextureLoader.h WinRecord.h X.h Mode.h prefix.h prefix.c +if AUDIO_ENABLED +audio_sources = Music.cxx Sound.cxx +else +audio_sources = +endif +crack_attack_SOURCES = Attack.cxx Block.cxx BlockManager.cxx CelebrationManager.cxx Clock.cxx ComboManager.cxx ComboTabulator.cxx Communicator.cxx ComputerPlayer.cxx ComputerPlayerAI.cxx Controller.cxx CountDownManager.cxx Creep.cxx Displayer.cxx Game.cxx Garbage.cxx GarbageFlavorImage.cxx GarbageGenerator.cxx GarbageManager.cxx GarbageQueue.cxx Grid.cxx LevelLights.cxx LightManager.cxx LoseBar.cxx MessageManager.cxx MetaState.cxx Random.cxx Sine.cxx Score.cxx ScoreRecordManager.cxx Swapper.cxx SparkleManager.cxx Spring.cxx SignManager.cxx String.cxx TextureLoader.cxx WinRecord.cxx X.cxx DrawBlocks.cxx DrawGarbage.cxx DrawCandy.cxx DrawScoreRecord.cxx DrawSwapper.cxx DrawExternalCandy.cxx DrawLevelLights.cxx DrawCountDown.cxx DrawMessages.cxx DrawWinRecord.cxx obj_block.cxx obj_garbage.cxx obj_garbage_thin_middle.cxx obj_garbage_thin_cap.cxx obj_garbage_thick_corner.cxx obj_garbage_thick_edge.cxx obj_garbage_thick_middle.cxx obj_garbage_small.cxx obj_sparkle.cxx obj_sign.cxx obj_swapper.cxx obj_external_candy.cxx obj_level_lights.cxx obj_messages.cxx obj_clock.cxx obj_name.cxx obj_score_record.cxx Attack.h Block.h BlockManager.h CelebrationManager.h Clock.h ComboManager.h ComboTabulator.h Communicator.h ComputerPlayer.h ComputerPlayerAI.h Controller.h CountDownManager.h Creep.h Displayer.h Game.h Garbage.h GarbageFlavorImage.h GarbageGenerator.h GarbageManager.h GarbageQueue.h Grid.h LevelLights.h LightManager.h LoseBar.h MessageManager.h MetaState.h Random.h Sine.h Score.h ScoreRecordManager.h Swapper.h SparkleManager.h Spring.h SignManager.h String.h TextureLoader.h WinRecord.h X.h Mode.h prefix.h prefix.c $(audio_sources) # prefix sources compiled whether we use them or not @@ -8,14 +13,10 @@ GUI_DIR = gtk-gui GUI_LIBS = gtk-gui/libgtkgui.a endif -if AUDIO_ENABLED - AUDIO_CXXFLAGS=${CXXFLAGS} ${SDL_CFLAGS} - AUDIO_LIBS=${SDL_LIBS} -endif SUBDIRS = $(GUI_DIR) -AM_CXXFLAGS = -O3 -s -DBR_PTHREAD=0 @DEBUG_CFLAGS@ ${AUDIO_CXXFLAGS} +AM_CXXFLAGS = -DBR_PTHREAD=0 @DEBUG_CFLAGS@ @AUDIO_CFLAGS@ if WANT_BINRELOC PATH_INCLUDES = -DDATA_DIRECTORY='"${pkgdatadir}/"' \ @@ -29,4 +30,4 @@ crack_attack_DEPENDENCIES = $(GUI_LIBS) AM_LDFLAGS = ${all_libraries} -crack_attack_LDADD = ${X_PRE_LIBS} ${X_LIBS} ${X_EXTRA_LIBS} -lGL -lGLU -lglut -lXi -lX11 -lXmu $(GUI_LIBS) @PACKAGE_LIBS@ $(AUDIO_LIBS) +crack_attack_LDADD = ${X_PRE_LIBS} ${X_LIBS} ${X_EXTRA_LIBS} -lGL -lGLU -lglut -lXi -lX11 -lXmu $(GUI_LIBS) @PACKAGE_LIBS@ @AUDIO_LIBS@ Index: src/config.h.in =================================================================== RCS file: /cvsroot/crack-attack/crack-attack/src/config.h.in,v retrieving revision 1.4 diff -u -r1.4 config.h.in --- src/config.h.in 1 Apr 2005 21:04:56 -0000 1.4 +++ src/config.h.in 13 Apr 2005 02:04:09 -0000 @@ -1,5 +1,8 @@ /* src/config.h.in. Generated from configure.ac by autoheader. */ +/* Has audio support */ +#undef AUDIO_ENABLED + /* Include pthread support for binary relocation? */ #undef BR_PTHREAD --- src/Music.cxx 2005-04-12 22:00:01.604575296 -0400 +++ src/Music.cxx 2005-04-12 22:02:51.000000000 -0400 @@ -0,0 +1,165 @@ +/* + * Music.cxx + * Miguel Ángel Vilela García - 8/29/03 + * + * Copyright (C) 2003 Miguel Ángel Vilela García + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Miguel Ángel Vilela García - www.miguev.net + */ + +#include "Random.h" +#include "Sound.h" +#include "Music.h" + +Mix_Music *music = NULL; +int music_available = 0; +int keep_playing = 0; +int current_track = 0; + +vector music_filelist; +char *music_filename; +string music_dirname; +dirent *music_dirent; +DIR *music_dir; + +void Music::initialize ( ) +{ + if (!Sound::audio_available()) return; + music_dirname = string( getenv( "HOME") ); + music_dirname.append( "/.crack-attack/music/" ); + if ( (music_dir = opendir( music_dirname.c_str() ) ) == NULL ) { + music_dirname = string( DATA_DIRECTORY ); + music_dirname.append( "/music/" ); + } + if ( (music_dir = opendir( music_dirname.c_str() ) ) == NULL ) { + cout << "WARNING *** Unable to open music directory!" << endl; + return; + } + #ifndef NDEBUG + cout << "Music dir: " << music_dirname.c_str() << endl; + #endif + while ( music_dirent = readdir ( music_dir ) ) { + music_filename = music_dirent->d_name; + if ( ( music_filename == string( GC_MUSIC_GAME_TRACK ) ) ) { + music_filelist.clear(); + music_filelist.push_back( music_dirname + string( music_filename ) ); + #ifndef NDEBUG + cout << "Added music file: " << music_filename << endl; + #endif + break; + } + if ( ( music_filename == string( "." ) ) + || ( music_filename == string( ".." ) ) + || ( music_filename == string( GC_MUSIC_PRELUDE_TRACK ) ) + || ( music_filename == string( GC_MUSIC_GAMEOVER_TRACK ) ) + || ( music_filename == string( GC_MUSIC_YOUWIN_TRACK ) ) ) + continue; + music_filelist.push_back( music_dirname + string( music_filename ) ); + #ifndef NDEBUG + cout << "Added music file: " << music_filename << endl; + #endif + } + closedir( music_dir ); + music_available = music_filelist.size(); +} + +void Music::play( ) +{ + if ( !music_available ) return; + current_track = Random::number( music_filelist.size() ); + #ifndef NDEBUG + cout << "Playing " << music_filelist[current_track].c_str() << endl; + #endif + music = Mix_LoadMUS( music_filelist[current_track].c_str() ); + Mix_VolumeMusic( MIX_MAX_VOLUME / 4 ); + Mix_PlayMusic( music , 0 ); + Mix_HookMusicFinished(Music::finished); + keep_playing = 1; +} + +void Music::play_prelude( ) +{ + Music::play_track( GC_MUSIC_PRELUDE_TRACK ); +} + +void Music::play_game( ) +{ + Music::play_track( GC_MUSIC_GAME_TRACK ); +} + +void Music::play_gameover( ) +{ + Music::play_track( GC_MUSIC_GAMEOVER_TRACK ); +} + +void Music::play_youwin( ) +{ + Music::play_track( GC_MUSIC_YOUWIN_TRACK ); +} + +void Music::play_track( char *track ) +{ + string Track = string( music_dirname.c_str() ); + Track.append( string( track ) ); + if ( !music_available ) return; + #ifndef NDEBUG + cout << "Playing " << Track.c_str() << endl; + #endif + music = Mix_LoadMUS( Track.c_str() ); + Mix_VolumeMusic( MIX_MAX_VOLUME / 4 ); + Mix_PlayMusic( music , 0 ); + keep_playing = 0; +} + + +void Music::finished( ) +{ + Mix_HaltMusic(); + if ( keep_playing ) Music::play(); +} + +void Music::pause( ) +{ + if ( !Mix_PlayingMusic() ) return; + Mix_PauseMusic(); +} + +void Music::resume( ) +{ + if ( !Mix_PlayingMusic() ) return; + Mix_ResumeMusic(); +} + +void Music::stop( ) +{ + if ( !Mix_PlayingMusic() ) return; + keep_playing = 0; + Mix_HaltMusic(); +} + +void Music::fadeout( int ms ) +{ + if ( !Mix_PlayingMusic() ) return; + keep_playing = 0; + Mix_FadeOutMusic(ms); +} + +void Music::cleanup ( ) +{ + Mix_FreeMusic( music ); + music = NULL; +} --- src/Music.h 2005-04-12 22:00:01.604575296 -0400 +++ src/Music.h 2005-04-12 22:03:30.000000000 -0400 @@ -0,0 +1,61 @@ +/* + * Music.h + * Miguel Ángel Vilela García - 8/29/03 + * + * Copyright (C) 2003 Miguel Ángel Vilela García + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Miguel Ángel Vilela García - www.miguev.net + */ + +#ifndef MUSIC_H +#define MUSIC_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#define GC_MUSIC_FILENAME_LENGTH 128 +#define GC_MUSIC_PRELUDE_TRACK "prelude.ogg" +#define GC_MUSIC_GAME_TRACK "game.ogg" +#define GC_MUSIC_GAMEOVER_TRACK "gameover.ogg" +#define GC_MUSIC_YOUWIN_TRACK "youwin.ogg" + +class Music { + public: + static void Music::initialize ( ); + static void Music::play(); + static void Music::play_prelude(); + static void Music::play_game(); + static void Music::play_gameover(); + static void Music::play_youwin(); + static void Music::pause(); + static void Music::resume(); + static void Music::stop(); + static void Music::fadeout( int ms ); + static void Music::cleanup ( ); + static void Music::load( ); + private: + static void Music::play_track( char *track ); + static void Music::finished(); +}; + +#endif /* MUSIC_H */ --- src/Sound.cxx 2005-04-12 22:00:01.604575296 -0400 +++ src/Sound.cxx 2005-04-12 22:02:59.000000000 -0400 @@ -0,0 +1,110 @@ +/* + * Sound.cxx + * Miguel Ángel Vilela García - 8/29/03 + * + * Copyright (C) 2003 Miguel Ángel Vilela García + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Miguel Ángel Vilela García - www.miguev.net + */ + +#include "Random.h" +#include "Sound.h" + +typedef map ChunkMap; +vector sounds; +string sound_dirname; +ChunkMap chunks; + +int audio_rate = 22050; +int audio_channels = 2; +int audio_buffers = 1024; /* small enough buffer to get synchronized sound */ +Uint16 audio_format = AUDIO_S16; /* 16-bit stereo */ +int has_audio_available = 0; + +void Sound::initialize( void ) +{ + SDL_Init( SDL_INIT_AUDIO ); + if (Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers)) { + cout << "WARNING *** Unable to open audio device!" << endl; + return; + } + Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels); + // Initialize some global variables + has_audio_available = 1; + // Load chunks filenames + sounds.push_back (GC_SOUND_COUNTDOWN); + sounds.push_back (GC_SOUND_BLOCK_FALLEN); + sounds.push_back (GC_SOUND_BLOCK_AWAKING); + sounds.push_back (GC_SOUND_BLOCK_DYING); + sounds.push_back (GC_SOUND_GARBAGE_FALLEN); + sounds.push_back (GC_SOUND_GARBAGE_SHATTERING); + // Load chunk files to ChunkMap + Mix_Chunk *chunk; + string File; + for (int i = 0; i < sounds.size(); i++) { + #ifndef NDEBUG + cout << "Loading " << sounds[i]; + #endif + // Try to load chunk in $HOME/.crack-attack/sounds/ + sound_dirname = string( getenv( "HOME") ); + sound_dirname.append( "/.crack-attack/sounds/" ); + File = sound_dirname + sounds[i]; + chunk = Mix_LoadWAV (File.c_str()); + if ( chunk == NULL ) { // Try to load chunk in DATA_DIRECTORY/sounds/ + sound_dirname = string (DATA_DIRECTORY); + sound_dirname.append( "/sounds/" ); + File = sound_dirname + sounds[i]; + chunk = Mix_LoadWAV (File.c_str()); + } + // If chunk is NULL there is no WAV available for this sound + if (!chunk) cout << "WARNING *** Unable to open " << sounds[i] << endl; + chunks[sounds[i]] = chunk; + #ifndef NDEBUG + cout << endl; + #endif + } +} + +void Sound::play( const char *file, int vol ) +{ + if (!has_audio_available || !chunks[file]) + return; + + int channel, i; + + if (vol > 10) vol = 10; + #ifndef NDEBUG + cout << "Playing sound: " << File.c_str() << endl; + #endif + // string File (file); + Mix_VolumeChunk( chunks[file], vol * MIX_MAX_VOLUME / 10 ); + channel = Mix_PlayChannel( -1, chunks[file], 0 ); +} + +int Sound::audio_available( ) +{ + return has_audio_available; +} + +void Sound::cleanup( ) +{ + if (!has_audio_available) + return; + + Mix_CloseAudio(); + SDL_Quit(); +} --- src/Sound.h 2005-04-12 22:00:01.604575296 -0400 +++ src/Sound.h 2005-04-12 22:03:56.000000000 -0400 @@ -0,0 +1,54 @@ +/* + * Sound.h + * Miguel Ángel Vilela García - 8/29/03 + * + * Copyright (C) 2003 Miguel Ángel Vilela García + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Miguel Ángel Vilela García - www.miguev.net + */ + +#ifndef SOUND_H +#define SOUND_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// const char GC_SOUND_FILENAME_LENGTH = 128; +const char GC_SOUND_COUNTDOWN[] = "countdown.wav"; +const char GC_SOUND_BLOCK_FALLEN[] = "block_fallen.wav"; +const char GC_SOUND_BLOCK_AWAKING[] = "block_awaking.wav"; +const char GC_SOUND_BLOCK_DYING[] = "block_dying.wav"; +const char GC_SOUND_GARBAGE_FALLEN[] = "garbage_fallen.wav"; +const char GC_SOUND_GARBAGE_SHATTERING[] = "garbage_shattering.wav"; + +class Sound { + public: + static void Sound::initialize ( void ); + static void Sound::play( const char *file, int vol ); + static void Sound::cleanup ( void ); + static int Sound::audio_available( void ); + private: +}; + +#endif /* SOUND_H */