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  * MIT License:
22  *
23  * Copyright (c) 2009 Alexei Svitkine, Eugene Sandulenko
24  *
25  * Permission is hereby granted, free of charge, to any person
26  * obtaining a copy of this software and associated documentation
27  * files (the "Software"), to deal in the Software without
28  * restriction, including without limitation the rights to use,
29  * copy, modify, merge, publish, distribute, sublicense, and/or sell
30  * copies of the Software, and to permit persons to whom the
31  * Software is furnished to do so, subject to the following
32  * conditions:
33  *
34  * The above copyright notice and this permission notice shall be
35  * included in all copies or substantial portions of the Software.
36  *
37  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
38  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
39  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
40  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
41  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
42  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
43  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
44  * OTHER DEALINGS IN THE SOFTWARE.
45  *
46  */
47 
48 #include "audio/audiostream.h"
49 #include "audio/mixer.h"
50 #include "audio/decoders/raw.h"
51 #include "common/stream.h"
52 #include "common/system.h"
53 
54 #include "wage/wage.h"
55 #include "wage/entities.h"
56 #include "wage/sound.h"
57 #include "wage/world.h"
58 
59 namespace Wage {
60 
61 static const int8 deltas[] = { 0,-49,-36,-25,-16,-9,-4,-1,0,1,4,9,16,25,36,49 };
62 
Sound(Common::String name,Common::SeekableReadStream * data)63 Sound::Sound(Common::String name, Common::SeekableReadStream *data) : _name(name) {
64 	_size = data->size() - 20;
65 	_data = (byte *)calloc(2 * _size, 1);
66 
67 	data->skip(20); // Skip header
68 
69 	byte value = 0x80;
70 	for (uint i = 0; i < _size; i++) {
71 		byte d = data->readByte();
72 		value += deltas[d & 0xf];
73 		_data[i * 2] = value;
74 		value += deltas[(d >> 4) & 0xf];
75 		_data[i * 2 + 1] = value;
76 	}
77 }
78 
~Sound()79 Sound::~Sound() {
80 	free(_data);
81 }
82 
playSound(Common::String soundName)83 void WageEngine::playSound(Common::String soundName) {
84 	soundName.toLowercase();
85 
86 	if (!_world->_sounds.contains(soundName)) {
87 		warning("playSound: Sound '%s' does not exist", soundName.c_str());
88 		return;
89 	}
90 
91 	Sound *s = _world->_sounds[soundName];
92 
93 	Audio::AudioStream *stream = Audio::makeRawStream(s->_data, s->_size, 11000, Audio::FLAG_UNSIGNED);
94 
95 	_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, stream,
96 		-1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
97 
98 	while (_mixer->isSoundHandleActive(_soundHandle) && !_shouldQuit) {
99 		Common::Event event;
100 
101 		if (_eventMan->pollEvent(event)) {
102 			switch (event.type) {
103 			case Common::EVENT_QUIT:
104 				if (saveDialog())
105 					_shouldQuit = true;
106 				break;
107 			default:
108 				break;
109 			}
110 		}
111 
112 		_system->updateScreen();
113 		_system->delayMillis(10);
114 	}
115 }
116 
updateSoundTimerForScene(Scene * scene,bool firstTime)117 void WageEngine::updateSoundTimerForScene(Scene *scene, bool firstTime) {
118 	//warning("STUB: WageEngine::updateSoundTimerForScene()");
119 	if (_world->_player->_currentScene != scene)
120 			return;
121 
122 	if (scene->_soundFrequency > 0 && !scene->_soundName.empty()) {
123 		Common::String soundName(scene->_soundName);
124 
125 		soundName.toLowercase();
126 
127 		if (!_world->_sounds.contains(soundName)) {
128 			warning("updateSoundTimerForScene: Sound '%s' does not exist", soundName.c_str());
129 			return;
130 		}
131 
132 		warning("STUB: updateSoundTimerForScene: sound: '%s', %s", soundName.c_str(),
133 				scene->_soundType == Scene::PERIODIC ? "PERIODIC" : "RANDOM");
134 
135 #if 0
136 		soundTimer = new Timer();
137 		switch (scene.getSoundType()) {
138 		case Scene.PERIODIC:
139 			if (firstTime)
140 				soundTimer.schedule(new PlaySoundTask(scene, sound), 0);
141 			int delay = 60000 / scene.getSoundFrequency();
142 			soundTimer.schedule(new PlaySoundTask(scene, sound), delay);
143 			soundTimer.schedule(new UpdateSoundTimerTask(scene), delay + 1);
144 			break;
145 		case Scene.RANDOM:
146 			for (int i = 0; i < scene.getSoundFrequency(); i++)
147 				soundTimer.schedule(new PlaySoundTask(scene, sound), (int)(Math.random() * 60000));
148 			soundTimer.schedule(new UpdateSoundTimerTask(scene), 60000);
149 			break;
150 		}
151 #endif
152 	}
153 
154 }
155 
156 
157 } // End of namespace Wage
158