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 "graphics/cursorman.h"
24
25 #include "gob/gob.h"
26 #include "gob/global.h"
27 #include "gob/util.h"
28 #include "gob/surface.h"
29 #include "gob/dataio.h"
30 #include "gob/palanim.h"
31 #include "gob/draw.h"
32 #include "gob/video.h"
33 #include "gob/aniobject.h"
34
35 #include "gob/sound/sound.h"
36
37 #include "gob/pregob/pregob.h"
38 #include "gob/pregob/gctfile.h"
39
40
41 namespace Gob {
42
43 const char PreGob::kLanguageSuffixShort[5] = { 't', 'g', 'a', 'e', 'i'};
44 const char *PreGob::kLanguageSuffixLong [5] = {"fr", "al", "an", "it", "es"};
45
46
PreGob(GobEngine * vm)47 PreGob::PreGob(GobEngine *vm) : _vm(vm), _fadedOut(false) {
48 }
49
~PreGob()50 PreGob::~PreGob() {
51 }
52
fadeOut()53 void PreGob::fadeOut() {
54 if (_fadedOut || _vm->shouldQuit())
55 return;
56
57 // Fade to black
58 _vm->_palAnim->fade(0, 0, 0);
59
60 _fadedOut = true;
61 }
62
fadeIn()63 void PreGob::fadeIn() {
64 if (!_fadedOut || _vm->shouldQuit())
65 return;
66
67 // Fade to palette
68 _vm->_draw->blitInvalidated();
69 _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, 0, 0);
70 _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199);
71
72 _fadedOut = false;
73 }
74
clearScreen()75 void PreGob::clearScreen() {
76 _vm->_draw->_backSurface->clear();
77 _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199);
78 _vm->_draw->blitInvalidated();
79 _vm->_video->retrace();
80 }
81
initScreen()82 void PreGob::initScreen() {
83 _vm->_util->setFrameRate(15);
84
85 _fadedOut = true;
86
87 _vm->_draw->initScreen();
88
89 _vm->_draw->_backSurface->clear();
90 _vm->_util->clearPalette();
91
92 _vm->_draw->forceBlit();
93 _vm->_video->retrace();
94
95 _vm->_util->processInput();
96 }
97
setPalette(const byte * palette,uint16 size)98 void PreGob::setPalette(const byte *palette, uint16 size) {
99 memcpy(_vm->_draw->_vgaPalette, palette, 3 * size);
100
101 // If we didn't fade out prior, immediately set the palette
102 if (!_fadedOut)
103 _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
104 }
105
addCursor()106 void PreGob::addCursor() {
107 CursorMan.pushCursor(0, 0, 0, 0, 0, 0);
108 }
109
removeCursor()110 void PreGob::removeCursor() {
111 CursorMan.popCursor();
112 }
113
setCursor(Surface & sprite,int16 hotspotX,int16 hotspotY)114 void PreGob::setCursor(Surface &sprite, int16 hotspotX, int16 hotspotY) {
115 CursorMan.replaceCursor(sprite.getData(), sprite.getWidth(), sprite.getHeight(), hotspotX, hotspotY, 0);
116 }
117
setCursor(Surface & sprite,int16 left,int16 top,int16 right,int16 bottom,int16 hotspotX,int16 hotspotY)118 void PreGob::setCursor(Surface &sprite, int16 left, int16 top, int16 right, int16 bottom,
119 int16 hotspotX, int16 hotspotY) {
120
121 const int width = right - left + 1;
122 const int height = bottom - top + 1;
123
124 if ((width <= 0) || (height <= 0))
125 return;
126
127 Surface cursor(width, height, 1);
128
129 cursor.blit(sprite, left, top, right, bottom, 0, 0);
130
131 setCursor(cursor, hotspotX, hotspotX);
132 }
133
showCursor()134 void PreGob::showCursor() {
135 CursorMan.showMouse(true);
136
137 _vm->_draw->_showCursor = 4;
138 }
139
hideCursor()140 void PreGob::hideCursor() {
141 CursorMan.showMouse(false);
142
143 _vm->_draw->_showCursor = 0;
144 }
145
isCursorVisible() const146 bool PreGob::isCursorVisible() const {
147 return CursorMan.isVisible();
148 }
149
loadSounds(const char * const * sounds,uint soundCount)150 void PreGob::loadSounds(const char * const *sounds, uint soundCount) {
151 freeSounds();
152
153 _sounds.resize(soundCount);
154
155 for (uint i = 0; i < soundCount; i++)
156 loadSound(_sounds[i], sounds[i]);
157 }
158
freeSounds()159 void PreGob::freeSounds() {
160 _sounds.clear();
161 }
162
loadSound(SoundDesc & sound,const Common::String & file) const163 bool PreGob::loadSound(SoundDesc &sound, const Common::String &file) const {
164 return _vm->_sound->sampleLoad(&sound, SOUND_SND, file.c_str());
165 }
166
playSound(uint sound,int16 frequency,int16 repCount)167 void PreGob::playSound(uint sound, int16 frequency, int16 repCount) {
168 if (sound >= _sounds.size())
169 return;
170
171 _vm->_sound->blasterPlay(&_sounds[sound], repCount, frequency);
172 }
173
stopSound()174 void PreGob::stopSound() {
175 _vm->_sound->blasterStop(0);
176 }
177
playSoundFile(const Common::String & file,int16 frequency,int16 repCount,bool interruptible)178 void PreGob::playSoundFile(const Common::String &file, int16 frequency, int16 repCount, bool interruptible) {
179 stopSound();
180
181 SoundDesc sound;
182 if (!loadSound(sound, file))
183 return;
184
185 _vm->_sound->blasterPlay(&sound, repCount, frequency);
186
187 _vm->_util->forceMouseUp();
188
189 bool finished = false;
190 while (!_vm->shouldQuit() && !finished && _vm->_sound->blasterPlayingSound()) {
191 endFrame(true);
192
193 finished = hasInput();
194 }
195
196 _vm->_util->forceMouseUp();
197
198 stopSound();
199 }
200
beep(int16 frequency,int32 length)201 void PreGob::beep(int16 frequency, int32 length) {
202 _vm->_sound->speakerOn(frequency, length);
203 }
204
endFrame(bool doInput)205 void PreGob::endFrame(bool doInput) {
206 _vm->_draw->blitInvalidated();
207 _vm->_util->waitEndFrame();
208
209 if (doInput)
210 _vm->_util->processInput();
211 }
212
checkInput(int16 & mouseX,int16 & mouseY,MouseButtons & mouseButtons)213 int16 PreGob::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons) {
214 _vm->_util->getMouseState(&mouseX, &mouseY, &mouseButtons);
215 _vm->_util->forceMouseUp();
216
217 return _vm->_util->checkKey();
218 }
219
waitInput(int16 & mouseX,int16 & mouseY,MouseButtons & mouseButtons)220 int16 PreGob::waitInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons) {
221 bool finished = false;
222
223 int16 key = 0;
224 while (!_vm->shouldQuit() && !finished) {
225 endFrame(true);
226
227 key = checkInput(mouseX, mouseY, mouseButtons);
228
229 finished = (mouseButtons != kMouseButtonsNone) || (key != 0);
230 }
231
232 return key;
233 }
234
waitInput()235 int16 PreGob::waitInput() {
236 int16 mouseX, mouseY;
237 MouseButtons mouseButtons;
238
239 return waitInput(mouseX, mouseY, mouseButtons);
240 }
241
hasInput()242 bool PreGob::hasInput() {
243 int16 mouseX, mouseY;
244 MouseButtons mouseButtons;
245
246 return checkInput(mouseX, mouseY, mouseButtons) || (mouseButtons != kMouseButtonsNone);
247 }
248
clearAnim(ANIObject & anim)249 void PreGob::clearAnim(ANIObject &anim) {
250 int16 left, top, right, bottom;
251
252 if (anim.clear(*_vm->_draw->_backSurface, left, top, right, bottom))
253 _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
254 }
255
drawAnim(ANIObject & anim)256 void PreGob::drawAnim(ANIObject &anim) {
257 int16 left, top, right, bottom;
258
259 if (anim.draw(*_vm->_draw->_backSurface, left, top, right, bottom))
260 _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
261 anim.advance();
262 }
263
redrawAnim(ANIObject & anim)264 void PreGob::redrawAnim(ANIObject &anim) {
265 clearAnim(anim);
266 drawAnim(anim);
267 }
268
clearAnim(const ANIList & anims)269 void PreGob::clearAnim(const ANIList &anims) {
270 for (int i = (anims.size() - 1); i >= 0; i--)
271 clearAnim(*anims[i]);
272 }
273
drawAnim(const ANIList & anims)274 void PreGob::drawAnim(const ANIList &anims) {
275 for (ANIList::const_iterator a = anims.begin(); a != anims.end(); ++a)
276 drawAnim(**a);
277 }
278
redrawAnim(const ANIList & anims)279 void PreGob::redrawAnim(const ANIList &anims) {
280 clearAnim(anims);
281 drawAnim(anims);
282 }
283
loadAnims(ANIList & anims,ANIFile & ani,uint count,const AnimProperties * props) const284 void PreGob::loadAnims(ANIList &anims, ANIFile &ani, uint count, const AnimProperties *props) const {
285 freeAnims(anims);
286
287 anims.resize(count);
288 for (uint i = 0; i < count; i++) {
289 anims[i] = new ANIObject(ani);
290
291 setAnim(*anims[i], props[i]);
292 }
293 }
294
freeAnims(ANIList & anims) const295 void PreGob::freeAnims(ANIList &anims) const {
296 for (ANIList::iterator a = anims.begin(); a != anims.end(); ++a)
297 delete *a;
298
299 anims.clear();
300 }
301
setAnim(ANIObject & anim,const AnimProperties & props) const302 void PreGob::setAnim(ANIObject &anim, const AnimProperties &props) const {
303 anim.setAnimation(props.animation);
304 anim.setFrame(props.frame);
305 anim.setMode(props.mode);
306 anim.setPause(props.paused);
307 anim.setVisible(props.visible);
308
309 if (props.hasPosition)
310 anim.setPosition(props.x, props.y);
311 else
312 anim.setPosition();
313 }
314
getLocFile(const Common::String & file) const315 Common::String PreGob::getLocFile(const Common::String &file) const {
316 if (_vm->_global->_language >= ARRAYSIZE(kLanguageSuffixShort))
317 return file;
318
319 return file + kLanguageSuffixShort[_vm->_global->_language];
320 }
321
loadTXT(const Common::String & txtFile,TXTFile::Format format) const322 TXTFile *PreGob::loadTXT(const Common::String &txtFile, TXTFile::Format format) const {
323 Common::SeekableReadStream *txtStream = _vm->_dataIO->getFile(txtFile);
324 if (!txtStream)
325 error("PreGob::loadTXT(): Failed to open \"%s\"", txtFile.c_str());
326
327 TXTFile *txt = new TXTFile(*txtStream, format);
328
329 delete txtStream;
330
331 fixTXTStrings(*txt);
332
333 return txt;
334 }
335
fixTXTStrings(TXTFile & txt) const336 void PreGob::fixTXTStrings(TXTFile &txt) const {
337 }
338
loadGCT(const Common::String & gctFile) const339 GCTFile *PreGob::loadGCT(const Common::String &gctFile) const {
340 Common::SeekableReadStream *gctStream = _vm->_dataIO->getFile(gctFile);
341 if (!gctStream)
342 error("PreGob::loadGCT(): Failed to open \"%s\"", gctFile.c_str());
343
344 GCTFile *gct = new GCTFile(*gctStream, _vm->_rnd);
345
346 delete gctStream;
347
348 return gct;
349 }
350
351 } // End of namespace Gob
352