initial commit, lordsawar source, slightly modified
[lordsawar] / src / sound.h
1 // Copyright (C) 2006 Ulf Lorenz
2 // Copyright (C) 2006 Andrea Paternesi
3 // Copyright (C) 2007, 2009 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 #ifndef SOUND_H
21 #define SOUND_H
22
23 #include "xmlhelper.h"
24
25 #include <string>
26 #include <map>
27 #include <vector>
28 #include <sigc++/trackable.h>
29 #ifdef FL_SOUND
30 #include <SDL_mixer.h>
31 #endif
32
33 /** Sound class
34   * 
35   * The purpose of putting the sound code into one class is (besides hiding the
36   * internals and supplying a friendly interface) to put all these ugly ifdefs
37   * in one place (sound can be disabled for fewer dependencies).
38   *
39   * @note: As this becomes too complicated, I throw away the caching stuff.
40   *
41   * Sound and music are treated a bit differently since the mixer calls are others.
42   * However, both are referenced by strings (I think in this case, id's aren't
43   * very readable). There are basically two types of music. Background music
44   * is enabled by enableBackground(). It will always play until disabled again
45   * by looking through the databse of available background music pieces. On top
46   * of that, it is possible to play other music pieces. In this case, the
47   * background music fades out (maybe), the other music fades or pops in
48   * and goes away again with the backgroun dmusic taking its place again
49   * afterwards.
50   */
51
52 struct MusicItem
53 {
54     // The file where the sound piece can be loaded from
55     std::string file;
56     // Can it be played in the background?
57     bool background;
58     // If loading this file fails, we can define an alias to load instead.
59     std::string alias;
60 };
61
62
63 //! This class manages sound within the game.
64 class Sound : 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
76         // Set Methods
77
78         /** Enables/disables music and sets volume. If the sound is disabled,
79           * subsequent calls to play sounds will be silently ignored.
80           *
81           * @param enable       enable/disable sound
82           * @param volume       set the sound volume in the range from 0 to 128
83           *
84           * @return false for wrong volume data, otherwise true
85           */
86         bool setMusic(bool enable, int volume);
87
88
89         // Methods that operate on class data and modify the class.
90
91         /** Plays a given music piece.
92           *
93           * The current (background) track will be stopped (faded out) if
94           * neccessary and the new piece will be faded in. Each call to
95           * playMusic should be accompanied by a call to haltMusic(), otherwise the
96           * background music wil not continue.
97           * 
98           * @param piece        the identifier(name) of the music track to play.
99           * @param nloops       the amount of time the piece should be played
100           *                     (-1: infinitely often)
101           * @param fade         if set to true, fade out a playing music piece 
102           * @return false if any error occurred.
103           */
104         bool playMusic(std::string piece, int nloops = -1, bool fade = true);
105         
106         /** Stops the current (event) music. Note that the background music might
107           * continue with playing.
108           *
109           * @param fade         if set to true, fade out a playing piece.
110           *
111           * @return false on error.
112           */
113         bool haltMusic(bool fade = true);
114
115         /** Enables background music.
116           * 
117           * Starts playing background music. Picks a random piece that has
118           * the background tag enabled and starts playing it, then picks the
119           * next etc.
120           */
121         void enableBackground();
122
123         /** Stops playing of background music
124           * 
125           * @param fade     if set to true, fade out.
126           */
127         void disableBackground(bool fade=true);
128
129         //! Activates the next background piece
130         void nextPiece();
131
132
133         // Static Methods
134
135         //! Singleton getter
136         static Sound* getInstance();
137
138         //! Explicitely delete the singleton
139         static void deleteInstance();
140
141     private:
142         //! Constructor.  Initializes the sound and loads the music data
143         Sound();
144
145         //! Destructor.  Deinitializes sound
146         ~Sound();
147
148         //! Callback for the music data, see XML_Helper
149         bool loadMusic(std::string tag, XML_Helper* helper);
150
151         // DATA
152         
153         // music is stored here, access by d_musicMap[name]
154         std::map<std::string, MusicItem*> d_musicMap;
155         std::vector<std::string> d_bgMap;  // shallow copy of background pieces
156
157         // currently playing background and foreground piece
158 #ifdef FL_SOUND
159         Mix_Music* d_music;
160 #endif
161
162         // if initialization failed, set this to true => no music/sound played
163         bool d_broken;
164
165         // if set to true, play background music
166         bool d_background;
167
168         // if set to true, don't continue with next piece
169         bool d_block;
170
171         // static instanton pointer
172         static Sound* s_instance;
173 };
174
175 #endif //SOUND_H