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  * Additional copyright for this file:
8  * Copyright (C) 1995 Presto Studios, Inc.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14 
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19 
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23  *
24  */
25 
26 #include "buried/biochip_right.h"
27 #include "buried/buried.h"
28 #include "buried/gameui.h"
29 #include "buried/graphics.h"
30 #include "buried/inventory_window.h"
31 #include "buried/message.h"
32 #include "buried/navarrow.h"
33 #include "buried/resources.h"
34 #include "buried/sound.h"
35 #include "buried/scene_view.h"
36 #include "buried/environ/scene_common.h"
37 
38 #include "common/stream.h"
39 #include "common/system.h"
40 #include "graphics/surface.h"
41 
42 namespace Buried {
43 
BasicDoor(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int left,int top,int right,int bottom,int timeZone,int environment,int node,int facing,int orientation,int depth,int transitionType,int transitionData,int transitionStartFrame,int transitionLength,int openingSoundID)44 BasicDoor::BasicDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
45 		int left, int top, int right, int bottom, int timeZone, int environment, int node, int facing,
46 		int orientation, int depth, int transitionType, int transitionData,
47 		int transitionStartFrame, int transitionLength, int openingSoundID) :
48 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
49 	_clicked = false;
50 
51 	_clickable = Common::Rect(left, top, right, bottom);
52 
53 	_destData.destinationScene.timeZone = timeZone;
54 	_destData.destinationScene.environment = environment;
55 	_destData.destinationScene.node = node;
56 	_destData.destinationScene.facing = facing;
57 	_destData.destinationScene.orientation = orientation;
58 	_destData.destinationScene.depth = depth;
59 
60 	_destData.transitionType = transitionType;
61 	_destData.transitionData = transitionData;
62 	_destData.transitionStartFrame = transitionStartFrame;
63 	_destData.transitionLength = transitionLength;
64 
65 	_openingSoundID = openingSoundID;
66 }
67 
mouseDown(Window * viewWindow,const Common::Point & pointLocation)68 int BasicDoor::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
69 	if (_clickable.contains(pointLocation))
70 		_clicked = true;
71 
72 	return SC_TRUE;
73 }
74 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)75 int BasicDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
76 	if (_clicked) {
77 		_clicked = false;
78 
79 		if (_openingSoundID >= 0)
80 			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _openingSoundID));
81 
82 		if (_clickable.contains(pointLocation))
83 			((SceneViewWindow *)viewWindow)->moveToDestination(_destData);
84 	}
85 
86 	return SC_TRUE;
87 }
88 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)89 int BasicDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
90 	if (_clickable.contains(pointLocation))
91 		return kCursorFinger;
92 
93 	return kCursorArrow;
94 }
95 
TurnDepthPreChange(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int flagOffset,int upDepth,int leftDepth,int rightDepth,int downDepth,int forwardDepth)96 TurnDepthPreChange::TurnDepthPreChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
97 		int flagOffset, int upDepth, int leftDepth, int rightDepth, int downDepth, int forwardDepth) :
98 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
99 	if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(flagOffset)) {
100 		if (upDepth >= 0)
101 			_staticData.destUp.destinationScene.depth = upDepth;
102 
103 		if (leftDepth >= 0)
104 			_staticData.destLeft.destinationScene.depth = leftDepth;
105 
106 		if (rightDepth >= 0)
107 			_staticData.destRight.destinationScene.depth = rightDepth;
108 
109 		if (downDepth >= 0)
110 			_staticData.destDown.destinationScene.depth = downDepth;
111 
112 		if (forwardDepth >= 0)
113 			_staticData.destForward.destinationScene.depth = forwardDepth;
114 	}
115 }
116 
GenericItemAcquire(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int left,int top,int right,int bottom,int itemID,int clearStillFrame,int itemFlagOffset)117 GenericItemAcquire::GenericItemAcquire(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
118 		int left, int top, int right, int bottom, int itemID, int clearStillFrame, int itemFlagOffset) :
119 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
120 	_itemPresent = true;
121 	_itemID = itemID;
122 	_acquireRegion = Common::Rect(left, top, right, bottom);
123 	_fullFrameIndex = sceneStaticData.navFrameIndex;
124 	_clearFrameIndex = clearStillFrame;
125 	_itemFlagOffset = itemFlagOffset;
126 
127 	if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_itemFlagOffset) != 0) {
128 		_itemPresent = false;
129 		_staticData.navFrameIndex = _clearFrameIndex;
130 	}
131 }
132 
mouseDown(Window * viewWindow,const Common::Point & pointLocation)133 int GenericItemAcquire::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
134 	if (_acquireRegion.contains(pointLocation) && _itemPresent) {
135 		_itemPresent = false;
136 		_staticData.navFrameIndex = _clearFrameIndex;
137 
138 		if (_itemFlagOffset >= 0)
139 			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 1);
140 
141 		// Call inventory drag start function
142 		Common::Point ptInventoryWindow = viewWindow->convertPointToGlobal(pointLocation);
143 		ptInventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->convertPointToLocal(ptInventoryWindow);
144 		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(_itemID, ptInventoryWindow);
145 
146 		// Update the biochips
147 		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
148 
149 		return SC_TRUE;
150 	}
151 
152 	return SC_FALSE;
153 }
154 
droppedItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)155 int GenericItemAcquire::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
156 	if (pointLocation.x == -1 && pointLocation.y == -1)
157 		return SIC_REJECT;
158 
159 	if (itemID == _itemID && !_itemPresent) {
160 		// Redraw the background
161 		_itemPresent = true;
162 		_staticData.navFrameIndex = _fullFrameIndex;
163 
164 		if (_itemFlagOffset >= 0)
165 			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 0);
166 
167 		viewWindow->invalidateWindow();
168 
169 		// Update the biochips
170 		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
171 
172 		return SIC_ACCEPT;
173 	}
174 
175 	return SIC_REJECT;
176 }
177 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)178 int GenericItemAcquire::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
179 	if (_acquireRegion.contains(pointLocation) && _itemPresent)
180 		return kCursorOpenHand;
181 
182 	return kCursorArrow;
183 }
184 
PlaySoundExitingFromScene(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int soundFileNameID)185 PlaySoundExitingFromScene::PlaySoundExitingFromScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
186 		int soundFileNameID) :
187 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
188 	_soundFileNameID = soundFileNameID;
189 }
190 
postExitRoom(Window * viewWindow,const Location & newLocation)191 int PlaySoundExitingFromScene::postExitRoom(Window *viewWindow, const Location &newLocation) {
192 	if (_soundFileNameID >= 0 && _staticData.location.depth != newLocation.depth && _staticData.location.timeZone == newLocation.timeZone)
193 		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _soundFileNameID), 128, false, true);
194 
195 	return SC_TRUE;
196 }
197 
PlaySoundExitingFromSceneDeux(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int soundFileNameID)198 PlaySoundExitingFromSceneDeux::PlaySoundExitingFromSceneDeux(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
199 		int soundFileNameID) :
200 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
201 	_soundFileNameID = soundFileNameID;
202 }
203 
postExitRoom(Window * viewWindow,const Location & newLocation)204 int PlaySoundExitingFromSceneDeux::postExitRoom(Window *viewWindow, const Location &newLocation) {
205 	if (_soundFileNameID >= 0 && _staticData.location.node == newLocation.node && _staticData.location.timeZone == newLocation.timeZone)
206 		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _soundFileNameID), 128, false, true);
207 
208 	return SC_TRUE;
209 }
210 
PlaySoundEnteringScene(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int soundFileNameID,int flagOffset)211 PlaySoundEnteringScene::PlaySoundEnteringScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
212 		int soundFileNameID, int flagOffset) :
213 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
214 	_soundFileNameID = soundFileNameID;
215 	_flagOffset = flagOffset;
216 }
217 
postEnterRoom(Window * viewWindow,const Location & priorLocation)218 int PlaySoundEnteringScene::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
219 	if (_flagOffset >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_flagOffset) == 0) {
220 		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _soundFileNameID));
221 		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
222 	}
223 
224 	return SC_TRUE;
225 }
226 
ClickChangeScene(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int left,int top,int right,int bottom,int cursorID,int timeZone,int environment,int node,int facing,int orientation,int depth,int transitionType,int transitionData,int transitionStartFrame,int transitionLength)227 ClickChangeScene::ClickChangeScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
228 		int left, int top, int right, int bottom, int cursorID,
229 		int timeZone, int environment, int node, int facing, int orientation, int depth,
230 		int transitionType, int transitionData, int transitionStartFrame, int transitionLength) :
231 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
232 	_clickRegion = Common::Rect(left, top, right, bottom);
233 	_cursorID = cursorID;
234 
235 	_clickDestination.destinationScene.timeZone = timeZone;
236 	_clickDestination.destinationScene.environment = environment;
237 	_clickDestination.destinationScene.node = node;
238 	_clickDestination.destinationScene.facing = facing;
239 	_clickDestination.destinationScene.orientation = orientation;
240 	_clickDestination.destinationScene.depth = depth;
241 	_clickDestination.transitionType = transitionType;
242 	_clickDestination.transitionData = transitionData;
243 	_clickDestination.transitionStartFrame = transitionStartFrame;
244 	_clickDestination.transitionLength = transitionLength;
245 }
246 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)247 int ClickChangeScene::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
248 	if (_clickRegion.contains(pointLocation))
249 		((SceneViewWindow *)viewWindow)->moveToDestination(_clickDestination);
250 
251 	return SC_FALSE;
252 }
253 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)254 int ClickChangeScene::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
255 	if (_clickRegion.contains(pointLocation))
256 		return _cursorID;
257 
258 	return kCursorArrow;
259 }
260 
261 
ClickPlayVideoSwitchAI(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int animID,int cursorID,int flagOffset,int left,int top,int right,int bottom)262 ClickPlayVideoSwitchAI::ClickPlayVideoSwitchAI(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
263 		int animID, int cursorID, int flagOffset, int left, int top, int right, int bottom) :
264 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
265 	_cursorID = cursorID;
266 	_animID = animID;
267 	_clickRegion = Common::Rect(left, top, right, bottom);
268 	_flagOffset = flagOffset;
269 }
270 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)271 int ClickPlayVideoSwitchAI::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
272 	if (_clickRegion.contains(pointLocation)) {
273 		// Play the animation clip
274 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animID);
275 		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
276 
277 		// Play any spontaneous AI comments
278 		if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI)) {
279 			((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
280 			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
281 		}
282 
283 		return SC_TRUE;
284 	}
285 
286 	return SC_FALSE;
287 }
288 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)289 int ClickPlayVideoSwitchAI::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
290 	if (_clickRegion.contains(pointLocation))
291 		return _cursorID;
292 
293 	return kCursorArrow;
294 }
295 
ClickChangeSceneSetFlag(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int left,int top,int right,int bottom,int cursorID,int timeZone,int environment,int node,int facing,int orientation,int depth,int transitionType,int transitionData,int transitionStartFrame,int transitionLength,int flagIndex)296 ClickChangeSceneSetFlag::ClickChangeSceneSetFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
297 		int left, int top, int right, int bottom, int cursorID,
298 		int timeZone, int environment, int node, int facing, int orientation, int depth,
299 		int transitionType, int transitionData, int transitionStartFrame, int transitionLength, int flagIndex) :
300 		ClickChangeScene(vm, viewWindow, sceneStaticData, priorLocation, left, top, right, bottom, cursorID, timeZone, environment, node, facing, orientation, depth,
301 			transitionType, transitionData, transitionStartFrame, transitionLength) {
302 	if (flagIndex >= 0)
303 		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(flagIndex, 1);
304 }
305 
PlayStingers(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int stingerVolume,int lastStingerFlagOffset,int effectIDFlagOffset,int firstStingerFileID,int lastStingerFileID)306 PlayStingers::PlayStingers(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
307 		int stingerVolume, int lastStingerFlagOffset, int effectIDFlagOffset, int firstStingerFileID, int lastStingerFileID) :
308 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
309 	_stingerVolume = stingerVolume;
310 	_lastStingerFlagOffset = lastStingerFlagOffset;
311 	_effectIDFlagOffset = effectIDFlagOffset;
312 	_firstStingerFileID = firstStingerFileID;
313 	_lastStingerFileID = lastStingerFileID;
314 }
315 
postEnterRoom(Window * viewWindow,const Location & priorLocation)316 int PlayStingers::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
317 	if (_effectIDFlagOffset >= 0) {
318 		// More evil.
319 		byte effectID = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_effectIDFlagOffset);
320 
321 		if (!_vm->_sound->isSoundEffectPlaying(effectID - 1)) {
322 			byte lastStinger = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_lastStingerFlagOffset);
323 			lastStinger++;
324 
325 			uint32 fileNameIndex = _vm->computeFileNameResourceID(_staticData.location.timeZone, _staticData.location.environment, _firstStingerFileID + lastStinger - 1);
326 			byte newStingerID = _vm->_sound->playSoundEffect(_vm->getFilePath(fileNameIndex), _stingerVolume, false, true) + 1;
327 
328 			if (lastStinger > _lastStingerFileID - _firstStingerFileID)
329 				lastStinger = 0;
330 
331 			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_effectIDFlagOffset, newStingerID);
332 			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_lastStingerFlagOffset, lastStinger);
333 		}
334 	}
335 
336 	return SC_TRUE;
337 }
338 
ClickPlaySound(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int flagOffset,int soundID,int cursorID,int left,int top,int right,int bottom)339 ClickPlaySound::ClickPlaySound(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
340 		int flagOffset, int soundID, int cursorID, int left, int top, int right, int bottom) :
341 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
342 	_cursorID = cursorID;
343 	_soundID = soundID;
344 	_clickRegion = Common::Rect(left, top, right, bottom);
345 	_flagOffset = flagOffset;
346 }
347 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)348 int ClickPlaySound::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
349 	if (_clickRegion.contains(pointLocation)) {
350 		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _soundID), 127, false, true);
351 
352 		if (_flagOffset >= 0)
353 			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
354 
355 		if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
356 			((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
357 
358 		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
359 		return SC_TRUE;
360 	}
361 
362 	return SC_FALSE;
363 }
364 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)365 int ClickPlaySound::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
366 	if (_clickRegion.contains(pointLocation))
367 		return _cursorID;
368 
369 	return kCursorArrow;
370 }
371 
ClickZoom(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int animInID,int stillInID,int animOutID,int stillOutID,int cursorID,int left,int top,int right,int bottom)372 ClickZoom::ClickZoom(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
373 		int animInID, int stillInID, int animOutID, int stillOutID,
374 		int cursorID, int left, int top, int right, int bottom) :
375 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
376 	_cursorID = cursorID;
377 	_animInID = animInID;
378 	_stillInID = stillInID;
379 	_animOutID = animOutID;
380 	_stillOutID = stillOutID;
381 	_zoomedIn = false;
382 	_clickRegion = Common::Rect(left, top, right, bottom);
383 	_savedNavData = _staticData;
384 }
385 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)386 int ClickZoom::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
387 	if (_zoomedIn) {
388 		_staticData.navFrameIndex = _stillOutID;
389 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animOutID);
390 		_zoomedIn = false;
391 		_staticData = _savedNavData;
392 		((GameUIWindow *)viewWindow->getParent())->_navArrowWindow->updateAllArrows(_staticData);
393 		return SC_TRUE;
394 	} else if (_clickRegion.contains(pointLocation)) {
395 		_staticData.navFrameIndex = _stillInID;
396 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animInID);
397 		_zoomedIn = true;
398 		_staticData.destUp.destinationScene = Location(-1, -1, -1, -1, -1, -1);
399 		_staticData.destLeft.destinationScene = Location(-1, -1, -1, -1, -1, -1);
400 		_staticData.destRight.destinationScene = Location(-1, -1, -1, -1, -1, -1);
401 		_staticData.destDown.destinationScene = Location(-1, -1, -1, -1, -1, -1);
402 		_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
403 		((GameUIWindow *)viewWindow->getParent())->_navArrowWindow->updateAllArrows(_staticData);
404 		return SC_TRUE;
405 	}
406 
407 	return SC_FALSE;
408 }
409 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)410 int ClickZoom::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
411 	if (_zoomedIn)
412 		return kCursorPutDown;
413 
414 	if (_clickRegion.contains(pointLocation))
415 		return _cursorID;
416 
417 	return kCursorArrow;
418 }
419 
PlaySoundEnteringFromScene(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int soundFileNameID,int timeZone,int environment,int node,int facing,int orientation,int depth)420 PlaySoundEnteringFromScene::PlaySoundEnteringFromScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
421 		int soundFileNameID, int timeZone, int environment, int node, int facing, int orientation, int depth) :
422 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
423 	_soundFileNameID = soundFileNameID;
424 	_soundLocation.timeZone = timeZone;
425 	_soundLocation.environment = environment;
426 	_soundLocation.node = node;
427 	_soundLocation.facing = facing;
428 	_soundLocation.orientation = orientation;
429 	_soundLocation.depth = depth;
430 }
431 
postEnterRoom(Window * viewWindow,const Location & priorLocation)432 int PlaySoundEnteringFromScene::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
433 	if (_soundLocation.timeZone == priorLocation.timeZone &&
434 			_soundLocation.environment == priorLocation.environment &&
435 			_soundLocation.node == priorLocation.node &&
436 			_soundLocation.facing == priorLocation.facing &&
437 			_soundLocation.orientation == priorLocation.orientation &&
438 			_soundLocation.depth == priorLocation.depth) {
439 		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _soundFileNameID), 127, false, true);
440 	}
441 
442 	return SC_TRUE;
443 }
444 
SetFlagOnEntry(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int flagOffset,byte flagNewValue)445 SetFlagOnEntry::SetFlagOnEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
446 		int flagOffset, byte flagNewValue) :
447 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
448 	if (flagOffset >= 0)
449 		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(flagOffset, flagNewValue);
450 }
451 
InteractiveNewsNetwork(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int enterTransition,int timeZone,int environment,int node,int facing,int orientation,int depth,int transitionType,int transitionData,int transitionStartFrame,int transitionLength)452 InteractiveNewsNetwork::InteractiveNewsNetwork(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
453 		int enterTransition, int timeZone, int environment, int node, int facing, int orientation, int depth,
454 		int transitionType, int transitionData, int transitionStartFrame, int transitionLength) :
455 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
456 	// Close the cycle/still movies
457 	((SceneViewWindow *)viewWindow)->changeStillFrameMovie("");
458 	((SceneViewWindow *)viewWindow)->changeCycleFrameMovie("");
459 
460 	_currentMovieFrame = 0;
461 	_returnDestination.destinationScene.timeZone = timeZone;
462 	_returnDestination.destinationScene.environment = environment;
463 	_returnDestination.destinationScene.node = node;
464 	_returnDestination.destinationScene.facing = facing;
465 	_returnDestination.destinationScene.orientation = orientation;
466 	_returnDestination.destinationScene.depth = depth;
467 	_returnDestination.transitionType = transitionType;
468 	_returnDestination.transitionData = transitionData;
469 	_returnDestination.transitionStartFrame = transitionStartFrame;
470 	_returnDestination.transitionLength = transitionLength;
471 	_playingMovie = false;
472 	_loopingMovie = false;
473 	_playingAudio = false;
474 	_enterTransition = enterTransition;
475 	_audioChannel = -1;
476 
477 	loadFrameDatabase();
478 	loadMovieDatabase();
479 
480 	if (!_stillFrames.open(_vm->getFilePath(IDS_INN_STILL_FRAME_FILENAME)))
481 		error("Failed to open INN still frames");
482 }
483 
~InteractiveNewsNetwork()484 InteractiveNewsNetwork::~InteractiveNewsNetwork() {
485 	// Restart sound
486 	_vm->_sound->restart();
487 }
488 
postEnterRoom(Window * viewWindow,const Location & priorLocation)489 int InteractiveNewsNetwork::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
490 	// Play any entry animation
491 	if (_enterTransition >= 0)
492 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_enterTransition);
493 
494 	// Stop the ambient sound
495 	_vm->_sound->setAmbientSound();
496 
497 	// Play the intro movie
498 	_playingMovie = ((SceneViewWindow *)viewWindow)->playSynchronousAnimationExtern(IDS_INN_MEDIA_FILENAME_BASE);
499 	_currentMovieFrame = 1;
500 
501 	// Start the INN ambient
502 	_vm->_sound->setAmbientSound(_vm->getFilePath(IDS_INN_AMBIENT_FILENAME));
503 	return SC_TRUE;
504 }
505 
preExitRoom(Window * viewWindow,const Location & newLocation)506 int InteractiveNewsNetwork::preExitRoom(Window *viewWindow, const Location &newLocation) {
507 	// Stop a playing movie
508 	if (_playingMovie) {
509 		((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
510 		_playingMovie = false;
511 		_loopingMovie = false;
512 		_vm->_sound->restart();
513 	}
514 
515 	// Stop audio
516 	if (_playingAudio && _audioChannel != -1) {
517 		_vm->_sound->stopSoundEffect(_audioChannel);
518 		_audioChannel = -1;
519 		_playingAudio = false;
520 	}
521 
522 	// Stop the INN ambient
523 	_vm->_sound->setAmbientSound();
524 
525 	// Start the environment ambient
526 	((SceneViewWindow *)viewWindow)->startEnvironmentAmbient(-1, -1, _staticData.location.timeZone, _staticData.location.environment);
527 
528 	return SC_TRUE;
529 }
530 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)531 int InteractiveNewsNetwork::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
532 	int oldMovieFrame = _currentMovieFrame;
533 
534 	if (_currentMovieFrame > (int)_frameDatabase.size())
535 		return SC_FALSE;
536 
537 	const INNFrame &currentData = _frameDatabase[_currentMovieFrame];
538 
539 	for (int i = 0; i < 8; i++) {
540 		const INNHotspotData &hotspotData = currentData.hotspots[i];
541 
542 		if (hotspotData.stillFrameOffset >= 0 || hotspotData.stillFrameOffset == -2) {
543 			Common::Rect currentRegion(hotspotData.left, hotspotData.top, hotspotData.right, hotspotData.bottom);
544 
545 			if (currentRegion.contains(pointLocation)) {
546 				if (hotspotData.stillFrameOffset == -2) {
547 					// Return from a hyperlink
548 					if (!_hyperLinkHistory.empty()) {
549 						_currentMovieFrame = _hyperLinkHistory.back();
550 						_hyperLinkHistory.pop_back();
551 					}
552 				} else {
553 					// Check if we clicked on a hyperlink
554 					int newMovieFrame = hotspotData.stillFrameOffset - 1;
555 
556 					if (i < 5 && newMovieFrame > 58 && newMovieFrame < 157)
557 						_hyperLinkHistory.push_back(_currentMovieFrame);
558 
559 					_currentMovieFrame = newMovieFrame;
560 				}
561 
562 				// Check for the exit frame
563 				if (_currentMovieFrame == 157) {
564 					((SceneViewWindow *)viewWindow)->moveToDestination(_returnDestination);
565 					return SC_TRUE;
566 				}
567 
568 				// If we are in Agent 3's lair, and we clicked on the symbiotry talks, change the destination
569 				if (_staticData.location.timeZone == 3 && _currentMovieFrame == 8 && oldMovieFrame != 7) {
570 					_currentMovieFrame = 7;
571 					((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchINNUpdate = 1;
572 				}
573 
574 				// If we are playing a video, make sure it's stipped
575 				if (_playingMovie) {
576 					((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
577 					_playingMovie = false;
578 					_loopingMovie = false;
579 				}
580 
581 				if (_playingAudio && _audioChannel != -1) {
582 					_vm->_sound->stopSoundEffect(_audioChannel);
583 					_audioChannel = -1;
584 					_playingAudio = false;
585 				}
586 
587 				// Repaint
588 				viewWindow->invalidateWindow();
589 
590 				// Start playing any video clip
591 				const INNFrame &newFrame = _frameDatabase[_currentMovieFrame];
592 
593 				// No full screen video -> restart the sound
594 				if (newFrame.pageType != MEDIA_TYPE_VIDEO_FULL)
595 					_vm->_sound->restart();
596 
597 				if (newFrame.pageType > 0) {
598 					for (uint j = 0; j < _movieDatabase.size(); j++) {
599 						const INNMediaElement &mediaCurrentData = _movieDatabase[j];
600 
601 						if (mediaCurrentData.frameIndex == _currentMovieFrame) {
602 							switch (mediaCurrentData.mediaType) {
603 							case MEDIA_TYPE_VIDEO_FULL:
604 								// Check for a commercial, play the sponsor clip
605 								if (_currentMovieFrame >= 2 && _currentMovieFrame <= 4)
606 									_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(IDS_INN_MEDIA_FILENAME_BASE + 39));
607 
608 
609 								_vm->_sound->stop();
610 								_playingMovie = ((SceneViewWindow *)viewWindow)->startAsynchronousAnimationExtern(IDS_INN_MEDIA_FILENAME_BASE + mediaCurrentData.fileIDOffset, -1, -1, -1, false);
611 								_loopingMovie = false;
612 								break;
613 							case MEDIA_TYPE_VIDEO_SMALL_A:
614 								_playingMovie = ((SceneViewWindow *)viewWindow)->startPlacedAsynchronousAnimationExtern(275, 16, 120, 120, IDS_INN_MEDIA_FILENAME_BASE + mediaCurrentData.fileIDOffset, -1, -1, -1, true);
615 								_loopingMovie = true;
616 								break;
617 							case MEDIA_TYPE_VIDEO_SMALL_B:
618 								_playingMovie = ((SceneViewWindow *)viewWindow)->startPlacedAsynchronousAnimationExtern(255, 16, 159, 120, IDS_INN_MEDIA_FILENAME_BASE + mediaCurrentData.fileIDOffset, -1, -1, -1, true);
619 								_loopingMovie = true;
620 								break;
621 							case MEDIA_TYPE_AUDIO:
622 								_playingAudio = true;
623 								_audioChannel = _vm->_sound->playSoundEffect(_vm->getFilePath(IDS_INN_MEDIA_FILENAME_BASE + mediaCurrentData.fileIDOffset));
624 								break;
625 							}
626 						}
627 					}
628 				}
629 
630 				// Check for scoring frames
631 				switch (_currentMovieFrame) {
632 				case 20:
633 					((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchINNHighBidder = 1;
634 					break;
635 				case 25:
636 					((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchINNAppeal = 1;
637 					break;
638 				case 109:
639 					((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchINNJumpsuit = 1;
640 					break;
641 				case 159: // Read global_flags.h to see why I hate this
642 					((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchINNLouvreReport = 1;
643 					break;
644 				}
645 
646 				return SC_TRUE;
647 			}
648 		}
649 	}
650 
651 	return SC_FALSE;
652 }
653 
paint(Window * viewWindow,Graphics::Surface * preBuffer)654 int InteractiveNewsNetwork::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
655 	const Graphics::Surface *stillFrame = _stillFrames.getFrame(_currentMovieFrame);
656 
657 	if (stillFrame)
658 		_vm->_gfx->crossBlit(preBuffer, 0, 0, 432, 189, stillFrame, 0, 0);
659 
660 	return SC_REPAINT;
661 }
662 
movieCallback(Window * viewWindow,VideoWindow * movie,int animationID,int status)663 int InteractiveNewsNetwork::movieCallback(Window *viewWindow, VideoWindow *movie, int animationID, int status) {
664 	// Restart sound if the movie has ended
665 	if (animationID == -1 && status == MOVIE_STOPPED) {
666 		_vm->_sound->restart();
667 		return SC_FALSE;
668 	}
669 
670 	return SC_TRUE;
671 }
672 
timerCallback(Window * viewWindow)673 int InteractiveNewsNetwork::timerCallback(Window *viewWindow) {
674 	// Check to see if audio has stopped
675 	if (_playingAudio && _audioChannel != -1 && !_vm->_sound->isSoundEffectPlaying(_audioChannel)) {
676 		_audioChannel = -1;
677 		_playingAudio = false;
678 	}
679 
680 	return SC_TRUE;
681 }
682 
loadFrameDatabase()683 void InteractiveNewsNetwork::loadFrameDatabase() {
684 	Common::SeekableReadStream *frameData = _vm->getINNData(IDBD_INN_BINARY_DATA);
685 
686 	if (!frameData)
687 		error("Failed to find INN frame database");
688 
689 	uint16 count = frameData->readUint16LE();
690 	_frameDatabase.resize(count);
691 
692 	for (uint16 i = 0; i < count; i++) {
693 		 INNFrame &frame = _frameDatabase[i];
694 		 frame.topicID = frameData->readSint16LE();
695 		 frame.pageType = frameData->readSint16LE();
696 		 frame.stillFrameOffset = frameData->readSint32LE();
697 
698 		for (int j = 0; j < 8; j++) {
699 			frame.hotspots[j].left = frameData->readSint16LE();
700 			frame.hotspots[j].top = frameData->readSint16LE();
701 			frame.hotspots[j].right = frameData->readSint16LE();
702 			frame.hotspots[j].bottom = frameData->readSint16LE();
703 			frame.hotspots[j].stillFrameOffset = frameData->readSint32LE();
704 		}
705 	}
706 
707 	delete frameData;
708 }
709 
loadMovieDatabase()710 void InteractiveNewsNetwork::loadMovieDatabase() {
711 	Common::SeekableReadStream *movieData = _vm->getINNData(IDBD_INN_MEDIA_BINARY_DATA);
712 
713 	if (!movieData)
714 		error("Failed to find INN movie database");
715 
716 	uint16 count = movieData->readUint16LE();
717 	_movieDatabase.resize(count);
718 
719 	for (uint16 i = 0; i < count; i++) {
720 		INNMediaElement &element = _movieDatabase[i];
721 		element.frameIndex = movieData->readSint32LE();
722 		element.mediaType = movieData->readSint16LE();
723 		element.fileIDOffset = movieData->readSint16LE();
724 	}
725 
726 	delete movieData;
727 }
728 
DisplayMessageWithEvidenceWhenEnteringNode(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int evidenceID,int messageBoxTextID)729 DisplayMessageWithEvidenceWhenEnteringNode::DisplayMessageWithEvidenceWhenEnteringNode(BuriedEngine *vm, Window *viewWindow,
730 			const LocationStaticData &sceneStaticData, const Location &priorLocation, int evidenceID, int messageBoxTextID) :
731 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
732 	_evidenceID = evidenceID;
733 	_messageBoxTextID = messageBoxTextID;
734 }
735 
postEnterRoom(Window * viewWindow,const Location & priorLocation)736 int DisplayMessageWithEvidenceWhenEnteringNode::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
737 	if ((_staticData.location.timeZone != priorLocation.timeZone ||
738 			_staticData.location.environment != priorLocation.environment ||
739 			_staticData.location.node != priorLocation.node ||
740 			_staticData.location.facing != priorLocation.facing ||
741 			_staticData.location.orientation != priorLocation.orientation ||
742 			_staticData.location.depth != priorLocation.depth) &&
743 			!((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), _evidenceID)) {
744 		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(_messageBoxTextID));
745 	}
746 
747 	return SC_TRUE;
748 }
749 
ClickPlayLoopingVideoClip(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int cursorID,int animID,int left,int top,int right,int bottom,int flagOffset,int newFlagValue)750 ClickPlayLoopingVideoClip::ClickPlayLoopingVideoClip(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
751 		int cursorID, int animID, int left, int top, int right, int bottom, int flagOffset, int newFlagValue) :
752 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
753 	_cursorID = cursorID;
754 	_animID = animID;
755 	_clickRegion = Common::Rect(left, top, right, bottom);
756 	_flagOffset = flagOffset;
757 	_flagValue = newFlagValue;
758 	_playing = false;
759 }
760 
preExitRoom(Window * viewWindow,const Location & newLocation)761 int ClickPlayLoopingVideoClip::preExitRoom(Window *viewWindow, const Location &newLocation) {
762 	if (_playing) {
763 		((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
764 		_vm->_sound->restart();
765 		_playing = false;
766 
767 		if (_flagOffset >= 0 && _flagValue >= 0)
768 			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, _flagValue);
769 	}
770 
771 	return SC_TRUE;
772 }
773 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)774 int ClickPlayLoopingVideoClip::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
775 	if (_clickRegion.contains(pointLocation)) {
776 		if (_playing) {
777 			// Stop the clip
778 			((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
779 			_playing = false;
780 			_vm->_sound->restart();
781 
782 			// Change the flag
783 			if (_flagOffset >= 0 && _flagValue >= 0)
784 				((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, _flagValue);
785 
786 			// Check for spontaneous AI comments
787 			if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
788 				((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
789 
790 			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
791 			return SC_TRUE;
792 		} else {
793 			// Start playing asynchronously
794 			_vm->_sound->stop();
795 			_playing = ((SceneViewWindow *)viewWindow)->startAsynchronousAnimation(_animID, true);
796 			return SC_TRUE;
797 		}
798 	}
799 
800 	return SC_FALSE;
801 }
802 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)803 int ClickPlayLoopingVideoClip::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
804 	if (_clickRegion.contains(pointLocation))
805 		return _cursorID;
806 
807 	return kCursorArrow;
808 }
809 
OneShotEntryVideoWarning(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int animID,int flagOffset,int warningMessageID)810 OneShotEntryVideoWarning::OneShotEntryVideoWarning(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
811 		int animID, int flagOffset, int warningMessageID) : SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
812 	_animID = animID;
813 	_flagOffset = flagOffset;
814 	_warningMessageID = warningMessageID;
815 }
816 
postEnterRoom(Window * viewWindow,const Location & priorLocation)817 int OneShotEntryVideoWarning::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
818 	if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_flagOffset) == 0) {
819 		if (_warningMessageID >= 0)
820 			((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(_warningMessageID));
821 
822 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animID);
823 		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
824 	}
825 
826 	return SC_TRUE;
827 }
828 
DisableForwardMovement(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int flagOffset,int flagValue)829 DisableForwardMovement::DisableForwardMovement(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
830 		int flagOffset, int flagValue) :
831 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
832 	if (flagOffset >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(flagOffset) == flagValue)
833 		_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
834 }
835 
CycleEntryVideoWarning(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int animIDA,int animIDB,int flagOffset,int warningMessageID)836 CycleEntryVideoWarning::CycleEntryVideoWarning(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
837 		int animIDA, int animIDB, int flagOffset, int warningMessageID) : SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
838 	_animIDA = animIDA;
839 	_animIDB = animIDB;
840 	_flagOffset = flagOffset;
841 	_warningMessageID = warningMessageID;
842 }
843 
postEnterRoom(Window * viewWindow,const Location & priorLocation)844 int CycleEntryVideoWarning::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
845 	if (_warningMessageID >= 0)
846 		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(_warningMessageID));
847 
848 	if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_flagOffset) == 0) {
849 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animIDA);
850 		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
851 	} else {
852 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animIDB);
853 		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 0);
854 	}
855 
856 	return SC_TRUE;
857 }
858 
ClickPlayVideoSwitch(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int animID,int cursorID,int flagOffset,int left,int top,int right,int bottom)859 ClickPlayVideoSwitch::ClickPlayVideoSwitch(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
860 		int animID, int cursorID, int flagOffset, int left, int top, int right, int bottom) :
861 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
862 	_cursorID = cursorID;
863 	_animID = animID;
864 	_clickRegion = Common::Rect(left, top, right, bottom);
865 	_flagOffset = flagOffset;
866 }
867 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)868 int ClickPlayVideoSwitch::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
869 	if (_clickRegion.contains(pointLocation)) {
870 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animID);
871 
872 		if (_flagOffset >= 0) {
873 			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
874 
875 			if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
876 				((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
877 
878 			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
879 		}
880 
881 		return SC_TRUE;
882 	}
883 
884 	return SC_FALSE;
885 }
886 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)887 int ClickPlayVideoSwitch::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
888 	if (_clickRegion.contains(pointLocation))
889 		return _cursorID;
890 
891 	return kCursorArrow;
892 }
893 
ClickPlayVideo(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int animID,int cursorID,int left,int top,int right,int bottom)894 ClickPlayVideo::ClickPlayVideo(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
895 		int animID, int cursorID, int left, int top, int right, int bottom)
896 		: SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
897 
898 	_cursorID = cursorID;
899 	_animID = animID;
900 	_clickRegion = Common::Rect(left, top, right, bottom);
901 }
902 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)903 int ClickPlayVideo::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
904 	if (_clickRegion.contains(pointLocation)) {
905 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animID);
906 		return SC_TRUE;
907 	}
908 
909 	return SC_FALSE;
910 }
911 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)912 int ClickPlayVideo::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
913 	if (_clickRegion.contains(pointLocation))
914 		return _cursorID;
915 
916 	return kCursorArrow;
917 }
918 
VideoDeath(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int deathID,int messageTextID)919 VideoDeath::VideoDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation, int deathID, int messageTextID) :
920 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation), _deathID(deathID), _messageTextID(messageTextID) {
921 }
922 
postEnterRoom(Window * viewWindow,const Location & priorLocation)923 int VideoDeath::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
924 	if (_messageTextID >= -1)
925 		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(_messageTextID));
926 
927 	return SC_TRUE;
928 }
929 
postExitRoom(Window * viewWindow,const Location & newLocation)930 int VideoDeath::postExitRoom(Window *viewWindow, const Location &newLocation) {
931 	if (newLocation.timeZone == _staticData.location.timeZone &&
932 			newLocation.environment == _staticData.location.environment &&
933 			newLocation.node == _staticData.location.node &&
934 			newLocation.facing == _staticData.location.facing &&
935 			newLocation.orientation == _staticData.location.orientation &&
936 			newLocation.depth == _staticData.location.depth) {
937 		// Notify the player of his gruesome death
938 		((SceneViewWindow *)viewWindow)->showDeathScene(_deathID);
939 		return SC_DEATH;
940 	}
941 
942 	return SC_TRUE;
943 }
944 
ClickChangeDepth(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int newDepth,int cursorID,int left,int top,int right,int bottom)945 ClickChangeDepth::ClickChangeDepth(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
946 		int newDepth, int cursorID, int left, int top, int right, int bottom) :
947 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
948 	_newDepth = newDepth;
949 	_cursorID = cursorID;
950 	_clickableRegion = Common::Rect(left, top, right, bottom);
951 }
952 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)953 int ClickChangeDepth::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
954 	if (_clickableRegion.contains(pointLocation)) {
955 		DestinationScene clickDestination;
956 		clickDestination.destinationScene = _staticData.location;
957 		clickDestination.destinationScene.depth = _newDepth;
958 		clickDestination.transitionType = TRANSITION_FADE;
959 		clickDestination.transitionData = -1;
960 		clickDestination.transitionStartFrame = -1;
961 		clickDestination.transitionLength = -1;
962 		((SceneViewWindow *)viewWindow)->moveToDestination(clickDestination);
963 	}
964 
965 	return SC_TRUE;
966 }
967 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)968 int ClickChangeDepth::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
969 	if (_clickableRegion.contains(pointLocation))
970 		return _cursorID;
971 
972 	return kCursorArrow;
973 }
974 
OpenFirstItemAcquire(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int openLeft,int openTop,int openRight,int openBottom,int getLeft,int getTop,int getRight,int getBottom,int animOpenWith,int animOpenWithout,int itemID,int fullStillFrame,int clearStillFrame,int itemFlagOffset)975 OpenFirstItemAcquire::OpenFirstItemAcquire(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
976 		int openLeft, int openTop, int openRight, int openBottom, int getLeft, int getTop, int getRight,
977 		int getBottom, int animOpenWith, int animOpenWithout, int itemID, int fullStillFrame, int clearStillFrame,
978 		int itemFlagOffset):
979 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
980 	_open = false;
981 	_itemPresent = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(itemFlagOffset) == 0;
982 	_openClickRegion = Common::Rect(openLeft, openTop, openRight, openBottom);
983 	_acquireRegion = Common::Rect(getLeft, getTop, getRight, getBottom);
984 	_fullFrameIndex = fullStillFrame;
985 	_clearFrameIndex = clearStillFrame;
986 	_itemID = itemID;
987 	_itemFlagOffset = itemFlagOffset;
988 	_animOpenWith = animOpenWith;
989 	_animOpenWithout = animOpenWithout;
990 }
991 
mouseDown(Window * viewWindow,const Common::Point & pointLocation)992 int OpenFirstItemAcquire::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
993 	if (_acquireRegion.contains(pointLocation) && _itemPresent && _open) {
994 		_itemPresent = false;
995 		_staticData.navFrameIndex = _clearFrameIndex;
996 
997 		if (_itemFlagOffset >= 0)
998 			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 1);
999 
1000 		// Call inventory drag start function
1001 		Common::Point ptInventoryWindow = viewWindow->convertPointToGlobal(pointLocation);
1002 		ptInventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->convertPointToLocal(ptInventoryWindow);
1003 		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(_itemID, ptInventoryWindow);
1004 
1005 		return SC_TRUE;
1006 	}
1007 
1008 	return SC_FALSE;
1009 }
1010 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)1011 int OpenFirstItemAcquire::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
1012 	if (_openClickRegion.contains(pointLocation) && !_open) {
1013 		_open = true;
1014 
1015 		if (_itemPresent) {
1016 			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animOpenWith);
1017 			_staticData.navFrameIndex = _fullFrameIndex;
1018 		} else {
1019 			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animOpenWithout);
1020 			_staticData.navFrameIndex = _clearFrameIndex;
1021 		}
1022 
1023 		return SC_TRUE;
1024 	}
1025 
1026 	return SC_FALSE;
1027 }
1028 
droppedItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)1029 int OpenFirstItemAcquire::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
1030 	if (_itemID == itemID && !_itemPresent && _open && pointLocation.x != -1 && pointLocation.y != -1) {
1031 		_itemPresent = true;
1032 		_staticData.navFrameIndex = _fullFrameIndex;
1033 
1034 		if (_itemFlagOffset >= 0)
1035 			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 0);
1036 
1037 		viewWindow->invalidateWindow(false);
1038 		return SIC_ACCEPT;
1039 	}
1040 
1041 	return SIC_REJECT;
1042 }
1043 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)1044 int OpenFirstItemAcquire::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
1045 	if (_openClickRegion.contains(pointLocation) && !_open)
1046 		return kCursorFinger;
1047 
1048 	if (_acquireRegion.contains(pointLocation) && _itemPresent && _open)
1049 		return kCursorOpenHand;
1050 
1051 	return kCursorArrow;
1052 }
1053 
BrowseBook(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int bookResID,int textStartResID,int startingPageID,int timeZone,int environment,int node,int facing,int orientation,int depth,int transitionType,int transitionData,int transitionStartFrame,int transitionLength)1054 BrowseBook::BrowseBook(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
1055 		int bookResID, int textStartResID, int startingPageID, int timeZone, int environment,
1056 		int node, int facing, int orientation, int depth, int transitionType, int transitionData,
1057 		int transitionStartFrame, int transitionLength) :
1058 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1059 	_putDownDestination.destinationScene.timeZone = timeZone;
1060 	_putDownDestination.destinationScene.environment = environment;
1061 	_putDownDestination.destinationScene.node = node;
1062 	_putDownDestination.destinationScene.facing = facing;
1063 	_putDownDestination.destinationScene.orientation = orientation;
1064 	_putDownDestination.destinationScene.depth = depth;
1065 	_putDownDestination.transitionType = transitionType;
1066 	_putDownDestination.transitionData = transitionData;
1067 	_putDownDestination.transitionStartFrame = transitionStartFrame;
1068 	_putDownDestination.transitionLength = transitionLength;
1069 
1070 	Common::SeekableReadStream *pageData = _vm->getBookData(bookResID);
1071 	if (!pageData)
1072 		error("Failed to find book resource %d", bookResID);
1073 
1074 	uint16 pageCount = pageData->readUint16LE();
1075 
1076 	for (uint16 i = 0; i < pageCount; i++) {
1077 		BookPage page;
1078 		page.pageID = pageData->readSint16LE();
1079 		page.pageFrameIndex = pageData->readSint32LE();
1080 		page.numLines = pageData->readSint16LE();
1081 		page.up.typeOfTrans = pageData->readSint16LE();
1082 		page.up.destPage = pageData->readSint16LE();
1083 		page.left.typeOfTrans = pageData->readSint16LE();
1084 		page.left.destPage = pageData->readSint16LE();
1085 		page.right.typeOfTrans = pageData->readSint16LE();
1086 		page.right.destPage = pageData->readSint16LE();
1087 		page.down.typeOfTrans = pageData->readSint16LE();
1088 		page.down.destPage = pageData->readSint16LE();
1089 		_bookDatabase.push_back(page);
1090 	}
1091 
1092 	delete pageData;
1093 
1094 	_curPage = _bookDatabase[startingPageID].pageID;
1095 	_staticData.navFrameIndex = _bookDatabase[startingPageID].pageFrameIndex;
1096 	_curLineIndex = -1;
1097 	_translatedTextResourceID = textStartResID;
1098 
1099 	_top = Common::Rect(150, 0, 282, 70);
1100 	_bottom = Common::Rect(150, 119, 282, 189);
1101 	_left = Common::Rect(0, 0, 150, 189);
1102 	_right = Common::Rect(282, 0, 432, 189);
1103 	_putDown = Common::Rect(150, 70, 282, 119);
1104 
1105 	// Mark that we read the journals in the King's Study
1106 	if (_staticData.location.timeZone == 1 && _staticData.location.environment == 8)
1107 		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgKSReadJournal = 1;
1108 }
1109 
gdiPaint(Window * viewWindow)1110 int BrowseBook::gdiPaint(Window *viewWindow) {
1111 	if (_curLineIndex >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
1112 		int lineCount = _bookDatabase[_curPage].numLines;
1113 		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
1114 		Common::Rect rect(1, (187 / lineCount) * _curLineIndex, 430, (187 / lineCount) * (_curLineIndex + 1) - 1);
1115 		rect.translate(absoluteRect.left, absoluteRect.top);
1116 		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
1117 	}
1118 
1119 	return SC_REPAINT;
1120 }
1121 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)1122 int BrowseBook::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
1123 	const BookPage &pageData = _bookDatabase[_curPage];
1124 
1125 	if (_top.contains(pointLocation) && pageData.up.destPage >= 0) {
1126 		// Change the still
1127 		_curPage = pageData.up.destPage;
1128 		_staticData.navFrameIndex = _bookDatabase[_curPage].pageFrameIndex;
1129 
1130 		// Perform the transition
1131 		Graphics::Surface *newBackground = ((SceneViewWindow *)viewWindow)->getStillFrameCopy(_staticData.navFrameIndex);
1132 		((SceneViewWindow *)viewWindow)->pushNewTransition(newBackground, 0, _vm->_gfx->computeVPushOffset(_vm->getTransitionSpeed()), 0);
1133 		newBackground->free();
1134 		delete newBackground;
1135 		_curLineIndex = -1;
1136 		viewWindow->invalidateWindow(false);
1137 		pageChanged(viewWindow);
1138 		return SC_TRUE;
1139 	} else if (_bottom.contains(pointLocation) && pageData.down.destPage >= 0) {
1140 		// Change the still
1141 		_curPage = pageData.down.destPage;
1142 		_staticData.navFrameIndex = _bookDatabase[_curPage].pageFrameIndex;
1143 
1144 		// Perform the transition
1145 		Graphics::Surface *newBackground = ((SceneViewWindow *)viewWindow)->getStillFrameCopy(_staticData.navFrameIndex);
1146 		((SceneViewWindow *)viewWindow)->pushNewTransition(newBackground, 3, _vm->_gfx->computeVPushOffset(_vm->getTransitionSpeed()), 0);
1147 		newBackground->free();
1148 		delete newBackground;
1149 		_curLineIndex = -1;
1150 		viewWindow->invalidateWindow(false);
1151 		pageChanged(viewWindow);
1152 		return SC_TRUE;
1153 	} else if (_left.contains(pointLocation) && pageData.left.destPage >= 0) {
1154 		// Change the still
1155 		_curPage = pageData.left.destPage;
1156 		_staticData.navFrameIndex = _bookDatabase[_curPage].pageFrameIndex;
1157 
1158 		// Perform the transition
1159 		Graphics::Surface *newBackground = ((SceneViewWindow *)viewWindow)->getStillFrameCopy(_staticData.navFrameIndex);
1160 		((SceneViewWindow *)viewWindow)->pushNewTransition(newBackground, 1, _vm->_gfx->computeHPushOffset(_vm->getTransitionSpeed()), 0);
1161 		newBackground->free();
1162 		delete newBackground;
1163 		_curLineIndex = -1;
1164 		viewWindow->invalidateWindow(false);
1165 		pageChanged(viewWindow);
1166 		return SC_TRUE;
1167 	} else if (_right.contains(pointLocation) && pageData.right.destPage >= 0) {
1168 		// Change the still
1169 		_curPage = pageData.right.destPage;
1170 		_staticData.navFrameIndex = _bookDatabase[_curPage].pageFrameIndex;
1171 
1172 		// Perform the transition
1173 		Graphics::Surface *newBackground = ((SceneViewWindow *)viewWindow)->getStillFrameCopy(_staticData.navFrameIndex);
1174 		((SceneViewWindow *)viewWindow)->pushNewTransition(newBackground, 1, _vm->_gfx->computeHPushOffset(_vm->getTransitionSpeed()), 0);
1175 		newBackground->free();
1176 		delete newBackground;
1177 		_curLineIndex = -1;
1178 		viewWindow->invalidateWindow(false);
1179 		pageChanged(viewWindow);
1180 		return SC_TRUE;
1181 	} else if (_putDown.contains(pointLocation) && _putDownDestination.destinationScene.timeZone >= 0) {
1182 		// Move to the new destination
1183 		((SceneViewWindow *)viewWindow)->moveToDestination(_putDownDestination);
1184 		return SC_TRUE;
1185 	}
1186 
1187 	return SC_FALSE;
1188 }
1189 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)1190 int BrowseBook::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
1191 	const BookPage &pageData = _bookDatabase[_curPage];
1192 
1193 	if (_top.contains(pointLocation) && pageData.up.destPage >= 0)
1194 		return kCursorMoveUp;
1195 	else if (_bottom.contains(pointLocation) && pageData.down.destPage >= 0)
1196 		return kCursorMoveDown;
1197 	else if (_left.contains(pointLocation) && pageData.left.destPage >= 0)
1198 		return kCursorPrevPage;
1199 	else if (_right.contains(pointLocation) && pageData.right.destPage >= 0)
1200 		return kCursorNextPage;
1201 	else if (_putDown.contains(pointLocation) && _putDownDestination.destinationScene.timeZone >= 0)
1202 		return kCursorPutDown;
1203 
1204 	return kCursorArrow;
1205 }
1206 
mouseMove(Window * viewWindow,const Common::Point & pointLocation)1207 int BrowseBook::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
1208 	if (_translatedTextResourceID >= 0) {
1209 		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
1210 			int lineCount = _bookDatabase[_curPage].numLines;
1211 
1212 			int textLineNumber = 0;
1213 			for (int i = 0; i < _curPage; i++)
1214 				textLineNumber += _bookDatabase[i].numLines;
1215 
1216 			// Determine the line index of the cursor
1217 			int lineIndex = (pointLocation.y - 2) / (187 / lineCount);
1218 			if (lineIndex > lineCount - 1)
1219 				lineIndex = lineCount - 1;
1220 
1221 			if (_curLineIndex != lineIndex) {
1222 				_curLineIndex = lineIndex;
1223 				viewWindow->invalidateWindow(false);
1224 
1225 				Common::String translatedText = _vm->getString(_translatedTextResourceID + textLineNumber + _curLineIndex);
1226 				((SceneViewWindow *)viewWindow)->displayTranslationText(translatedText);
1227 				textTranslated(viewWindow);
1228 			}
1229 
1230 			return SC_TRUE;
1231 		}
1232 
1233 		if (_curLineIndex != -1) {
1234 			_curLineIndex = -1;
1235 			viewWindow->invalidateWindow(false);
1236 		}
1237 	}
1238 
1239 	return SC_FALSE;
1240 }
1241 
pageChanged(Window * viewWindow)1242 int BrowseBook::pageChanged(Window *viewWindow) {
1243 	if (_translatedTextResourceID == IDBD_DIARY2_TRANS_TEXT_BASE && _curPage >= 7 && _curPage <= 10)
1244 		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgKSSmithyEntryRead = 1;
1245 
1246 	return SC_TRUE;
1247 }
1248 
textTranslated(Window * viewWindow)1249 int BrowseBook::textTranslated(Window *viewWindow) {
1250 	if (_translatedTextResourceID == IDBD_DIARY2_TRANS_TEXT_BASE && _curPage >= 7 && _curPage <= 10)
1251 		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgKSSmithyEntryTranslated = 1;
1252 
1253 	return SC_TRUE;
1254 }
1255 
ClickPlaySoundSynchronous(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int flagOffset,int soundID,int cursorID,int left,int top,int right,int bottom)1256 ClickPlaySoundSynchronous::ClickPlaySoundSynchronous(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
1257 		int flagOffset, int soundID, int cursorID, int left, int top, int right, int bottom) :
1258 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1259 	_cursorID = cursorID;
1260 	_soundID = soundID;
1261 	_clickRegion = Common::Rect(left, top, right, bottom);
1262 	_flagOffset = flagOffset;
1263 }
1264 
mouseUp(Window * viewWindow,const Common::Point & pointLocation)1265 int ClickPlaySoundSynchronous::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
1266 	if (_clickRegion.contains(pointLocation)) {
1267 		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _soundID), 127);
1268 
1269 		if (_flagOffset >= 0)
1270 			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
1271 
1272 		if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
1273 			((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
1274 
1275 		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
1276 		return SC_TRUE;
1277 	}
1278 
1279 	return SC_FALSE;
1280 }
1281 
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)1282 int ClickPlaySoundSynchronous::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
1283 	if (_clickRegion.contains(pointLocation))
1284 		return _cursorID;
1285 
1286 	return kCursorArrow;
1287 }
1288 
TrialRecallScene(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)1289 TrialRecallScene::TrialRecallScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
1290 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1291 	// Disable all movement
1292 	_staticData.destUp.destinationScene = Location(-1, -1, -1, -1, -1, -1);
1293 	_staticData.destLeft.destinationScene = Location(-1, -1, -1, -1, -1, -1);
1294 	_staticData.destRight.destinationScene = Location(-1, -1, -1, -1, -1, -1);
1295 	_staticData.destDown.destinationScene = Location(-1, -1, -1, -1, -1, -1);
1296 	_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
1297 }
1298 
postEnterRoom(Window * viewWindow,const Location & priorLocation)1299 int TrialRecallScene::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
1300 	// Display the message
1301 	static const char *const message =
1302 		"This timezone is not available in this Trial Version.  "
1303 		"Call (800) 943-3664 to purchase the complete version of Buried in Time.\n"
1304 		"Initiating Auto-Recall to Future Apartment...";
1305 	((SceneViewWindow *)viewWindow)->displayLiveText(message, false);
1306 
1307 	// Wait about 10 seconds
1308 	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
1309 	uint32 start = g_system->getMillis();
1310 	while (g_system->getMillis() - start < 10000)
1311 		_vm->yield();
1312 	_vm->_gfx->setCursor(oldCursor);
1313 
1314 	// Force a recall
1315 	((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->changeCurrentBioChip(kItemBioChipJump);
1316 	((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sendMessage(new LButtonUpMessage(Common::Point(50, 150), 0));
1317 
1318 	return SC_TRUE;
1319 }
1320 
1321 } // End of namespace Buried
1322