From aea1b715f22599f5e202693cb93a0852704d6422 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Mon, 31 May 2004 22:13:15 +0000 Subject: [PATCH] introduce a new SoundManager class and merged MusicManager with it. Using this class we can create real stereo effects based on player position, without adding strange hacks to badguy.cpp SVN-Revision: 1376 --- src/Makefile.am | 4 +- src/badguy.cpp | 36 ++++--------- src/gameloop.cpp | 7 ++- src/level.cpp | 1 - src/leveleditor.cpp | 1 - src/moving_object.h | 3 ++ src/musicref.cpp | 4 +- src/musicref.h | 8 +-- src/physic.cpp | 17 ++++-- src/physic.h | 3 ++ src/player.cpp | 11 ++-- src/resources.cpp | 15 +++--- src/resources.h | 4 +- src/sector.cpp | 30 +++++------ src/setup.cpp | 4 +- src/sound.cpp | 35 ------------- src/sound.h | 9 ---- src/{music_manager.cpp => sound_manager.cpp} | 78 ++++++++++++++++++++++------ src/{music_manager.h => sound_manager.h} | 27 ++++++---- src/special.cpp | 14 ++--- src/worldmap.cpp | 11 ++-- 21 files changed, 164 insertions(+), 158 deletions(-) rename src/{music_manager.cpp => sound_manager.cpp} (62%) rename src/{music_manager.h => sound_manager.h} (74%) diff --git a/src/Makefile.am b/src/Makefile.am index fb4eb3a24..0f8302b0c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,8 +46,6 @@ menu.cpp \ menu.h \ mousecursor.cpp \ mousecursor.h \ -music_manager.cpp \ -music_manager.h \ musicref.cpp \ musicref.h \ particlesystem.cpp \ @@ -62,6 +60,8 @@ setup.cpp \ setup.h \ sound.cpp \ sound.h \ +sound_manager.h \ +sound_manager.cpp \ special.cpp \ special.h \ sprite.h \ diff --git a/src/badguy.cpp b/src/badguy.cpp index cfdc7ac43..6b61c573c 100644 --- a/src/badguy.cpp +++ b/src/badguy.cpp @@ -356,7 +356,7 @@ BadGuy::action_mriceblock(double elapsed_time) tux.kick_timer.start(KICKING_TIME); set_sprite(img_mriceblock_flat_left, img_mriceblock_flat_right); physic.set_velocity_x((dir == LEFT) ? -3.5 : 3.5); - play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_KICK], this); } } @@ -366,15 +366,7 @@ BadGuy::action_mriceblock(double elapsed_time) check_horizontal_bump(); if(mode == KICK && changed != dir) { - float scroll_x = Sector::current()->camera->get_translation().x; - - /* handle stereo sound (number 10 should be tweaked...)*/ - if (base.x < scroll_x + screen->w/2 - 10) - play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER); - else if (base.x > scroll_x + screen->w/2 + 10) - play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER); - else - play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_RICOCHET], get_pos()); } } @@ -568,16 +560,7 @@ BadGuy::action_bomb(double elapsed_time) dying = DYING_NOT; // now the bomb hurts timer.start(EXPLODETIME); - float scroll_x = Sector::current()->camera->get_translation().x; - - /* play explosion sound */ // FIXME: is the stereo all right? maybe we should use player cordinates... - if (base.x < scroll_x + screen->w/2 - 10) - play_sound(sounds[SND_EXPLODE], SOUND_LEFT_SPEAKER); - else if (base.x > scroll_x + screen->w/2 + 10) - play_sound(sounds[SND_EXPLODE], SOUND_RIGHT_SPEAKER); - else - play_sound(sounds[SND_EXPLODE], SOUND_CENTER_SPEAKER); - + sound_manager->play_sound(sounds[SND_EXPLODE], this); } else if(mode == BOMB_EXPLODE) { remove_me(); return; @@ -1054,7 +1037,8 @@ BadGuy::squish_me(Player* player) Sector::current()->add_score(Vector(base.x, base.y), 50 * player_status.score_multiplier); - play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER); + + sound_manager->play_sound(sounds[SND_SQUISH], get_pos()); player_status.score_multiplier++; dying = DYING_SQUISHED; @@ -1074,7 +1058,7 @@ BadGuy::squish(Player* player) make_player_jump(player); Sector::current()->add_score(Vector(base.x, base.y), 50 * player_status.score_multiplier); - play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_SQUISH], get_pos()); player_status.score_multiplier++; return; @@ -1082,7 +1066,7 @@ BadGuy::squish(Player* player) if (mode == NORMAL || mode == KICK) { /* Flatten! */ - play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_STOMP], get_pos()); mode = FLAT; set_sprite(img_mriceblock_flat_left, img_mriceblock_flat_right); physic.set_velocity_x(0); @@ -1090,7 +1074,7 @@ BadGuy::squish(Player* player) timer.start(4000); } else if (mode == FLAT) { /* Kick! */ - play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_KICK], this); if (player->base.x < base.x + (base.width/2)) { physic.set_velocity_x(5); @@ -1191,7 +1175,7 @@ BadGuy::kill_me(int score) score * player_status.score_multiplier); /* Play death sound: */ - play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_FALL], this); } void @@ -1354,7 +1338,7 @@ BadGuy::collision(void *p_c_object, int c_object, CollisionType type) /* Get kicked if were flat */ if (mode == FLAT && !dying) { - play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_KICK], this); // Hit from left side if (player->base.x < base.x) { diff --git a/src/gameloop.cpp b/src/gameloop.cpp index 08df4819a..613d92764 100644 --- a/src/gameloop.cpp +++ b/src/gameloop.cpp @@ -55,7 +55,6 @@ #include "resources.h" #include "background.h" #include "tilemap.h" -#include "music_manager.h" GameSession* GameSession::current_ = 0; @@ -145,7 +144,7 @@ GameSession::~GameSession() void GameSession::levelintro(void) { - music_manager->halt_music(); + sound_manager->halt_music(); char str[60]; @@ -459,7 +458,7 @@ GameSession::check_end_conditions() { end_sequence = ENDSEQUENCE_RUNNING; last_x_pos = -1; - music_manager->play_music(level_end_song, 0); + sound_manager->play_music(level_end_song, 0); endsequence_timer.start(7000); // 5 seconds until we finish the map tux->invincible_timer.start(7000); //FIXME: Implement a winning timer for the end sequence (with special winning animation etc.) } @@ -689,7 +688,7 @@ void bumpbrick(float x, float y) Sector::current()->add_bouncy_brick(Vector(((int)(x + 1) / 32) * 32, (int)(y / 32) * 32)); - play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_BRICK], Vector(x, y)); } /* (Status): */ diff --git a/src/level.cpp b/src/level.cpp index cc30db43f..bc6a69af4 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -36,7 +36,6 @@ #include "tile.h" #include "lispreader.h" #include "resources.h" -#include "music_manager.h" #include "gameobjs.h" #include "lispwriter.h" diff --git a/src/leveleditor.cpp b/src/leveleditor.cpp index bb163d8c0..cb8f714cd 100644 --- a/src/leveleditor.cpp +++ b/src/leveleditor.cpp @@ -43,7 +43,6 @@ #include "button.h" #include "tile.h" #include "resources.h" -#include "music_manager.h" #include "background.h" // TODO diff --git a/src/moving_object.h b/src/moving_object.h index f4c93b6d6..988c75238 100644 --- a/src/moving_object.h +++ b/src/moving_object.h @@ -39,6 +39,9 @@ public: virtual void collision(const MovingObject& other_object, int collision_type) = 0; + Vector get_pos() const + { return Vector(base.x, base.y); } + base_type base; base_type old_base; diff --git a/src/musicref.cpp b/src/musicref.cpp index 3ba754bcc..55d0e6781 100644 --- a/src/musicref.cpp +++ b/src/musicref.cpp @@ -24,7 +24,7 @@ MusicRef::MusicRef() { } -MusicRef::MusicRef(MusicManager::MusicResource* newmusic) +MusicRef::MusicRef(SoundManager::MusicResource* newmusic) : music(newmusic) { if(music) @@ -50,7 +50,7 @@ MusicRef::MusicRef(const MusicRef& other) MusicRef& MusicRef::operator =(const MusicRef& other) { - MusicManager::MusicResource* oldres = music; + SoundManager::MusicResource* oldres = music; music = other.music; if(music) music->refcount++; diff --git a/src/musicref.h b/src/musicref.h index baa0cd583..330601ba6 100644 --- a/src/musicref.h +++ b/src/musicref.h @@ -19,7 +19,7 @@ #ifndef HEADER_MUSIC_RESOURCE_H #define HEADER_MUSIC_RESOURCE_H -#include "music_manager.h" +#include "sound_manager.h" /** This class holds a reference to a music file and maintains a correct * refcount for that file. @@ -34,10 +34,10 @@ public: MusicRef& operator= (const MusicRef& other); private: - friend class MusicManager; - MusicRef(MusicManager::MusicResource* music); + friend class SoundManager; + MusicRef(SoundManager::MusicResource* music); - MusicManager::MusicResource* music; + SoundManager::MusicResource* music; }; #endif diff --git a/src/physic.cpp b/src/physic.cpp index ef6d94c24..7300b9e3c 100644 --- a/src/physic.cpp +++ b/src/physic.cpp @@ -122,7 +122,7 @@ Physic::enable_gravity(bool enable_gravity) } void -Physic::apply(float frame_ratio, float &x, float &y) +Physic::apply(float elapsed_time, float &x, float &y) { float gravity = Sector::current()->gravity; float grav; @@ -131,8 +131,15 @@ Physic::apply(float frame_ratio, float &x, float &y) else grav = 0; - x += vx * frame_ratio + ax * frame_ratio * frame_ratio; - y += vy * frame_ratio + (ay + grav) * frame_ratio * frame_ratio; - vx += ax * frame_ratio; - vy += (ay + grav) * frame_ratio; + x += vx * elapsed_time + ax * elapsed_time * elapsed_time; + y += vy * elapsed_time + (ay + grav) * elapsed_time * elapsed_time; + vx += ax * elapsed_time; + vy += (ay + grav) * elapsed_time; } + +void +Physic::apply(Vector& vector, float elapsed_time) +{ + apply(elapsed_time, vector.x, vector.y); +} + diff --git a/src/physic.h b/src/physic.h index 558cebd4c..002b42f80 100644 --- a/src/physic.h +++ b/src/physic.h @@ -63,6 +63,9 @@ public: /** applies the physical simulation to given x and y coordinates */ void apply(float frame_ratio, float &x, float &y); + /** applies the physical simulation to given x and y coordinates */ + void apply(Vector& vector, float frame_ratio); + private: /// horizontal and vertical acceleration float ax, ay; diff --git a/src/player.cpp b/src/player.cpp index f9a6032fd..655911dd3 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -31,6 +31,7 @@ #include "tilemap.h" #include "camera.h" #include "gameobjs.h" +#include "resources.h" #include "interactive_object.h" #include "screen/screen.h" @@ -413,7 +414,7 @@ Player::handle_horizontal_input() if(on_ground() && ((vx < 0 && dirsign >0) || (vx>0 && dirsign<0))) { if(fabs(vx)>SKID_XM && !skidding_timer.check()) { skidding_timer.start(SKID_TIME); - play_sound(sounds[SND_SKID], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_SKID]); ax *= 2.5; } else { ax *= 2; @@ -480,9 +481,9 @@ Player::handle_vertical_input() jumping = true; can_jump = false; if (size == SMALL) - play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_JUMP]); else - play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_BIGJUMP]); } // Let go of jump key else if(input.up == UP && jumping && physic.get_velocity_y() > 0) @@ -668,7 +669,7 @@ Player::grabdistros() if(player_status.lives < MAX_LIVES) ++player_status.lives; /*We want to hear the sound even, if MAX_LIVES is reached*/ - play_sound(sounds[SND_LIFEUP], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_LIFEUP]); } } @@ -906,7 +907,7 @@ Player::kill(HurtMode mode) if(dying) return; - play_sound(sounds[SND_HURT], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_HURT]); physic.set_velocity_x(0); diff --git a/src/resources.cpp b/src/resources.cpp index 62928e497..921e4d50a 100644 --- a/src/resources.cpp +++ b/src/resources.cpp @@ -25,6 +25,7 @@ #include "special.h" #include "resources.h" #include "sprite_manager.h" +#include "sound_manager.h" #include "setup.h" Surface* img_waves[3]; @@ -39,7 +40,7 @@ MusicRef herring_song; MusicRef level_end_song; SpriteManager* sprite_manager = 0; -MusicManager* music_manager = 0; +SoundManager* sound_manager = 0; /* Load graphics/sounds shared between all levels: */ void loadshared() @@ -47,8 +48,8 @@ void loadshared() int i; sprite_manager = new SpriteManager(datadir + "/supertux.strf"); - music_manager = new MusicManager(); - music_manager->enable_music(use_music); + sound_manager = new SoundManager(); + sound_manager->enable_music(use_music); /* Tuxes: */ smalltux_star = sprite_manager->load("smalltux-star"); @@ -214,8 +215,8 @@ void loadshared() sounds[i] = load_sound(datadir + soundfilenames[i]); /* Herring song */ - herring_song = music_manager->load_music(datadir + "/music/SALCON.MOD"); - level_end_song = music_manager->load_music(datadir + "/music/tux-leveldone.mod"); + herring_song = sound_manager->load_music(datadir + "/music/SALCON.MOD"); + level_end_song = sound_manager->load_music(datadir + "/music/tux-leveldone.mod"); } @@ -251,8 +252,8 @@ void unloadshared(void) delete sprite_manager; sprite_manager = 0; - delete music_manager; - music_manager = 0; + delete sound_manager; + sound_manager = 0; } /* EOF */ diff --git a/src/resources.h b/src/resources.h index 18c3fb5d9..edff837ee 100644 --- a/src/resources.h +++ b/src/resources.h @@ -23,7 +23,7 @@ #include "musicref.h" class SpriteManager; -class MusicManager; +class SoundManager; extern Surface* img_waves[3]; extern Surface* img_water; @@ -38,7 +38,7 @@ extern MusicRef herring_song; extern MusicRef level_end_song; extern SpriteManager* sprite_manager; -extern MusicManager* music_manager; +extern SoundManager* sound_manager; void loadshared(); void unloadshared(); diff --git a/src/sector.cpp b/src/sector.cpp index 0976bb806..434582b0c 100644 --- a/src/sector.cpp +++ b/src/sector.cpp @@ -33,7 +33,7 @@ #include "particlesystem.h" #include "tile.h" #include "tilemap.h" -#include "music_manager.h" +#include "sound_manager.h" #include "gameloop.h" #include "resources.h" #include "interactive_object.h" @@ -608,7 +608,7 @@ Sector::add_bullet(const Vector& pos, float xm, Direction dir) throw std::runtime_error("wrong bullet type."); add_object(new_bullet); - play_sound(sounds[SND_SHOOT], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_SHOOT]); return true; } @@ -643,7 +643,7 @@ Sector::trybreakbrick(const Vector& pos, bool small) solids->change_at(pos, tile->next_tile); } - play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_DISTRO]); player_status.score = player_status.score + SCORE_DISTRO; player_status.distros++; return true; @@ -659,7 +659,7 @@ Sector::trybreakbrick(const Vector& pos, bool small) (int)(pos.y / 32) * 32), tile); /* Get some score: */ - play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_BRICK]); player_status.score = player_status.score + SCORE_BRICK; return true; @@ -689,7 +689,7 @@ Sector::tryemptybox(const Vector& pos, Direction col_side) { case 1: // Box with a distro! add_bouncy_distro(Vector(posx, posy)); - play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_DISTRO]); player_status.score = player_status.score + SCORE_DISTRO; player_status.distros++; break; @@ -699,7 +699,7 @@ Sector::tryemptybox(const Vector& pos, Direction col_side) add_upgrade(Vector(posx, posy), col_side, UPGRADE_GROWUP); else /* Tux is big, add a fireflower: */ add_upgrade(Vector(posx, posy), col_side, UPGRADE_FIREFLOWER); - play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_UPGRADE]); break; case 5: // Add an ice flower upgrade! @@ -707,7 +707,7 @@ Sector::tryemptybox(const Vector& pos, Direction col_side) add_upgrade(Vector(posx, posy), col_side, UPGRADE_GROWUP); else /* Tux is big, add an iceflower: */ add_upgrade(Vector(posx, posy), col_side, UPGRADE_ICEFLOWER); - play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_UPGRADE]); break; case 3: // Add a golden herring @@ -734,7 +734,7 @@ Sector::trygrabdistro(const Vector& pos, int bounciness) return; solids->change_at(pos, tile->next_tile); - play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_DISTRO]); if (bounciness == BOUNCE) { @@ -778,7 +778,7 @@ Sector::load_music() char* song_path; char* song_subtitle; - level_song = music_manager->load_music(datadir + "/music/" + song_title); + level_song = sound_manager->load_music(datadir + "/music/" + song_title); song_path = (char *) malloc(sizeof(char) * datadir.length() + strlen(song_title.c_str()) + 8 + 5); @@ -786,10 +786,10 @@ Sector::load_music() strcpy(strstr(song_subtitle, "."), "\0"); sprintf(song_path, "%s/music/%s-fast%s", datadir.c_str(), song_subtitle, strstr(song_title.c_str(), ".")); - if(!music_manager->exists_music(song_path)) { + if(!sound_manager->exists_music(song_path)) { level_song_fast = level_song; } else { - level_song_fast = music_manager->load_music(song_path); + level_song_fast = sound_manager->load_music(song_path); } free(song_subtitle); free(song_path); @@ -801,16 +801,16 @@ Sector::play_music(int type) currentmusic = type; switch(currentmusic) { case HURRYUP_MUSIC: - music_manager->play_music(level_song_fast); + sound_manager->play_music(level_song_fast); break; case LEVEL_MUSIC: - music_manager->play_music(level_song); + sound_manager->play_music(level_song); break; case HERRING_MUSIC: - music_manager->play_music(herring_song); + sound_manager->play_music(herring_song); break; default: - music_manager->halt_music(); + sound_manager->halt_music(); break; } } diff --git a/src/setup.cpp b/src/setup.cpp index 34891f281..055356bb3 100644 --- a/src/setup.cpp +++ b/src/setup.cpp @@ -51,7 +51,7 @@ #include "worldmap.h" #include "resources.h" #include "intro.h" -#include "music_manager.h" +#include "sound_manager.h" #include "player.h" @@ -558,7 +558,7 @@ void process_options_menu(void) if(use_music != options_menu->isToggled(MNID_MUSIC)) { use_music = !use_music; - music_manager->enable_music(use_music); + sound_manager->enable_music(use_music); } break; case MNID_SHOWFPS: diff --git a/src/sound.cpp b/src/sound.cpp index 6f4d82f48..83c8bbb42 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -17,7 +17,6 @@ // 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. - #include "defines.h" #include "globals.h" #include "sound.h" @@ -66,13 +65,6 @@ int open_audio (int frequency, Uint16 format, int channels, int chunksize) if (Mix_AllocateChannels(8) != 8) return -2; - /* reserve some channels and register panning effects */ - if (Mix_ReserveChannels(SOUND_RESERVED_CHANNELS) != SOUND_RESERVED_CHANNELS) - return -3; - - /* prepare the spanning effects */ - Mix_SetPanning( SOUND_LEFT_SPEAKER, 230, 24 ); - Mix_SetPanning( SOUND_RIGHT_SPEAKER, 24, 230 ); return 0; } @@ -82,8 +74,6 @@ int open_audio (int frequency, Uint16 format, int channels, int chunksize) void close_audio( void ) { if (audio_device) { - Mix_UnregisterAllEffects( SOUND_LEFT_SPEAKER ); - Mix_UnregisterAllEffects( SOUND_RIGHT_SPEAKER ); Mix_CloseAudio(); } } @@ -104,31 +94,6 @@ Mix_Chunk* load_sound(const std::string& file) return(snd); } -/* --- PLAY A SOUND ON LEFT OR RIGHT OR CENTER SPEAKER --- */ - -void play_sound(Mix_Chunk * snd, enum Sound_Speaker whichSpeaker) -{ - /* this won't call the function if the user has disabled sound - * either via menu or via command-line option - */ - if(!audio_device || !use_sound) - return; - - Mix_PlayChannel( whichSpeaker, snd, 0); - - /* prepare for panning effects for next call */ - switch (whichSpeaker) { - case SOUND_LEFT_SPEAKER: - Mix_SetPanning( SOUND_LEFT_SPEAKER, 230, 24 ); - break; - case SOUND_RIGHT_SPEAKER: - Mix_SetPanning( SOUND_RIGHT_SPEAKER, 24, 230 ); - break; - default: // keep the compiler happy - break; - } -} - void free_chunk(Mix_Chunk *chunk) { Mix_FreeChunk( chunk ); diff --git a/src/sound.h b/src/sound.h index d38b1ff5a..c2545a235 100644 --- a/src/sound.h +++ b/src/sound.h @@ -36,14 +36,6 @@ enum Music_Type { HERRING_MUSIC }; -/* panning effects: terrible :-) ! */ -enum Sound_Speaker { - SOUND_LEFT_SPEAKER = 0, - SOUND_RIGHT_SPEAKER = 1, - SOUND_RESERVED_CHANNELS = 2, // 2 channels reserved for left/right speaker - SOUND_CENTER_SPEAKER = -1 -}; - /* Sound files: */ enum { SND_JUMP, @@ -82,6 +74,5 @@ void close_audio( void ); Mix_Chunk * load_sound(const std::string& file); void free_chunk(Mix_Chunk*chunk); -void play_sound(Mix_Chunk * snd, enum Sound_Speaker whichSpeaker); #endif /*SUPERTUX_SOUND_H*/ diff --git a/src/music_manager.cpp b/src/sound_manager.cpp similarity index 62% rename from src/music_manager.cpp rename to src/sound_manager.cpp index 7cf9e9c79..c95902e17 100644 --- a/src/music_manager.cpp +++ b/src/sound_manager.cpp @@ -1,7 +1,7 @@ // $Id$ // -// SuperTux -// Copyright (C) 2004 Ingo Ruhnke +// SuperTux - A Jump'n Run +// Copyright (C) 2004 Matthias Braun #include -#include "music_manager.h" #include "musicref.h" -#include "sound.h" #include "setup.h" +#include "sector.h" +#include "camera.h" +#include "sound.h" +#include "globals.h" +#include "moving_object.h" -MusicManager::MusicManager() +SoundManager::SoundManager() : current_music(0), music_enabled(true) -{ } +{ +} -MusicManager::~MusicManager() +SoundManager::~SoundManager() { if(audio_device) Mix_HaltMusic(); } +void +SoundManager::play_sound(Mix_Chunk* sound) +{ + if(!audio_device || !use_sound) + return; + + Mix_PlayChannel(-1, sound, 0); +} + +void +SoundManager::play_sound(Mix_Chunk* sound, const MovingObject* object) +{ + // TODO keep track of the object later and move the sound along with the + // object. + play_sound(sound, object->get_pos()); +} + +void +SoundManager::play_sound(Mix_Chunk* sound, const Vector& pos) +{ + if(!audio_device || !use_sound) + return; + + // TODO make sure this formula is good + float distance + = Sector::current()->player->get_pos().x - pos.x; + int loud = int(255.0/float(screen->w*2) * fabsf(distance)); + if(loud > 255) + return; + + int chan = Mix_PlayChannel(-1, sound, 0); + if(chan < 0) + return; + Mix_SetDistance(chan, loud); + + // very bad way to do this... + if(distance > 100) + Mix_SetPanning(chan, 230, 24); + else if(distance < -100) + Mix_SetPanning(chan, 24, 230); +} + MusicRef -MusicManager::load_music(const std::string& file) +SoundManager::load_music(const std::string& file) { if(!audio_device) return MusicRef(0); @@ -48,7 +96,7 @@ MusicManager::load_music(const std::string& file) } bool -MusicManager::exists_music(const std::string& file) +SoundManager::exists_music(const std::string& file) { if(!audio_device) return true; @@ -75,14 +123,14 @@ MusicManager::exists_music(const std::string& file) } void -MusicManager::free_music(MusicResource* ) +SoundManager::free_music(MusicResource* ) { // TODO free music, currently we can't do this since SDL_mixer seems to have // some bugs if you load/free alot of mod files. } void -MusicManager::play_music(const MusicRef& musicref, int loops) +SoundManager::play_music(const MusicRef& musicref, int loops) { if(!audio_device) return; @@ -101,7 +149,7 @@ MusicManager::play_music(const MusicRef& musicref, int loops) } void -MusicManager::halt_music() +SoundManager::halt_music() { if(!audio_device) return; @@ -117,7 +165,7 @@ MusicManager::halt_music() } void -MusicManager::enable_music(bool enable) +SoundManager::enable_music(bool enable) { if(!audio_device) return; @@ -133,9 +181,9 @@ MusicManager::enable_music(bool enable) } } -MusicManager::MusicResource::~MusicResource() +SoundManager::MusicResource::~MusicResource() { - // buggy SDL_mixer :-/ + // don't free music buggy SDL_Mixer crashs for some mod files // Mix_FreeMusic(music); } diff --git a/src/music_manager.h b/src/sound_manager.h similarity index 74% rename from src/music_manager.h rename to src/sound_manager.h index 80706fd05..d34082a73 100644 --- a/src/music_manager.h +++ b/src/sound_manager.h @@ -1,8 +1,7 @@ // $Id$ // // SuperTux - A Jump'n Run -// Copyright (C) 2000 Bill Kendrick -// Copyright (C) 2004 Duong-Khang NGUYEN +// Copyright (C) 2004 Matthias Braun #include #include class MusicRef; +class MovingObject; -/** This class manages a list of music resources and is responsible for playing - * the music. +/** This class handles all sounds that are played */ -class MusicManager +class SoundManager { public: - MusicManager(); - ~MusicManager(); - + SoundManager(); + ~SoundManager(); + + void play_sound(Mix_Chunk* sound); + void play_sound(Mix_Chunk* sound, const Vector& pos); + void play_sound(Mix_Chunk* sound, const MovingObject* object); + MusicRef load_music(const std::string& file); bool exists_music(const std::string& filename); @@ -44,13 +48,14 @@ public: void enable_music(bool enable); private: + // music part friend class MusicRef; class MusicResource { public: ~MusicResource(); - MusicManager* manager; + SoundManager* manager; Mix_Music* music; int refcount; }; diff --git a/src/special.cpp b/src/special.cpp index 0c8828846..1ff38f040 100644 --- a/src/special.cpp +++ b/src/special.cpp @@ -265,7 +265,7 @@ Upgrade::bump(Player* player) if(kind != UPGRADE_GROWUP) return; - play_sound(sounds[SND_BUMP_UPGRADE], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_BUMP_UPGRADE], Vector(base.x, base.y)); // determine new direction if (player->base.x + player->base.width/2 > base.x + base.width/2) @@ -308,30 +308,30 @@ Upgrade::collision(void* p_c_object, int c_object, CollisionType type) if (kind == UPGRADE_GROWUP) { - play_sound(sounds[SND_EXCELLENT], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_EXCELLENT]); pplayer->grow(true); } else if (kind == UPGRADE_FIREFLOWER) { - play_sound(sounds[SND_COFFEE], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_COFFEE]); pplayer->grow(true); pplayer->got_power = pplayer->FIRE_POWER; } else if (kind == UPGRADE_ICEFLOWER) { - play_sound(sounds[SND_COFFEE], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_COFFEE]); pplayer->grow(true); pplayer->got_power = pplayer->ICE_POWER; } else if (kind == UPGRADE_FIREFLOWER) { - play_sound(sounds[SND_COFFEE], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_COFFEE]); pplayer->grow(true); pplayer->got_power = pplayer->FIRE_POWER; } else if (kind == UPGRADE_HERRING) { - play_sound(sounds[SND_HERRING], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_HERRING]); pplayer->invincible_timer.start(TUX_INVINCIBLE_TIME); Sector::current()->play_music(HERRING_MUSIC); } @@ -339,7 +339,7 @@ Upgrade::collision(void* p_c_object, int c_object, CollisionType type) { if(player_status.lives < MAX_LIVES) { player_status.lives++; - play_sound(sounds[SND_LIFEUP], SOUND_CENTER_SPEAKER); + sound_manager->play_sound(sounds[SND_LIFEUP]); } } diff --git a/src/worldmap.cpp b/src/worldmap.cpp index 3f529e01c..5a523572f 100644 --- a/src/worldmap.cpp +++ b/src/worldmap.cpp @@ -31,6 +31,7 @@ #include "setup.h" #include "sector.h" #include "worldmap.h" +#include "sound_manager.h" #include "resources.h" namespace WorldMapNS { @@ -690,8 +691,8 @@ WorldMap::update(float delta) if (!level->extro_filename.empty()) { MusicRef theme = - music_manager->load_music(datadir + "/music/theme.mod"); - music_manager->play_music(theme); + sound_manager->load_music(datadir + "/music/theme.mod"); + sound_manager->play_music(theme); // Display final credits and go back to the main menu display_text_file(level->extro_filename, "/images/background/extro.jpg", SCROLL_SPEED_MESSAGE); @@ -745,7 +746,7 @@ WorldMap::update(float delta) break; } - music_manager->play_music(song); + sound_manager->play_music(song); Menu::set_current(0); if (!savegame_file.empty()) savegame(savegame_file); @@ -901,8 +902,8 @@ WorldMap::display() quit = false; - song = music_manager->load_music(datadir + "/music/" + music); - music_manager->play_music(song); + song = sound_manager->load_music(datadir + "/music/" + music); + sound_manager->play_music(song); unsigned int last_update_time; unsigned int update_time; -- 2.11.0