1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  *
22  *              Originally written by Syn9 in FreeBASIC with SDL
23  *              http://syn9.thehideoutgames.com/index_backup.php
24  *
25  *            Ported to plain C for GCW-Zero handheld by Dmitry Smagin
26  *                http://github.com/dmitrysmagin/griffon_legend
27  *
28  *
29  *                 Programming/Graphics: Daniel "Syn9" Kennedy
30  *                     Music/Sound effects: David Turner
31  *
32  *                   Beta testing and gameplay design help:
33  *                    Deleter, Cha0s, Aether Fox, and Kiz
34  *
35  */
36 
37 #include "audio/audiostream.h"
38 #include "audio/decoders/vorbis.h"
39 #include "common/memstream.h"
40 
41 #include "common/file.h"
42 #include "common/system.h"
43 
44 #include "griffon/griffon.h"
45 
46 namespace Griffon {
47 
setChannelVolume(int channel,int volume)48 void GriffonEngine::setChannelVolume(int channel, int volume) {
49 	if (channel >= 0 && channel < kSoundHandles)
50 		_mixer->setChannelVolume(_handles[channel], volume);
51 }
52 
getSoundHandle()53 int GriffonEngine::getSoundHandle() {
54 	for (uint i = 0; i < kSoundHandles; i++) {
55 		if (!_mixer->isSoundHandleActive(_handles[i])) {
56 			return i;
57 		}
58 	}
59 
60 	return -1;
61 }
62 
playSound(DataChunk * chunk,bool looped)63 int GriffonEngine::playSound(DataChunk *chunk, bool looped) {
64 	int ch = -1;
65 
66 #ifdef USE_VORBIS
67 	if ((ch = getSoundHandle()) != -1) {
68 		Audio::SeekableAudioStream *audioStream = Audio::makeVorbisStream(new Common::MemoryReadStream(chunk->data, chunk->size), DisposeAfterUse::YES);
69 
70 		if (looped) {
71 			Audio::AudioStream *loopingStream = new Audio::LoopingAudioStream(audioStream, 0, DisposeAfterUse::YES);
72 			_mixer->playStream(Audio::Mixer::kSFXSoundType, &_handles[ch], loopingStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::YES, false, false);
73 
74 		} else {
75 			_mixer->playStream(Audio::Mixer::kSFXSoundType, &_handles[ch], audioStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::YES, false, false);
76 		}
77 	}
78 #endif // USE_VORBIS
79 
80 	return ch;
81 }
82 
pauseSoundChannel(int channel)83 void GriffonEngine::pauseSoundChannel(int channel) {
84 	if (channel >= 0 && channel < kSoundHandles)
85 		_mixer->pauseHandle(_handles[channel], true);
86 }
87 
haltSoundChannel(int channel)88 void GriffonEngine::haltSoundChannel(int channel) {
89 	if (channel == -1) {
90 		for (int i = 0; i < kSoundHandles; i++)
91 			_mixer->stopHandle(_handles[i]);
92 	} else if (channel >= 0 && channel < kSoundHandles) {
93 		_mixer->stopHandle(_handles[channel]);
94 	}
95 }
96 
resumeSoundChannel(int channel)97 void GriffonEngine::resumeSoundChannel(int channel) {
98 	if (channel >= 0 && channel < kSoundHandles)
99 		_mixer->pauseHandle(_handles[channel], false);
100 }
101 
isSoundChannelPlaying(int channel)102 bool GriffonEngine::isSoundChannelPlaying(int channel) {
103 	return (channel >= 0 && channel < kSoundHandles) ? _mixer->isSoundHandleActive(_handles[channel]) : false;
104 }
105 
cacheSound(const char * name)106 DataChunk *cacheSound(const char *name) {
107 	Common::File file;
108 	DataChunk *res = new DataChunk;
109 
110 	file.open(name);
111 	if (!file.isOpen())
112 		error("Cannot open file %s", name);
113 
114 	res->size = file.size();
115 	res->data = (byte *)malloc(res->size);
116 
117 	file.read(res->data, res->size);
118 
119 	return res;
120 }
121 
setupAudio()122 void GriffonEngine::setupAudio() {
123 	const char *stri = "Loading...";
124 	drawString(_videoBuffer, stri, 160 - 4 * strlen(stri), 116, 0);
125 
126 	Graphics::TransparentSurface *loadimg = loadImage("art/load.bmp", true);
127 
128 	rcSrc.left = 0;
129 	rcSrc.top = 0;
130 	rcSrc.setWidth(88);
131 	rcSrc.setHeight(32);
132 
133 	rcDest.left = 160 - 44;
134 	rcDest.top = 116 + 12;
135 
136 	loadimg->blit(*_videoBuffer, rcDest.left, rcDest.top, Graphics::FLIP_NONE, &rcSrc, TS_ARGB(160, 255, 255, 255));
137 
138 	g_system->copyRectToScreen(_videoBuffer->getPixels(), _videoBuffer->pitch, 0, 0, _videoBuffer->w, _videoBuffer->h);
139 	g_system->updateScreen();
140 
141 	rcDest.left = 160 - 44 + 7;
142 	rcDest.top = 116 + 12 + 12;
143 	rcDest.setHeight(8);
144 
145 	_musicBoss = cacheSound("music/boss.ogg");
146 	drawProgress(1, 21);
147 	_musicGardens1 = cacheSound("music/gardens.ogg");
148 	drawProgress(2, 21);
149 	_musicGardens2 = cacheSound("music/gardens2.ogg");
150 	drawProgress(3, 21);
151 	_musicGardens3 = cacheSound("music/gardens3.ogg");
152 	drawProgress(4, 21);
153 	_musicGardens4 = cacheSound("music/gardens4.ogg");
154 	drawProgress(5, 21);
155 	_musicEndOfGame = cacheSound("music/endofgame.ogg");
156 	drawProgress(6, 21);
157 	_musicMenu = cacheSound("music/menu.ogg");
158 	drawProgress(7, 21);
159 
160 	_sfx[kSndBite] = cacheSound("sfx/bite.ogg");
161 	drawProgress(8, 21);
162 	_sfx[kSndCrystal] = cacheSound("sfx/crystal.ogg");
163 	drawProgress(9, 21);
164 	_sfx[kSndDoor] = cacheSound("sfx/door.ogg");
165 	drawProgress(10, 21);
166 	_sfx[kSndEnemyHit] = cacheSound("sfx/enemyhit.ogg");
167 	drawProgress(11, 21);
168 	_sfx[kSndIce] = cacheSound("sfx/ice.ogg");
169 	drawProgress(12, 21);
170 	_sfx[kSndLever] = cacheSound("sfx/lever.ogg");
171 	drawProgress(13, 21);
172 	_sfx[kSndLightning] = cacheSound("sfx/lightning.ogg");
173 	drawProgress(14, 21);
174 	_sfx[kSndMetalHit] = cacheSound("sfx/metalhit.ogg");
175 	drawProgress(15, 21);
176 	_sfx[kSndPowerUp] = cacheSound("sfx/powerup.ogg");
177 	drawProgress(16, 21);
178 	_sfx[kSndRocks] = cacheSound("sfx/rocks.ogg");
179 	drawProgress(17, 21);
180 	_sfx[kSndSwordHit] = cacheSound("sfx/swordhit.ogg");
181 	drawProgress(18, 21);
182 	_sfx[kSndThrow] = cacheSound("sfx/throw.ogg");
183 	drawProgress(19, 21);
184 	_sfx[kSndChest] = cacheSound("sfx/chest.ogg");
185 	drawProgress(20, 21);
186 	_sfx[kSndFire] = cacheSound("sfx/fire.ogg");
187 	drawProgress(21, 21);
188 	_sfx[kSndBeep] = cacheSound("sfx/beep.ogg");
189 }
190 
updateMusic()191 void GriffonEngine::updateMusic() {
192 	static int loopseta = 0;
193 
194 	DataChunk *iplaysound = NULL;
195 
196 	if (config.music) {
197 		// if(_curmap > 5 && _curmap < 42) iplaysound = macademy;
198 		// if(_curmap > 47) iplaysound = _mgardens;
199 		iplaysound = _musicGardens1;
200 		if (_roomLock)
201 			iplaysound = _musicBoss;
202 
203 		if (iplaysound == _musicBoss && _playingBoss)
204 			iplaysound = NULL;
205 		if (iplaysound == _musicGardens1 && _playingGardens)
206 			iplaysound = NULL;
207 
208 		if (iplaysound != NULL) {
209 			haltSoundChannel(_musicChannel);
210 
211 			_playingBoss = (iplaysound == _musicBoss);
212 			_playingGardens = (iplaysound == _musicGardens1);
213 
214 			_musicChannel = playSound(iplaysound, true);
215 			setChannelVolume(_musicChannel, config.musicVol);
216 		} else {
217 			if (!isSoundChannelPlaying(_musicChannel)) {
218 				loopseta += 1;
219 				if (loopseta == 4)
220 					loopseta = 0;
221 
222 				if (_playingGardens) {
223 					haltSoundChannel(_musicChannel);
224 					if (_playingGardens) {
225 						switch (loopseta) {
226 						case 0:
227 							playSound(_musicGardens1);
228 							break;
229 						case 1:
230 							playSound(_musicGardens2);
231 							break;
232 						case 2:
233 							playSound(_musicGardens3);
234 							break;
235 						case 3:
236 							playSound(_musicGardens4);
237 						default:
238 							break;
239 						}
240 					}
241 				}
242 
243 				setChannelVolume(_musicChannel, config.musicVol);
244 			}
245 		}
246 	}
247 }
248 
249 
250 } // end of namespace Griffon
251