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