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