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 
23 #include "asylum/system/speech.h"
24 
25 #include "asylum/resources/actor.h"
26 #include "asylum/resources/worldstats.h"
27 
28 #include "asylum/system/text.h"
29 
30 #include "asylum/views/scene.h"
31 
32 #include "asylum/asylum.h"
33 #include "asylum/staticres.h"
34 
35 namespace Asylum {
36 
Speech(AsylumEngine * engine)37 Speech::Speech(AsylumEngine *engine): _vm(engine), _textData(0), _textDataPos(0) {
38 	_tick            = _vm->getTick();
39 	_soundResourceId = kResourceNone;
40 	_textResourceId  = kResourceNone;
41 }
42 
play(ResourceId soundResourceId,ResourceId textResourceId)43 ResourceId Speech::play(ResourceId soundResourceId, ResourceId textResourceId) {
44 	if (soundResourceId)
45 		if (getSound()->isPlaying(_soundResourceId))
46 			getSound()->stopAll(_soundResourceId);
47 
48 	_soundResourceId = soundResourceId;
49 	_textResourceId = textResourceId;
50 
51 	prepareSpeech();
52 
53 	return soundResourceId;
54 }
55 
playIndexed(int32 index)56 ResourceId Speech::playIndexed(int32 index) {
57 	int processedIndex;
58 
59 	if (getWorld()->actorType || index != -1) {
60 		processedIndex = (int)speechIndex[index + 5 * getWorld()->actorType] + (int)rnd(speechIndexRandom[index + 5 * getWorld()->actorType]);
61 	} else {
62 		switch(_vm->getRandom(3)) {
63 		default:
64 		case 0:
65 			processedIndex = 23;
66 			break;
67 
68 		case 1:
69 			processedIndex = 400;
70 			break;
71 
72 		case 2:
73 			processedIndex = 401;
74 			break;
75 
76 		case 3:
77 			processedIndex = index;
78 			break;
79 		}
80 
81 		if (processedIndex >= 259)
82 			processedIndex -=9;
83 	}
84 
85 	switch (getWorld()->actorType) {
86 	default:
87 		break;
88 
89 	case kActorMax:
90 		return play(MAKE_RESOURCE(kResourcePackSpeech, processedIndex), MAKE_RESOURCE(kResourcePackText, processedIndex + 83));
91 
92 	case kActorSarah:
93 		return play(MAKE_RESOURCE(kResourcePackSharedSound, processedIndex + 1927), MAKE_RESOURCE(kResourcePackText, processedIndex + 586));
94 
95 	case kActorCyclops:
96 		return play(MAKE_RESOURCE(kResourcePackSharedSound, processedIndex + 2084), MAKE_RESOURCE(kResourcePackText, processedIndex + 743));
97 
98 	case kActorAztec:
99 		return play(MAKE_RESOURCE(kResourcePackSharedSound, processedIndex + 2234), MAKE_RESOURCE(kResourcePackText, processedIndex + 893));
100 	}
101 
102 	return kResourceNone;
103 }
104 
playScene(int32 type,int32 index)105 ResourceId Speech::playScene(int32 type, int32 index) {
106 	switch (type) {
107 	default:
108 		play(kResourceNone, kResourceNone);
109 		break;
110 
111 	case 0:
112 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2363), MAKE_RESOURCE(kResourcePackText, index + 1022));
113 
114 	case 1:
115 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2366), MAKE_RESOURCE(kResourcePackText, index + 1025));
116 
117 	case 2:
118 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2371), MAKE_RESOURCE(kResourcePackText, index + 1030));
119 
120 	case 3:
121 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2398), MAKE_RESOURCE(kResourcePackText, index + 1057));
122 
123 	case 4:
124 		return play(MAKE_RESOURCE(kResourcePackSpeech, index + 503), MAKE_RESOURCE(kResourcePackText, index + 1060));
125 
126 	case 5:
127 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2401), MAKE_RESOURCE(kResourcePackText, index + 1068));
128 
129 	case 6:
130 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2409), MAKE_RESOURCE(kResourcePackText, index + 1076));
131 
132 	case 7:
133 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2415), MAKE_RESOURCE(kResourcePackText, index + 1082));
134 
135 	case 8:
136 		return play(MAKE_RESOURCE(kResourcePackSpeech, index + 511), MAKE_RESOURCE(kResourcePackText, index + 1084));
137 
138 	case 9:
139 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2417), MAKE_RESOURCE(kResourcePackText, index + 1088));
140 
141 	case 10:
142 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2417), MAKE_RESOURCE(kResourcePackText, index + 1093));
143 
144 	case 11:
145 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2424), MAKE_RESOURCE(kResourcePackText, index + 1100));
146 
147 	case 12:
148 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2424), MAKE_RESOURCE(kResourcePackText, index + 1102));
149 
150 	case 13:
151 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2430), MAKE_RESOURCE(kResourcePackText, index + 1108));
152 
153 	case 14:
154 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2432), MAKE_RESOURCE(kResourcePackText, index + 1110));
155 
156 	case 15:
157 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2434), MAKE_RESOURCE(kResourcePackText, index + 1112));
158 
159 	case 16:
160 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2435), MAKE_RESOURCE(kResourcePackText, index + 1113));
161 
162 	case 17:
163 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2436), MAKE_RESOURCE(kResourcePackText, index + 1114));
164 
165 	case 18:
166 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2438), MAKE_RESOURCE(kResourcePackText, index + 1116));
167 
168 	case 19:
169 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2439), MAKE_RESOURCE(kResourcePackText, index + 1117));
170 	}
171 
172 	return kResourceNone;
173 }
174 
playPlayer(int32 index)175 ResourceId Speech::playPlayer(int32 index) {
176 	switch (getWorld()->actorType) {
177 	default:
178 		break;
179 
180 	case kActorMax: {
181 		int32 soundResourceIndex = index;
182 		int32 textResourceIndex = index;
183 
184 		if (index >= 259) {
185 			soundResourceIndex -= 9;
186 			textResourceIndex -= 9;
187 		}
188 
189 		ResourceId soundResourceId = MAKE_RESOURCE(kResourcePackSpeech, soundResourceIndex);
190 
191 		return play(soundResourceId, MAKE_RESOURCE(kResourcePackText, textResourceIndex + 83));
192 		}
193 
194 	case kActorSarah:
195 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 1927), MAKE_RESOURCE(kResourcePackText, index + 586));
196 
197 	case kActorCyclops:
198 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2084), MAKE_RESOURCE(kResourcePackText, index + 743));
199 
200 	case kActorAztec:
201 		return play(MAKE_RESOURCE(kResourcePackSharedSound, index + 2234), MAKE_RESOURCE(kResourcePackText, index + 893));
202 	}
203 
204 	return kResourceNone;
205 }
206 
resetResourceIds()207 void Speech::resetResourceIds() {
208 	_soundResourceId = kResourceNone;
209 	_textResourceId = kResourceNone;
210 }
211 
resetTextData()212 void Speech::resetTextData() {
213 	_textData = NULL;
214 	_textDataPos = NULL;
215 }
216 
217 //////////////////////////////////////////////////////////////////////////
218 // Private methods
219 //////////////////////////////////////////////////////////////////////////
220 
prepareSpeech()221 void Speech::prepareSpeech() {
222 	int32 startTick = _vm->getTick();
223 
224 	if (_soundResourceId) {
225 		if (!getSound()->isPlaying(_soundResourceId) || (_tick && startTick >= _tick))
226 			process();
227 
228 		if (Config.showEncounterSubtitles) {
229 			Common::Point point;
230 			Actor *actor = getScene()->getActor();
231 			actor->adjustCoordinates(&point);
232 
233 			int16 posY = (point.y >= 240) ? 40 : 320;
234 
235 			getText()->draw(_textDataPos, getWorld()->font3, posY);
236 			getText()->draw(_textData, getWorld()->font1, posY);
237 		}
238 	}
239 }
240 
241 
process()242 void Speech::process() {
243 	_tick = 0;
244 
245 	char *txt = getText()->get(_textResourceId);
246 
247 	if (*(txt + strlen((const char *)txt) - 2) == 1) {
248 		_textResourceId = kResourceNone;
249 		_textData = 0;
250 		_textDataPos = 0;
251 	} else if (*txt == '{') {
252 		_textData = txt + 3;
253 		_textDataPos = 0;
254 
255 		getText()->loadFont(getWorld()->font1);
256 		getSound()->playSound(_soundResourceId, false, Config.voiceVolume, 0);
257 	} else {
258 		_textData = 0;
259 		_textDataPos = txt;
260 
261 		if (*txt == '/') {
262 			_textDataPos = txt + 2;
263 		}
264 
265 		getText()->loadFont(getWorld()->font3);
266 		getSound()->playSound(_soundResourceId, false, Config.voiceVolume, 0);
267 	}
268 }
269 
270 } // end of namespace Asylum
271