1 // Copyright (C) 2006 Ulf Lorenz 2 // Copyright (C) 2006 Andrea Paternesi 3 // Copyright (C) 2007, 2009, 2014, 2015 Ben Asselstine 4 // 5 // This program is free software; you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation; either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Library General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with this program; if not, write to the Free Software 17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 // 02110-1301, USA. 19 20 #pragma once 21 #ifndef SND_H 22 #define SND_H 23 24 #include <map> 25 #include <vector> 26 #include <sigc++/trackable.h> 27 28 class XML_Helper; 29 namespace Gst{ 30 class Message; 31 } 32 33 //! A helper struct to represent a single item in the sound configuration file. 34 struct MusicItem 35 { 36 // The file where the sound piece can be loaded from 37 Glib::ustring file; 38 // Can it be played in the background? 39 bool background; 40 // If loading this file fails, we can define an alias to load instead. 41 Glib::ustring alias; 42 }; 43 44 45 //! This class manages sound within the game. 46 /** Snd class 47 * 48 * The purpose of putting the sound code into one class is (besides hiding the 49 * internals and supplying a friendly interface) to put all these ugly ifdefs 50 * in one place (sound can be disabled for fewer dependencies). 51 * 52 * @note: As this becomes too complicated, I throw away the caching stuff. 53 * 54 * Sound and music are treated a bit differently since the mixer calls are others. 55 * However, both are referenced by strings (I think in this case, id's aren't 56 * very readable). There are basically two types of music. Background music 57 * is enabled by enableBackground(). It will always play until disabled again 58 * by looking through the databse of available background music pieces. On top 59 * of that, it is possible to play other music pieces. In this case, the 60 * background music fades out (maybe), the other music fades or pops in 61 * and goes away again with the background music taking its place again 62 * afterwards. 63 */ 64 class Snd : public sigc::trackable 65 { 66 public: 67 // Get Methods 68 69 //! Returns whether music is enabled 70 bool isMusicEnabled(); 71 72 //! Returns the music volume in the range 0..128 73 int getMusicVolume(); 74 75 //! Get the filename for the given piece. 76 Glib::ustring getFile(Glib::ustring piece); 77 78 // Set Methods 79 80 /** Enables/disables music and sets volume. If the sound is disabled, 81 * subsequent calls to play sounds will be silently ignored. 82 * 83 * @param enable enable/disable sound 84 * @param volume set the sound volume in the range from 0 to 128 85 * 86 * @return false for wrong volume data, otherwise true 87 */ 88 bool setMusic(bool enable, int volume); 89 90 91 // Methods that operate on class data and modify the class. 92 93 /** Plays a given music piece. 94 * 95 * The current (background) track will be stopped (faded out) if 96 * neccessary and the new piece will be faded in. Each call to 97 * play should be accompanied by a call to halt(), otherwise the 98 * background music wil not continue. 99 * 100 * @param piece the identifier(name) of the music track to play. 101 * @param nloops the amount of time the piece should be played 102 * (-1: infinitely often) 103 * @param fade if set to true, fade out a playing music piece 104 * @return false if any error occurred. 105 */ 106 bool play(Glib::ustring piece, int nloops = -1, bool fade = true); 107 108 void updateVolume(); 109 110 /** Stops the current (event) music. Note that the background music might 111 * continue with playing. 112 * 113 * @param fade if set to true, fade out a playing piece. 114 * 115 * @return false on error. 116 */ 117 bool halt(bool fade = true); 118 119 /** Enables background music. 120 * 121 * Starts playing background music. Picks a random piece that has 122 * the background tag enabled and starts playing it, then picks the 123 * next etc. 124 */ 125 void enableBackground(); 126 127 /** Stops playing of background music 128 * 129 */ 130 void disableBackground(); 131 132 //! Activates the next background piece 133 void nextPiece(); 134 135 136 // Static Methods 137 138 //! Singleton getter 139 static Snd* getInstance(); 140 141 //! Explicitly delete the singleton 142 static void deleteInstance(); 143 144 private: 145 //! Constructor. Initializes the sound and loads the music data 146 Snd(); 147 148 //! Destructor. Deinitializes sound 149 ~Snd(); 150 151 //! Callback for the music data, see XML_Helper 152 bool loadMusic(Glib::ustring tag, XML_Helper* helper); 153 154 // DATA 155 156 // music is stored here, access by d_musicMap[name] 157 std::map<Glib::ustring, MusicItem*> d_musicMap; 158 std::vector<Glib::ustring> d_bgMap; // shallow copy of background pieces 159 160 161 // how many more times we have to loop an effect. 162 gint32 d_nloops; 163 164 // if initialization failed, set this to true => no music/sound played 165 bool d_broken; 166 167 // if set to true, play background music 168 bool d_background; 169 170 struct Impl; 171 Impl *impl; 172 // callbacks 173 174 bool on_bus_message(const Glib::RefPtr<Gst::Message> & msg, guint32 source); 175 bool on_effect_fade (double step); 176 177 // static instanton pointer 178 static Snd* s_instance; 179 }; 180 181 #endif //SND_H 182