Add documentation on placing tiles.
[Tsunagari.git] / src / music.cpp
blob531327dfc93714e9e87d790a00ebc6402ed711f1
1 /*********************************
2 ** Tsunagari Tile Engine **
3 ** music.cpp **
4 ** Copyright 2011-2012 OmegaSDG **
5 *********************************/
7 // **********
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to
10 // deal in the Software without restriction, including without limitation the
11 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12 // sell copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 // IN THE SOFTWARE.
25 // **********
27 #include "music.h"
28 #include "python.h"
30 Music::Music()
31 : volume(1.0),
32 paused(false),
33 state(NOT_PLAYING)
35 pythonSetGlobal("Music", this);
38 Music::~Music()
40 if (musicInst && musicInst->playing())
41 musicInst->stop();
44 std::string Music::getIntro()
46 return newIntro;
49 std::string Music::getLoop()
51 return newLoop;
54 void Music::setIntro(const std::string& filename)
56 if (newIntro == filename)
57 return;
59 switch (state) {
60 case NOT_PLAYING:
61 case PLAYING_INTRO:
62 case PLAYING_LOOP:
63 setState(CHANGED_INTRO);
64 default: break;
67 Resourcer* rc = Resourcer::instance();
69 newIntro = filename;
70 // Optimize XXX: Don't load until played.
71 introMusic = filename.size() ?
72 rc->getSong(filename) : SongRef();
75 void Music::setLoop(const std::string& filename)
77 if (newLoop == filename)
78 return;
80 switch (state) {
81 case NOT_PLAYING:
82 case PLAYING_INTRO:
83 case PLAYING_LOOP:
84 setState(CHANGED_LOOP);
85 default: break;
88 Resourcer* rc = Resourcer::instance();
90 newLoop = filename;
91 // Optimize XXX: Don't load until played.
92 loopMusic = filename.size() ?
93 rc->getSong(filename) : SongRef();
96 double Music::getVolume()
98 return volume;
101 void Music::setVolume(double level)
103 volume = level;
104 if (musicInst)
105 musicInst->changeVolume(level);
108 bool Music::isPaused()
110 return paused;
113 void Music::setPaused(bool p)
115 if (paused == p)
116 return;
117 paused = p;
118 if (musicInst) {
119 if (p)
120 musicInst->pause();
121 else
122 musicInst->play();
126 void Music::stop()
128 paused = false;
129 if (musicInst)
130 musicInst->stop();
131 state = NOT_PLAYING;
134 void Music::tick()
136 if (paused)
137 return;
139 switch (state) {
140 case NOT_PLAYING:
141 if (musicInst && musicInst->playing())
142 musicInst->stop();
143 break;
144 case PLAYING_INTRO:
145 if (!musicInst->playing()) {
146 if (newLoop.size() && loopMusic)
147 playLoop();
148 else
149 setState(NOT_PLAYING);
151 break;
152 case PLAYING_LOOP:
153 break;
154 case CHANGED_INTRO:
155 if (newIntro.size() && introMusic)
156 playIntro();
157 else if (newLoop.size() && newLoop != curLoop)
158 setState(CHANGED_LOOP);
159 else if (newLoop.size())
160 setState(PLAYING_LOOP);
161 else
162 setState(NOT_PLAYING);
163 break;
164 case CHANGED_LOOP:
165 if (newIntro.size() && loopMusic)
166 playIntro();
167 else if (newLoop.size() && loopMusic)
168 playLoop();
169 else
170 setState(NOT_PLAYING);
171 break;
175 void Music::playIntro()
177 if (musicInst && musicInst->playing())
178 musicInst->stop();
179 curIntro = newIntro;
180 introMusic->play(false);
181 introMusic->changeVolume(volume);
182 musicInst = introMusic;
183 setState(PLAYING_INTRO);
186 void Music::playLoop()
188 if (musicInst && musicInst->playing())
189 musicInst->stop();
190 curLoop = newLoop;
191 loopMusic->play(true);
192 loopMusic->changeVolume(volume);
193 musicInst = loopMusic;
194 setState(PLAYING_LOOP);
198 static const char* stateStr(MUSIC_STATE state)
200 switch (state) {
201 case NOT_PLAYING:
202 return "NOT_PLAYING";
203 case PLAYING_INTRO:
204 return "PLAYING_INTRO";
205 case PLAYING_LOOP:
206 return "PLAYING_LOOP";
207 case CHANGED_INTRO:
208 return "CHANGED_INTRO";
209 case CHANGED_LOOP:
210 return "CHANGED_LOOP";
211 default:
212 return "";
217 void Music::setState(MUSIC_STATE state)
219 // printf("State changed from %s to %s.\n", stateStr(this->state), stateStr(state));
220 this->state = state;
223 void exportMusic()
225 boost::python::class_<Music>("MusicManager", boost::python::no_init)
226 .add_property("intro", &Music::getIntro, &Music::setIntro)
227 .add_property("loop", &Music::getLoop, &Music::setLoop)
228 .add_property("volume", &Music::getVolume, &Music::setVolume)
229 .add_property("paused", &Music::isPaused, &Music::setPaused)
230 .def("stop", &Music::stop)